Opengl GLFW3,不能同时更新两个对象的顶点
Opengl GLFW3, Cant update vertices of two object at the same time
所以我正在尝试制作一款我想更新我的玩家和敌人的游戏。
敌人和玩家是正方形。我有一个正方形 class,其中包含 VAO、VBO、EBO 和我加载正方形的顶点。
void Square::loadSquare()
{
unsigned int indices[] = {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
// bind vertex array object
glBindVertexArray(VAO);
// bind vertex buffer object
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
// bind element buffer objects
// EBO is stored in the VAO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// registered VBO as the vertex attributes
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// unbind the VAO
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
及绘制方法:
void Square::drawSquare()
{
// Bind the VAO so OpenGL knows to use it
glBindVertexArray(VAO);
// Draw the triangle using the GL_TRIANGLES primitive
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}
Player 和 Enemy classes 继承自 square class,它们有自己的更新方法,我在我的 Carte classes 更新方法中调用。
void Carte::update(){
drawMap();
enemy.update(GrapMap,0);
player.update(GrapMap);
}
在绘制地图中,我只是绘制了我的敌人和玩家。
void Carte::drawMap(){
enemy.drawSquare();
player.drawSquare();
for(auto & wall : walls){
wall.drawSquare();
}
}
墙也是正方形的,但在我的例子中,我在我想要的地方画了它们,我对它们没有问题。
在改变敌人和玩家的顶点后,每次更新结束时,我调用
glBindBuffer(GL_ARRAY_BUFFER, VAO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
当我更新的只是播放器时,它运行完美。但是对于敌人,我看不到玩家,但我可以看到它的顶点根据用户的键输入而变化。
当我注释掉玩家并尝试更新敌人时,只有敌人没有更新,但我再次看到它的顶点发生了应有的变化。
在主要创建我的 Carte 对象之前,我这样做了:
// Vertex Shader source code
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}[=15=]";
//Fragment Shader source code
const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(0.8f, 0.3f, 0.02f, 1.0f);\n"
"}\n[=15=]";
int main()
{
// Initialize GLFW
glfwInit();
// Tell GLFW what version of OpenGL we are using
// In this case we are using OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// Tell GLFW we are using the CORE profile
// So that means we only have the modern functions
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Create a GLFWwindow object of 800 by 800 pixels, naming it "window"
GLFWwindow* window = glfwCreateWindow(1000, 1000, "Window", NULL, NULL);
// Error check if the window fails to create
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
// Introduce the window into the current context
glfwMakeContextCurrent(window);
//Load GLAD so it configures OpenGL
gladLoadGL();
// Specify the viewport of OpenGL in the Window
// In this case the viewport goes from x = 0, y = 0, to x = 800, y = 800
//glViewport(0, 0, 1400, 1400);
// Create Vertex Shader Object and get its reference
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
// Attach Vertex Shader source to the Vertex Shader Object
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
// Compile the Vertex Shader into machine code
glCompileShader(vertexShader);
// Create Fragment Shader Object and get its reference
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
// Attach Fragment Shader source to the Fragment Shader Object
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
// Compile the Vertex Shader into machine code
glCompileShader(fragmentShader);
// Create Shader Program Object and get its reference
GLuint shaderProgram = glCreateProgram();
// Attach the Vertex and Fragment Shaders to the Shader Program
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
// Wrap-up/Link all the shaders together into the Shader Program
glLinkProgram(shaderProgram);
// Delete the now useless Vertex and Fragment Shader objects
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
在我的 while 循环中,我这样做:
// Specify the color of the background
glClearColor(0.07f, 0.13f, 0.17f, 1.0f);
// Clean the back buffer and assign the new color to it
glClear(GL_COLOR_BUFFER_BIT);
// Tell OpenGL which Shader Program we want to use
glUseProgram(shaderProgram);
int keyW = glfwGetKey(window, GLFW_KEY_W);
int keyA = glfwGetKey(window, GLFW_KEY_A);
int keyS = glfwGetKey(window, GLFW_KEY_S);
int keyD = glfwGetKey(window, GLFW_KEY_D);
carte.update();
if(keyW)
deneme.setPlayerDirection(Directions::UP);
else if(keyA)
deneme.setPlayerDirection(Directions::LEFT);
else if(keyS)
deneme.setPlayerDirection(Directions::DOWN);
else if(keyD)
deneme.setPlayerDirection(Directions::RIGHT);
// Swap the back buffer with the front buffer
glfwSwapBuffers(window);
// Take care of all GLFW events
glfwPollEvents();
我不明白为什么我不能同时更新我的两个对象。当有多个对象顶点发生变化时,为什么我无法绘制正方形,因为顶点发生变化。
编辑以显示我如何在播放器中更改顶点:
if(getDirection() == Directions::UP){
trans = glm::translate(trans, glm::vec3(0.0f, 0.0002f, 0.0f));
setCenter(center.first,center.second + 0.0002f);
}
else if (getDirection() == Directions::LEFT){
trans = glm::translate(trans, glm::vec3(-0.0002f, 0.0f, 0.0f));
setCenter(center.first-0.0002f,center.second);
}
else if (getDirection() == Directions::DOWN){
trans = glm::translate(trans, glm::vec3(0.0f, -0.0002f, 0.0f));
setCenter(center.first,center.second-0.0002f);
}
else if (getDirection() == Directions::RIGHT){
trans = glm::translate(trans, glm::vec3(0.0002f, 0.0f, 0.0f));
setCenter(center.first+0.0002f,center.second);
}
else if (getDirection() == Directions::STOP)
trans = glm::translate(trans, glm::vec3(0.0f, 0.0f, 0.0f));
for(int i=0; i < 4; i ++){
glm::vec4 tmp = trans * glm::vec4(getVertices()[i],1);
setVertices(i, tmp.x, tmp.y, tmp.z);
}
glBindBuffer(GL_ARRAY_BUFFER, VAO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
这不是有效代码:glBindBuffer(GL_ARRAY_BUFFER, VAO);
您正在尝试将顶点 array 对象绑定到顶点 buffer地点。这是两种完全不同的类型。您可能打算写 glBindBuffer(GL_ARRAY_BUFFER, VBO);
但打错了。
除非 VAO
和 VBO
碰巧具有相同的值,否则您要么更新了错误的缓冲区,要么根本没有缓冲区。
所以我正在尝试制作一款我想更新我的玩家和敌人的游戏。 敌人和玩家是正方形。我有一个正方形 class,其中包含 VAO、VBO、EBO 和我加载正方形的顶点。
void Square::loadSquare()
{
unsigned int indices[] = {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
// bind vertex array object
glBindVertexArray(VAO);
// bind vertex buffer object
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
// bind element buffer objects
// EBO is stored in the VAO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// registered VBO as the vertex attributes
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// unbind the VAO
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
及绘制方法:
void Square::drawSquare()
{
// Bind the VAO so OpenGL knows to use it
glBindVertexArray(VAO);
// Draw the triangle using the GL_TRIANGLES primitive
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}
Player 和 Enemy classes 继承自 square class,它们有自己的更新方法,我在我的 Carte classes 更新方法中调用。
void Carte::update(){
drawMap();
enemy.update(GrapMap,0);
player.update(GrapMap);
}
在绘制地图中,我只是绘制了我的敌人和玩家。
void Carte::drawMap(){
enemy.drawSquare();
player.drawSquare();
for(auto & wall : walls){
wall.drawSquare();
}
}
墙也是正方形的,但在我的例子中,我在我想要的地方画了它们,我对它们没有问题。 在改变敌人和玩家的顶点后,每次更新结束时,我调用
glBindBuffer(GL_ARRAY_BUFFER, VAO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
当我更新的只是播放器时,它运行完美。但是对于敌人,我看不到玩家,但我可以看到它的顶点根据用户的键输入而变化。 当我注释掉玩家并尝试更新敌人时,只有敌人没有更新,但我再次看到它的顶点发生了应有的变化。
在主要创建我的 Carte 对象之前,我这样做了:
// Vertex Shader source code
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}[=15=]";
//Fragment Shader source code
const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(0.8f, 0.3f, 0.02f, 1.0f);\n"
"}\n[=15=]";
int main()
{
// Initialize GLFW
glfwInit();
// Tell GLFW what version of OpenGL we are using
// In this case we are using OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// Tell GLFW we are using the CORE profile
// So that means we only have the modern functions
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Create a GLFWwindow object of 800 by 800 pixels, naming it "window"
GLFWwindow* window = glfwCreateWindow(1000, 1000, "Window", NULL, NULL);
// Error check if the window fails to create
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
// Introduce the window into the current context
glfwMakeContextCurrent(window);
//Load GLAD so it configures OpenGL
gladLoadGL();
// Specify the viewport of OpenGL in the Window
// In this case the viewport goes from x = 0, y = 0, to x = 800, y = 800
//glViewport(0, 0, 1400, 1400);
// Create Vertex Shader Object and get its reference
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
// Attach Vertex Shader source to the Vertex Shader Object
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
// Compile the Vertex Shader into machine code
glCompileShader(vertexShader);
// Create Fragment Shader Object and get its reference
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
// Attach Fragment Shader source to the Fragment Shader Object
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
// Compile the Vertex Shader into machine code
glCompileShader(fragmentShader);
// Create Shader Program Object and get its reference
GLuint shaderProgram = glCreateProgram();
// Attach the Vertex and Fragment Shaders to the Shader Program
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
// Wrap-up/Link all the shaders together into the Shader Program
glLinkProgram(shaderProgram);
// Delete the now useless Vertex and Fragment Shader objects
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
在我的 while 循环中,我这样做:
// Specify the color of the background
glClearColor(0.07f, 0.13f, 0.17f, 1.0f);
// Clean the back buffer and assign the new color to it
glClear(GL_COLOR_BUFFER_BIT);
// Tell OpenGL which Shader Program we want to use
glUseProgram(shaderProgram);
int keyW = glfwGetKey(window, GLFW_KEY_W);
int keyA = glfwGetKey(window, GLFW_KEY_A);
int keyS = glfwGetKey(window, GLFW_KEY_S);
int keyD = glfwGetKey(window, GLFW_KEY_D);
carte.update();
if(keyW)
deneme.setPlayerDirection(Directions::UP);
else if(keyA)
deneme.setPlayerDirection(Directions::LEFT);
else if(keyS)
deneme.setPlayerDirection(Directions::DOWN);
else if(keyD)
deneme.setPlayerDirection(Directions::RIGHT);
// Swap the back buffer with the front buffer
glfwSwapBuffers(window);
// Take care of all GLFW events
glfwPollEvents();
我不明白为什么我不能同时更新我的两个对象。当有多个对象顶点发生变化时,为什么我无法绘制正方形,因为顶点发生变化。
编辑以显示我如何在播放器中更改顶点:
if(getDirection() == Directions::UP){
trans = glm::translate(trans, glm::vec3(0.0f, 0.0002f, 0.0f));
setCenter(center.first,center.second + 0.0002f);
}
else if (getDirection() == Directions::LEFT){
trans = glm::translate(trans, glm::vec3(-0.0002f, 0.0f, 0.0f));
setCenter(center.first-0.0002f,center.second);
}
else if (getDirection() == Directions::DOWN){
trans = glm::translate(trans, glm::vec3(0.0f, -0.0002f, 0.0f));
setCenter(center.first,center.second-0.0002f);
}
else if (getDirection() == Directions::RIGHT){
trans = glm::translate(trans, glm::vec3(0.0002f, 0.0f, 0.0f));
setCenter(center.first+0.0002f,center.second);
}
else if (getDirection() == Directions::STOP)
trans = glm::translate(trans, glm::vec3(0.0f, 0.0f, 0.0f));
for(int i=0; i < 4; i ++){
glm::vec4 tmp = trans * glm::vec4(getVertices()[i],1);
setVertices(i, tmp.x, tmp.y, tmp.z);
}
glBindBuffer(GL_ARRAY_BUFFER, VAO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
这不是有效代码:glBindBuffer(GL_ARRAY_BUFFER, VAO);
您正在尝试将顶点 array 对象绑定到顶点 buffer地点。这是两种完全不同的类型。您可能打算写 glBindBuffer(GL_ARRAY_BUFFER, VBO);
但打错了。
除非 VAO
和 VBO
碰巧具有相同的值,否则您要么更新了错误的缓冲区,要么根本没有缓冲区。