在错误位置渲染的顶点(OpenGl)

Posted

技术标签:

【中文标题】在错误位置渲染的顶点(OpenGl)【英文标题】:Verticies rendered at the wrong position (OpenGl) 【发布时间】:2016-08-23 16:01:19 【问题描述】:

当我尝试渲染 PERFECT 立方体时,一个顶点在立方体的中间渲染 - (.5, .5, -.5) 而不是 (1, 1, 1) -并且一个渲染一个单位太高 - (1, 1, 1) 而不是 (1, 0, 0)。我真的不知道这是怎么发生的。我首先检查了它是否与 obj 加载有关并单独定义了数组,但它没有。这是program 的输出。这是从另一个角度更好地理解problem。

首先我初始化glfw,创建一个窗口,创建一个上下文并设置各种变量:

if (!glfwInit())
    
        std::cout << "Failed to initialize GLFW, press enter to close the application..." << std::endl;
        std::cin.get();
        return false;
    
    GLFWWindow *window= glfwCreateWindow(m_Width, m_Height, m_Title, NULL, NULL);

    if (!window)
    
        glfwTerminate();
        std::cout << "Failed to creat GLFW window, press enter to close the application..." << std::endl;
        std::cin.get();
        return false;
    
    glfwMakeContextCurrent(m_GLFWWindow);

然后我初始化一些启用一些 gl 选项并设置各种其他变量:

glClearColor(0, 0, 0, 0);

    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    glFrontFace(GL_CW);
    glEnable(GL_DEPTH_TEST);
    glDepthRange(0, 1);
    glEnable(GL_FRAMEBUFFER_SRGB);

完成后,我声明一个顶点数组和一个索引数组并将它们传递给 OpenGL:(顶点只是一个包含三个浮点数的结构)

Vertex verticies[] =   Vertex(Vector3(  1, -1, -1)),
                            Vertex(Vector3(  1, -1,  1)),
                            Vertex(Vector3( -1, -1,  1)),
                            Vertex(Vector3( -1, -1, -1)),
                            Vertex(Vector3(  1,  1, -1)),
                            Vertex(Vector3(  1,  1,  1)),
                            Vertex(Vector3( -1,  1,  1)),
                            Vertex(Vector3( -1,  1, -1)) ;

    unsigned int indicies[] =  2, 4, 1,
                                8, 6, 5,
                                5, 2, 1,
                                6, 3, 2,
                                3, 8, 4,
                                1, 8, 5,
                                2, 3, 4,
                                8, 7, 6,
                                5, 6, 2,
                                6, 7, 3,
                                3, 7, 8,
                                1, 4, 8;

GLu vbo;
Glu ibo;
glGenBuffers(1, &vbi);
glGenBuffers(1, &ino);
glBindBuffer(GL_ARRAY_BUFFER, m_Vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(verticies[0]) * 8, &verticies, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_Ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indicies[0]) * 36, &indicies, GL_STATIC_DRAW);

然后我创建一个程序,编译着色器并将它们链接到程序:

GLuint program = glCreateProgram();
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
GLchar vertexCode = "vertexShader code";
GLchar fragmentCode = "fragmenShader code";
glShaderSource(vertexShader , 1, &vertexCode, NULL);
glCompileShader(vertexShader );
glShaderSource(fragmentShader, 1, &fragmentCode, NULL);
glCompileShader(fragmentShader);
glAttachShader(program , vertexShader );
glAttachShader(program , fragmentShader);
glLinkProgram(m_Program);
glValidateProgram(m_Program);

现在我们进入游戏循环:

while(1)

   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   glUseProgram(program);
   glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glDisableVertexAttribArray(0);

【问题讨论】:

【参考方案1】:

您的索引减一,它们在 OpenGL 中是从 0 开始的,因此只有 0 到 7 的值对您的数组有效,使用 8 将访问一些具有未定义内容的越界内存。

【讨论】:

这是不正确的。 glBufferData 需要以字节为单位的大小。所以 3 * 8。 @SeanO'Hanlon 他们不是这么说的。他们说的和我的回答一样,但措辞不同。 @SeanO'Hanlon:我(和@Xirema)从未谈论过glBufferData。我们讨论了 indicies 数组中的实际值。 @SeanO'Hanlon indicies 数组中的数字必须与verticies 数组中的元素相对应。元素从 0 开始。 @derhass 我真的被你们的意思弄糊涂了。【参考方案2】:

您的索引数组看起来不正确。它应该在[0...7]而不是[1...8]范围内被索引。

【讨论】:

以上是关于在错误位置渲染的顶点(OpenGl)的主要内容,如果未能解决你的问题,请参考以下文章

使用 OpenGL 和顶点数组对象渲染两个对象

哪些 OpenGL 函数在顶点着色器之前修改顶点位置?

OpenGL渲染管道

OpenGL渲染管道

初识OpenGL (-)顶点之“链接顶点属性“

初识OpenGL (-)顶点之“链接顶点属性“