gpt4 book ai didi

c++ - 在没有着色器的情况下在 OpenGL 中渲染深度缓冲区

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:10:16 25 4
gpt4 key购买 nike

我有以下 C++ OpenGL 代码,它呈现场景中像素的 RGB 值:

glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, _windowWidth, _windowHeight);

glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);

glMatrixMode( GL_PROJECTION );
glLoadIdentity();

float aspectRatio = float(_windowWidth) / float(_windowHeight);
gluPerspective(60.0f, aspectRatio, 0.1f, 1000.0f);

glMatrixMode(GL_MODELVIEW);
_camera.Update();
glLoadMatrixf(_camera.Matrix()[0]);

_scene.Render();

glutSwapBuffers();

但是,我想渲染场景的深度缓冲区,即每个像素值都是相机前面的 z 距离。

也就是说,我目前正在获取顶部图像,但我想要底部图像(来自 here 的图像):

enter image description here

我该怎么办?我不认为我在使用着色器(是吗?)——以及给出的建议 here似乎暗示这可能只有着色器才有可能。

还有this code ,尽管这看起来也像是在使用着色器。修改我的代码以使用着色器有多难?

最佳答案

您可以通过 glReadPixels()GL_DEPTH_COMPONENT 将深度缓冲区写入主机内存,然后将缓冲区作为 GL_LUMINANCE 纹理重新上传:

screenshot

#include <GL/glew.h>
#include <GL/glut.h>

#include <vector>
using namespace std;

void display()
{
int w = glutGet( GLUT_WINDOW_WIDTH );
int h = glutGet( GLUT_WINDOW_HEIGHT );

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double ar = w / static_cast< double >( h );
const float zNear = 0.1;
const float zFar = 10.0;
gluPerspective( 60, ar, zNear, zFar );

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( 0, 0, -4 );

static float angle = 0;
angle += 3;

glPushMatrix();
glRotatef( angle, 0.1, 0.5, 0.3 );
glColor3ub( 255, 0, 0 );
glutSolidTeapot( 1 );
glPopMatrix();

vector< GLfloat > depth( w * h, 0 );
glReadPixels( 0, 0, w, h, GL_DEPTH_COMPONENT, GL_FLOAT, &depth[0] );

// linearize depth
// http://www.geeks3d.com/20091216/geexlab-how-to-visualize-the-depth-buffer-in-glsl/
for( size_t i = 0; i < depth.size(); ++i )
{
depth[i] = ( 2.0 * zNear ) / ( zFar + zNear - depth[i] * ( zFar - zNear ) );
}

static GLuint tex = 0;
if( tex > 0 )
glDeleteTextures( 1, &tex );
glGenTextures(1, &tex);
glBindTexture( GL_TEXTURE_2D, tex);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_LUMINANCE, w, h, 0, GL_LUMINANCE, GL_FLOAT, &depth[0] );

glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, w, 0, h, -1, 1 );

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

glEnable( GL_TEXTURE_2D );
glColor3ub( 255, 255, 255 );
glScalef( 0.3, 0.3, 1 );
glBegin( GL_QUADS );
glTexCoord2i( 0, 0 );
glVertex2i( 0, 0 );
glTexCoord2i( 1, 0 );
glVertex2i( w, 0 );
glTexCoord2i( 1, 1 );
glVertex2i( w, h);
glTexCoord2i( 0, 1 );
glVertex2i( 0, h );
glEnd();
glDisable( GL_TEXTURE_2D );

glutSwapBuffers();
}

void timer( int value )
{
glutPostRedisplay();
glutTimerFunc( 16, timer, 0 );
}

int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutInitWindowSize( 600, 600 );
glutCreateWindow( "GLUT" );
glewInit();
glutDisplayFunc( display );
glutTimerFunc( 0, timer, 0 );
glEnable( GL_DEPTH_TEST );
glutMainLoop();
return 0;
}

到 CPU 的往返速度不是很快(尤其是在主机端线性化的情况下)。您可以使用 PBOs使其成为 GPU 到 GPU 的传输,但您将失去线性化。

关于c++ - 在没有着色器的情况下在 OpenGL 中渲染深度缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24266815/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com