Et bien je crois que c'est clair.
There is a rather simple solution but assumes there is no translucent object (except the water surface) : first render the underwater scene, then render the water with its reflections, and finally render everything over the water. The algorithm should be something like :
1 Render everything underwater (terrain, fish, submarines...) with a clip plane to make sure you never render something above.
2 Render the water surface into stencil buffer only
3 Push your modelview matrix and flip the scene (scale -1 in y axis for instance)
4 Clear the depth buffer
5 Render the reflected scene in depth buffer only (not in color buffer), with stencil test enabled (in order to render reflections only where it should)
6 Render the reflected scene again (this time, in the framebuffer), with depth function GL_EQUAL (kind of multipasss) and with blending enabled
7 Pop the modelview matrix
8 Set the depth function back to something usual (GL_LEQUAL or GL_LESS)
9 Render your water surface with blending enabled
X Render everything over the water (terrain, birds, planes...) with a clip plane to make sure you never render something under.
The problem is that you can't reflect translucent objects. If you really have translucent objects, render them opaque in the reflected scene : unless the translucent object is really big or has a very special color, it will not be noticed.
[edited by - vincoof on November 25, 2002 10:33:35 AM]
reflections
Ok still having problems with the stencil buffer, but I''d like to overcome these by myself for the time being. It seems to me, however, that this way I''d have to draw the scene at least 2,5 - 3 times which might prove too ineffective.... However I finally put my brain to work and thought about the rendering to texture method - the one last thing I''m having trouble with is calculating contiguous texture coordinates for the reflected image. Once I capture the reflected image (from the frame buffer - how do I access the color buffer? glCopyTexImagexx and glCopyPixels, glDrawPixels etc all deal with the frame buffer), it''s pretty much "out of sync" compared to the rest of the world.
Crispy
Crispy
"Literally, it means that Bob is everything you can think of, but not dead; i.e., Bob is a purple-spotted, yellow-striped bumblebee/dragon/pterodactyl hybrid with a voracious addiction to Twix candy bars, but not dead."- kSquared
Many septs 
If this is a school project (which grade btw?) then shouldnt you be woried about the speed(and efficiency) of your program?
If you are then i think i may help you a bit with my water algorithm:
- i took the algorithm originally from a 2d implementation and reprogrammed it for 3d so it may not be all that efficient, but it works
- one major mod i did was remove one of the buffers from the 2d implemntation. Originally there were two buffers and the ripples go out in all direction. Now the ripples move out in only one direction, but you can get away with it because it looks like the waves are being blown
- the rain function, which i use to generate the waves checks each sopt for a hit and then creates a ripple. This is innefficient. You can just as easily have the program select random points and then assign the values. This saves on checking each update
- my access method for the elements in the array of points is a bit involved. You can try to use pointers to pointers and create a multidimentional array of points. That way when you want to access something its faster and no calculation has to be preformed.
One more thing:
- If you decide to do reflections using the stencil method then your water will look like a mirror. If you texture my ripples, that is, if you cube map the ripples, then you will produce a neat effect. If you take a look at my demo, particularly at a point where multiple colors on the water''s texture are (looks like a blue rainbow on the water''s surface) then you will see that the reflection sort of ripples along with the water. It looks like a real reflection off the surface of the water because the texture moves along with the ripples. If you do this method you will also find that transparent objects are not a problem.
All you do is:
*just draw the scene upside down (with the transparent objects).
*Create a texture out of the scene.
*Clear the scene.
*Draw the real scene.
*Draw the water with the texture you created onto the new scene.
One last question:
As far as i know OGL has different buffers. If you use multithreading, could you not draw the scene onto the frame buffer while generating the reflection? That way, once both tasks are complete, you could just draw the water. Just a thought, not too sure if it will work, or should i say help?
"Free advice is seldom cheap."
-- Rule of Acquisition #59

If this is a school project (which grade btw?) then shouldnt you be woried about the speed(and efficiency) of your program?
If you are then i think i may help you a bit with my water algorithm:
- i took the algorithm originally from a 2d implementation and reprogrammed it for 3d so it may not be all that efficient, but it works
- one major mod i did was remove one of the buffers from the 2d implemntation. Originally there were two buffers and the ripples go out in all direction. Now the ripples move out in only one direction, but you can get away with it because it looks like the waves are being blown
- the rain function, which i use to generate the waves checks each sopt for a hit and then creates a ripple. This is innefficient. You can just as easily have the program select random points and then assign the values. This saves on checking each update
- my access method for the elements in the array of points is a bit involved. You can try to use pointers to pointers and create a multidimentional array of points. That way when you want to access something its faster and no calculation has to be preformed.
One more thing:
- If you decide to do reflections using the stencil method then your water will look like a mirror. If you texture my ripples, that is, if you cube map the ripples, then you will produce a neat effect. If you take a look at my demo, particularly at a point where multiple colors on the water''s texture are (looks like a blue rainbow on the water''s surface) then you will see that the reflection sort of ripples along with the water. It looks like a real reflection off the surface of the water because the texture moves along with the ripples. If you do this method you will also find that transparent objects are not a problem.
All you do is:
*just draw the scene upside down (with the transparent objects).
*Create a texture out of the scene.
*Clear the scene.
*Draw the real scene.
*Draw the water with the texture you created onto the new scene.
One last question:
As far as i know OGL has different buffers. If you use multithreading, could you not draw the scene onto the frame buffer while generating the reflection? That way, once both tasks are complete, you could just draw the water. Just a thought, not too sure if it will work, or should i say help?
"Free advice is seldom cheap."
-- Rule of Acquisition #59
quote:
However I finally put my brain to work and thought about the rendering to texture method - the one last thing I''m having trouble with is calculating contiguous texture coordinates for the reflected image. Once I capture the reflected image (from the frame buffer - how do I access the color buffer? glCopyTexImagexx and glCopyPixels, glDrawPixels etc all deal with the frame buffer), it''s pretty much "out of sync" compared to the rest of the world.
The lesson on radial blur shows how to capture the image from the frame buffer.
Anyway, about the "out of sync" part, cube mapping should take care of orientation. Ask RipTorn, he managed to pull it off. If that doesnt work you could always fool around with the texture matrix. Maybe setting it to the viewport matrix, or maybe it''s inverse might work - just guessing

"Free advice is seldom cheap."
-- Rule of Acquisition #59
The thing is - the school (uni, 2nd course) I go to kinda sucks when it comes to summing up all the really cool things they teach us there. I mean - our half-semester assignment in "Progamming in C", the subject, was something like this "read a bunch of lines from a file, find lines that contain the same person''s name and merge them; there are no mistakes in the source file so basically you don''t have to do zip. you can use any means you see fit although we just leraned what pointers are and we will never go as far as learning what stl is or what cool things you can actually do with templates and, alas, we will never learn that OpenGL and DirectX are API''s, not operating systems, and we will never learn how to make sounds aside from the fact that WinAMP runs from the StartMenu and there is no icon for it on the desktop". I''ll stop the sarcasm here. Anyway, we have this subject we can take that involves ganging up with a couple of people and creating "an IT project", so I kinda figured it''d be nice if me, a web designer and a couple of others joined our forces against boredom and created something cool - a game, naturellement. The idea is there (and a cool one I dare say
) - my problem is that I have to write all of the code since none of them can program. Bah! Well - good for me because I get to get to know all the cool stuff and they get most of the credit - but I guess life is always like that...
Anyways - the sequence of events you described is how I''m doing things, but once I capture the reflection, I can''t figure out how to bind the texture to the water surface. As for the island demo - the reflection there is kinda wrong, imo - it''s mapped incorrectly (I think) because there is no way you can see the reflection of that pretty island and the nice palm tree.
Crispy

Anyways - the sequence of events you described is how I''m doing things, but once I capture the reflection, I can''t figure out how to bind the texture to the water surface. As for the island demo - the reflection there is kinda wrong, imo - it''s mapped incorrectly (I think) because there is no way you can see the reflection of that pretty island and the nice palm tree.
Crispy
"Literally, it means that Bob is everything you can think of, but not dead; i.e., Bob is a purple-spotted, yellow-striped bumblebee/dragon/pterodactyl hybrid with a voracious addiction to Twix candy bars, but not dead."- kSquared
Yah, i sort of got lazy when my many attempts at a fast reflection were foiled by illegal operations and the such. I got fed up and quit but still ended up with a half decent program. The texturing looks messed up because of the sphere mapping. The reason i use sphere mapping was because it constantly changed and produced nice "rainbows" and patterns on the surface of the water.
As for me, im in my last year of highschool. We learnt bullshit in programming - turing and pascal - and even then i was the only one who could keep up with the course. Luckily i took it in grade 11 so i moved on as quickly as possible. My final project for that grade 12 was my own 3d api - rendered a pretty mean 3d chess board.
Anyway, you were saying that this is a second course in university programming? I guess im in store for a long and expensive refresher on stuff that can be learnt in 5 secs on the internet, while the cool stuff isnt even mentioned - i think you know what im talking about
What we will do for a piece of paper *sigh*
(bachelors degree).
We did something similar in OAC problem solving. In that course you and a group are supposed to gang up and create a product. We had a pretty good team. We had a modelor/animator, a flash programmer, and someone to handle all the paperwork. I did the coding. We ended up with a demo of a game, and we wrote our own, fairly primitave engine. The project was reprogramming the game "Earthbound" originally for the snes. We ended up with a 3rd person interface, animation, and music. All you really could do is walk about a museum showcasing the enemies in the game, and change the environment music. We also did two other levels, that had animated doors and other stuff. The flash guy did a web page that was exactly like the original 2d game - it was neat. Our final looked pretty good among the other front page web pages the other groups did. The only thing that we had a problem with was getting everything to work together - the code seemed to be merging together into a big mess. Had we done that the game would have progressed easier and would have been much better. If you guys plan to succeed at making a game i suggust you read the article "code on the cob". It will really help. As for the water, i suggust you do it quickly and focus on the rest of the game. Debugging can take longer than you think
Eye candy really isnt that important...but it is fun to program
"Free advice is seldom cheap."
-- Rule of Acquisition #59
As for me, im in my last year of highschool. We learnt bullshit in programming - turing and pascal - and even then i was the only one who could keep up with the course. Luckily i took it in grade 11 so i moved on as quickly as possible. My final project for that grade 12 was my own 3d api - rendered a pretty mean 3d chess board.
Anyway, you were saying that this is a second course in university programming? I guess im in store for a long and expensive refresher on stuff that can be learnt in 5 secs on the internet, while the cool stuff isnt even mentioned - i think you know what im talking about


quote:
Anyway, we have this subject we can take that involves ganging up with a couple of people and creating "an IT project", so I kinda figured it''d be nice if me, a web designer and a couple of others joined our forces against boredom and created something cool - a game, naturellement. The idea is there (and a cool one I dare say ) - my problem is that I have to write all of the code since none of them can program.
We did something similar in OAC problem solving. In that course you and a group are supposed to gang up and create a product. We had a pretty good team. We had a modelor/animator, a flash programmer, and someone to handle all the paperwork. I did the coding. We ended up with a demo of a game, and we wrote our own, fairly primitave engine. The project was reprogramming the game "Earthbound" originally for the snes. We ended up with a 3rd person interface, animation, and music. All you really could do is walk about a museum showcasing the enemies in the game, and change the environment music. We also did two other levels, that had animated doors and other stuff. The flash guy did a web page that was exactly like the original 2d game - it was neat. Our final looked pretty good among the other front page web pages the other groups did. The only thing that we had a problem with was getting everything to work together - the code seemed to be merging together into a big mess. Had we done that the game would have progressed easier and would have been much better. If you guys plan to succeed at making a game i suggust you read the article "code on the cob". It will really help. As for the water, i suggust you do it quickly and focus on the rest of the game. Debugging can take longer than you think


"Free advice is seldom cheap."
-- Rule of Acquisition #59
quote:
Original post by vincoof
5 Render the reflected scene in depth buffer only (not in color buffer), with stencil test enabled (in order to render reflections only where it should)
I think this is last thing that''s messing up the image - how do I render stuff into a certain buffer? Here''s a screenshot of what I think you have in mind:

1. As you can see the reflection of a mountain in the background is visible on this side of an island (which is wrong)
2. There is still a gap between the reflected and the actual image - the reflection starts well below water level/off the coast (which is also wrong). How do I fix this?
RipTorn - I understand you used cube mapping to do your reflections. Is there another way (texture matrix manipulation? - how?) because I''d like people with non-gf class cards to be able to see nice reflections as well (cards that don''t support hardware cube mapping) and are too slow for the stencil buffer solution.
Crispy
"Literally, it means that Bob is everything you can think of, but not dead; i.e., Bob is a purple-spotted, yellow-striped bumblebee/dragon/pterodactyl hybrid with a voracious addiction to Twix candy bars, but not dead."- kSquared
ok... ok... ok... 
I'm going to go over this my way... withe the help of Ati
this does not need the stencil buffer for a start. Nor cube maps, Not pixel buffers (but they would help)...
OK..
ok. first things first, create a 256x256 texture (or such) that matches the format of the colour buffer - ie, if your in 32bit, make it 32bit (RGBA), if your in 16, then it must be a 16 bit format too..
to start with, we render the reflection onto the screen, in a corner, or whatnot, the size of the reflection texture (say, 256x256)... (ie, glViewPort)
now,
we take the water plane.
say it's an easy one, flat along x,y where z=0... thats nice and simple.
Now.
take the camera position.. say, 5,6,13
reflect that along the mirror... which is easy, since it's flat on along z...
the reflected camera position is now 5,6,-13... Ie, under the water...
Now, take all your camera view direction, and reflect that as well... so if the camera is pointing down slightly, the reflected camera must point up slightly...
Now, enable a clip plane running along the water plane... since the water is running alone z=0, that makes the clip plane really easy too... 0,0,1,0.... ie, it's a 4 component plane equation.. x,y,z,d... (look it up distance to plane if your not sure)
Now, render the mountains... it's a good idea to pre calculate the stuff above the water, so you don't need to waste time drawing stuff that the clip plane will kill off...
Now. we have a reflection
Copy it the 256x256 texture! (glCopyTexSubImage2D)
clear the colour buffer and depth buffer (in one call), we don't want to see that texture..
(note, these two very expensive operations are not needed when using a pixel buffer, but your tnt may not support them - I'm not sure)
OK..
set up your normal camera
render your mountains...
then,
this is the bit where I'm going to leave the code up to you to get right, because I can't do this off the top of my head, all I can tell you is the last time I did it, in that shot I showed, it involved texture coord generation using eye linear mode on S T, R and possible Q coords, and a texture matrix using glFustrum (although a guess would say that gluPerspective would be better)...
this is where you render the water... preferably as a mesh, so there are a decent number of verticies to generate tex coords off of (NOT as one gigantic huge quad!)..
I'm sure there is a much better way to do this (and manually using the CPU to place the vertices with line/plane intercepts from the corners of the frustum would be MUCH better, but thats how I did it... back then...
the end result, you have a reflection :-)
heres the bit from ATi:
this is a rip from the nature demo, it's not perfect, buy you should be able to see what I've just told you in it..

note they only render some small stuff in the reflection (the stuff around the shore).. which makes it harder to tell..
[edit]
mentally flip the reflection image vertically if it doesn't click.... that might help the idea of viewing from below the water...
| - Project-X - my mega project.. big things comming soon - | - adDeath - an ad blocker I made - | - email me - |
[edited by - RipTorn on November 26, 2002 6:59:02 AM]

I'm going to go over this my way... withe the help of Ati

this does not need the stencil buffer for a start. Nor cube maps, Not pixel buffers (but they would help)...
OK..
ok. first things first, create a 256x256 texture (or such) that matches the format of the colour buffer - ie, if your in 32bit, make it 32bit (RGBA), if your in 16, then it must be a 16 bit format too..
to start with, we render the reflection onto the screen, in a corner, or whatnot, the size of the reflection texture (say, 256x256)... (ie, glViewPort)
now,
we take the water plane.
say it's an easy one, flat along x,y where z=0... thats nice and simple.
Now.
take the camera position.. say, 5,6,13
reflect that along the mirror... which is easy, since it's flat on along z...
the reflected camera position is now 5,6,-13... Ie, under the water...
Now, take all your camera view direction, and reflect that as well... so if the camera is pointing down slightly, the reflected camera must point up slightly...
Now, enable a clip plane running along the water plane... since the water is running alone z=0, that makes the clip plane really easy too... 0,0,1,0.... ie, it's a 4 component plane equation.. x,y,z,d... (look it up distance to plane if your not sure)
Now, render the mountains... it's a good idea to pre calculate the stuff above the water, so you don't need to waste time drawing stuff that the clip plane will kill off...
Now. we have a reflection

Copy it the 256x256 texture! (glCopyTexSubImage2D)
clear the colour buffer and depth buffer (in one call), we don't want to see that texture..
(note, these two very expensive operations are not needed when using a pixel buffer, but your tnt may not support them - I'm not sure)
OK..
set up your normal camera
render your mountains...
then,
this is the bit where I'm going to leave the code up to you to get right, because I can't do this off the top of my head, all I can tell you is the last time I did it, in that shot I showed, it involved texture coord generation using eye linear mode on S T, R and possible Q coords, and a texture matrix using glFustrum (although a guess would say that gluPerspective would be better)...
this is where you render the water... preferably as a mesh, so there are a decent number of verticies to generate tex coords off of (NOT as one gigantic huge quad!)..
I'm sure there is a much better way to do this (and manually using the CPU to place the vertices with line/plane intercepts from the corners of the frustum would be MUCH better, but thats how I did it... back then...
the end result, you have a reflection :-)
heres the bit from ATi:
this is a rip from the nature demo, it's not perfect, buy you should be able to see what I've just told you in it..

note they only render some small stuff in the reflection (the stuff around the shore).. which makes it harder to tell..
[edit]
mentally flip the reflection image vertically if it doesn't click.... that might help the idea of viewing from below the water...
| - Project-X - my mega project.. big things comming soon - | - adDeath - an ad blocker I made - | - email me - |
[edited by - RipTorn on November 26, 2002 6:59:02 AM]
Those overlapping mountains may be caused by two symptoms :
1- you''re not flipping the modelview matrix along the y-axis correctly (for instance, calling glScalef(1, -1, 1) is not enough if the water altitude is different than 0).
2- you''re messsing up the depth buffer which finally don''t quite get what is near and what is far.
For texture reflections, there is a method that is not really optimized but that is very simple (at least I think!) :
1- call glViewport with the texture size (power-of-two certainly) and clear it (glClear)
2- flip the scene along the z-axis and render it (don''t forget the clipping plane)
3- get this picture with glCopyTexImage
4- call glViewport back with the "normal" size and clear it
5- render the scene, without flip
In that last point, when you render your water surface you may use glTexGen with GL_EYE_LINEAR. This will map automatically the grabbed texture (in point "3"). There is very little setup there : 1 call to glTexEnv with GL_EYE_LINEAR, 1 call to glTexEnv with the corresponding eye equation, and 2 calls to glEnable with GL_TEXTURE_GEN_S and GL_TEXTURE_GEN_T.
1- you''re not flipping the modelview matrix along the y-axis correctly (for instance, calling glScalef(1, -1, 1) is not enough if the water altitude is different than 0).
2- you''re messsing up the depth buffer which finally don''t quite get what is near and what is far.
For texture reflections, there is a method that is not really optimized but that is very simple (at least I think!) :
1- call glViewport with the texture size (power-of-two certainly) and clear it (glClear)
2- flip the scene along the z-axis and render it (don''t forget the clipping plane)
3- get this picture with glCopyTexImage
4- call glViewport back with the "normal" size and clear it
5- render the scene, without flip
In that last point, when you render your water surface you may use glTexGen with GL_EYE_LINEAR. This will map automatically the grabbed texture (in point "3"). There is very little setup there : 1 call to glTexEnv with GL_EYE_LINEAR, 1 call to glTexEnv with the corresponding eye equation, and 2 calls to glEnable with GL_TEXTURE_GEN_S and GL_TEXTURE_GEN_T.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement