🔒 Locked
Shadow mapping with framebuffer
Advertisement
Original Post
Hey I like to do shadow mappign by using the EXT_framebuffer_object extension. Do anyone know of any god resource for this? I'm currently reading the specs. for the extension od the OpenGL Extension Registry but I would like to have a tutorial or similar, but I can't seam to find that with google. Regards Lizard
Take a look at www.codesampler.com in the opengl source section. They've got a good tutorial on the EXT_framebuffer_object extension and on shadow mapping.
The shadowmapping tutorial works with the old pBuffer extensions, but you should be able to mix the 2 tutorials without problems.
Hope I've been able to help,
Jeroen
The shadowmapping tutorial works with the old pBuffer extensions, but you should be able to mix the 2 tutorials without problems.
Hope I've been able to help,
Jeroen
Hello,
the framebuffer affects what's being rendered onscreen and this is what the enduser is eventually going to see. If you want to render something offscreen, you have to render it to another buffer then the framebuffer. A buffer is just a section in memory where data resides and this is also the best way of visualizing it. Now that you have rendered to an offscreen buffer, this buffer has to be bound to a texture so that when this texture is rendered in the framebuffer, you actually get to see the contents of the offscreen buffer where the texture is.
I'm hoping you're still with me. If not, read the above lines again a few times and try to understand.
Hope I've been able to help,
Jeroen
the framebuffer affects what's being rendered onscreen and this is what the enduser is eventually going to see. If you want to render something offscreen, you have to render it to another buffer then the framebuffer. A buffer is just a section in memory where data resides and this is also the best way of visualizing it. Now that you have rendered to an offscreen buffer, this buffer has to be bound to a texture so that when this texture is rendered in the framebuffer, you actually get to see the contents of the offscreen buffer where the texture is.
I'm hoping you're still with me. If not, read the above lines again a few times and try to understand.
Hope I've been able to help,
Jeroen
Quote:
Original post by godmodder
Hello,
the framebuffer affects what's being rendered onscreen and this is what the enduser is eventually going to see. If you want to render something offscreen, you have to render it to another buffer then the framebuffer. A buffer is just a section in memory where data resides and this is also the best way of visualizing it. Now that you have rendered to an offscreen buffer, this buffer has to be bound to a texture so that when this texture is rendered in the framebuffer, you actually get to see the contents of the offscreen buffer where the texture is.
I'm hoping you're still with me. If not, read the above lines again a few times and try to understand.
Hope I've been able to help,
Jeroen
Ok yes I follow that. But is a renderbuffer really needed? It doesn't look like it in the specs: http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt
See example "(7) Render to depth texture with no color attachments".
Regards
Lizard
Quote:
Original post by LizardCPP
But is a renderbuffer really needed?
It depends. Renderbuffer is just a buffer that you use to store things only. Let's take rendering to texture with depth testing. If you want to do that you must set a texture as a color buffer. But what about the depth buffer? Well here's where the renderbuffer comes in. You just create the renderbuffer and use it as a depth buffer. Alternatively you could use another texture for the depth buffer but, since you only want to render the colorbuffer to the texture, doing so would have no sense.
In example #7 you only need to render the depth values so you don't need the colorbuffer. So you just bind a texture as a depth buffer and turn off color writing. In this example there is no need for a renderbuffer.
I hope I explained what renderbuffers are for.
Quote:
Original post by Lord Faron Quote:
Original post by LizardCPP
But is a renderbuffer really needed?
It depends. Renderbuffer is just a buffer that you use to store things only. Let's take rendering to texture with depth testing. If you want to do that you must set a texture as a color buffer. But what about the depth buffer? Well here's where the renderbuffer comes in. You just create the renderbuffer and use it as a depth buffer. Alternatively you could use another texture for the depth buffer but, since you only want to render the colorbuffer to the texture, doing so would have no sense.
In example #7 you only need to render the depth values so you don't need the colorbuffer. So you just bind a texture as a depth buffer and turn off color writing. In this example there is no need for a renderbuffer.
I hope I explained what renderbuffers are for.
Yes thank you for explaining it.
But when doing shadowmapping it's the depth values I'm after so I could just attach a depth texture and don't use a render buffer at all?
Lizard
Quote:
Original post by LizardCPP
I could just attach a depth texture and don't use a render buffer at all?
Yes, but remember to disable drawing to the colorbuffer. Just like in the example.
Hey again
I have tried to get a example working with redering depth values to a texture
and then applayng it to a quad to se it. But I couldn't get it working so I
tried to get the codesample example working instead: link
And that worked fine, so I started to modify my implementation of that example
so that it would only render depth values instead. But no luck. See source code below (it's java with jogl).
Can anyone see what I'm doing wrong?
Lizard
Edit: The rendered quad with the depth texture attached are rendered totaly white.
EDIT: OK it WORKS =) It's just really hard to se on a laptop screen. Hope anyone has use of the code.
I have tried to get a example working with redering depth values to a texture
and then applayng it to a quad to se it. But I couldn't get it working so I
tried to get the codesample example working instead: link
And that worked fine, so I started to modify my implementation of that example
so that it would only render depth values instead. But no luck. See source code below (it's java with jogl).
Can anyone see what I'm doing wrong?
Lizard
Edit: The rendered quad with the depth texture attached are rendered totaly white.
EDIT: OK it WORKS =) It's just really hard to se on a laptop screen. Hope anyone has use of the code.
import com.sun.opengl.util.texture.TextureIO;import com.sun.opengl.util.texture.Texture;import javax.media.opengl.GLEventListener;import javax.media.opengl.GLAutoDrawable;import javax.media.opengl.GL;import javax.media.opengl.glu.GLU;import java.io.File;import java.io.IOException;/** * Date: 2006-aug-06 * Time: 11:40:09 */public class Main implements GLEventListener{ private static int WINDOW_WIDTH = 640; private static int WINDOW_HEIGHT = 480; private static final int RENDERBUFFER_WIDTH = 512; private static final int RENDERBUFFER_HEIGHT = 512; private JOGLWindow window; private GL gl; private GLU glu; private int[] frameBuffer = new int[1]; private int[] textureId = new int[1]; private Texture regularTexture; public Main() { window = new JOGLWindow("JOGL EXT_framebuffer_object extension test", WINDOW_WIDTH, WINDOW_HEIGHT, false); window.addJOGLContextThread(this); glu = new GLU(); window.activate(); while(window.isActivated()) { window.display(); try { Thread.sleep(1); } catch(InterruptedException e) { e.printStackTrace(); } } } public void init(GLAutoDrawable glAutoDrawable) { this.gl = glAutoDrawable.getGL(); gl.glClearColor(0.0f, 0.0f, 1.0f, 1.0f); gl.glEnable(GL.GL_TEXTURE_2D); gl.glEnable(GL.GL_DEPTH_TEST); gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); gl.glGenFramebuffersEXT(1, frameBuffer, 0); // Check for errors checkFramebufferStatus(); // Create dynamic texture gl.glGenTextures(1, textureId, 0); gl.glBindTexture(GL.GL_TEXTURE_2D, textureId[0]); gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_DEPTH_COMPONENT16, RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT, 0, GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_BYTE, null); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR ); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR ); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_COMPARE_MODE_ARB, GL.GL_NONE); // Load a regulat texture File file = new File("C:\\dev\\projects\\JOGLShadowMapping\\src\\NeHe.png"); try { regularTexture = TextureIO.newTexture(file, true); regularTexture.setTexParameteri(GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); regularTexture.setTexParameteri(GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); } catch (IOException e) { e.printStackTrace(); } } public void display(GLAutoDrawable glAutoDrawable) { this.gl = glAutoDrawable.getGL(); /* Offscreen rendering */ gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, frameBuffer[0]); gl.glFramebufferTexture2DEXT(GL.GL_FRAMEBUFFER_EXT, GL.GL_DEPTH_ATTACHMENT_EXT, GL.GL_TEXTURE_2D, textureId[0], 0); gl.glDrawBuffer(GL.GL_NONE); gl.glReadBuffer(GL.GL_NONE); checkFramebufferStatus(); gl.glViewport(0, 0, RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT); gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.glClear(GL.GL_DEPTH_BUFFER_BIT); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); // gl.glBindTexture(GL.GL_TEXTURE_2D, regularTexture.getTextureObject()); // Render gl.glBegin(GL.GL_TRIANGLES); // gl.glTexCoord2f(0, 0); gl.glVertex3f(-2, 0, -6); // gl.glTexCoord2f(0.5f, 1); gl.glVertex3f(0, 2, -6); // gl.glTexCoord2f(1, 0); gl.glVertex3f(2, 0, -6); gl.glEnd(); gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0); /* On-screen rendering */ gl.glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); gl.glClearColor(0.0f, 0.0f, 1.0f, 1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT ); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); gl.glBindTexture(GL.GL_TEXTURE_2D, textureId[0]); // Render qaud gl.glBegin(GL.GL_TRIANGLES); gl.glTexCoord2f(0, 0); gl.glVertex3f(-2, 0, -6); gl.glTexCoord2f(0, 1); gl.glVertex3f(-2, 2, -6); gl.glTexCoord2f(1, 1); gl.glVertex3f(2, 2, -6); gl.glTexCoord2f(1, 1); gl.glVertex3f(2, 2, -6); gl.glTexCoord2f(1, 0); gl.glVertex3f(2, 0, -6); gl.glTexCoord2f(0, 0); gl.glVertex3f(-2, 0, -6); gl.glEnd(); } public void reshape(GLAutoDrawable glAutoDrawable, int x, int y, int width, int height) { this.gl = glAutoDrawable.getGL(); WINDOW_WIDTH = width; WINDOW_HEIGHT = height; // Calculate aspect ratio if (WINDOW_HEIGHT <= 0) { WINDOW_HEIGHT = 1; } final float aspect = (float) WINDOW_WIDTH / (float) WINDOW_HEIGHT; // Create projection matrix gl.glMatrixMode(GL.GL_PROJECTION); glu.gluPerspective(45.0, aspect, 0.1, 10.0); // gl.glMatrixMode(GL.GL_MODELVIEW); // gl.glLoadIdentity(); } public void displayChanged(GLAutoDrawable glAutoDrawable, boolean b, boolean b1) { this.gl = glAutoDrawable.getGL(); } private void checkFramebufferStatus() { int status = gl.glCheckFramebufferStatusEXT(GL.GL_FRAMEBUFFER_EXT); switch(status) { case GL.GL_FRAMEBUFFER_COMPLETE_EXT: // All good break; case GL.GL_FRAMEBUFFER_UNSUPPORTED_EXT: throw new RuntimeException("Frame buffer extension not supported."); case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENTS_EXT: throw new RuntimeException("Incompleat attachments"); case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: throw new RuntimeException("Incompleat dimensions"); case GL.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: throw new RuntimeException("Incompleat drw buffer"); case GL.GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT: throw new RuntimeException("Incompleat duplciate attachments"); case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: throw new RuntimeException("incompleate foramts"); case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: throw new RuntimeException("incompleate attachments"); case GL.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: throw new RuntimeException("Incompleate read buffer"); default: throw new RuntimeException("Logic error"); } } public static void main(String[] args) { new Main(); }}Quote:
Original post by LizardCPP
OK it WORKS =)
Glad to hear (read) it :)
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement