Related
I just started working on opengl in qt, using texture i am displaying image in quard.
then i set gltexture wrap mode to gl_repeat but its not repeating.
I tried even gl_clamp_to_edge still its not working.
images size 256*256
code:
GLuint _textureId; //The id of the texture
int _wdth;
int _hight;
void LoadGLTextures( const char * name )
{
QImage img;
if(!img.load(name)){
qDebug() << "ERROR in loading image";
}
QImage t = QGLWidget::convertToGLFormat(img);
_wdth = t.width();
_hight = t.height();
qDebug()<<"width = "<<_wdth<<"height ="<<_hight;
glGenTextures(1, &_textureId);
glBindTexture(GL_TEXTURE_2D, _textureId);
glTexImage2D(GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits());
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
}
void GLWin::initializeGL()
{
qglColor(Qt::black);
glEnable(GL_CULL_FACE);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_MULTISAMPLE);
static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
///cameraPos = 0;
glEnable(GL_TEXTURE_2D);
LoadGLTextures("resources/Green_Dragon.jpeg");
}
void GLWin::paintGL()
{
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f);
glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glColor3f(0.5, 0.5, 0);
glBindTexture(GL_TEXTURE_2D, _textureId);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(-0.5f, -0.5f); // vertex 1
glTexCoord2f(1.0f, 0.0f); glVertex2f(0.5f, -0.5f); // vertex 2
glTexCoord2f(1.0f, 1.0f); glVertex2f(0.5f, 0.5f); // vertex 3
glTexCoord2f(0.0f, 1.0f); glVertex2f(-0.5f, 0.5f); // vertex 4
glEnd();
glDisable(GL_TEXTURE_2D);
glFlush();
}
void GLWin::resizeGL(int width, int height)
{
glViewport(0, 0, (GLint)width, (GLint)height);
glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix
glLoadIdentity();
glOrtho(-0.5, 0.5, -0.5, 0.5, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
glTexCoord2f(0.0f, 0.0f); glVertex2f(-0.5f, -0.5f); // vertex 1
glTexCoord2f(1.0f, 0.0f); glVertex2f(0.5f, -0.5f); // vertex 2
glTexCoord2f(1.0f, 1.0f); glVertex2f(0.5f, 0.5f); // vertex 3
glTexCoord2f(0.0f, 1.0f); glVertex2f(-0.5f, 0.5f); // vertex 4
If those are your texture coordinates, then it's not going to repeat. Texture wrap modes only apply when the texture coordinate exceeds the [0, 1] range. Since your texture coordinates are within that range, no repeating will happen.
You see scaling of the texture because you are scaling the positions of the triangles. And therefore, the texture will be mapped in accord with those scaled positions.
You could use the texture matrix to do some transformations on the texture coordinates if you want to scale them.
I'm having trouble getting my texture to map to a quad using OpenGL and Qt. I've looked at several other SO threads, but a lot of the function calls have to be used slightly differently for me to compile (Qt Verison 4.8.6). Here's my relevant code, right now all that happens is a window is displayed with a black background, but nothing else.
void LoadGLTextures( const char * name )
{
QImage img;
if(!img.load("resources/Green_Dragon.bmp")){
std::cerr << "ERROR in loading image" << std::endl;
}
QImage t = QGLWidget::convertToGLFormat(img);
glGenTextures(1, &texture[0]);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits());
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glBindTexture( GL_TEXTURE_2D, 0 );
}
void GLWidget::initializeGL()
{
qglClearColor(qtBlack.dark());
glEnable(GL_CULL_FACE);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_MULTISAMPLE);
static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
cameraPos = 0;
glEnable(GL_TEXTURE_2D);
LoadGLTextures("resources/Green_Dragon.jpeg");
}
void GLWidget::paintGL()
{
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f);
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glShadeModel( GL_FLAT );
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glColor3f(0.5, 0.5, 0);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f); glVertex2f(-0.5f, 0.5f); // vertex 1
glTexCoord2f(0.0f, 0.0f); glVertex2f(-0.5f, -0.5f); // vertex 2
glTexCoord2f(1.0f, 0.0f); glVertex2f(0.5f, -0.5f); // vertex 3
glTexCoord2f(1.0f, 1.0f); glVertex2f(0.5f, 0.5f); // vertex 4
glEnd();
glDisable(GL_TEXTURE_2D);
glFlush();
}
Looking at your comment, the answer is fairly clear now, sorry that I missed it in the question comments.
You are seeing a black screen because you are enabling depth testing, but you are not clearing the depth buffer between frames. Therefore, the previous frame's depth buffer values remain in place, and the depth tests fail for all subsequent frames (note that the default depth function is GL_LESS).
You may leave depth testing enabled. The correct solution is to clear your depth buffer in addition to your color buffer before each render. You have:
glClear( GL_COLOR_BUFFER_BIT );
But you need:
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
See also: glClear()
Removing glEnable(GL_DEPTH_TEST) solved this for me, in case anyone runs into a similar problem.
I am trying to learn about using OpenGL with the 4th edition of OpenGL Super Bible, but whenever I try to copy one of the example codes in Visual Studio 2010, I get a "Open_GL.exe -System Error: The program can't start because libGLESv2.dll is missing from your computer".
I do have this .dll somewhere on my computer, but don't know how to make it available towards VS. The pre-built binaries on the site do work however.
The code I used, for reference:
// Block.cpp
// OpenGL SuperBible, Chapter 1
// Demonstrates an assortment of basic 3D concepts
// Program by Richard S. Wright Jr.
#include "../../shared/gltools.h" // OpenGL toolkit
#include "../../shared/math3d.h"
#include <math.h>
// Keep track of effects step
int nStep = 0;
// Lighting data
GLfloat lightAmbient[] = { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat lightDiffuse[] = { 0.7f, 0.7f, 0.7f, 1.0f };
GLfloat lightSpecular[] = { 0.9f, 0.9f, 0.9f };
GLfloat materialColor[] = { 0.8f, 0.0f, 0.0f };
GLfloat vLightPos[] = { -80.0f, 120.0f, 100.0f, 0.0f };
GLfloat ground[3][3] = { { 0.0f, -25.0f, 0.0f },
{ 10.0f, -25.0f, 0.0f },
{ 10.0f, -25.0f, -10.0f } };
GLuint textures[4];
// Called to draw scene
void RenderScene(void)
{
M3DMatrix44f mCubeTransform;
M3DVector4f pPlane;
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glShadeModel(GL_SMOOTH);
glEnable(GL_NORMALIZE);
glPushMatrix();
// Draw plane that the cube rests on
glDisable(GL_LIGHTING);
if(nStep == 5)
{
glColor3ub(255,255,255);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-100.0f, -25.3f, -100.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-100.0f, -25.3f, 100.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(100.0f, -25.3f, 100.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(100.0f, -25.3f, -100.0f);
glEnd();
}
else
{
glColor3f(0.0f, 0.0f, 0.90f); // Blue
glBegin(GL_QUADS);
glVertex3f(-100.0f, -25.3f, -100.0f);
glVertex3f(-100.0f, -25.3f, 100.0f);
glVertex3f(100.0f, -25.3f, 100.0f);
glVertex3f(100.0f, -25.3f, -100.0f);
glEnd();
}
// Set drawing color to Red
glColor3f(1.0f, 0.0f, 0.0f);
// Enable, disable lighting
if(nStep > 2)
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_COLOR_MATERIAL);
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glMaterialfv(GL_FRONT, GL_SPECULAR,lightSpecular);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materialColor);
glMateriali(GL_FRONT, GL_SHININESS,128);
}
// Move the cube slightly forward and to the left
glTranslatef(-10.0f, 0.0f, 10.0f);
switch(nStep)
{
// Just draw the wire framed cube
case 0:
glutWireCube(50.0f);
break;
// Same wire cube with hidden line removal simulated
case 1:
// Front Face (before rotation)
glBegin(GL_LINES);
glVertex3f(25.0f,25.0f,25.0f);
glVertex3f(25.0f,-25.0f,25.0f);
glVertex3f(25.0f,-25.0f,25.0f);
glVertex3f(-25.0f,-25.0f,25.0f);
glVertex3f(-25.0f,-25.0f,25.0f);
glVertex3f(-25.0f,25.0f,25.0f);
glVertex3f(-25.0f,25.0f,25.0f);
glVertex3f(25.0f,25.0f,25.0f);
glEnd();
// Top of cube
glBegin(GL_LINES);
// Front Face
glVertex3f(25.0f,25.0f,25.0f);
glVertex3f(25.0f,25.0f,-25.0f);
glVertex3f(25.0f,25.0f,-25.0f);
glVertex3f(-25.0f,25.0f,-25.0f);
glVertex3f(-25.0f,25.0f,-25.0f);
glVertex3f(-25.0f,25.0f,25.0f);
glVertex3f(-25.0f,25.0f,25.0f);
glVertex3f(25.0f,25.0f,25.0f);
glEnd();
// Last two segments for effect
glBegin(GL_LINES);
glVertex3f(25.0f,25.0f,-25.0f);
glVertex3f(25.0f,-25.0f,-25.0f);
glVertex3f(25.0f,-25.0f,-25.0f);
glVertex3f(25.0f,-25.0f,25.0f);
glEnd();
break;
// Uniform colored surface, looks 2D and goofey
case 2:
glutSolidCube(50.0f);
break;
case 3:
glutSolidCube(50.0f);
break;
// Draw a shadow with some lighting
case 4:
glGetFloatv(GL_MODELVIEW_MATRIX, mCubeTransform);
glutSolidCube(50.0f);
glPopMatrix();
// Disable lighting, we'll just draw the shadow as black
glDisable(GL_LIGHTING);
glPushMatrix();
m3dGetPlaneEquation(pPlane, ground[0], ground[1], ground[2]);
m3dMakePlanarShadowMatrix(mCubeTransform, pPlane, vLightPos);
//MakeShadowMatrix(ground, lightpos, cubeXform);
glMultMatrixf(mCubeTransform);
glTranslatef(-10.0f, 0.0f, 10.0f);
// Set drawing color to Black
glColor3f(0.0f, 0.0f, 0.0f);
glutSolidCube(50.0f);
break;
case 5:
glColor3ub(255,255,255);
glGetFloatv(GL_MODELVIEW_MATRIX, mCubeTransform);
// Front Face (before rotation)
glBindTexture(GL_TEXTURE_2D, textures[1]);
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(25.0f,25.0f,25.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(25.0f,-25.0f,25.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-25.0f,-25.0f,25.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-25.0f,25.0f,25.0f);
glEnd();
// Top of cube
glBindTexture(GL_TEXTURE_2D, textures[2]);
glBegin(GL_QUADS);
// Front Face
glTexCoord2f(0.0f, 0.0f);
glVertex3f(25.0f,25.0f,25.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(25.0f,25.0f,-25.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-25.0f,25.0f,-25.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-25.0f,25.0f,25.0f);
glEnd();
// Last two segments for effect
glBindTexture(GL_TEXTURE_2D, textures[3]);
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(25.0f,25.0f,-25.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(25.0f,-25.0f,-25.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(25.0f,-25.0f,25.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(25.0f,25.0f,25.0f);
glEnd();
glPopMatrix();
// Disable lighting, we'll just draw the shadow as black
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glPushMatrix();
m3dGetPlaneEquation(pPlane, ground[0], ground[1], ground[2]);
m3dMakePlanarShadowMatrix(mCubeTransform, pPlane, vLightPos);
glMultMatrixf(mCubeTransform);
glTranslatef(-10.0f, 0.0f, 10.0f);
// Set drawing color to Black
glColor3f(0.0f, 0.0f, 0.0f);
glutSolidCube(50.0f);
break;
}
glPopMatrix();
// Flush drawing commands
glutSwapBuffers();
}
// This function does any needed initialization on the rendering
// context.
void SetupRC()
{
GLbyte *pBytes;
GLint nWidth, nHeight, nComponents;
GLenum format;
// Black background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_MODULATE);
glGenTextures(4, textures);
// Load the texture objects
pBytes = gltLoadTGA("floor.tga", &nWidth, &nHeight, &nComponents, &format);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D,0,nComponents,nWidth, nHeight, 0,
format, GL_UNSIGNED_BYTE, pBytes);
free(pBytes);
pBytes = gltLoadTGA("Block4.tga", &nWidth, &nHeight, &nComponents, &format);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D,0,nComponents,nWidth, nHeight, 0,
format, GL_UNSIGNED_BYTE, pBytes);
free(pBytes);
pBytes = gltLoadTGA("block5.tga", &nWidth, &nHeight, &nComponents, &format);
glBindTexture(GL_TEXTURE_2D, textures[2]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D,0,nComponents,nWidth, nHeight, 0,
format, GL_UNSIGNED_BYTE, pBytes);
free(pBytes);
pBytes = gltLoadTGA("block6.tga", &nWidth, &nHeight, &nComponents, &format);
glBindTexture(GL_TEXTURE_2D, textures[3]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D,0,nComponents,nWidth, nHeight, 0,
format, GL_UNSIGNED_BYTE, pBytes);
free(pBytes);
}
void KeyPressFunc(unsigned char key, int x, int y)
{
if(key == 32)
{
nStep++;
if(nStep > 5)
nStep = 0;
}
// Refresh the Window
glutPostRedisplay();
}
void ChangeSize(int w, int h)
{
// Calculate new clipping volume
GLfloat windowWidth;
GLfloat windowHeight;
// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == 0)
h = 1;
// Keep the square square
if (w <= h)
{
windowHeight = 100.0f*(GLfloat)h/(GLfloat)w;
windowWidth = 100.0f;
}
else
{
windowWidth = 100.0f*(GLfloat)w/(GLfloat)h;
windowHeight = 100.0f;
}
// Set the viewport to be the entire window
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set the clipping volume
glOrtho(-100.0f, windowWidth, -100.0f, windowHeight, -200.0f, 200.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLightfv(GL_LIGHT0,GL_POSITION, vLightPos);
glRotatef(30.0f, 1.0f, 0.0f, 0.0f);
glRotatef(330.0f, 0.0f, 1.0f, 0.0f);
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("3D Effects Demo");
glutReshapeFunc(ChangeSize);
glutKeyboardFunc(KeyPressFunc);
glutDisplayFunc(RenderScene);
SetupRC();
glutMainLoop();
glDeleteTextures(4,textures);
return 0;
}
I do have this .dll somewhere on my computer
libGLESv2.dll sounds suspiciously like an implementation of OpenGL ES 2.0. Which will not execute your code, since your code is written for desktop OpenGL.
In short, you are linking to the wrong library. On Windows, you should be linking to OpenGL32.lib.
I'm trying to draw a few simple 3D rectangular prisms, but glBindTexture does not seem to be working properly.
I have N number of "pieces", each with a material name.
I am looping through each piece, finding its texture based on its material name, calling glBindTexture, then drawing the piece.
It seems though, if i have multiple pieces with the same material name, only the first is drawn with a texture, and the rest are just white.
Any help would be greatly appreciated.
Here is the code:
OpenGL initialisation:
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32, // bit depth
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16, // z-buffer depth
0, 0, 0, 0, 0, 0, 0,
};
GLfloat light_pos1[] = {0.0f, 0.0f, 15.0f, 1.0f};
GLfloat light_ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};
// Get device context only once.
hdc = GetDC()->m_hDC;
// Pixel format.
m_nPixelFormat = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, m_nPixelFormat, &pfd);
// Create the OpenGL Rendering Context.
hrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc);
//texture
glEnable(GL_TEXTURE_2D);
//Setup:
glClearColor(0.5f, 0.5f, 0.5f, 0.0f);
glClearDepth(1.0f);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
//lighting
glLightfv(GL_LIGHT0, GL_POSITION, light_pos1);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
// Send draw request
OnDraw(NULL);
texture loading
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, t.texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 256, 256, GL_RGB, GL_UNSIGNED_BYTE, data);
Then the drawing code:
glPolygonMode(GL_FRONT_AND_BACK, GL_FLAT);
for(int i = 0; i < mPieces.GetCount(); i++)
{
C3DPiece p = mPieces.GetAt(mPieces.FindIndex(i));
if(p.visible)
{
//GetTextureForMaterial finds the texture id based on the "piece"'s material name
//have checked this and it is always returning a valid id (>0)
GLuint tex = GetTextureForMaterial(p.material);
glBindTexture(GL_TEXTURE_2D, tex);
glBegin(GL_QUADS);
glNormal3f(..., ..., ...);
glTextCoord2f(..., ...);
glVertex3F(..., ..., ...);
glTextCoord2f(..., ...);
glVertex3F(..., ..., ...);
glTextCoord2f(..., ...);
glVertex3F(..., ..., ...);
glTextCoord2f(..., ...);
glVertex3F(..., ..., ...);
glEnd();
}
}
There's no such thing like OpenGL initialization (apart from setting up a context). All what you do to in the "initialization" code either belongs in the render function or texture loading code:
All the following semantically belongs into the render path. OpenGL is a state machine, and like all state machines you put it into a proper start condition before you're doing some job.
//texture
glEnable(GL_TEXTURE_2D);
//Setup:
glClearColor(0.5f, 0.5f, 0.5f, 0.0f);
glClearDepth(1.0f);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
//lighting
glLightfv(GL_LIGHT0, GL_POSITION, light_pos1);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
In your texture loader you have this:
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, t.texture);
Either this is a typo, or the generated texture name doesn't make it into 't.' texture.
I think i have fixed it.
Seems there was an actual problem with the texture file (.RAW images) and it was displaying as white instead of the colour/pattern it should have.
I tested again with a smaller amount of materials (3 instead of 3663) and it seems to work OK.
I created 4 textures and attach them to FBO, named fbo_texture0 - fbo_texture3. All of them are successfully created, as given by the following screenshot:
image 1
Now, i wanted to create the 5th texture which is obtained from the previous textures (fbo_texture0 - fbo_texture3) using GLSL. For now, i just want to copy the first texture into the fifth texture. Unfortunately, here is what i got:
image 2
The question is:
How can i access these fbo textures in GLSL?
How can i create the 5th texture? (or copy from the first texture to the fifth texture?)
Here's the complete code of the program (in case needed):
#include <windows.h>
#include <GL/glew.h> // Include the GLEW header file
#include <GL/glut.h> // Include the GLUT header file
#include <iostream> // Allow us to print to the console
using namespace std;
bool* keyStates = new bool[256]; // Create an array of boolean values of length 256 (0-255)
unsigned int fbo; // The frame buffer object
unsigned int fbo_depth; // The depth buffer for the frame buffer object
unsigned int fbo_texture0; // The texture object to write our frame buffer object to
unsigned int fbo_texture1;
unsigned int fbo_texture2;
unsigned int fbo_texture3;
unsigned int fbo_texture4;
GLhandleARB shaderProgram;
GLhandleARB vertexShader;
GLhandleARB fragmentShader;
int window_width = 500; // The width of our window
int window_height = 500; // The height of our window
void initFrameBufferDepthBuffer(void) {
glGenRenderbuffers(1, &fbo_depth); // Generate one render buffer and store the ID in fbo_depth
glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth); // Bind the fbo_depth render buffer
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, window_width, window_height); // Set the render buffer storage to be a depth component, with a width and height of the window
glBindRenderbuffer(GL_RENDERBUFFER, 0); // Unbind the render buffer
}
void initFrameBufferTextures(void) {
glGenTextures(1, &fbo_texture0); // Generate one ture
glBindTexture(GL_TEXTURE_2D, fbo_texture0); // Bind the ture fbo_texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window_width, window_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Create a standard ture with the width and height of our window
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
glGenTextures(1, &fbo_texture1); // Generate one ture
glBindTexture(GL_TEXTURE_2D, fbo_texture1); // Bind the ture fbo_texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window_width, window_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Create a standard ture with the width and height of our window
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
glGenTextures(1, &fbo_texture2); // Generate one ture
glBindTexture(GL_TEXTURE_2D, fbo_texture2); // Bind the ture fbo_texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window_width, window_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Create a standard ture with the width and height of our window
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
glGenTextures(1, &fbo_texture3); // Generate one ture
glBindTexture(GL_TEXTURE_2D, fbo_texture3); // Bind the ture fbo_texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window_width, window_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Create a standard ture with the width and height of our window
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
glGenTextures(1, &fbo_texture4); // Generate one ture
glBindTexture(GL_TEXTURE_2D, fbo_texture4); // Bind the ture fbo_texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window_width, window_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Create a standard ture with the width and height of our window
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
}
void printInfoLog(GLhandleARB obj)
{
int infologLength = 0;
int charsWritten = 0;
char* infoLog;
glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength);
if (infologLength > 0)
{
infoLog = (char*)malloc(infologLength);
glGetInfoLogARB(obj, infologLength, &charsWritten, infoLog);
printf("%s\n",infoLog);
free(infoLog);
}
}
void initFrameBuffer(void) {
initFrameBufferDepthBuffer(); // Initialize our frame buffer depth buffer
initFrameBufferTextures(); // Initialize our frame buffer ture
glGenFramebuffers(1, &fbo); // Generate one frame buffer and store the ID in fbo
glBindFramebuffer(GL_FRAMEBUFFER, fbo); // Bind our frame buffer
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_texture0, 0);// Attach the ture fbo_texturen to the color buffer in our frame buffer
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, fbo_texture1, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, fbo_texture2, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, fbo_texture3, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, fbo_texture4, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth); // Attach the depth buffer fbo_depth to our frame buffer
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); // Check that status of our generated frame buffer
if (status != GL_FRAMEBUFFER_COMPLETE) // If the frame buffer does not report back as complete
{
cout << "Couldn't create frame buffer" << endl; // Output an error to the console
exit(0); // Exit the application
}
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind our frame buffer
}
void init(void) {
//glEnable(GL_TEXTURE_2D); // Enable turing so we can bind our frame buffer ture
glEnable(GL_DEPTH_TEST); // Enable depth testing
initFrameBuffer(); // Create our frame buffer object
}
void keyOperations (void) {
if (keyStates['a']) { // If the a key has been pressed
// Perform 'a' key operations
}
}
void renderTextures(void) {
glBindFramebuffer(GL_FRAMEBUFFER, fbo); // Bind our frame buffer for rendering
glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); // Push our glEnable and glViewport states
glViewport(0, 0, window_width, window_height); // Set the size of the frame buffer view port
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set the clear colour
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Clear the depth and colour buffers
glLoadIdentity();// Reset the modelview matrix
glTranslatef(0.0f, 0.0f, -5.0f);
//Add ambient light
GLfloat ambientColor[] = {0.2f, 0.2f, 0.2f, 1.0f}; //Color(0.2, 0.2, 0.2)
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);
//Add positioned light
GLfloat lightColor0[] = {0.5f, 0.5f, 0.5f, 1.0f}; //Color (0.5, 0.5, 0.5)
GLfloat lightPos0[] = {4.0f, 0.0f, 8.0f, 1.0f}; //Positioned at (4, 0, 8)
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);
//Add directed light
GLfloat lightColor1[] = {0.5f, 0.2f, 0.2f, 1.0f}; //Color (0.5, 0.2, 0.2)
//Coming from the direction (-1, 0.5, 0.5)
GLfloat lightPos1[] = {-1.0f, 0.5f, 0.5f, 0.0f};
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor1);
glLightfv(GL_LIGHT1, GL_POSITION, lightPos1);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_DEPTH_TEST);
glutSolidTeapot(2.0);
glColor3f(0.1,0.2,0.7);
glDrawBuffer(GL_COLOR_ATTACHMENT1);
glClearColor(0.5f, 0.5f, 0.0f, 1.0f); // Set the clear colour
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Clear the depth and colour buffers
glLoadIdentity();// Reset the modelview matrix
glTranslatef(0.0f, 0.0f, -5.0f);
glutSolidTorus(0.80, 1.6, 50, 100);
glColorMaterial ( GL_FRONT_AND_BACK, GL_EMISSION ) ;
glEnable ( GL_COLOR_MATERIAL ) ;
glDrawBuffer(GL_COLOR_ATTACHMENT2);
glClearColor(0.5f, 0.0f, 0.0f, 1.0f); // Set the clear colour
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Clear the depth and colour buffers
glLoadIdentity();// Reset the modelview matrix
glTranslatef(0.0f, 0.0f, -2.0f);
glutSolidTetrahedron();
glColorMaterial ( GL_FRONT_AND_BACK, GL_EMISSION ) ;
glEnable ( GL_COLOR_MATERIAL ) ;
glDrawBuffer(GL_COLOR_ATTACHMENT3);
glClearColor(0.5f, 0.0f, 0.3f, 1.0f); // Set the clear colour
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Clear the depth and colour buffers
glLoadIdentity();// Reset the modelview matrix
glTranslatef(0.0f, 0.0f, -2.0f);
glutSolidOctahedron();
glColorMaterial ( GL_FRONT_AND_BACK, GL_EMISSION ) ;
glEnable ( GL_COLOR_MATERIAL ) ;
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind our ture
glActiveTexture(GL_TEXTURE0);
//glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, fbo_texture0);
glUniform1i(glGetUniformLocation(shaderProgram, "tex0"), 0);
glActiveTexture(GL_TEXTURE1);
//glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, fbo_texture1);
glUniform1i(glGetUniformLocation(shaderProgram, "tex1"), 1);
glActiveTexture(GL_TEXTURE2);
//glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, fbo_texture2);
glUniform1i(glGetUniformLocation(shaderProgram, "tex2"), 2);
glActiveTexture(GL_TEXTURE3);
//glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, fbo_texture3);
glUniform1i(glGetUniformLocation(shaderProgram, "tex3"), 3);
glPopAttrib(); // Restore our glEnable and glViewport states
glutSwapBuffers();
}
static char* textFileRead(const char *fileName) {
char* text;
if (fileName != NULL) {
FILE *file = fopen(fileName, "rt");
if (file != NULL) {
fseek(file, 0, SEEK_END);
int count = ftell(file);
rewind(file);
if (count > 0) {
text = (char*)malloc(sizeof(char) * (count + 1));
count = fread(text, sizeof(char), count, file);
text[count] = '\0';
}
fclose(file);
}
}
return text;
}
void initShader(){
char* vsSource = textFileRead("./shader/multitexture.vs");
char* fsSource = textFileRead("./shader/multitexture.fs");
printf("%s\n",fsSource);
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, (const GLchar **)(&vsSource), NULL);
glCompileShader(vertexShader);
printInfoLog(vertexShader);
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, (const GLchar **)(&fsSource), NULL);
glCompileShader(fragmentShader);
printInfoLog(fragmentShader);
delete [] vsSource;
delete [] fsSource;
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
}
void display (void) {
keyOperations(); // Perform any key presses
glUseProgram(0);
renderTextures(); // Render our teapot scene into our frame buffer
GLsync s = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glUseProgram(shaderProgram);
glClearColor(0.0f, 1.0f, 0.0f, 1.0f); // Clear the background of our window to red
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear the colour buffer (more buffers later on)
glLoadIdentity(); // Load the Identity Matrix to reset our drawing locations
glTranslatef(-4.7f, 1.0f, -4.0f);
glWaitSync(s, 0, GL_TIMEOUT_IGNORED);
glDeleteSync(s);
glBindTexture(GL_TEXTURE_2D, fbo_texture0); // Bind our frame buffer ture
glBegin(GL_QUADS);
glColor4f(1, 1, 1, 1);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 0.0f); // The top left corner
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f); // The top right corner
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f); // The bottom right corner
glEnd();
glBindTexture(GL_TEXTURE_2D, 0); // Unbind any tures
glLoadIdentity();
glTranslatef(-2.5f, 1.0f, -4.0f);
glBindTexture(GL_TEXTURE_2D, fbo_texture1); // Bind our frame buffer ture
glBegin(GL_QUADS);
glColor4f(1, 1, 1, 1);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 0.0f); // The top left corner
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f); // The top right corner
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f); // The bottom right corner
glEnd();
glBindTexture(GL_TEXTURE_2D, 0); // Unbind any tures
glLoadIdentity();
glTranslatef(-0.3f, 1.0f, -4.0f);
glBindTexture(GL_TEXTURE_2D, fbo_texture2); // Bind our frame buffer ture
glBegin(GL_QUADS);
glColor4f(1, 1, 1, 1);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 0.0f); // The top left corner
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f); // The top right corner
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f); // The bottom right corner
glEnd();
glBindTexture(GL_TEXTURE_2D, 0); // Unbind any tures
glLoadIdentity();
glTranslatef(1.9f, 1.0f, -4.0f);
glBindTexture(GL_TEXTURE_2D, fbo_texture3); // Bind our frame buffer ture
glBegin(GL_QUADS);
glColor4f(1, 1, 1, 1);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 0.0f); // The top left corner
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f); // The top right corner
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f); // The bottom right corner
glEnd();
glBindTexture(GL_TEXTURE_2D, 0); // Unbind any tures
glLoadIdentity();
glTranslatef(4.1f, 1.0f, -4.0f);
glBindTexture(GL_TEXTURE_2D, fbo_texture4); // Bind our frame buffer ture
glBegin(GL_QUADS);
glColor4f(1, 1, 1, 1);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 0.0f); // The top left corner
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f); // The top right corner
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f); // The bottom right corner
glEnd();
glBindTexture(GL_TEXTURE_2D, 0); // Unbind any tures
glutSwapBuffers();
}
void reshape (int width, int height) {
glViewport(0, 0, (GLsizei)width, (GLsizei)height); // Set our viewport to the size of our window
glMatrixMode(GL_PROJECTION); // Switch to the projection matrix so that we can manipulate how our scene is viewed
glLoadIdentity(); // Reset the projection matrix to the identity matrix so that we don't get any artifacts (cleaning up)
gluPerspective(60, (GLfloat)width / (GLfloat)height, 1.0, 100.0); // Set the Field of view angle (in degrees), the aspect ratio of our window, and the new and far planes
glMatrixMode(GL_MODELVIEW); // Switch back to the model view matrix, so that we can start drawing shapes correctly
}
void keyPressed (unsigned char key, int x, int y) {
keyStates[key] = true; // Set the state of the current key to pressed
}
void keyUp (unsigned char key, int x, int y) {
keyStates[key] = false; // Set the state of the current key to not pressed
}
int main (int argc, char **argv) {
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA); // Set up a basic display buffer (only single buffered for now)
glutInitWindowSize (1280, 500); // Set the width and height of the window
glutInitWindowPosition (100, 100); // Set the position of the window
glutCreateWindow ("OpenGL FBO"); // Set the title for the window
if (GLEW_OK != glewInit()) {
std::cout << "Couldn't initialize GLEW" << std::endl;
exit(0);
}
initShader();
init();
glutDisplayFunc(display); // Tell GLUT to use the method "display" for rendering
glutIdleFunc(display); // Tell GLUT to use the method "display" for rendering
glutReshapeFunc(reshape); // Tell GLUT to use the method "reshape" for reshaping
glutKeyboardFunc(keyPressed); // Tell GLUT to use the method "keyPressed" for key presses
glutKeyboardUpFunc(keyUp); // Tell GLUT to use the method "keyUp" for key up events
glutMainLoop(); // Enter GLUT's main loop
}
Here is the vertex shader:
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}
And here is the fragment shader:
uniform sampler2D tex0;
uniform sampler2D tex1;
uniform sampler2D tex2;
uniform sampler2D tex3;
void main(void)
{
gl_FragColor = texture2D(tex0, gl_TexCoord[0].st);
}
EDIT #1
After modifying the code as suggested by #Damon (the code has been edited as well) , here's the screenshot of the result:
image 3
Now, I don't really know what the problem actually is. I tried to change the fragment shader to access another texture e.g. gl_FragColor = texture2D(tex2, gl_TexCoord[0].st); but i still got the same display as above. So i think it is definitely not the modelview/projection problem.
EDIT #2
The problem still left unclear. However, I tried to give only one glActiveTexture(GL_TEXTUREn); command at the program, and comment out other glActiveTexture command (without shader modification), and got the following result:
image 4 Only glActiveTexture(GL_TEXTURE0);activated.
image 5 Only glActiveTexture(GL_TEXTURE1);activated.
image 6 Only glActiveTexture(GL_TEXTURE2);activated.
image 7 Only glActiveTexture(GL_TEXTURE3);activated.
When at least 2 glActiveTexture(GL_TEXTUREn); activated, i got the same result as image 5. That left me wondering what the problem actually is.
initShader compiles and links a shader. You seem to be binding the textures to texture units within renderTextures in an OK manner, too (after unbinding the FBO, which is important to sync). So far so good, but I can't find glUseProgram anywhere in the code. That would mean the rendering falls back to fixed function, which does not have any textures bound at that time.
The fragment shader reads only from tex0, so of course you wouldn't expect to see tex1-tex3 anyway (but I guess that's just the minimum working example code).
Other than that, it looks OK from what I can see by reading over the code in 5 mins.
(As a sidenote: init calls glEnable(GL_TEXTURE_2D), this is not strictly wrong, but useless as soon as you use a shader, see this.)
How about this:
glBindFramebuffer(GL_FRAMEBUFFER, fbo); // Bind our frame buffer for rendering
glDrawBuffer(GL_COLOR_ATTACHMENT4);
glBindTexture(GL_TEXTURE_2D, fbo_texture0); // bind texture that is rendered in 0-th attachment
glBegin(GL_QUADS);
glColor4f(1, 1, 1, 1);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 0.0f); // The top left corner
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f); // The top right corner
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f); // The bottom right corner
glEnd();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
You just render into 4th attachment with binded texture from 0-th attachment.