[英]OpenGL is not rendering my cube
I have recently started learning OpenGL with the tutorial on http://www.opengl-tutorial.org . 我最近开始使用http://www.opengl-tutorial.org上的教程学习OpenGL。 The first few tutorials went fine, and I got my triangle on the screen.
前几个教程很顺利,我在屏幕上显示了三角形。 Now I moved on to the cube tutorial, but I got stuck on the following problem.
现在我转到了立方体教程,但我遇到了以下问题。 I only made 2 big changes to the triangle program to render my cube:
我只对三角形程序进行了两次大的更改来渲染我的立方体:
The problem is that when I run the program, it compiles fine and shows me a dark blue screen (the color I had set for clearing the screen), but it doesn't render my cube. 问题是,当我运行程序时,它编译得很好,并向我显示一个深蓝色屏幕(我为清除屏幕设置的颜色),但它不会渲染我的立方体。
My full code is here: 我的完整代码在这里:
#include "common/shader/loadShader.h"
#include "common/logpp/log++.h"
#include <GL\glew.h>
#include <GL\glfw3.h>
#include <vector>
logpp::FileLog mainLog;
//Contains all functions for initializing OpenGL, GLEW and GLFW
namespace GLInit
{
void SetGLFWWindowHints()
{
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); /*OpenGL 3.3*/
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
}
void InitGLFW()
{
if (!glfwInit())
{
logpp::Console::error("Failed to initialize GLFW!");
return;
}
SetGLFWWindowHints();
}
void InitGLEW()
{
glewExperimental = true; //Needed in core profile
if (glewInit() != GLEW_OK)
{
logpp::Console::error("Failed to initialize GLEW!");
return;
}
}
GLuint CreateVAO()
{
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
return VertexArrayID;
}
GLFWwindow* CreateWin(int width, int height, char const* caption)
{
auto window = glfwCreateWindow(width, height, caption, nullptr, nullptr);
if (window == nullptr)
{
std::string msg = "Failed to create window!";
logpp::Console::error(msg);
mainLog.write("[ERROR]: " + msg);
glfwTerminate();
return nullptr;
}
glfwMakeContextCurrent(window);
return window;
}
GLFWwindow* Init(int width, int height, char const* caption)
{
InitGLFW();
auto window = CreateWin(width, height, caption);
InitGLEW();
return window;
}
}
using namespace GLInit;
int main()
{
static const int VERTICES_IN_TRIANGLE = 3;
PathConverter::setBase(R"(C:\Users\michi_000\Desktop\C++\OpenGL\A Colored Cube\x64\Debug\)");
try
{
mainLog.open(PathConverter::convert("logs\\main.log"), false);
}
catch (logpp::FileLog::Exception e)
{
logpp::Console::error(e.what());
}
auto window = Init(800, 600, "A Colored Cube");
auto VertexArrayID = CreateVAO();
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
static const std::vector<GLfloat> cube //Vertices for the cube
{
-1.0f,-1.0f,-1.0f, // triangle 1 : begin
-1.0f,-1.0f, 1.0f,
-1.0f, 1.0f, 1.0f, // triangle 1 : end
1.0f, 1.0f,-1.0f, // triangle 2 : begin
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f,-1.0f, // triangle 2 : end
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f
};
static const std::vector<GLfloat> cube_colors
{
0.583f, 0.771f, 0.014f,
0.609f, 0.115f, 0.436f,
0.327f, 0.483f, 0.844f,
0.822f, 0.569f, 0.201f,
0.435f, 0.602f, 0.223f,
0.310f, 0.747f, 0.185f,
0.597f, 0.770f, 0.761f,
0.559f, 0.436f, 0.730f,
0.359f, 0.583f, 0.152f,
0.483f, 0.596f, 0.789f,
0.559f, 0.861f, 0.639f,
0.195f, 0.548f, 0.859f,
0.014f, 0.184f, 0.576f,
0.771f, 0.328f, 0.970f,
0.406f, 0.615f, 0.116f,
0.676f, 0.977f, 0.133f,
0.971f, 0.572f, 0.833f,
0.140f, 0.616f, 0.489f,
0.997f, 0.513f, 0.064f,
0.945f, 0.719f, 0.592f,
0.543f, 0.021f, 0.978f,
0.279f, 0.317f, 0.505f,
0.167f, 0.620f, 0.077f,
0.347f, 0.857f, 0.137f,
0.055f, 0.953f, 0.042f,
0.714f, 0.505f, 0.345f,
0.783f, 0.290f, 0.734f,
0.722f, 0.645f, 0.174f,
0.302f, 0.455f, 0.848f,
0.225f, 0.587f, 0.040f,
0.517f, 0.713f, 0.338f,
0.053f, 0.959f, 0.120f,
0.393f, 0.621f, 0.362f,
0.673f, 0.211f, 0.457f,
0.820f, 0.883f, 0.371f,
0.982f, 0.099f, 0.879f
};
/* static const std::vector<GLfloat> cube
{
1.0, -1.0, 0.0,
-1.0, -1.0, 0.0,
0.0, 1.0, 0.0
};*/
static const std::vector<GLfloat>::size_type triangleCount = cube.size() / VERTICES_IN_TRIANGLE;
GLuint programID = LoadShaders(PathConverter::convert("shaders\\vertex.glsl").c_str(),
PathConverter::convert("shaders\\fragment.glsl").c_str());
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, cube.size(), &cube, GL_STATIC_DRAW);
GLuint colorbuffer;
glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, cube_colors.size(), &cube_colors, GL_STATIC_DRAW);
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
do
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
glEnableVertexAttribArray(0); //enable vertices
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, triangleCount, GL_FLOAT, GL_FALSE, 0, nullptr);
glDisableVertexAttribArray(0);
// 2nd attribute buffer : colors
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(
1, // attribute. No particular reason for 1, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
nullptr // array buffer offset
);
glDisableVertexAttribArray(1);
logpp::Console::debug("Drawing triangles");
glDrawArrays(GL_TRIANGLES, 0, triangleCount);
// glDisableVertexAttribArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
} while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS
&& !glfwWindowShouldClose(window));
glfwTerminate();
return 0;
}
One last note, if I remove the color attribute and just set the entire cube to be red, it still gives the same dark blue screen. 最后一点,如果我删除了颜色属性并将整个立方体设置为红色,它仍会提供相同的深蓝色屏幕。
There are several problems in the code: 代码中有几个问题:
You are disabling all vertex attributes before drawing. 您在绘制之前禁用所有顶点属性。 The calls to
glDisableVertexAttribArray
have to go after glDrawArrays
, otherwise no data is attached when drawing. 对
glDisableVertexAttribArray
的调用必须在glDrawArrays
之后,否则在绘制时不会附加任何数据。
The even better solution would be to move the VAO setup before the main-loop and never call glDisableVertexAttribArray
at all. 更好的解决方案是在主循环之前移动VAO设置,从不调用
glDisableVertexAttribArray
。 The pointers never change anyway, and storing the vertex attribute setup is exactly what a VAO is made for. 无论如何,指针永远不会改变,存储顶点属性设置正是VAO的制作方式。 Seems that the tutorial is very suboptimal in explaining/using them.
似乎教程在解释/使用它们时非常不理想。
Another problem is that this line: 另一个问题是这一行:
glVertexAttribPointer(0, triangleCount, GL_FLOAT, GL_FALSE, 0, nullptr);
should generate a GL_INVALID_VALUE
error since the size (second parameter) is only allowed to be 1, 2, 3 or 4. In your case triangleCount equals 12. The size describes how many elements each of the vertices should consume. 应该生成
GL_INVALID_VALUE
错误,因为size(第二个参数)只允许为1,2,3或4.在你的情况下,triangleCount等于12.大小描述了每个顶点应该消耗多少个元素。 So if the attributes is of type vec3, then it should be 3. 因此,如果属性是vec3类型,那么它应该是3。
You should always check if glGetError
returns any errors before asking on SO. 在询问SO之前,您应该始终检查
glGetError
返回任何错误。 That saves a lot of time because you already know which line is problematic. 这节省了大量时间,因为您已经知道哪条线存在问题。
Also note, that triangleCount does not actually contain the triangle count but the number of vertices. 另请注意,triangleCount实际上并不包含三角形计数,而是包含顶点数。
The first issue is that the 2nd paramter of glBufferData
is the size of the buffer in bytes . 第一个问题是
glBufferData
的第二个参数是缓冲区的大小(以字节为单位) 。 Further operator &
returns not a pointer to the data of a std::vector
. 进一步的
operator &
返回不是指向std::vector
数据的指针。 You have to use std::vector::data()
: 你必须使用
std::vector::data()
:
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,
cube.size()*sizeof(GLfloat),
cube.data(),
GL_STATIC_DRAW);
GLuint colorbuffer;
glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER,
cube_colors.size()*sizeof(GLfloat),
cube_colors.data(),
GL_STATIC_DRAW);
Further glDisableVertexAttribArray
, disables the generic vertex attribute array. 进一步的
glDisableVertexAttribArray
,禁用通用顶点属性数组。 This has to be done after the drawing. 这必须在绘图后完成。 The
size
parameter of glVertexAttribPointer
specifies the number of components per generic vertex attribute and must be 1, 2, 3, 4: glVertexAttribPointer
的size
参数指定每个通用顶点属性的组件数,并且必须为1,2,3,4:
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glDrawArrays(GL_TRIANGLES, 0, triangleCount);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.