Some intro:
I'm currently trying to see how I can convert a depth map into a point cloud. In order to do this, I render a scene as usually and produce a depth map. From the depth map I try to recreate the scene as a point cloud from the given camera angle.
In order to do this I created a FBO so I can render my scene's depth map on a texture. The depth map is rendered on the texture successfully. I know it is done because I'm able to generate the point cloud from the depth texture using glGetTexImage and converting the data acquired.
The problem:
For presentation purposes, I want the depth map to be visible on a separate window. So, I just created a simple shader to draw the depth map texture on a quad. However, instead of the depth texture being drawn on the quad, the texture being drawn is the last that was bound using GlBindTexture. For example :
glUseProgram(simpleTextureViewerProgram);
glBindVertexArray(quadVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,randomTexture);
glBindTexture(GL_TEXTURE_2D, depthTexture);
glUniform1i(quadTextureSampler, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
The code above renders the "randomTexure" on the quad instead of the "depthTexture". As I said earlier, "depthTexture" is the one I use in glGetTexImage, so it does contain the depth map.
I may be wrong but if I had to make a guess then the last GlBindTexture command fails and the problem is that "depthTexture" is not an RGB texture but a depth component texture. Is this the reason? How can I draw my depth map on the quad then?
Related
I use OpenGL 3.2 to render shadow maps. For this, I construct a framebuffer that renders to a depth texture.
To attach the texture to the framebuffer, I use:
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shdw_texture, 0 );
This works great. After rendering the light view, my GLSL shader can sample the depth texture to solve visibility of light.
The problem I am trying to solve now, is to have many more shadow maps, let's say 50 of them. In my main render pass I don't want to be sampling from 50 different textures. I could use an atlas, but I wondered: could I pass all these shadow maps as slices from a 2D texture array?
So, somehow create a GL_TEXTURE_2D_ARRAY with a DEPTH format, and bind one layer of the array to the framebuffer?
Can framebuffers be backed for DEPTH by a texture array layer, instead of just a depth texture?
In general, you need to distinguish whether you want to create a layered framebuffer (see Layered Images) or whether you want to attach a single layer of a multilayered texture to a framebuffer.
Use glFramebufferTexture3D to attach a layer of a 3D texture (TEXTURE_3D) or array texture to a framebuffer or use glFramebufferTextureLayer to attach a layer of a three-dimensional or array texture to the framebuffer. In either case the last argument specifies the layer of the texture.
Layered attachments can be attached with glFramebufferTexture. See Layered rendering.
Wanting to decal multiple irregular textures onto a curved surface (mesh with xyz vertices and uv specified at each). I am loading the mesh from a model file, and don't have any a priori knowledge of the surface... all we know is that it will have a "reasonable" uv mapping. Want to select a few uv regions and apply textures to them. Each region is specified by a bounding poly in uv coordinates. Don't know the equivalent xyz poly in this case, or I think the answer would be simple.
We have this working for flat surfaces and also simple cylindrical surfaces (which we approximate as a series of flat stripes, smoothed by choosing the normal as averages). In both cases we know a unique mapping from uv to xyz so we set up the stencil buffer to limit drawing to the desired uv region by drawing the equivalent xyz poly to the stencil buffer ahead of binding a texture and drawing the real surface.
We are also using rgba transparency within the textures when decaling those onto the surface. Typically each textured region is a small rotated rectangle so we draw the four vertices to the stencil buffer, then use the texture matrix to rotate that, and use the rgba transparency within the texture to ensure only the right part of the texture is applied. This all works nicely.
Would like to reuse our working code, but now apply these textures to an arbitrary curved surface/mesh. We are loading and drawing these models, and can already apply textures to whole faces [ie uv goes from (0,0) to (1,1) ]. Now we want to extend this and apply "placed" textures to regions of each surface.
Thought it might be possible draw the uv poly to the stencil buffer directly, not even knowing the equivalent xyz poly... then all the existing code would work. Perhaps could use some trick like a frame buffer object, and do the initial draw of the stencil poly to that, then using that as the stencil during the "real" draw of the curved surface mesh. Would that be a good approach? Or is there a better way?
Any advice or url links to relevant samples welcome...
PS Have looked at these threads... sort of relevant but not quite the same problem I think...
Binding a stencil render buffer to a frame buffer in opengl
Visualizing the Stencil Buffer to a texture
I am currently looking at some working FBO setup/usage code I have for off-screen shadow mapping, and trying to make it work for this seemingly simpler situation. The bit I'm unclear on is the setup gl calls needed ... I am rather confused about how to set this up. Here's an extract of the hardware shadowing FBO setup with bits chopped out and ?? added... any help on correct sequence here appreciated.
glBindTexture(GL_TEXTURE_2D, tex);
?? not
::glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, shadowsize, shadowsize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
?? but a more normal binding approp to drawing RGBA textures
::glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_Framebuffer);
// Attach everything, tell fbo there will be a drawbuffer, unlike shadows tex draw
// ?? use GL_COLOR_ATTACHMENT0_EXT
glDrawBuffer(GL_NONE);
// no color buffer dest...
??wrong glReadBuffer(GL_NONE);
// no color buffer src
?? glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, tex, 0);
//??
Note: tex, m_Frambuffer are ints, correctly allocated textureid and framebuffer, think that bit is ok. My main points of confusion are
Seems that code does glBindTexture, glTexImage2D, glBindTexture release to 0: is it correct to release this early?
glDrawBuffer + glReadBuffer calls required?
I'm trying to implement a deferred shader with OpenGL and GLSL and I'm having trouble with the light geometry. These are the steps I'm taking:
Bind multitarget framebuffer
Render color, position, normal and depth
Unbind framebuffer
Enable blend
Disable depth testing
Render every light
Enable depth testing
Disable blend
Render to screen
But since I'm only rendering the front face, when I'm inside a light it disappears completely, rendering the back face does not work, since I would get double the light power (And when inside, half [or the normal amount]).
How can I render the same light value from inside and outside the light geometry?
well in my case, i do it like that:
Bind gbuffer framebuffer
Render color, position, normal
Unbind framebuffer
Enable blend
Enable depth testing
glDepthMask(0);
glCullFace(GL_FRONT); //to render only backfaces
glDepthFunc(GL_GEQUAL); //to test if light fragment is "behind geometry", or it shouldn't affect it
Bind light framebuffer
Blit depth from gbuffer to light framebuffer //so you can depth-test light volumes against geometry
Render every light
If i remember correctly, in my deferred renderer i just render only the backfaces of the light volume. The drawback is you cannot depth test, you will only know if a light is behind a geometry after the light calculation is done and discard the pixel.
As another answer explained, you can do depth testing. Test for greater or equal to see if the backface is behind or on a geometry, therefore intersects with the surface of the geometry.
Alternatively you could check if you are inside the light volume when rendering and switch front faces accordingly.
I have an image from an external source (say a software ray tracer) that also has a depth buffer. I want to render that image in an OpenGL scene (which contains several other 3D objects) such that the OpenGL depth buffer is correctly updated, i.e. the image and the other 3D objects should be combined using correct depth testing. Any ideas? A solution without shaders would be nice.
Load your depth map via glDrawPixels(..., ..., GL_DEPTH_COMPONENT, ..., ...) and render as usual.
Using OpenGL pixel_buffer_object, you can bind depth textures. So the process would be as follows:
Load external texture
Load external depth texture
Create pixel_buffer_object with the two textures
Set PBO as render target and render the rest of your geometry (don't glClear before rendering).
I'm working on a shadow mapping algorithm, and I'd like to debug the depth map that it's generating on its first pass. However, depth textures don't seem to render properly to the viewport. Is there any easy way to display a depth texture as a greyscale image, preferably without using a shader?
You may need to change the depth texture parameters to display it as greyscale levels :
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE )
glTexParameteri( GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE )
You can then normally use the texture as a 'normal' greyscale 2d texture, either via fixed function, or a 'sampler2d' shader uniform.
Depth textures (2D) can be used just like any regular grayscale texture. The only problem might be that the values inside it are all too high and you only see a white texture. If that's the case play around with the z-near and -far planes that are used when creating the depth texture (or scale the values with a shader or maybe glTexEnv).
Sure, just bind your depth texture to your favourite texture unit, enable texturing, and draw a 2D quad! You could also size the quad to only fill part of the screen so that you can view the shadowmap in realtime.
OpenGL also has functions which can copy the texture into an array for you. You could save this as an image and use an image viewer to view it.