Skip to main content
Commonmark migration
Source Link

And so, if you can't clean the buffer, there is a trick I learned back when I was trying to do 3D graphics back in the 90's, before we had (???) cards, and things that would do for us, and OpenGL to do it for us.

 

You had to, actually, go draw pixel by pixel, via triangle, and you had the texture coordinate and you would be updating them as you went.

 

And you'd have the kind of the depth of it. You have to update that as you went along the triangle. And then to avoid triangles being printed over each other when they shouldn't be, that depth should be stored in the buffer.

 

(...)

 

And so, the big problem with the z-buffer is that you got a screen. (...) You have to clear it every single time, if you were thinking naively about it. And that just kills the game.

And so the path-finding buffer would work like that in Dwarf Fortress. I know what the longest path could be, and then that's the value we work with, and the I had (???) reset the floor. So that we were working from 0 to 200000, and 200 to 400, and 400 to 600...

 

And I almost never have to clean the path map now; it cleans like every 100000 paths that are made through a section of it.

Depth Buffer Precision

 

When you select a pixelformat for your window, and you ask for a Depth Buffer, the depth buffer is typically stored as a Normalized Integer with a bitdepth of 16, 24, or 32 bits.

 

Note: You can create images with true floating-point depth formats. But these can only be used with Framebuffer Objects, not the Default Framebuffer.

 

In OpenGL, all depth values lie in the range [0, 1]. The integer normalization process simply converts this floating-point range into integer values of the appropriate precision. It is the integer value that is stored in the depth buffer.

 

(...)

 

Now that the misconception about depth buffers being floating point is resolved, what is wrong with this call?

 
glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, mypixels);
 

Because the depth format is a normalized integer format, the driver will have to use the CPU to convert the normalized integer data into floating-point values. This is slow.

 
 

Swap Buffers

 

A modern OpenGL program should always use double buffering. A modern 3D OpenGL program should also have a depth buffer.

 

Render sequence should be like this:

 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
RenderScene();
SwapBuffers(hdc);  //For Windows
 

The buffers should always be cleared. On much older hardware, there was a technique to get away without clearing the scene, but on even semi-recent hardware, this will actually make things slower. So always do the clear.

And so, if you can't clean the buffer, there is a trick I learned back when I was trying to do 3D graphics back in the 90's, before we had (???) cards, and things that would do for us, and OpenGL to do it for us.

 

You had to, actually, go draw pixel by pixel, via triangle, and you had the texture coordinate and you would be updating them as you went.

 

And you'd have the kind of the depth of it. You have to update that as you went along the triangle. And then to avoid triangles being printed over each other when they shouldn't be, that depth should be stored in the buffer.

 

(...)

 

And so, the big problem with the z-buffer is that you got a screen. (...) You have to clear it every single time, if you were thinking naively about it. And that just kills the game.

And so the path-finding buffer would work like that in Dwarf Fortress. I know what the longest path could be, and then that's the value we work with, and the I had (???) reset the floor. So that we were working from 0 to 200000, and 200 to 400, and 400 to 600...

 

And I almost never have to clean the path map now; it cleans like every 100000 paths that are made through a section of it.

Depth Buffer Precision

 

When you select a pixelformat for your window, and you ask for a Depth Buffer, the depth buffer is typically stored as a Normalized Integer with a bitdepth of 16, 24, or 32 bits.

 

Note: You can create images with true floating-point depth formats. But these can only be used with Framebuffer Objects, not the Default Framebuffer.

 

In OpenGL, all depth values lie in the range [0, 1]. The integer normalization process simply converts this floating-point range into integer values of the appropriate precision. It is the integer value that is stored in the depth buffer.

 

(...)

 

Now that the misconception about depth buffers being floating point is resolved, what is wrong with this call?

 
glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, mypixels);
 

Because the depth format is a normalized integer format, the driver will have to use the CPU to convert the normalized integer data into floating-point values. This is slow.

 
 

Swap Buffers

 

A modern OpenGL program should always use double buffering. A modern 3D OpenGL program should also have a depth buffer.

 

Render sequence should be like this:

 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
RenderScene();
SwapBuffers(hdc);  //For Windows
 

The buffers should always be cleared. On much older hardware, there was a technique to get away without clearing the scene, but on even semi-recent hardware, this will actually make things slower. So always do the clear.

And so, if you can't clean the buffer, there is a trick I learned back when I was trying to do 3D graphics back in the 90's, before we had (???) cards, and things that would do for us, and OpenGL to do it for us.

You had to, actually, go draw pixel by pixel, via triangle, and you had the texture coordinate and you would be updating them as you went.

And you'd have the kind of the depth of it. You have to update that as you went along the triangle. And then to avoid triangles being printed over each other when they shouldn't be, that depth should be stored in the buffer.

(...)

And so, the big problem with the z-buffer is that you got a screen. (...) You have to clear it every single time, if you were thinking naively about it. And that just kills the game.

And so the path-finding buffer would work like that in Dwarf Fortress. I know what the longest path could be, and then that's the value we work with, and the I had (???) reset the floor. So that we were working from 0 to 200000, and 200 to 400, and 400 to 600...

And I almost never have to clean the path map now; it cleans like every 100000 paths that are made through a section of it.

Depth Buffer Precision

When you select a pixelformat for your window, and you ask for a Depth Buffer, the depth buffer is typically stored as a Normalized Integer with a bitdepth of 16, 24, or 32 bits.

Note: You can create images with true floating-point depth formats. But these can only be used with Framebuffer Objects, not the Default Framebuffer.

In OpenGL, all depth values lie in the range [0, 1]. The integer normalization process simply converts this floating-point range into integer values of the appropriate precision. It is the integer value that is stored in the depth buffer.

(...)

Now that the misconception about depth buffers being floating point is resolved, what is wrong with this call?

glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, mypixels);

Because the depth format is a normalized integer format, the driver will have to use the CPU to convert the normalized integer data into floating-point values. This is slow.


Swap Buffers

A modern OpenGL program should always use double buffering. A modern 3D OpenGL program should also have a depth buffer.

Render sequence should be like this:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
RenderScene();
SwapBuffers(hdc);  //For Windows

The buffers should always be cleared. On much older hardware, there was a technique to get away without clearing the scene, but on even semi-recent hardware, this will actually make things slower. So always do the clear.

added 159 characters in body
Source Link
Theraot
  • 27.5k
  • 4
  • 52
  • 79

Because of that, for early games, they did a trick: They manage avoid clearing the depth buffer, but instead they make sure to that everything they are drawing is in front of what was previously there. That means higher depth values in this case.

NoteNote: He seems to be working with an inverted depth buffer (what has a higher value is ontop of what has a lower value). If he is handling the depth buffer in CPU - which seems to be the case - it is not a problem implementing it like that. To be clear: The default depth test function is to overwrite what has a higher value (That is GL_LESS in OpenGL). Instead he overwrites what has a lower value.

Because of that, for early games, they did a trick: They manage avoid clearing the depth buffer, but instead they make sure to that everything they are drawing is in front of what was previously there. That means higher depth values in this case.

Note: He seems to be working with an inverted depth buffer (what has a higher value is ontop of what has a lower value). If he is handling the depth buffer in CPU - which seems to be the case - it is not a problem implementing it like that.

Because of that, for early games, they did a trick: They avoid clearing the depth buffer, but instead they make sure to that everything they are drawing is in front of what was previously there. That means higher depth values in this case.

Note: He seems to be working with an inverted depth buffer (what has a higher value is ontop of what has a lower value). If he is handling the depth buffer in CPU - which seems to be the case - it is not a problem implementing it like that. To be clear: The default depth test function is to overwrite what has a higher value (That is GL_LESS in OpenGL). Instead he overwrites what has a lower value.

added 121 characters in body
Source Link
Theraot
  • 27.5k
  • 4
  • 52
  • 79

I want to note that it is possible to invert the way the depth buffer works (regardless if you are doing it in on CPU or in GPU - as you should). To do that, you can flip your projection matrix along the depth axis and configure the depth test function appropiately.

I would like to recommend the Computerphile series Triangles and Pixels. The video "The Visibility Problem - Computerphile" (third in the series) explains the motivation of the depth buffer and how it works.

I want to note that it is possible to invert the way the depth buffer works (regardless if you are doing it in on CPU or in GPU - as you should).

I want to note that it is possible to invert the way the depth buffer works (regardless if you are doing it in on CPU or in GPU - as you should). To do that, you can flip your projection matrix along the depth axis and configure the depth test function appropiately.

I would like to recommend the Computerphile series Triangles and Pixels. The video "The Visibility Problem - Computerphile" (third in the series) explains the motivation of the depth buffer and how it works.

added 47 characters in body
Source Link
Theraot
  • 27.5k
  • 4
  • 52
  • 79
Loading
Source Link
Theraot
  • 27.5k
  • 4
  • 52
  • 79
Loading