OpenGL 生成三角形而不是预期的 2D 矩形 [关闭]

问题描述 投票:0回答:1

我的代码应该使用 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);
}

这段代码最终生成的形状如下:

如您所见,我正在尝试生成一个矩形,但没有生成左上角的顶点。

我不确定如何解决这个问题,如果有任何关于如何生成左上角顶点的提示,我将不胜感激。谢谢!

c++ opengl graphics glfw
1个回答
-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

© www.soinside.com 2019 - 2024. All rights reserved.