我知道,这个错误通常意味着错误地启用了顶点属性数组。但我不明白我的错误。 我尝试将此代码从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);
}
答案 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);
同样的事情也适用于索引数据。