【问题标题】:OpenGL Render To Texture (To screen) blankOpenGL 渲染到纹理(到屏幕)空白
【发布时间】:2014-03-18 09:23:48
【问题描述】:

我在屏幕上绘制了很多点,我试图让它们渲染到纹理以进行后期处理,然后再将纹理渲染回屏幕。目前我正试图通过并获得纹理渲染,但它似乎什么也没渲染。

我的片段着色器工作(没有渲染到纹理 - 在 mEllipseTextureProgram 中使用波纹管),我所做的唯一更改是包含

out vec3 color;

渲染到纹理本身(显然更改为 color= 而不是 gl_FragColor=)。下面引用的第二个程序(mScreenProgram)如下:

顶点着色器:

    #version 330 compatibility
    in vec2 vUV;

    out vec2 UV;

    void main()
    {
        gl_Position = gl_Vertex;
        UV = vUV;
    }

片段着色器:

    #version 330 core

    in vec2 UV;

    out vec3 color;

    uniform sampler2D renderedTexture;

    void main(){
        color = texture( renderedTexture, UV ).xyz; 
    }

我将渲染设置为纹理 stuff,如下所示:

    glGenFramebuffers(1, &mGaussianFrameBuffer);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mGaussianFrameBuffer);
    glGenTextures(1, &mGaussianRenderTexture);
    glBindTexture(GL_TEXTURE_2D, mGaussianRenderTexture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 
                        1024,
                        768, 
                        0, GL_RGBA, GL_UNSIGNED_BYTE,
                        NULL); 
    glBindTexture(GL_TEXTURE_2D, 0);
    glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mGaussianRenderTexture, 0);
    glGenTextures(1, &mGaussianDepthBuffer);
    glBindTexture(GL_TEXTURE_2D, mGaussianDepthBuffer);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 
                        1024,
                        768, 
                        0, GL_DEPTH_COMPONENT, GL_FLOAT,
                        NULL); 
    glBindTexture(GL_TEXTURE_2D, 0);
    glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, mGaussianDepthBuffer, 0);

返回一个成功的 GL_FRAMEBUFFER_COMPLETE。

以下是三个相关的渲染函数:

    void Draw()
    {
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        //gluPerspective(45, 1024.0/768.0, 3.0, 20000);
        perspectiveGL(45, 1024.0/768.0, 1.0, 20000);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glPushMatrix();
        gluLookAt(cameraData[0],cameraData[1], cameraData[2],
                  cameraData[3],cameraData[4], cameraData[5],
                  0,1,0);

        glEnable(GL_DEPTH_TEST);
        glClearColor( 0.2f, 0.2f, 0.9f, 0.0f );
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  

        // OTHER STUFF POTENTIALLY DRAW HERE IN DIFFERENT WAYS

        glUseProgram(mEllipseTextureProgram);
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mGaussianFrameBuffer);
        GLuint attachments[1] = {GL_COLOR_ATTACHMENT0};
        glDrawBuffers(1, attachments);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        DrawEllipseToTexture();
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
        glUseProgram(mScreenProgram);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        DrawTextureToScreen();
    }

    void DrawEllipseToTexture()
    {
        glEnableClientState(GL_VERTEX_ARRAY); 

        glBindBuffer(GL_ARRAY_BUFFER, mVBO);
        glVertexPointer(3, GL_FLOAT, 0, 0);

        glEnable(GL_PROGRAM_POINT_SIZE);

        glEnable(GL_POINT_SPRITE);

        glEnable( GL_TEXTURE_2D );
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, mBMP);
        glProgramUniform1i(mEllipseTextureProgram, mTextureLocation, 0);

        glBindBuffer(GL_ARRAY_BUFFER, mUV);
        glEnableVertexAttribArray(mTexCoordLocation);
        glVertexAttribPointer(mTexCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);

        glBindBuffer(GL_ARRAY_BUFFER, mSpacial);
        glEnableVertexAttribArray(mSpacialLocation);
        glVertexAttribPointer(mSpacialLocation, 1, GL_FLOAT, GL_FALSE, 0, 0);

        glBindBuffer(GL_ARRAY_BUFFER, mNormals);
        glEnableVertexAttribArray(mNormalLocation);
        glVertexAttribPointer(mNormalLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);

        glBindBuffer(GL_ARRAY_BUFFER, mVerticalSpat);
        glEnableVertexAttribArray(mMajorLocation);
        glVertexAttribPointer(mMajorLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);

        glBindBuffer(GL_ARRAY_BUFFER, mHorizontalSpat);
        glEnableVertexAttribArray(mMinorLocation);
        glVertexAttribPointer(mMinorLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);

        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
        glEnable( GL_BLEND );

        glDrawArrays(GL_POINTS, 0, mNumberPoints);

        glBindBuffer(GL_ARRAY_BUFFER, 0);

        glDisable( GL_TEXTURE_2D );
        glDisableVertexAttribArray(mSpacialLocation);
        glDisable(GL_POINT_SPRITE);
        glDisable( GL_POINT_SMOOTH );
        glDisable(GL_PROGRAM_POINT_SIZE);
        glDisableClientState(GL_VERTEX_ARRAY); 
    }

    void DrawTextureToScreen()
    {
        glEnableClientState(GL_VERTEX_ARRAY); 

        glEnable( GL_TEXTURE_2D );
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, mGaussianRenderTexture);
        glProgramUniform1i(mScreenProgram, mGaussianTextureLocation, 0);

        GLfloat vertices[] = { -1, -1, 2,
                               1, -1, 2,
                               1, 1, 2,
                               -1, 1, 2 };
        GLfloat uv[] = { 0, 0,
                        1, 0,
                        1, 1,
                        0, 1,};

        glVertexPointer(3, GL_FLOAT, 0, vertices);

        glEnableVertexAttribArray(mGaussianUV);
        glVertexAttribPointer(mGaussianUV, 2, GL_FLOAT, GL_FALSE, 0, uv);

        glDrawArrays(GL_TRIANGLES, 0, 4);

        glDisable ( GL_TEXTURE_2D );
        glDisableClientState(GL_VERTEX_ARRAY); 
    }

【问题讨论】:

    标签: c++ opengl glsl shader render


    【解决方案1】:

    我仍然不知道我上面的解决方案出了什么问题(我尝试了很多变体) - 但是按照本教程让它工作:Tutorial

    【讨论】:

      【解决方案2】:

      我通常使用`out vec4 color',我不确定在你将纹理类型设置为GL_RGBA然后为每个片段返回vec3之后它是否会起作用。

      而且我没有看到您在代码中设置 glViewport(),这意味着没有指定仿射变换来将屏幕位置 (x,y) 从 NDC 映射到屏幕空间。如果您在 fbo 渲染期间没有视口,那肯定不会给您任何帮助。

      我和你一样在类似的情况下挣扎。从 GL 文档而不是博客中阅读您不知道的功能是正确理解事物的更好方法... :)

      【讨论】: