OpenGL: Can not write to framebuffer - c++

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...

Related

How to properly use glTexImage2D to render an object each frame?

This is the code for a ground object that gets rendered every frame in a game I'm making with c++ and openGl.
Ground::Ground() {
this->loadedObject = loadObject("ground.obj");
this->vertices = getVerticesFromLoadedObject(this->loadedObject);
this->textureCoords = getTextureCoordsFromLoadedObject(this->loadedObject);
this->textureData = loadTexture("ground.jpg");
glGenTextures(1, &this->textureId);
glBindTexture(GL_TEXTURE_2D, this->textureId);
}
void Ground::draw() {
glEnable(GL_TEXTURE_2D);
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_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, this->textureData.width, this->textureData.height, 0, GL_RGB, GL_UNSIGNED_BYTE, this->textureData.data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY_EXT);
tinyobj::shape_t shape = this->loadedObject.shape;
unsigned int vertexCount = shape.mesh.num_face_vertices.size() * 3;
glTexCoordPointer(2, GL_FLOAT, 0, this->textureCoords);
glVertexPointer(3, GL_FLOAT, 0, this->vertices);
glDrawArrays(GL_TRIANGLES, 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY_EXT);
glDisable(GL_TEXTURE_2D);
}
Even though this works, calling glTexImage2D every frame causes a memory leak, but I can't get the texture to show otherwise, I tried doing the call in Ground's constructor but it doesn't load the image at all. How do I load the image just once to avoid the memory leak?
Update: with glTexImage2D in the constructor
Ground::Ground() {
this->loadedObject = loadObject("ground.obj");
this->vertices = getVerticesFromLoadedObject(this->loadedObject);
this->textureCoords = getTextureCoordsFromLoadedObject(this->loadedObject);
this->textureData = loadTexture("ground.jpg");
glGenTextures(1, &this->textureId);
glBindTexture(GL_TEXTURE_2D, this->textureId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, this->textureData.width, this->textureData.height, 0, GL_RGB, GL_UNSIGNED_BYTE, this->textureData.data);
}
void Ground::draw() {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, this->textureId);
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_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY_EXT);
tinyobj::shape_t shape = this->loadedObject.shape;
unsigned int vertexCount = shape.mesh.num_face_vertices.size() * 3;
glTexCoordPointer(2, GL_FLOAT, 0, this->textureCoords);
glVertexPointer(3, GL_FLOAT, 0, this->vertices);
glDrawArrays(GL_TRIANGLES, 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY_EXT);
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.

Using FBO to render YUV data

I was able to render YUV image on the screen using shaders.
To improve performance I want to use FBO. But I am not able to do it.
My initialization code is as below
void opengl_init(int w, int h) {
glGenFramebuffers(1, &framebuffer);
checkGlError("glGenFramebuffers");
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
checkGlError("glBindFramebuffer");
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &gYTexture);
glBindTexture(GL_TEXTURE_2D, gYTexture);
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_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FRAME_WIDTH, FRAME_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
glGenRenderbuffers(1, &colorbuffer);
checkGlError("glGenRenderbuffers");
glBindRenderbuffer(GL_RENDERBUFFER, colorbuffer);
checkGlError("glBindRenderbuffer");
glRenderbufferStorage(GL_RENDERBUFFER,
GL_RGB565, FRAME_WIDTH, FRAME_HEIGHT);
checkGlError("glRenderbufferStorage");
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, depthbuffer);
checkGlError("glFramebufferRenderbuffer");
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
gYTexture, 0);
checkGlError("glFramebufferTexture2D");
int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
printf("Framebuffer is not complete: *status* = %d", status);
if (status != GL_FRAMEBUFFER_COMPLETE) {
printf("Framebuffer is not complete: *status* = %d", status);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
checkGlError("glBindFramebuffer");
glGenBuffers(1, ioBuf);
checkGlError("glGenBuffers");
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &gUTexture);
glBindTexture(GL_TEXTURE_2D, gUTexture);
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_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glActiveTexture(GL_TEXTURE2);
glGenTextures(1, &gVTexture);
glBindTexture(GL_TEXTURE_2D, gVTexture);
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_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glViewport(0, 0, w, h);
checkGlError("glViewport");
}
I render my frame using the below code
void opengl_renderframe(void *yuvbuf,int framewidth, int frameheight) {
static void *ubuf, *vbuf;
ubuf = (char *)yuvbuf + (framewidth * frameheight);
vbuf = (char *)ubuf + ((framewidth * frameheight) / 4);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
checkGlError("glBindFramebuffer");
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
checkGlError("glClearColor");
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
checkGlError("glClear");
glUseProgram(gProgram);
checkGlError("glUseProgram");
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gYTexture);
glBindBuffer(GL_ARRAY_BUFFER, ioBuf);
checkGlError("glBindBuffer");
glBufferData(GL_ARRAY_BUFFER, (FRAME_WIDTH * FRAME_HEIGHT) , yuvbuf, GL_STATIC_DRAW);
checkGlError("glBufferData");
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, FRAME_WIDTH, FRAME_HEIGHT, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
checkGlError("glTexImage2D");
glBindBuffer(GL_ARRAY_BUFFER, 0);
checkGlError("glBindBuffer");
glUniform1i(Ysamp, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, gUTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, framewidth/2, frameheight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, ubuf );
glUniform1i(Usamp, 1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, gVTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, framewidth/2, frameheight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, vbuf );
glUniform1i(Vsamp, 2);
glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
checkGlError("glVertexAttribPointer");
glEnableVertexAttribArray(gvPositionHandle);
checkGlError("glEnableVertexAttribArray");
glVertexAttribPointer(gaTextureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices2);
checkGlError("glVertexAttribPointer");
glEnableVertexAttribArray(gaTextureCoordHandle);
checkGlError("glEnableVertexAttribArray");
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
checkGlError("glDrawArrays");
glBindFramebuffer(GL_FRAMEBUFFER, 0);
checkGlError("glBindFramebuffer 0");
}
my fragment shader to render only Y data is as below
static const char gGrayScaleFragmentShader[] =
"precision mediump float;\n"
"varying vec2 vTextureCoord;\n"
"uniform sampler2D sTexture;\n"
"void main() {\n"
" gl_FragColor = texture2D(sTexture, vTextureCoord);\n"
"}\n";

Why does framebuffer freeze in Derelict3?

I am using Derelict3 which uses the specific openGL3 standard and I am having an issue with the screen freezing (not updating) if glEnable(GL_DEPTH_TEST) is called, and the depth buffers not working if it is not. I have noticed that calls to set the clear color and enable depth testing are ignored if they are made prior to setting up the SDL_GL context and reloading Derelict3. I had to make them in the following order:
win=SDL_CreateWindow("3Doodle", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, flags);
if(!win){
writefln("Error creating SDL window");
SDL_Quit();
}
context=SDL_GL_CreateContext(win);
SDL_GL_SetSwapInterval(1);
glVersion=DerelictGL3.reload();
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClearDepth(1.0);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
While this sorted out depth culling while writing to the standard double buffer, when I implement a framebuffer object with a renderBuffer as the new depth buffer I get a freeze... the program compiles and runs without warnings, but the rendered image to the screen aligned quad remains fixed. If I comment out glEnable(GL_DEPTH_TEST); the camera moves freely but the the rendered image pays no mind to depth testing and simply draws objects in order.
The framebuffer initialization code is:
//fbo
glEnable (GL_FRAMEBUFFER_SRGB);
glGenFramebuffers(1, &fbo);
assert(fbo > 0);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glGenRenderbuffers(1, &rbo);
assert(rbo > 0);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, projMat.w, projMat.h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glGenTextures(1, &fbon);
assert(fbon > 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fbon);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, projMat.w, projMat.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(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);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbon, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glGenTextures(1, &fboc);
assert(fboc > 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, fboc);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, projMat.w, projMat.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(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);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, fboc, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glGenTextures(1, &fbop);
assert(fbop > 0);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, fbop);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, projMat.w, projMat.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(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);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, fbop, 0);
glBindTexture(GL_TEXTURE_2D, 0);
int status=glCheckFramebufferStatus(GL_FRAMEBUFFER);
assert(status == GL_FRAMEBUFFER_COMPLETE);
buffs=[GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2];
glDrawBuffers(3, buffs.ptr);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
The code calling the fbo in draw() is:
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shad);
glUniformMatrix4fv(viewLoc, 1, GL_TRUE, player.mat.ptr);
current.draw();
glUseProgram(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
rend.draw();
I am at a loss as the same codes is working in c# as it ought.
My stupidity. Forgot to specify glDepthFunc

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();