C++:OpenGL:绘制多个几何图形



我正在编写一个超级超级超级吕底亚-Über-3D-Game,我正在努力一个接一个地绘制多个几何图形。

绘制单个几何图形工作正常,但是如果我尝试绘制多个几何图形,则会切换其顶点数据和着色器程序;或者它们切换位置和旋转轴。如果我画一个立方体,这就是它的样子: https://i.stack.imgur.com/t7vdf.png 如果我在那个立方体之后画一艘宇宙飞船,它就是这样: https://i.stack.imgur.com/qXeS7.png 这是我对此应用程序的代码:

void MainLoop::loop()
{
VisibleObject cube("cube.obj", "vertexShader.glsl", "fragmentShaderCube.glsl");
cube.coordinates = glm::vec3(0.0f, 5.0f, -10.0f);
VisibleObject spaceship("spaceship.obj", "vertexShader.glsl", "fragmentShader.glsl");
spaceship.actualAxisOfRotation = glm::vec3(1.0f, 0.0f, 0.0f);
while (gameState != GAMESTATE_EXITING)
{
//check for input
while (SDL_PollEvent(&evnt))
{
switch (evnt.type)
{
case SDL_QUIT:
gameState = GAMESTATE_EXITING;
break;
default:
break;
}
}

//clear depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
spaceship.draw();
cube.draw();
//display result
SDL_GL_SwapWindow(window);
}
}
class VisibleObject
{
public:
VisibleObject(std::string modelPath, std::string vertexShaderPath, std::string fragmentShaderPath);
~VisibleObject();
void cleanup();
void draw();
glm::vec3 coordinates; //1.0f = 1.0 meter
glm::vec3 actualAxisOfRotation;
GLfloat actualRotation; //radians off the originposition
glm::vec3 velocity; //meters per second
glm::vec3 axisOfRotation;
GLfloat rotationSpeed; //radians per second
private:
short numberOfIndices;
std::vector<short> indices;
short numberOfVertices;
std::vector<glm::vec3> vertices;
glm::mat4 fullMatrix; 
GLuint fullMatrixUniformLocation;
GLuint shaderProgramID;
GLuint vertexBufferID;
GLuint indexBufferID;
GLuint vertexArrayObjectID;
};
VisibleObject::VisibleObject(std::string modelPath, std::string vertexShaderPath, std::string fragmentShaderPath)
{
coordinates = glm::vec3(0.0f, 0.0f, -10.0f);
actualAxisOfRotation = glm::vec3(0.0f, 1.0f, 0.0f);
actualRotation = 2.0f;
velocity = glm::vec3(0.0f, 0.0f, 0.0f);
axisOfRotation = glm::vec3(0.0f, 1.0f, 0.0f);
rotationSpeed = 0.0f;
//create shader-program
shaderProgramID = GlslUtilities::installShader(vertexShaderPath, fragmentShaderPath);
//create transformation-matrix-uniform
fullMatrixUniformLocation = glGetUniformLocation(shaderProgramID, "f_matrix");
//load model data
numberOfIndices = 0;
numberOfVertices = 0;
indices.clear();
vertices.clear();
something_that_works_and_loads_the_vertex_and_index_data_from_an_obj-file_into_the_vectors();
//sending data to opengl
glGenVertexArrays(1, &vertexArrayObjectID);
glGenBuffers(1, &indexBufferID);
glGenBuffers(1, &vertexBufferID);
glBindVertexArray(vertexArrayObjectID);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(vertices[0]), &vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(indices[0]), &indices[0], GL_STATIC_DRAW);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

VisibleObject::~VisibleObject()
{
}
void VisibleObject::cleanup()
{
glUseProgram(0);
glDeleteProgram(shaderProgramID);
glDeleteBuffers(1, &vertexBufferID);
glDeleteBuffers(1, &indexBufferID);
glDeleteBuffers(1, &vertexArrayObjectID);
}
void VisibleObject::draw()
{
glBindVertexArray(vertexArrayObjectID);

fullMatrix = glm::perspective(glm::radians(85.0f), 800.0f / 600, 0.1f, 150.0f);
fullMatrix = glm::translate(fullMatrix, coordinates);
fullMatrix = glm::rotate(fullMatrix, glm::radians(((float)SDL_GetTicks())/10), actualAxisOfRotation);
glUniformMatrix4fv(fullMatrixUniformLocation, 1, GL_FALSE, &fullMatrix[0][0]);
glUseProgram(shaderProgramID);
glDrawElements(GL_TRIANGLES, numberOfIndices, GL_UNSIGNED_SHORT, 0);
}

在绑定着色器之前将fullMatrix上传到着色器。由于glMatrix4fv调用始终在当前绑定的着色器上运行,因此在绘制时使用了错误的矩阵。

解决方案:以正确的顺序调用函数

glUseProgram(shaderProgramID);
glUniformMatrix4fv(fullMatrixUniformLocation, 1, GL_FALSE, &fullMatrix[0][0]);
glDrawElements(GL_TRIANGLES, numberOfIndices, GL_UNSIGNED_SHORT, 0);

最新更新