首页 > 解决方案 > 尝试渲染像素坐标时,简单线渲染失败

问题描述

我很抱歉把这个带到这里,但我花了大约 7 个小时也许是为了一件非常简单的事情。也许你们中的一些人发现了问题。

我尝试将一些像素坐标渲染到屏幕上。代码如下。

对于 800x600 屏幕。只需尝试计算线条的位置,然后将其渲染到屏幕上。

例如:点 A(400, 300, 0) 和点 B(500,300,0) 应该是一条从屏幕中心向右的简单黑线。

当我在渲染中调用这个类函数时,我想我可能会创建一个单独的渲染会话。但是,当我编写诸如 glCleanColor 之类的内容时,背景会发生变化。


#include <GLFW/glfw3.h>
#include <GL/gl.h>
#include <GL/glew.h>

#include <iostream>
#include <vector>

顶点着色器:

const GLchar *vertex_shader =
    "#version 410\n"
    "layout (location = 0) in vec3 pos;\n"
    "layout (location = 1) in vec4 col;\n"
    "uniform mat4 projection;\n"
    "out vec4 Frag_Color;\n"
    "void main()\n"
    "{\n"
    "    Frag_Color = col;\n"
    "    gl_Position =projection*vec4(pos.xyz,1);\n"
    "}\n";

片段着色器:

const GLchar *fragment_shader =
    "#version 410\n"
    "in vec4 Frag_Color;\n"
    "layout (location = 0) out vec4 Out_Color;\n"
    "void main()\n"
    "{\n"
    "    Out_Color = Frag_Color;\n"
    "}\n";

顶点结构

struct Vrtx
{
    float pos[3];
    float col[4] = {0.0f, 0.0f, 0.0f, 1.0f};
};

坐标轴类:

class CoordinateAxis
{
public:
    void coordinate_axis()
    {
        vertices.resize(6);
        for (int i = 0; i < 3; i++)
        {
            vertices[2 * i].pos[0] = 400;
            vertices[2 * i].pos[1] = 300;
            vertices[2 * i].pos[2] = 0;
        }
        vertices[1].pos[0] = 500;
        vertices[1].pos[1] = 300;
        vertices[1].pos[2] = 0;
        vertices[3].pos[0] = 400;
        vertices[3].pos[1] = 400;
        vertices[3].pos[2] = 0;
        vertices[3].pos[0] = 400;
        vertices[3].pos[1] = 430;
        vertices[3].pos[2] = 100;

        setupRender();
        glBindVertexArray(VAO);
        glDrawElements(GL_LINE, 6, GL_UNSIGNED_INT, 0);
        glBindVertexArray(0);
        glUseProgram(0);
    }
    CoordinateAxis()
    {
        initShaderProgram();
    };

private:
    void initShaderProgram()
    {
        // Vertex shader
        GLuint vHandle = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vHandle, 1, &vertex_shader, NULL);
        glCompileShader(vHandle);

        // Fragment shader
        GLuint fHandle = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fHandle, 1, &fragment_shader, NULL);
        glCompileShader(fHandle);

        // Create Program
        handleProgram = glCreateProgram();
        glAttachShader(handleProgram, vHandle);
        glAttachShader(handleProgram, fHandle);
        glLinkProgram(handleProgram);

        attribLocationProj = glGetUniformLocation(handleProgram, "projection");

        glGenVertexArrays(1, &VAO);
        // CreateBuffers
        glGenBuffers(1, &vboHandle);
        glGenBuffers(1, &iboHandle);
    }
    void setupRender()
    {
        GLint last_viewport[4];
        glGetIntegerv(GL_VIEWPORT, last_viewport);
        float L = last_viewport[0];
        float R = L + last_viewport[2];
        float B = last_viewport[1];
        float T = B + last_viewport[3];

        const float ortho_projection[4][4] =
            {
                {2.0f / (R - L), 0.0f, 0.0f, 0.0f},
                {0.0f, 2.0f / (T - B), 0.0f, 0.0f},
                {0.0f, 0.0f, -1.0f, 0.0f},
                {(R + L) / (L - R), (T + B) / (B - T), 0.0f, 1.0f},
            };
        glUseProgram(handleProgram);
        glUniformMatrix4fv(attribLocationProj, 1, GL_FALSE, &ortho_projection[0][0]);
        glBindVertexArray(VAO);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboHandle);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), GL_STATIC_DRAW);

        glBindBuffer(GL_ARRAY_BUFFER, vboHandle);
        glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vrtx), vertices.data(), GL_STATIC_DRAW);

        glBindBuffer(GL_ARRAY_BUFFER, vboHandle);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertices.size() * sizeof(Vrtx), 0);
        glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, vertices.size() * sizeof(Vrtx), (void *)(3 * sizeof(float)));

        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);
    }

    std::vector<Vrtx> vertices;
    std::vector<GLuint> indices;
    GLuint handleProgram, VAO, vboHandle, iboHandle, attribLocationProj;
};

标签: c++openglgraphics

解决方案


GL_LINE不是有效的原始类型。GL_LINE是一种模式glPolygonMode
有效的线原语类型是GL_LINES

glDrawElements(GL_LINE, 6, GL_UNSIGNED_INT, 0);

glDrawElements(GL_LINES, 6, GL_UNSIGNED_INT, 0);

此外,当您设置顶点属性数据数组时存在问题glVertexAttribPointer。第 5 个参数 ( strid ) 是连续属性元组之间的字节偏移量,而不是缓冲区的大小。sizeof(Vrtx)而不是vertices.size() * sizeof(Vrtx)

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vrtx), 0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Vrtx), (void *)(3*sizeof(float)));

请注意,索引数组似乎是空的。要么初始化索引数组:

indices = { 0, 1, 2, 3, 4, 5 };

glDrawArrays改用:

glDrawArrays(GL_LINES, 0, 6);

推荐阅读