Jump to content
  • Advertisement
Sign in to follow this  
fazekaim

how to render water reflection

This topic is 4820 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I tried to create water reflection. I made my render-to-texture code with framebuffer object:
public void reshape(GLDrawable glDrawable, int xstart,int ystart, int width, int height) {
        gl.glViewport(0,0,width,height);
        gl.glMatrixMode( GL.GL_PROJECTION);
        gl.glLoadIdentity();

        createNewFrameBuffer( width, height, MeadowLand.FBO, MeadowLand.FBORenderBuffer, MeadowLand.FBOTexture );

        gluPerspective(45,(double)width/height,1,10000);

        gl.glMatrixMode( GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    }
public static void createNewFrameBuffer(int width, int height, int[] FBO, int[] FBORenderBuffer, int[] FBOTexture ){

        if( FBO[0] > 0) gl.glDeleteFramebuffersEXT( 1, FBO  );
        if( FBOTexture[0] > 0) gl.glDeleteTextures( 1, FBOTexture  );

        gl.glGenFramebuffersEXT( 1, FBO  );
        gl.glGenTextures( 1, FBOTexture );
        gl.glBindFramebufferEXT( GL.GL_FRAMEBUFFER_EXT, FBO[0] );

        gl.glGenRenderbuffersEXT( 1, FBORenderBuffer );
        gl.glBindRenderbufferEXT( GL.GL_RENDERBUFFER_EXT, FBORenderBuffer[0] );
        gl.glRenderbufferStorageEXT( GL.GL_RENDERBUFFER_EXT, GL.GL_DEPTH_COMPONENT24, width, height );
        gl.glFramebufferRenderbufferEXT( GL.GL_FRAMEBUFFER_EXT, GL.GL_DEPTH_ATTACHMENT_EXT, GL.GL_RENDERBUFFER_EXT, FBORenderBuffer[0] );

        gl.glBindTexture( GL.GL_TEXTURE_2D, FBOTexture[0] );
        gl.glTexImage2D( GL.GL_TEXTURE_2D, 0, GL.GL_RGB, width, height, 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, BufferUtils.bufferOffset(0) );
        gl.glTexParameteri( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST );
        gl.glTexParameteri( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST );
        gl.glFramebufferTexture2DEXT( GL.GL_FRAMEBUFFER_EXT, GL.GL_COLOR_ATTACHMENT0_EXT, GL.GL_TEXTURE_2D, FBOTexture[0], 0 );

        if( !checkFrameBufferStatus( width, height ) ){
            JOptionPane.showMessageDialog(null, "FBO ohhh", "Some Error", JOptionPane.ERROR_MESSAGE);
            System.exit( -1 );
        }
        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);

    }


My render code:
            gl.glBindFramebufferEXT( GL.GL_FRAMEBUFFER_EXT, FBO[0] );
            gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
            gl.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
            gl.glPushMatrix();
                gl.glScalef( 1.0f, -1.0f, 1.0f );
                renderScene();
            gl.glPopMatrix();

            gl.glBindFramebufferEXT( GL.GL_FRAMEBUFFER_EXT, 0 );
            gl.glClearColor(0.0f, 1.0f, 0.0f, 0.0f);
            gl.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );
            gl.glPushMatrix();
                renderscene();
                renderWater();
            gl.glPopMatrix(); 

....
public void renderWater() {

        gl.glEnable( GL.GL_DEPTH_TEST);
        gl.glEnable(GL.GL_MULTISAMPLE_ARB);

        gl.glActiveTextureARB( GL.GL_TEXTURE0_ARB + 0);
        gl.glBindTexture( GL.GL_TEXTURE_2D, FBOTexture[0]);
        gl.glClientActiveTextureARB( GL.GL_TEXTURE0_ARB + 0);
        gl.glEnable( GL.GL_TEXTURE_2D);

            gl.glBegin( GL.GL_QUADS);
                gl.glMultiTexCoord2f( 0, 1, 1 );
                gl.glVertex3f( vertexes[0][0], waterLevel, vertexes[0][1] );

                gl.glMultiTexCoord2f( 0, 1 , 0 );
                gl.glVertex3f( vertexes[1][0], waterLevel, vertexes[1][1] );

                gl.glMultiTexCoord2f( 0, 0, 0 );
                gl.glVertex3f( vertexes[2][0], waterLevel, vertexes[2][1] );

                gl.glMultiTexCoord2f( 0, 0, 1 );
                gl.glVertex3f( vertexes[3][0], waterLevel, vertexes[3][1] );
            gl.glEnd();

        gl.glActiveTextureARB( GL.GL_TEXTURE0_ARB + 0);
        gl.glDisable( GL.GL_TEXTURE_2D);
        gl.glClientActiveTextureARB( GL.GL_TEXTURE0_ARB + 0);

        gl.glDisable( GL.GL_BLEND );

    }


My waterplane show the fbo texture very well, but I don't know how to compute the texture coordinates, to see the water like a mirror. Now, I just put the fbo texture to the water plane. Screenshot: http://delfin.klte.hu/~fazekaim/water.jpg I should project the texture on the waterplan, but I don't know how. Thanks.

Share this post


Link to post
Share on other sites
Advertisement
i use these functions to set the matrix, before and after have rendered the water:


void EnableWaterTextureMatrix()
{
glMatrixMode( GL_TEXTURE );

glScalef(0.5f, 0.5f, 1.0f);
glTranslatef(1.0f, 1.0f, 0.0f);
glMultMatrixf( g_Camera.GetProjection() );
glMultMatrixf( g_Camera.GetModelView() );

glMatrixMode(GL_MODELVIEW);
}

void DisableWaterTextureMatrix()
{
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
}




here's a screenshot from a demo i wrote:




[Edited by - b3rs3rk on July 11, 2005 8:11:51 AM]

Share this post


Link to post
Share on other sites
Wow, congratulation!

g_Camera.GetProjection()
g_Camera.GetModelView() how can I get these matrices?

and what are the texture coordinates?

Share this post


Link to post
Share on other sites
the texcoord you use on the quad you draw for the water plane are correct, but if you don't know how to get the modelview and the projection matrix i suggest to try with something simpler than a water reflection demo...

anyway, call glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); and glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);

Share this post


Link to post
Share on other sites
>>the texcoord you use on the quad you draw for the water plane are correct
Thanks.

>>anyway, call glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); and >>glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
Oh, i'm boob. I use it, but I thought to something else, sorry :)

It try it now...

Share this post


Link to post
Share on other sites
I tried it, with this code:


private void EnableWaterTextureMatrix(){
gl.glMatrixMode( GL.GL_TEXTURE );

gl.glScalef(0.5f, 0.5f, 1.0f);
gl.glTranslatef(1.0f, 1.0f, 0.0f);
float[] modelMatrix = new float[16];gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, modelMatrix);
float[] projectionlMatrix = new float[16];gl.glGetFloatv(GL.GL_PROJECTION_MATRIX, projectionlMatrix);
gl.glMultMatrixf( modelMatrix );
gl.glMultMatrixf( projectionlMatrix );

gl.glMatrixMode( GL.GL_MODELVIEW );
}

private void DisableWaterTextureMatrix() {
gl.glMatrixMode( GL.GL_TEXTURE );
gl.glLoadIdentity();
gl.glMatrixMode( GL.GL_MODELVIEW );
}

public void renderWater() {

EnableWaterTextureMatrix();

gl.glEnable( GL.GL_DEPTH_TEST);
gl.glEnable(GL.GL_MULTISAMPLE_ARB);

activateTexture( 0, MeadowLand.FBOTexture[0], GL.GL_TEXTURE_2D );

gl.glBegin( GL.GL_QUADS);
gl.glMultiTexCoord2f( 0, 1, 1 );
gl.glVertex3f( vertexes[0][0], waterLevel, vertexes[0][1] );

gl.glMultiTexCoord2f( 0, 1 , 0 );
gl.glVertex3f( vertexes[1][0], waterLevel, vertexes[1][1] );

gl.glMultiTexCoord2f( 0, 0, 0 );
gl.glVertex3f( vertexes[2][0], waterLevel, vertexes[2][1] );

gl.glMultiTexCoord2f( 0, 0, 1 );
gl.glVertex3f( vertexes[3][0], waterLevel, vertexes[3][1] );
gl.glEnd();

deactivateTexture( 0, GL.GL_TEXTURE_2D );

DisableWaterTextureMatrix();
}




The result: http://delfin.klte.hu/~fazekaim/water2.jpg

What did i wrong?

By the way, when I create the fbo texture I call glScale(1,-1,1);
Should i mirror the camera too?
glu.gluLookAt( eye.x, -eye.y, eye.z, focus.x, focus.y, focus.z, up.x, up.y, up.z );

Share this post


Link to post
Share on other sites
are you sure that the pbuffer texture is correctly filled? remember that when you render in the pbuffer you have to use the same modelview and projection you use in normal rendering, and then scale the scene up/down

Share this post


Link to post
Share on other sites
I'm using gl.glScalef( 1.0f, -1.0f, 1.0f ), and if i'm not mistaken, the framebuffer object don't switch gl context, so it use the same projection and model matrix.

here is my render code:


public void display(GLDrawable glDrawable) {
{
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
glu.gluLookAt( eye.x, eye.y, eye.z, focus.x, focus.y, focus.z, up.x, up.y, up.z );

gl.glBindFramebufferEXT( GL.GL_FRAMEBUFFER_EXT, FBO[0] );
gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
gl.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glPushMatrix();
gl.glScalef( 1.0f, -1.0f, 1.0f );
renderScene();
gl.glPopMatrix();

gl.glBindFramebufferEXT( GL.GL_FRAMEBUFFER_EXT, 0 );
gl.glClearColor(0.0f, 1.0f, 0.0f, 0.0f);
gl.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );
gl.glPushMatrix();
renderscene();
renderWater();
gl.glPopMatrix();
}

private void EnableWaterTextureMatrix(){
gl.glMatrixMode( GL.GL_TEXTURE );

gl.glScalef(0.5f, 0.5f, 1.0f);
gl.glTranslatef(1.0f, 1.0f, 0.0f);
float[] modelMatrix = new float[16];gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, modelMatrix);
float[] projectionlMatrix = new float[16];gl.glGetFloatv(GL.GL_PROJECTION_MATRIX, projectionlMatrix);
gl.glMultMatrixf( modelMatrix );
gl.glMultMatrixf( projectionlMatrix );

gl.glMatrixMode( GL.GL_MODELVIEW );
}

private void DisableWaterTextureMatrix() {
gl.glMatrixMode( GL.GL_TEXTURE );
gl.glLoadIdentity();
gl.glMatrixMode( GL.GL_MODELVIEW );
}

public void renderWater() {

EnableWaterTextureMatrix();

gl.glEnable( GL.GL_DEPTH_TEST);
gl.glEnable(GL.GL_MULTISAMPLE_ARB);

gl.glActiveTextureARB( GL.GL_TEXTURE0_ARB + 0);
gl.glBindTexture( GL.GL_TEXTURE_2D, FBOTexture[0]);
gl.glClientActiveTextureARB( GL.GL_TEXTURE0_ARB + 0);
gl.glEnable( GL.GL_TEXTURE_2D);

gl.glBegin( GL.GL_QUADS);
gl.glMultiTexCoord2f( 0, 1, 1 );
gl.glVertex3f( vertexes[0][0], waterLevel, vertexes[0][1] );

gl.glMultiTexCoord2f( 0, 1 , 0 );
gl.glVertex3f( vertexes[1][0], waterLevel, vertexes[1][1] );

gl.glMultiTexCoord2f( 0, 0, 0 );
gl.glVertex3f( vertexes[2][0], waterLevel, vertexes[2][1] );

gl.glMultiTexCoord2f( 0, 0, 1 );
gl.glVertex3f( vertexes[3][0], waterLevel, vertexes[3][1] );
gl.glEnd();

gl.glActiveTextureARB( GL.GL_TEXTURE0_ARB + 0);
gl.glDisable( GL.GL_TEXTURE_2D);
gl.glClientActiveTextureARB( GL.GL_TEXTURE0_ARB + 0);

gl.glDisable( GL.GL_BLEND );

DisableWaterTextureMatrix();

}


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!