我的代码应该使用 OpenGL 生成一个 2D 矩形。出于某种原因,虽然我的代码对我来说似乎是正确的(我是一个正在上大学课程的初学者),但它一直生成一个三角形而不是一个完整的 2D 矩形。矩形的左上顶点拒绝生成,可能是什么问题?
Source.cpp ->
// main function. Entry point to the OpenGL program
int main(int argc, char* argv[])
{
if (!UInitialize(argc, argv, &gWindow))
return EXIT_FAILURE;
// Create the mesh
UCreateMesh(gMesh); // Calls the function to create the Vertex Buffer Object
// Create the shader program
if (!UCreateShaderProgram(vertexShaderSource, fragmentShaderSource, gProgramId))
return EXIT_FAILURE;
// Sets the background color of the window to black (it will be implicitely used by glClear)
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// render loop
// -----------
while (!glfwWindowShouldClose(gWindow))
{
// input
// -----
UProcessInput(gWindow);
// Render this frame
URender();
glfwPollEvents();
}
// Release mesh data
UDestroyMesh(gMesh);
// Release shader program
UDestroyShaderProgram(gProgramId);
exit(EXIT_SUCCESS); // Terminates the program successfully
}
U初始化:
// Initialize GLFW, GLEW, and create a window
bool UInitialize(int argc, char* argv[], GLFWwindow** window)
{
// GLFW: initialize and configure
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
// GLFW: window creation
// ---------------------
* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE, NULL, NULL);
if (*window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return false;
}
glfwMakeContextCurrent(*window);
glfwSetFramebufferSizeCallback(*window, UResizeWindow);
// GLEW: initialize
// ----------------
// Note: if using GLEW version 1.13 or earlier
glewExperimental = GL_TRUE;
GLenum GlewInitResult = glewInit();
if (GLEW_OK != GlewInitResult)
{
std::cerr << glewGetErrorString(GlewInitResult) << std::endl;
return false;
}
// Displays GPU OpenGL version
cout << "INFO: OpenGL Version: " << glGetString(GL_VERSION) << endl;
return true;
}
渲染功能:
// Functioned called to render a frame
void URender()
{
// Clear the background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Set the shader to be used
glUseProgram(gProgramId);
// Activate the VBOs contained within the mesh's VAO
glBindVertexArray(gMesh.vao);
// Draws the triangle
glDrawArrays(GL_TRIANGLES, 0, gMesh.nvertices); // Draws the triangle
// Deactivate the VAO
glBindVertexArray(0);
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
glfwSwapBuffers(gWindow); // Flips the the back buffer with the front buffer every frame.
}
CreateMesh 函数:
// Implements the UCreateMesh function
void UCreateMesh(GLMesh& mesh)
{
// Specifies Normalized Device Coordinates (x,y,z) and color (r,g,b,a) for triangle vertices
GLfloat verts[] =
{
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
};
mesh.nvertices = 4;
glGenVertexArrays(1, &mesh.vao); // we can also generate multiple VAOs or buffers at the same time
glGenBuffers(1, &mesh.vbo); // Creates 1 buffer
glBindVertexArray(mesh.vao);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo); // Activates the buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); // Sends vertex or coordinate data to the GPU
// Creates the Vertex Attribute Pointer for the screen coordinates
const GLuint floatsPerVertex = 3; // Number of coordinates per vertex
const GLuint floatsPerColor = 4; // (r, g, b, a)
// Strides between vertex coordinates is 6 (x, y, r, g, b, a). A tightly packed stride is 0.
GLint stride = sizeof(float) * (floatsPerVertex + floatsPerColor);// The number of floats before each
// Creates the Vertex Attribute Pointer
glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, stride, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, floatsPerColor, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * floatsPerVertex));
glEnableVertexAttribArray(1);
}
这段代码最终生成的形状如下:
如您所见,我正在尝试生成一个矩形,但没有生成左上角的顶点。
我不确定如何解决这个问题,如果有任何关于如何生成左上角顶点的提示,我将不胜感激。谢谢!
你试过使用6个顶点吗?应该是因为它用前三个顶点创建了一个三角形,然后无法理解如何处理第四个。
如果你想对 2 个不同的三角形使用 4 个顶点,你应该查看“EBO”缓冲区。它基本上保存了你想要绘制的顶点的索引:
uint verts_to_use[] = {1, 2, 3, 0, 1 ,3}; // basically tells opengl to use this indices to choose from the verts array
unsigned int EBO;
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(verts_to_use), verts_to_use, GL_STATIC_DRAW);
然后如果你想在你的循环中使用它:
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
看看这个以获得更好的解释(最后它展示了如何用 2 个三角形绘制矩形):https://learnopengl.com/Getting-started/Hello-Triangle