我正在尝试使用多个VAO和VBO在OpenGL中渲染多个对象。要使用相同的顶点来渲染多个对象,但是我要为每个对象使用不同的顶点,例如绘制一个正方形和一个圆形。对于正方形,我仅需要6个顶点,对于圆形,我需要360。 我在读取或创建着色器时出错。
这里是顶点着色器:
#version 330 core
layout(location = 0) out vec4 color;
uniform vec4 u_Color;
void main()
{
color = u_Color;
}
片段着色器:
// Circle
std::vector<VertexFormat> vertices;
for (int i = 0; i < 360; i++)
{
GLfloat angle = i * ((2.0f * 3.14159f) / 360);
vertices.push_back(VertexFormat(glm::vec3(cos(angle) * 100.0f, sin(angle) * 100.0f, 0.0f)));
}
// Pipette object
std::vector<VertexFormat> pipetteVertices;
pipetteVertices.push_back(VertexFormat(glm::vec3(injPipette.x + 500.0f, injPipette.y + 500.0f, 0.0f))); // 0
pipetteVertices.push_back(VertexFormat(glm::vec3(injPipette.x + 700.0f, injPipette.y + 500.0f, 0.0f))); // 1
pipetteVertices.push_back(VertexFormat(glm::vec3(injPipette.x + 700.0f, injPipette.y + 700.0f, 0.0f))); // 2
pipetteVertices.push_back(VertexFormat(glm::vec3(injPipette.x + 500.0f, injPipette.y + 700.0f, 0.0f))); // 3
pipetteVertices.push_back(VertexFormat(glm::vec3(injPipette.x + 500.0f, injPipette.y + 500.0f, 0.0f)));
pipetteVertices.push_back(VertexFormat(glm::vec3(injPipette.x + 700.0f, injPipette.y + 700.0f, 0.0f)));
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexFormat) * 6, &pipetteVertices[0], GL_STATIC_DRAW);
//Position attribute
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexFormat), (GLvoid *)0);
GLuint vao2;
glGenVertexArrays(1, &vao2);
glBindVertexArray(vao2);
GLuint vbo2;
glGenBuffers(1, &vbo2);
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexFormat) * 360, &vertices[0], GL_STATIC_DRAW);
//Position attribute
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexFormat), (GLvoid *) 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
VAO和VBO生成和绑定
//Get the uniform locations of model, view and projection matrices
modelID = glGetUniformLocation(program, "model");
viewID = glGetUniformLocation(program, "view");
projectionID = glGetUniformLocation(program, "projection");
//View transform
glm::mat4 view = glm::lookAt(glm::vec3(0, 0, 2), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
//Projection transform
//glm::mat4 projection = glm::perspective(45.0f, (GLfloat)screenWidth / (GLfloat)screenHeight, 0.1f, 1000.0f);
glm::mat4 projection = glm::ortho(0.0f, (GLfloat)screenWidth, 0.0f, (GLfloat)screenHeight, 0.1f, 10.0f);
{
glUniformMatrix4fv(viewID, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projectionID, 1, GL_FALSE, glm::value_ptr(projection));
glm::mat4 translate = glm::translate(glm::mat4(1.0), glm::vec3(100.0f + move_x, 100.0f + move_y, 0.0f));
glm::mat4 rotate = glm::rotate(glm::mat4(1.0), 0.0f, glm::vec3(0.0f, 0.0f, 1.0f));
glm::mat4 scale = glm::scale(glm::mat4(1.0), glm::vec3(1.0f, 1.0f, 2.0f));
glm::mat4 model = translate * rotate * scale;
glUniformMatrix4fv(modelID, 1, GL_FALSE, glm::value_ptr(model));
glUniform4f(color, 0.0f, 0.0f, 1.0f, 1.0f);
//Render
glDrawArrays(GL_TRIANGLE_FAN, 0, 360);
}
{
glUniformMatrix4fv(viewID, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projectionID, 1, GL_FALSE, glm::value_ptr(projection));
glm::mat4 translate = glm::translate(glm::mat4(1.0), glm::vec3(300.0f + injPipette.x, 300.0f + injPipette.y, 0.0f));
glm::mat4 rotate = glm::rotate(glm::mat4(1.0), 0.0f, glm::vec3(0.0f, 0.0f, 1.0f));
glm::mat4 scale = glm::scale(glm::mat4(1.0), glm::vec3(1.0f, 1.0f, 2.0f));
glm::mat4 model = translate * rotate * scale;
glUniformMatrix4fv(modelID, 1, GL_FALSE, glm::value_ptr(model));
glUniform4f(color, 1.0f, 0.0f, 0.0f, 0.5f);
//Render
glDrawArrays(GL_TRIANGLES, 0, 6);
}
渲染循环中的绘制调用:
{{1}}
我重复一遍,使用已经完成的相同顶点绘制多个对象。我需要知道如何使用相同的顶点和片段着色器但顶点数量不同来绘制多个对象。该项目很小,仅能以2D渲染最多10个对象。
答案 0 :(得分:2)
像glDrawArrays
这样的绘制命令处理并绘制通用顶点属性数据的数组,这些数据在当前的Vertex Array Object中表示。
这意味着您必须在进行绘制调用之前绑定适当的顶点数组对象:
{
// [...]
glBindVertexArray(vao2);
glDrawArrays(GL_TRIANGLE_FAN, 0, 360);
}
{
// [ ...]
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
答案 1 :(得分:0)
@ Kenny83自从我碰到 var mainMenu = document.getElementById("mainTable");
mainMenu.scroll(0,1);
mainMenu.addEventListener("mouseleave", function(evt) {
console.log("exited");
});
以来已经有一段时间了,说实话,我不记得从哪里拿到OpenGL
了,但幸好我找到了带有代码的项目。我不知道如何添加摘要以添加评论,我认为这甚至是不可能的,因此我将其添加为答案:
VertexFormat
希望有帮助。