Texture Mapping bug in opengl (with multiple textures) - c++

i'm having trouble in using more then one texture in Opengl. I've written a test program that draws two squares, one bigger then other. When i texturize just one of then, everything works fine, but when i texture both, thats the result:
Thats the code i use to initialize the textures:
unsigned int grass_height, grass_width, wall_height, wall_width;
unsigned char *grass = loadBMP("./minegrama.bmp", &grass_height, &grass_width);
unsigned char *wall = loadBMP("./mineleaves.bmp", &wall_height, &wall_width);
glShadeModel(GL_SMOOTH);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glGenTextures(2, tex);
glBindTexture(GL_TEXTURE_2D, tex[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, grass_width, grass_height, 0, GL_BGR, GL_UNSIGNED_BYTE, grass);
gluBuild2DMipmaps(tex[0], GL_RGB, grass_width, grass_height, GL_RGB, GL_UNSIGNED_BYTE, grass);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, tex[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, wall_width, wall_height, 0, GL_BGR, GL_UNSIGNED_BYTE, wall);
gluBuild2DMipmaps(tex[1], GL_RGB, grass_width, grass_height, GL_RGB, GL_UNSIGNED_BYTE, wall);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
Thats the code of the drawing:
//Seta o MatrixMode pra usar texturas
glMatrixMode(GL_TEXTURE);
//INICIO DO CHAO
glPushMatrix();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex[0]);
//Desenhar o chao;
glColor3f(0, 0.39, 0);
glBegin(GL_QUADS);
glVertex3f(-30, -30, -0.001);
glTexCoord3f(-30, -30, -0.001);
glVertex3f(30, -30, -0.001);
glTexCoord3f(30, -30, -0.001);
glVertex3f(30, 30, -0.001);
glTexCoord3f(30, 30, -0.001);
glVertex3f(-30, 30, -0.001);
glTexCoord3f(-30, 30, -0.001);
glEnd();
glDisable(GL_TEXTURE_2D);
glPopMatrix();
//FIM DO CHAO
glPushMatrix();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex[1]);
glTranslatef(0, 0, 10);
glBegin(GL_QUADS);
glVertex3f(-1, -1, 0); glTexCoord3f(-1, -1, 0); //Especifica cada vértice
glVertex3f(1, -1, 0); glTexCoord3f(1, -1, 0);
glVertex3f(1, 1, 0); glTexCoord3f(1, 1, 0);
glVertex3f(-1, 1, 0); glTexCoord3f(-1, 1, 0);
glDisable(GL_TEXTURE_2D);
glEnd();
glPopMatrix();

The first parameter of gluBuild2DMipmaps is wrong. The documentation for the target paramter states:
Specifies the target texture. Must be GLU_TEXTURE_2D.
In addition, your texture coordinates don't look good. With the current values, the texture on the large rectangle will be repeated 60 times. In addition, the z-value of the texture coordinates should be 0, not 0.01. Even better: Use glTexCoord2f for 2-dimensional textures.

Related

How to blend RGB & BGRA raw images by opengl?

I am very new to OpenGL
Trying to blend RGB & BGRA raw images.
RGB is backgroung image
RGBA is foregroubng image
With the below source getting the output only ,"osd_raw" image .Blending is not happening.
In the below code loading the 2 raw images .
Creating 2 textures & binding with it.
Used glBlendFunc for blending.
The output is not getting blended.
Please tell me where it's getting wrong.
void display()
{
GLuint texture[2];
int width = 960;
int height = 540;
unsigned char *osd_raw = loadFile("./osd.raw");
unsigned char *video_raw = loadFile("./video.raw");
glClearColor(0.1, 0.1, 0.1, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glGenTextures(2, texture);
glEnable( GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, video_raw);
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_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, osd_raw);
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_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(-1, -1, 0);
glTexCoord2f(0, 1);
glVertex3f(-1, 1, 0);
glTexCoord2f(1, 1);
glVertex3f(1, 1, 0);
glTexCoord2f(1, 0);
glVertex3f(1, -1, 0);
glEnd();
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutInitWindowSize(960, 540);
glutInitWindowPosition(0, 0);
glutCreateWindow("glut test");
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
First of all, note that drawing with glBegin/glEnd sequences is deprecated since more than 10 years.
Read about Fixed Function Pipeline and see Vertex Specification for a state of the art way of rendering.
If you want to blend 2 textures, then you have to bind the first texture and to draw the quad with the proper texture coordinate attributes set.
After that you have to bind the 2nd texture and to draw the quad again, with enabled blending (see Blending):
glDisable( GL_BLEND);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(-1, -1, 0);
glTexCoord2f(0, 1);
glVertex3f(-1, 1, 0);
glTexCoord2f(1, 1);
glVertex3f(1, 1, 0);
glTexCoord2f(1, 0);
glVertex3f(1, -1, 0);
glEnd();
glEnable( GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(-1, -1, 0);
glTexCoord2f(0, 1);
glVertex3f(-1, 1, 0);
glTexCoord2f(1, 1);
glVertex3f(1, 1, 0);
glTexCoord2f(1, 0);
glVertex3f(1, -1, 0);
glEnd();
Further note, that the Depth Test has to be disabled or set to e.g. GL_LEQUAL, when the 2nd quad is drawn. Otherwise the 2nd quad would be discarded by the depth test.
Since the blend function is glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);, of course some alpha channels of the 2nd textue have to be less than 1.0.
As per Rabbid76 ,modified & below is the working source for reference.
void display()
{
GLuint texture[2];
int width = 960;
int height = 540;
unsigned char *osd_raw = loadFile("./osd.raw");
unsigned char *video_raw = loadFile("./video.raw");
glClearColor(0.1, 0.1, 0.1, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glGenTextures(2, texture);
glDisable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, video_raw);
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_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(-1, -1, 0);
glTexCoord2f(0, 1);
glVertex3f(-1, 1, 0);
glTexCoord2f(1, 1);
glVertex3f(1, 1, 0);
glTexCoord2f(1, 0);
glVertex3f(1, -1, 0);
glEnd();
glEnable( GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, osd_raw);
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_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(-1, -1, 0);
glTexCoord2f(0, 1);
glVertex3f(-1, 1, 0);
glTexCoord2f(1, 1);
glVertex3f(1, 1, 0);
glTexCoord2f(1, 0);
glVertex3f(1, -1, 0);
glEnd();
glFlush();
}

OpenGL: Can not write to framebuffer

I've been struggling with this for a while, without any positive result. I've also implemented framebuffers with multiple render targets before, without any issues, but right now it wont work for some reason.
Here's the code for initialization:
// LOAD TEXTURE 1
glGenTextures(1, &m_Texture1);
glBindTexture(GL_TEXTURE_2D, m_Texture1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.x, size.y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
// LOAD TEXTURE 2
glGenTextures(1, &m_Texture2);
glBindTexture(GL_TEXTURE_2D, m_Texture2);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, size.x, size.y, 0, GL_RGB, GL_FLOAT, NULL);
// LOAD TEXTURE 3
glGenTextures(1, &m_Texture3);
glBindTexture(GL_TEXTURE_2D, m_Texture3);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F_ARB, size.x, size.y, 0, GL_RGB, GL_FLOAT, NULL);
// Load FBO
glGenFramebuffers(1, &m_fbo);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_Texture1, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, m_Texture2, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, m_Texture3, 0);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
And for drawing:
glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);
/// Draw the buffers, 3 color textures
GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT };
glDrawBuffers(3, buffers);
/// Clear all the buffers
GLfloat color1[] = { 1.0f, 1.0, 0.0, 1.0 };
GLfloat color2[] = { 0.0f, 1.0, 0.0, 1.0 };
GLfloat color3[] = { 0.0f, 0.0, 1.0, 1.0 };
glClearBufferfv(GL_COLOR, 0, color1);
glClearBufferfv(GL_COLOR, 1, color2);
glClearBufferfv(GL_COLOR, 2, color3);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
I'm using gDEBugger for debugging buffers etc, and the 3 textures should be yellow, green and blue if i'm not right? But they are black for some reason...

Is there a way to put in a buffer FBO texture output format GL_ALPHA?

I am using ftgl font library.
ftgl function to create image has this code:
glBindTexture(GL_TEXTURE_2D, textID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, textureWidth, textureHeight,0, GL_ALPHA, GL_UNSIGNED_BYTE, textureMemory);
Format GL_ALPHA.
When I render to FBO images(GL_RGBA) they look ok.
But when I render fonts to fbo texture, there is some problems with colour and alpha.
This image should open in editor that don't touch pixels(browser uses anti-aliasing).
Code:
/// 1 step create FBO
// Create the color buffer
glGenTextures(1, &id_tex);
glBindTexture(GL_TEXTURE_2D, id_tex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, wid, hei, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // GL_RGBA GL_ALPHA
// Create the frame buffer
glGenFramebuffersEXT(1, &id_buf);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id_buf);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, id_tex, 0);
GLenum err = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
assert(err == GL_FRAMEBUFFER_COMPLETE_EXT);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
/// 2 step render to fbo
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id_buf);
glEnable(GL_TEXTURE_2D);
glEnable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0,0, 1920 , 1080);
ftgl::render();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDisable(GL_TEXTURE_2D);
glFlush ();
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glViewport (0, 0, 1920, 1080);
glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
/// 3 step render texture
glEnable(GL_TEXTURE_2D);
glEnable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR);
glBindTexture(GL_TEXTURE_2D, id_tex);
glBegin(GL_QUADS);
glTexCoord2d(0,0); glVertex3f(point4.X , point4.Y , point4.Z);
glTexCoord2d(0,1); glVertex3f(point1.X , point1.Y , point1.Z);
glTexCoord2d(1,1); glVertex3f(point2.X , point2.Y , point2.Z);
glTexCoord2d(1,0); glVertex3f(point3.X , point3.Y , point3.Z);
glEnd();
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glDisable(GL_TEXTURE_2D);

How to bind 2 textures correctly

I'm newbie in OpenGL and trying to get color difference between 2 textures.
It's my init function:
glGenTextures(1, &TEX0);
glBindTexture(GL_TEXTURE_2D, TEX0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glGenTextures(1, &TEX1);
glBindTexture(GL_TEXTURE_2D, TEX1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, MODE, GL_UNSIGNED_BYTE, BUFFER0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, MODE, GL_UNSIGNED_BYTE, BUFFER1);
It's my display func:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3f(1.0f, 1.0f, 1.0f);
glEnable(GL_TEXTURE_2D);
glUseProgram(shader);
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, TEX0);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, TEX1);
glUniform1i(glGetUniformLocation(shader, "tex0"), 0);
glUniform1i(glGetUniformLocation(shader, "tex1"), 1);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex2f(-1,-1);
glTexCoord2f(0,1); glVertex2f(-1,+1);
glTexCoord2f(1,1); glVertex2f(+1,+1);
glTexCoord2f(1,0); glVertex2f(+1,-1);
glEnd();
glDisable(GL_TEXTURE_2D);
glUseProgram(0);
glFlush();
glutSwapBuffers();
And it's my fragment shader:
uniform sampler2D tex0;
uniform sampler2D tex1;
void main()
{
vec4 otex = texture2D(oframe, gl_TexCoord[0].st);
vec4 ntex = texture2D(nframe, gl_TexCoord[0].st);
gl_FragColor = vec4(abs(otex.rgb - ntex.rgb), 1.0);
}
So the problem is the first activated texture always black. How to solve this?
There are a lot of similar topics, but none of them helped me. Thank you.
First mistake: OpenGL is a state machine. The call of glTexImage effects on the currently bound texture in the currently selective texture unit. You must write it this way:
glGenTextures(1, &tex0);
glBindTexture(GL_TEXTURE_2D, tex0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, MODE, GL_UNSIGNED_BYTE, BUFFER0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glGenTextures(1, &tex1);
glBindTexture(GL_TEXTURE_2D, tex1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, MODE, GL_UNSIGNED_BYTE, BUFFER1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
It doesn't really matter if glTexImage comes before or after glTexParameter of glTexEnv, it works either way. Since you're using a fragment shader glTexEnv is unneccesary. Everything glTexEnv could set has been replaced by the versatility of an expression in a fragment shader.

OpenGL: Render to FBO using multiple textures

I'm experimenting with a renderer. What I want is to write a color buffer and a normal buffer to two separate textures. I got that part figured out.
However, the color buffer is supposed to be a combination of two textures. This should do the trick:
glActiveTexture(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
g_Tex->Bind();
glActiveTexture(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
g_TexNormal->Bind();
g_Shader->Enable();
RenderScene();
g_Shader->Disable();
glActiveTexture(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);
And this is the fragment shader: (GLSL)
uniform sampler2D tex_diffuse;
uniform sampler2D tex_normal;
void main()
{
gl_FragColor = texture2D(tex_diffuse, gl_TexCoord[0].st);
//gl_FragColor = texture2D(tex_normal, gl_TexCoord[0].st);
}
However, the second texture is the same as the first! Whichever texture is attached to GL_TEXTURE0 is the one used for both samplers.
Initializing the FBO:
glGenFramebuffersEXT(1, &g_FBOColor);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_FBOColor);
glGenTextures(1, &g_FBOTexColor);
glBindTexture(GL_TEXTURE_2D, g_FBOTexColor);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, g_FBOTexColor, 0);
glGenTextures(1, &g_FBOTexNormal);
glBindTexture(GL_TEXTURE_2D, g_FBOTexNormal);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, g_FBOTexNormal, 0);
glGenTextures(1, &g_FBOTexDepth);
glBindTexture(GL_TEXTURE_2D, g_FBOTexDepth);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, w, h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, g_FBOTexDepth, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
Complete render section:
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_FBOColor);
glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT);
glViewport(
0, 0,
Window::GetSingleton()->GetWidth(), Window::GetSingleton()->GetHeight()
);
GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
glDrawBuffers(2, buffers);
//glReadBuffer(GL_COLOR_ATTACHMENT0_EXT | GL_COLOR_ATTACHMENT1_EXT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
g_Tex->Bind();
glActiveTexture(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
g_TexNormal->Bind();
g_Shader->Enable();
RenderScene();
g_Shader->Disable();
glActiveTexture(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);
glPopAttrib();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
Thanks in advance.
Well I figured it out. :)
The reason my textures didn't work was because I didn't set up the uniform locations. Fixed code:
g_Shader->Enable();
glActiveTexture(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
g_Tex->Bind();
glUniform1i(glGetUniformLocation(g_Shader->GetProgram(), "tex_diffuse"), 0);
glActiveTexture(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
g_TexNormal->Bind();
glUniform1i(glGetUniformLocation(g_Shader->GetProgram(), "tex_normal"), 1);
RenderScene();
glActiveTexture(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);
g_Shader->Disable();