【问题标题】:OpenGL program works on AMD but not on NVIDIAOpenGL 程序适用于 AMD 但不适用于 NVIDIA
【发布时间】:2014-11-11 22:16:15
【问题描述】:

错误是“nvoglv64.dll 中的访问冲突读取位置”


该程序在我的旧 AMD Radeon HD 6970 上按预期工作。几天前我买了 GTX 970。很棒的卡,但我希望我的程序可以工作。我想在屏幕上渲染一个四边形以进行延迟渲染。我尝试使用 OpenGL 4.4

来源:

准备四边形:

modelMatrix = mat4(1.0);

vertices.push_back(vec3(-1.0f, -1.0f, 0.0f));
vertices.push_back(vec3(1.0f, -1.0f, 0.0f));
vertices.push_back(vec3(1.0f, 1.0f, 0.0f));

vertices.push_back(vec3(-1.0f, -1.0f, 0.0f));
vertices.push_back(vec3(1.0f, 1.0f, 0.0f));
vertices.push_back(vec3(-1.0f, 1.0f, 0.0f));

normals.push_back(vec3(0.0f, 0.0f, 1.0f));
normals.push_back(vec3(0.0f, 0.0f, 1.0f));
normals.push_back(vec3(0.0f, 0.0f, 1.0f));

normals.push_back(vec3(0.0f, 0.0f, 1.0f));
normals.push_back(vec3(0.0f, 0.0f, 1.0f));
normals.push_back(vec3(0.0f, 0.0f, 1.0f));

indices.push_back(0);
indices.push_back(1);
indices.push_back(2);

indices.push_back(0);
indices.push_back(2);
indices.push_back(3);

uvs.push_back(vec2(0.0f, 0.0f));
uvs.push_back(vec2(1.0f, 0.0f));
uvs.push_back(vec2(1.0f, 1.0f));

uvs.push_back(vec2(0.0f, 0.0f));
uvs.push_back(vec2(1.0f, 1.0f));
uvs.push_back(vec2(0.0f, 1.0f));

indexCount = static_cast<int>(indices.size());
is2D = true;

unsigned int handle[2];
glGenBuffers(2, handle);

glBindBuffer(GL_ARRAY_BUFFER, handle[0]);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, handle[1]);
glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(glm::vec3), &uvs[0], GL_STATIC_DRAW);

glGenVertexArrays(1, &array2D);
glBindVertexArray(array2D);

glBindBuffer(GL_ARRAY_BUFFER, handle[0]);
glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, ((GLubyte *)NULL + (0)));
glEnableVertexAttribArray(0);  // Vertex position

glBindBuffer(GL_ARRAY_BUFFER, handle[1]);
glVertexAttribPointer((GLuint)2, 2, GL_FLOAT, GL_FALSE, 0, ((GLubyte *)NULL + (0)));
glEnableVertexAttribArray(1);  // Texture coordinates

glBindVertexArray(0);



渲染四边形:

// The following three lines are called in the render loop (as 2nd pass).
// I skip rendering meshes in the first pass to better understand this error.
//sp->useSubRoutine(srp2); // SP is the shader program
//sp->resetMatrices(); // Set matrices to mat4(1.0);
//dq->render(); // DQ is the display quad


glBindFramebuffer(GL_FRAMEBUFFER, fbo); // fbo is 0 for quad
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);

if (shader != nullptr)
{
    shader->use();
    shader->setModelMatrix(modelMatrix);
}

if (is2D)
{
    glBindVertexArray(array2D);
    glDrawArrays(GL_TRIANGLES, 0, indexCount); // ERROR HERE
    return;
}



顶点着色器:

#version 440

layout(location = 0) in vec3 vertexPosition;
layout(location = 1) in vec2 vertexUV;
layout(location = 2) in vec3 vertexNormal;

centroid out vec2 UV;
out vec4 position;
out vec3 normal;

uniform mat4 uniMatModel;
uniform mat4 uniMatView;
uniform mat4 uniMatProjection;
uniform mat4 uniMatModelView;
uniform mat4 uniMatModelViewProjection;
uniform mat3 uniMatNormal;




void main()
{
    UV = vertexUV;
    position = uniMatModelView * vec4(vertexPosition, 1.0);
    normal = normalize(uniMatNormal * vertexNormal);
    gl_Position = uniMatModelViewProjection * vec4(vertexPosition, 1.0);
}



片段着色器:

#version 440

struct lightInfo {
    vec4 position;
    vec3 intensity;
    bool isActive;
};


// IN
centroid in vec2 UV;
in vec4 position;
in vec3 normal;


// OUT
layout (location = 0) out vec4 fragColor;
layout (location = 1) out vec3 positionData;
layout (location = 2) out vec3 normalData;
layout (location = 3) out vec3 colorData;


// SUBROUTINES
subroutine void renderPassType();
subroutine uniform renderPassType renderPass;


// UNIFORMS
uniform sampler2D uniSamTexture;
uniform sampler2D uniSamAlpha;
uniform sampler2D uniSamAmbient;
uniform sampler2D uniSamSpecular;
uniform sampler2D uniSamShininess;

uniform lightInfo uniPointLights[32];
uniform vec3 uniVec3AmbientEmissiveness;

layout(binding=0) uniform sampler2D positionTex;
layout(binding=1) uniform sampler2D normalTex;
layout(binding=2) uniform sampler2D colorTex;

subroutine (renderPassType)
void renderWorld()
{
    if (texture2D(uniSamAlpha, UV).rgb[0] == 1.0) // Alphamaps have to be inverted
    {
        discard;
    }
    else
    {
        colorData = texture2D(uniSamTexture, UV).rgb;
    }

    positionData = vec3(position.x, position.y, position.z);
    normalData = normal;
    fragColor = vec4(colorData, 1.0);
}

subroutine (renderPassType)
void renderLight()
{
    fragColor = vec4(1.0,0.0,0.0,1.0); // For testing purposes set to red
}

void main()
{
    renderPass();
}

【问题讨论】:

  • 您是否按下了错误消息中的中断按钮?哪一行导致错误?
  • 是的,我已经逐行做了很多破坏和调试,因为这不是唯一的问题。错误行标有// ERROR HERE。它在渲染部分:)
  • 对不起。我只是过度阅读了评论:)。有关一些可能的问题,请参阅下面的答案。

标签: c++ opengl nvidia


【解决方案1】:

当您尝试从其中没有足够元素的顶点缓冲区中读取数据时,NVIDIA 卡上可能会出现此类问题。例如,从仅包含 6 个的缓冲区中渲染 9 个顶点。有趣的是,AMD 并没有抱怨这一点。

在您的情况下,您将顶点缓冲区绑定到属性位置 2,但您激活了位置 1。这:

glVertexAttribPointer((GLuint)2, 2, GL_FLOAT, GL_FALSE, 0, ((GLubyte *)NULL + (0)));
glEnableVertexAttribArray(1);  // Texture coordinates

应该是

                              ||
                              \/ 
glVertexAttribPointer((GLuint)1, 2, GL_FLOAT, GL_FALSE, 0, ((GLubyte *)NULL + (0)));
glEnableVertexAttribArray(1);  // Texture coordinates

编辑: 我刚刚看到了另一件事

glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(glm::vec3), &uvs[0], GL_STATIC_DRAW);

uvs.size() 在您的应用程序中等于 6,因此 OpenGL 将尝试读取 6 * 3 = 18 浮点数。您的 uvs-array 仅包含 12 个浮点数(因为您在此处使用 vec2)。

【讨论】:

  • 只是为了好奇:这两个问题中的哪一个导致了异常?
  • oooohh,我真的没有看到那个错误!这就是为什么当你遇到问题时与人交谈很重要^^最终呈现出来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-15
相关资源
最近更新 更多