[英]OpenGL is not rendering my cube
我最近開始使用http://www.opengl-tutorial.org上的教程學習OpenGL。 前幾個教程很順利,我在屏幕上顯示了三角形。 現在我轉到了立方體教程,但我遇到了以下問題。 我只對三角形程序進行了兩次大的更改來渲染我的立方體:
問題是,當我運行程序時,它編譯得很好,並向我顯示一個深藍色屏幕(我為清除屏幕設置的顏色),但它不會渲染我的立方體。
我的完整代碼在這里:
#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;
}
最后一點,如果我刪除了顏色屬性並將整個立方體設置為紅色,它仍會提供相同的深藍色屏幕。
代碼中有幾個問題:
您在繪制之前禁用所有頂點屬性。 對glDisableVertexAttribArray
的調用必須在glDrawArrays
之后,否則在繪制時不會附加任何數據。
更好的解決方案是在主循環之前移動VAO設置,從不調用glDisableVertexAttribArray
。 無論如何,指針永遠不會改變,存儲頂點屬性設置正是VAO的制作方式。 似乎教程在解釋/使用它們時非常不理想。
另一個問題是這一行:
glVertexAttribPointer(0, triangleCount, GL_FLOAT, GL_FALSE, 0, nullptr);
應該生成GL_INVALID_VALUE
錯誤,因為size(第二個參數)只允許為1,2,3或4.在你的情況下,triangleCount等於12.大小描述了每個頂點應該消耗多少個元素。 因此,如果屬性是vec3類型,那么它應該是3。
在詢問SO之前,您應該始終檢查glGetError
返回任何錯誤。 這節省了大量時間,因為您已經知道哪條線存在問題。
另請注意,triangleCount實際上並不包含三角形計數,而是包含頂點數。
第一個問題是glBufferData
的第二個參數是緩沖區的大小(以字節為單位) 。 進一步的operator &
返回不是指向std::vector
數據的指針。 你必須使用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);
進一步的glDisableVertexAttribArray
,禁用通用頂點屬性數組。 這必須在繪圖后完成。 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.