In my program it is necessary for me to do off-screen rendering. For that purpose I use a FBO. In order to see if the image I draw is the correct for testing purposes I copy it from the FBO to a texture then render the texture to a quad. The problem is that when I copy from the FBO into the texture and render it the image appears dark/get a black color but the shapes are correct. I have tried using a texture as attachment in the FBO and rendering it directly (without copying it into another texture) and the colors are correct.
Below is the code for texture creation
//initial texture which works when rendered to a quad
glGenTexturesEXT(3, &textureID[0]);
glBindTextureEXT(GL_TEXTURE_2D, textureID[0]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_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);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 600, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
//second one which should be a copy of the above but has tha dark color mentioned
glBindTextureEXT(GL_TEXTURE_2D, textureID[1]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_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);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); // automatic mipmap
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 600, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTextureEXT(GL_TEXTURE_2D, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,textureID[0],0);
//Attach depth buffer to FBO
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb);
st1=glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
Now in the rendering function
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); //biding FBO
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
//render code
unsigned char *pixels= new unsigned char [600*512*4];
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); //unbiding
glBindTextureEXT(GL_TEXTURE_2D,textureID[1]); //if I change to textureID[0] result is fine
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,600,512,0,GL_RGBA,GL_UNSIGNED_BYTE,pixels);
glBindTextureEXT(GL_TEXTURE_2D,0);
glViewport(0, 0, 600, 512);
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glBindTextureEXT(GL_TEXTURE_2D, textureID[1]);
//setting the correct matrixes + render a quad
//before rendering a quad I set the color with
glColor3f(1.0, 1.0, 1.0);
delete[] pixels;
glutSwapBuffers();
I'm using glut for the setup. I have tried other functions such as glGetTexImage2D after unbiding the FBO and biding the texture as an alternative to glReadPixels(...) but with no success.
I don't understand this call to glTexImage2D in your second code snippet. pixels will contain just garbage. What do you expect it to do?
Textures have been core OpenGL for a very, very long time. It's just glGenTextures and glBindTexture not ...EXT. Also I recommend to either use ...ARB versions of the FBO functionality, or just using OpenGL core framebuffer support (of later OpenGL versions).
Related
I was under the impression if you set your sampler uniforms to the correct texture unit, it doesn't matter if the currently bound texture target is 0 or not. For example,
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &mytexture);
glBindTexture(GL_TEXTURE_2D, mytexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, my_data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
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); // This is the line I'm wondering about
Sometime later when drawing ...
glUniform1i(glGetUniformLocation(program, "mysampler"), 1);
//draw_stuff
Unfortunately, the screen is all black unless I keep GL_TEXTURE_2D bound to mytexture. Is it illegal to sample when GL_TEXTURE_2D is bound to 0???
Exactly, think about GL_TEXTUREN as a slot of several texture target types (GL_TEXTURE_2D, GL_TEXTURE_3D etc). While activating GL_TEXTURE1 and binding a texture to GL_TEXTURE_2D you're telling the driver that 2d texture in slot 1 is going to be set to "mytexture".
Then you need to pass this information to your shader as well:
glUniform1i(glGetUniformLocation(program, "mysampler"), 1);
This simply tells your sampler2D in your shader that it should look for GL_TEXTURE_2D in slot 1. If you unbind the texture it will have nothing to sample from.
I am the new one here, and I have a question about the texture format in OpenGL for depth infomation, there is part of my code:
glGenTextures(1,&tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE16UI_EXT, width, height, 0, GL_LUMINANCE_INTEGER_EXT, GL_UNSIGNED_SHORT, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
The question is: in my Intel HD (graphics 5500), there will have problem in "glTexImage2D" when I want to deal with the depth camera (in unsigned short), but that is okey for NV (GeForce 940M). (The GL error is 0x0502)
Is the internal format "GL_LUMINANCE16UI_EXT" not suitable for Intel HD? or do I miss something or there have better format can used?
BTW, I had tried the internal format "GL_DEPTH_COMPONENT16" with "GL_DEPTH_COMPONENT" to make the error not happened, but some other problem will happen in the following code after the code above:
glBindTexture(GL_TEXTURE_2D, tex);
frameBuffer.Bind();
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, renderBuffer.width, renderBuffer.height);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GlSlProgram Bind;
.
glGetUniformLocation(...);
glUniform3f(...);
.
glDrawArrays(GL_POINTS, 0, 1);
frameBuffer.Unbind();
GlSlProgram Unbind;
glPopAttrib();
glFinish();
The gl error will happen in "glClear" and "glDrawArrays" with 0x0506, when this kind of format is used. I don't know how to fix that...
GL_LUMINANCE16UI is no depth buffer format and will most likely not work. A list of available depth buffer formats is here.
also, you probably shouldn't bind the texture itself but instead attach it to the framebuffer with glFrameBufferTexture2D and GL_DEPTH_ATTACHMENT.
I am trying to implement a simple multipass rendering scheme. I first blit the multisampled version of the scene to a FBO beforeEffectsContext.fbo. If I then blit this to the application provided FB it works fine. But I want to do another pass on the scene to blur it. I therefore bind the texture in the COLOR_ATTACHMENT0 in the beforeEffectsContext.fbo, sample it, drawing a quad with a blur effect added to another framebuffer blurContext.fbo.
If I know display the content of blurContext.fbo's color attachment to the screen using the same approach with a quad and a texture sampling, it works and I get a blurred scene.
But if I try to use glBlitFramebuffer() instead in this step, I get a black screeen. The problem seems to be in my misunderstanding of the blitting process and FBOs.
Initialization code for the blurContext.fbo:
// BeforeEffects Framebuffer
glGenFramebuffers(1, &renderContext->beforeEffectsContext.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, renderContext->beforeEffectsContext.fbo);
glGenTextures(1, &renderContext->beforeEffectsContext.colorAttachment);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, renderContext->beforeEffectsContext.colorAttachment);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderContext->beforeEffectsContext.colorAttachment, 0);
// Blur Framebuffer
glGenFramebuffers(1, &renderContext->blurContext.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, renderContext->blurContext.fbo);
glGenTextures(1, &renderContext->blurContext.colorAttachment);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, renderContext->blurContext.colorAttachment);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderContext->blurContext.colorAttachment, 0);
Rendering:
// Draw to the MSampled scene to the BeforeEffects framebuffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, renderContext->multiSamplingContext.fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, renderContext->beforeEffectsContext.fbo);
glBlitFramebuffer(0, 0, 800, 600, 0, 0, 800, 600, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
// Sample the texture attached to the beforeEffects FBO and draw to the blur FBO
glBindTexture(GL_TEXTURE_2D, renderContext->beforeEffectsContext.colorAttachment);
glBindFramebuffer(GL_FRAMEBUFFER, renderContext->blurContext.fbo);
glViewport(0, 0, 800, 600);
glUseProgram(renderContext->blurProgramContext.program);
glBindVertexArray(renderContext->vaoBlur);
glDrawArrays(GL_QUADS, 0, 4);
glUseProgram(0);
glBindVertexArray(0);
// Blit the content of the blur FBO to the app-provided Framebuffer (doesn't work, black screen)
glBindFramebuffer(GL_READ_FRAMEBUFFER, renderContext->blurContext.fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_BUFFER, 0);
glViewport(0, 0, 800, 600);
glBlitFramebuffer(0, 0, 800, 600, 0, 0, 800, 600, GL_COLOR_BUFFER_BIT,
GL_NEAREST);
In the line where you are binding the default framebuffer (0) for drawing you have the target as GL_DRAW_BUFFER. According to https://www.opengl.org/sdk/docs/man/html/glBindFramebuffer.xhtml the correct enum for setting the draw framebuffer is GL_DRAW_FRAMEBUFFER. If you add a call to glGetError you will probably see a GL_INVALID_ENUM error.
I would like to use the depth buffer to store the depth values of particles in eye space in a 2D texture by using OpenGL 2.1 / GLSL 1.2.
So far I found a way to use the colorbuffer
// create texture
glGenTextures(1, &g_hDepthTexture);
glBindTexture(GL_TEXTURE_2D, g_hDepthTexture);
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_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, g_windowWidth, g_windowHeight, 0, GL_RGBA, GL_FLOAT, 0);
// create framebuffer
glGenFramebuffersEXT(1, &g_hFBO);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_hFBO);glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, g_hDepthTexture, 0);
However, I don't need the BGA components. Hence, I have tried to use the depth buffer, but the following code clamps each value in the texture to 0...1
// create texture
glGenTextures(1, &g_hDepthTexture);
glBindTexture(GL_TEXTURE_2D, g_hDepthTexture);
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_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, g_windowWidth, g_windowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); // create framebuffer
glGenFramebuffersEXT(1, &g_hFBO);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_hFBO);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, g_hDepthTexture, 0);
I would like to know how to use the depth buffer (probably how to choose the correct internal format / format) so that the texture values are not clamped.
Normalized integer image formats are always clamped. That's why they're normalized integers. If you want an unclamped format, then you need floating point values.
I would suggest using an actual 1-channel floating-point image format, such as GL_R32F. Maybe GL_R16F, depending on how much precision I need. If you don't have GL 3.x hardware, you may be able to use GL_LUMINANCE32F_EXT, depending on what extensions are available.
BTW, if you're doing this for deferred rendering, don't bother. You can actually calculate the eye-space point directly from the regular depth buffer. Yes, really.
i have managed to load texture
// Load texture
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
pBytes = gltLoadTGA("../earth.tga", &iWidth, &iHeight, &iComponents, &eFormat);
glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);
free(pBytes);
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);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
when i texture the sphere like this it does not show (image 256x256 32bit)
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glutSolidSphere(35.0f, 30, 17);
glDisable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
but i have a ship made out of a pyramid shape the same technique works on it
glEnable(GL_TEXTURE_2D);
ship();
glDisable(GL_TEXTURE_2D);
anyone any idea why this is happening please...(please don't mark me down i'm working hard here)
You may have loaded the texture image. But you also need to supply texture coordinates. Your ship may do this. glutSolidSphere however does not, and there's nothing you can do about it. So don't use glutSolidSphere.