glDrawElements错误:nvoglv32.dll OpenGL

时间:2017-04-16 11:09:19

标签: c++ opengl

我知道,这个错误通常意味着错误地启用了顶点属性数组。但我不明白我的错误。 我尝试将此代码从java转换为c ++:code 地形的一部分:

RawModel Terrain::generateTerrain(Loader loader)
{
auto count = VERTEX_COUNT * VERTEX_COUNT;
std::vector<GLfloat> vertices(count * 3);
std::vector<GLfloat> normals(count * 3);
std::vector<GLfloat> textureCoords(count * 2);
std::vector<GLuint> indices(6 * (VERTEX_COUNT - 1)*(VERTEX_COUNT - 1));

...

return loader.loadToVao(vertices, normals, textureCoords, indices);
 }

loader class:

RawModel Loader::loadToVao(vector<GLfloat > positions, vector<GLfloat > texCoords, vector<GLfloat > normals, vector<GLuint> indices)    {   
     GLuint VAOid = createVAO();
     bindIndicesBuffer(indices);
     storeDataInAttributeList(0, 3, positions);
     storeDataInAttributeList(1, 2, texCoords);
     storeDataInAttributeList(2, 3, normals);
     glBindVertexArray(0);

     return RawModel(VAOid, size(indices));
 }

 GLuint Loader::createVAO()   {
     GLuint VAOid;
     glGenVertexArrays(1, &VAOid);
     glBindVertexArray(VAOid);
     vaos.push_back(VAOid);

     return VAOid;
 }

 void Loader::bindIndicesBuffer(vector<GLuint> indices)    {
     GLuint VBOid;
     glGenBuffers(1, &VBOid);
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBOid);
     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), &indices, GL_STATIC_DRAW);
     vbos.push_back(VBOid);
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 }

 void Loader::storeDataInAttributeList(int attributeNumber, int coordinateSize, vector<GLfloat> &data)     {
     GLuint VBOid;
     glGenBuffers(1, &VBOid);
     glBindBuffer(GL_ARRAY_BUFFER, VBOid);  
     glBufferData(GL_ARRAY_BUFFER, sizeof(data), &data, GL_STATIC_DRAW);
     glEnableVertexAttribArray(attributeNumber);
     glVertexAttribPointer(attributeNumber, coordinateSize, GL_FLOAT, GL_FALSE, coordinateSize*sizeof(GLfloat), (GLvoid*)(sizeof(data)));
     vbos.push_back(VBOid);
     glBindBuffer(GL_ARRAY_BUFFER, 0);
 }

主要周期:

terrainShader.Use();
        terrainShader.loadUniformMatrix4FVector("projection", 1, glm::value_ptr(projection));
        terrainShader.loadUniformMatrix4FVector("view", 1, glm::value_ptr(view));
        modelMatrix = glm::translate(modelMatrix, glm::vec3(0.0f, -5.00f, 0.0f));
        terrainShader.loadUniformMatrix4FVector("model", 1, glm::value_ptr(modelMatrix));
        terrainShader.loadUniformFVector("lightPos", &lightPos[0]);
        for (auto terrain : terrains) {
            RawModel rawModel = terrain.getModel();

            glBindVertexArray(rawModel.getVAOid());
            glEnableVertexAttribArray(0);
            glEnableVertexAttribArray(1);
            glEnableVertexAttribArray(2);   
terrainShader.loadUniformInt1("material.diffuse", 0);           
        terrainShader.loadUniformFloat1("material.shininess", 64.0f);
        glUniform3f(glGetUniformLocation(terrainShader.ShaderProgramID, "light.direction"), -0.2f, -1.0f, -0.3f);
        glUniform3f(glGetUniformLocation(terrainShader.ShaderProgramID, "light.ambient"), 0.2f, 0.2f, 0.2f);
        glUniform3f(glGetUniformLocation(terrainShader.ShaderProgramID, "light.diffuse"), 0.5f, 0.5f, 0.5f);
        glUniform3f(glGetUniformLocation(terrainShader.ShaderProgramID, "light.specular"), 1.0f, 1.0f, 1.0f);

            terrainShader.loadUniformMatrix4FVector("model", 1, glm::value_ptr(modelMatrix));
            glDrawElements(GL_TRIANGLES, rawModel.getVertexCount(), GL_UNSIGNED_INT, 0);
        }

着色器: 顶点:

#version 400 core
layout (location = 0) in vec3 Position_model;
layout (location = 1) in vec2 _texCoord;
layout (location = 2) in vec3 normal;    
out vec2 TexCoords;
out vec3 toLightVector;
out vec3 surfaceNormal;    

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform vec3 lightPos;

void main()
{
    vec4 worldPosition = model * vec4(Position_model, 1.0);
    gl_Position = projection * view * worldPosition ;   
    TexCoords = _texCoord;      
    surfaceNormal = mat3(transpose(inverse(model))) * normal; 
    toLightVector = lightPos - worldPosition.xyz;       
}

片段:

#version 400 core    
struct Material {
    sampler2D diffuse;        
    float     shininess;
};      
struct Light {       
    vec3 direction;    
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};

in vec2 TexCoords;
in vec3 toLightVector;
in vec3 surfaceNormal;

out vec4 o_color;  

uniform Material material;
uniform Light light;    
void main()
{
    // Ambient
    vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));

    // Diffuse 
    vec3 norm = normalize(surfaceNormal);
    vec3 lightDir = normalize(-light.direction);  
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));

    o_color = vec4(ambient + diffuse, 1.0f);    
}

1 个答案:

答案 0 :(得分:0)

您将错误的数据量上传到vbos。

glBufferData电话

glBufferData(GL_ARRAY_BUFFER, sizeof(data), &data, GL_STATIC_DRAW);

sizeof(data)是矢量对象的大小,而不是矢量中存储的数据的大小。与此类似,通过将&data作为内存地址,可以传递向量的地址,而不是向量管理的内存。你真正想要的是

glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * data.size(), data.data(), GL_STATIC_DRAW);

同样的事情也适用于索引数据。