【问题标题】:OpenGL: After buffer recreating, another extra point is appeared [closed]OpenGL:重新创建缓冲区后,出现另一个额外的点[关闭]
【发布时间】:2023-01-03 08:46:32
【问题描述】:

首先,我创建了一个大小为 3 的缓冲区,并向其中传递了一个顶点数组。当我按下空格键时,一个点被添加到顶点数组中。一个新点出现在屏幕上,另一个点出现在中间。为什么中间会出现另一个点?

glMapBuffer,glBufferSubdata - 同样的问题

附言 我想实现 perlin 噪声波形,所以我需要每帧更新屏幕上的几何图形。

这是我的代码:

#include <iostream>

#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include "shader.h"
#include <vector>

const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);

std::vector<float> vertices = {
        -0.5f, -0.5f, // bottom left 
         0.5f, -0.5f, // bottom right 
         0.5f,  0.5f  // top right
};

int count = 3;

int main()
{
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Terrain Generator", NULL, NULL);
    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    Shader ourShader("vertexShader.vert", "fragmentShader.frag");

    unsigned int VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    while (!glfwWindowShouldClose(window))
    {
        processInput(window);

        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW);

        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        ourShader.use();

        glBindVertexArray(VAO);
        glDrawArrays(GL_LINE_STRIP, 0, count);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

void processInput(GLFWwindow* window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
    {
        glfwSetWindowShouldClose(window, true);
    }
    if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
    {
        vertices.push_back(-0.5f);
        vertices.push_back(0.5f);
        ++count;
    }
}

void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    glViewport(0, 0, width, height);
}

【问题讨论】:

  • sizeof(vertices) 没有达到您的期望。你必须使用vertices.size() * sizeof(float)
  • 这回答了你的问题了吗? sizeof() a vector

标签: c++ opengl buffer render glfw


【解决方案1】:

正如 Rabbid76 在评论中指出的那样,这一行是不正确的(两种情况):

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW);

第二个参数应该是大小,以字节数为单位。然而,sizeof(vertices)返回std::vector对象本身的大小,而不是它封装的数据的大小。改用这个:

glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STATIC_DRAW);

在我的机器上,也许也在你的机器上,这两个值恰好都是 24 纯属巧合,这就是代码仍然可以正常工作的原因。当vertices附加更多的值时,glBufferData会继续上传原来的24字节数据。随着count 的增加,OpenGL 实现将尝试读取超过缓冲区的末尾。在这种情况下,那里的内存包含零,因此 OpenGL 将在窗口中间添加一个点。

请注意sizeof(vertices)vertices 被声明为 C 样式数组(即 float vertices[6])时工作,这可能是错误的来源。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多