2014-06-17 3 views
4

않고는 OpenGL에서 깊이 버퍼를 렌더링 나는 장면에서 픽셀의 RGB 값을 렌더링하는 다음과 같은 C++의 OpenGL 코드가 있습니다 그러나쉐이더

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과를 통해 메모리를 호스팅 할 depthbuffer 후루룩 소리 내며 먹기 수
+0

저는 그래픽 전문가가 아니지만 그 공이 phong-blinn, 아마도 원숭이와 큐브처럼 보입니다. 저는 쉐이더를 사용하고 있다고 생각합니다. 그러나 요점은 : 코드없이 어떻게 도울 수 있습니까? –

답변

5

GL_LUMINANCE 텍스처로 버퍼를 재 업로드 : CPU가되지 않습니다에

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; 
} 

라운드 트립 대단히 빠릅니다 (특히 호스트 측 선형화의 경우). PBOs을 사용하면 GPU-GPU 전송으로 설정할 수 있지만 선형화는 손실됩니다.

5

Framebuffer Object (fbo)을 사용하여 심도 값을 텍스처로 렌더링 할 수 있습니다. 그런 다음 두 번째 렌더링 패스에서 전체 뷰포트에 쿼드를 그리고 깊이 텍스처를 적용합니다.

또는 단편 패스로 렌더링 할 수있는 단편 셰이더를 깊이에 따라 출력하는 단편 셰이더를 작성할 수 있습니다.

here 몇 가지 예를 참조하십시오. 'fbo'에 대한 더 많은 검색을 찾을 수 있습니다.