OpenGL程序适用于AMD,但不适用于NVIDIA

时间:2014-11-11 22:16:15

标签: c++ opengl nvidia

错误是" nvoglv64.dll中的访问冲突读取位置"
Error Message
Console Log
该程序按原计划在我的旧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();
}

1 个答案:

答案 0 :(得分: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)。