【问题标题】:Can't render to texture (anymore)无法渲染到纹理(不再)
【发布时间】:2013-05-02 22:08:25
【问题描述】:

几个月前我实现了一个体积渲染演示应用程序。在 Windows XP-32bits 中一切正常。我使用 OpenGL -glew 和 SFML2.0-rc 作为窗口和输入库。 现在。我最近才搬到 Windows 7-64 位。

程序无法开箱即用,SFML 似乎崩溃了。我将窗口库更改为 GLFW,仍然使用 Glew。通过查看代码,我意识到非常基本的纹理渲染技术不再起作用。 因此,我将所有内容都分解为最小的情况,以便我可以将其呈现给您。 (我还移植到 Qt5.0.2 以交叉检查我的假设:相同的诊断)。

所以问题来了:

该程序应该在通道 1 中渲染一个简单的单位立方体,其中正面剔除到纹理。然后在通道 2 中,我切换到背面剔除并再次渲染相同的立方体。在片段着色器(第 2 步)中,我可以选择读取纹理(从第 1 步)并将其写入输出:但是当我应该看到正面剔除的立方体时,我得到一个大黑屏......

初始化代码:

glGenFramebuffers(1, &raycastingFrameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, raycastingFrameBuffer);    
glGenTextures(1, &cubeRenderTexture);
glBindTexture(GL_TEXTURE_2D, cubeRenderTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, viewWidth, viewHeight, 0, GL_RGBA, GL_FLOAT, 0);
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_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, cubeRenderTexture, 0);

GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, DrawBuffers);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    return false;
glBindFramebuffer(GL_FRAMEBUFFER, 0);

渲染通道:

    // PASS ONE :
    //              render the unit cube (with front face culling) to texture
    //              we end up with a texture whose colors represent outgoing rays locations on the box
    //
    glBindFramebuffer(GL_FRAMEBUFFER, raycastingFrameBuffer);
    glEnable(GL_CULL_FACE);
    glDisable(GL_DEPTH_TEST);
    glViewport(0, 0, viewWidth, viewHeight);
    glCullFace(GL_FRONT);
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(shaderRaycasting1.getProgramID());

        glBindBuffer(GL_ARRAY_BUFFER, cube_VBO_ID);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL + 0);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL + 108*sizeof(float));
        glEnableVertexAttribArray(1);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        glUniformMatrix4fv(glGetUniformLocation(shaderRaycasting1.getProgramID(), "modelview"), 1, GL_TRUE, modelview.getData());
        glUniformMatrix4fv(glGetUniformLocation(shaderRaycasting1.getProgramID(), "projection"), 1, GL_TRUE, projection.getData());

        glDrawArrays(GL_TRIANGLES, 0, 36);

        glDisableVertexAttribArray(1);
        glDisableVertexAttribArray(0);

    glUseProgram(0);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glEnable(GL_DEPTH_TEST);

    // PASS TWO :
    //              render the unit cube (with back face culling this time)
    //              we get colors representing ray entrance locations on the box
    //
    glViewport(0, 0, viewWidth, viewHeight);
    glCullFace(GL_BACK);
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClearDepth(1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glUseProgram(shaderRaycasting2.getProgramID());

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, cubeRenderTexture);
        glUniform1i(cubeRenderTextureID, 0);

        glUniform1i(glGetUniformLocation(shaderRaycasting2.getProgramID(), "displayWidth"), (GLint) viewWidth);
        glUniform1i(glGetUniformLocation(shaderRaycasting2.getProgramID(), "displayHeight"), (GLint) viewHeight);

        glBindBuffer(GL_ARRAY_BUFFER, cube_VBO_ID);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL + 0);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL + 108*sizeof(float));
        glEnableVertexAttribArray(1);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        glUniformMatrix4fv(glGetUniformLocation(shaderRaycasting1.getProgramID(), "modelview"), 1, GL_TRUE, modelview.getData());
        glUniformMatrix4fv(glGetUniformLocation(shaderRaycasting1.getProgramID(), "projection"), 1, GL_TRUE, projection.getData());

        glDrawArrays(GL_TRIANGLES, 0, 36);

        glDisableVertexAttribArray(1);
        glDisableVertexAttribArray(0);
        glActiveTexture(0);

    glUseProgram(0);

...最后是最小片段着色器:

#version 330

in vec3 color;
uniform int displayWidth;
uniform int displayHeight;
uniform sampler2D cubeTex;
layout (location = 0) out vec4 outColor;

void main()
{
    float viewWidth = displayWidth;
    float viewHeight = displayHeight;

    vec3 boxIn  = color;
    vec2 cubeCoord = vec2( (gl_FragCoord.x - 0.5) / viewWidth,   (gl_FragCoord.y - 0.5) / viewHeight);
    vec3 boxOut = texture(cubeTex, cubeCoord).rgb;
    vec3 rayColor = boxOut;       

    outColor = vec4(rayColor, 1); // i get a black screen here ...
}

一些遗言: - 一切编译都没有警告,没有错误(演示的 Qt 5.0.2 端口相同) - 我尝试了所有可能的小“调整”,例如 glEnable(...)、更改 opengl 版本、使用 texelFetch 等等……显然我找不到这段代码有什么问题。 - 原始代码要复杂得多并且确实可以运行,但在 XP 而不是 Win7 上。 - 等等。

【问题讨论】:

  • [添加] 安装 Windows 7 时我做的第一件事是确保 GPU 驱动程序是最新的 - 没有问题。
  • [已解决] 问题已解决。与驱动程序无关,Windows 7 或 glsl 纹理访问不起作用。这是上面代码中的一个简单的剪切和粘贴错误。我的错。很抱歉没有这个问题。

标签: opengl windows-7 glsl


【解决方案1】:

您是否安装了从供应商驱动程序支持网站下载的用于 GPU 的原始供应商驱动程序,还是仍然安装了 Windows 7 附带的残缺版本?

Windows 7 附带的驱动程序不提供现代 OpenGL 支持。 Microsoft 剥离了任何 OpenGL,Windows-7 的默认 OpenGL 实现只是 Direct3D 之上的 OpenGL-1.4 仿真。

如果您还没有安装,请从您的 GPU 供应商处下载原始驱动程序并安装这些驱动程序,然后报告结果是否有所改变。

【讨论】:

    猜你喜欢
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 2018-05-31
    • 1970-01-01
    相关资源
    最近更新 更多