【问题标题】:Shader design for multiple vertex types多种顶点类型的着色器设计
【发布时间】:2019-08-04 15:28:21
【问题描述】:

我正在编写一个 OpenGL 库,但偶然发现了一个关于多个顶点类型和顶点着色器的问题。我是否需要为每个处理其属性的新顶点类型编写一个新的顶点/片段着色器?还是我需要编写一个处理所有可能属性的顶点/片段着色器?

这些是我用于顶点类型的一些基本类“模式”。

 struct simple_vertex
{
    glm::vec3 position;

    simple_vertex(glm::vec3 pos) {
        position = pos;
    }

    simple_vertex() {
        position = glm::vec3(0, 0, 0);
    }


    static void enable_attributes() {
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(simple_vertex),
                              (const GLvoid *) offsetof(simple_vertex, position));
        glEnableVertexAttribArray(0);
    }


    glm::vec3 get_position() const {
        return position;
    }
};

struct colored_vertex {//vertex that holds position and color data

    glm::vec3 position;
    glm::vec3 color;

    colored_vertex(glm::vec3 pos, glm::vec3 c) {
        color = c;
        position = pos;
    }

    colored_vertex() {
        color = glm::vec3(0, 0, 0);
        position = glm::vec3(0, 0, 0);
    }

    static void enable_attributes() {
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(colored_vertex),
                              (const GLvoid *) offsetof(colored_vertex, position));
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(colored_vertex),
                              (const GLvoid *) offsetof(colored_vertex, color));
        glEnableVertexAttribArray(1);

    }

    glm::vec3 get_position() const {
        return position;
    }


};


struct textured_vertex {//vertex that holds position and texture coordinates

    glm::vec3 position;
    glm::vec2 texture_coords;

    textured_vertex(glm::vec3 pos, glm::vec2 text_coords) {
        texture_coords = text_coords;
        position = pos;
    }

    textured_vertex() {
        texture_coords = glm::vec2(0, 0);
        position = glm::vec3(0, 0, 0);
    }

    static void enable_attributes() {
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(textured_vertex),
                              (const GLvoid *) offsetof(textured_vertex, position));
        glEnableVertexAttribArray(0);

        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(textured_vertex),
                              (const GLvoid *) offsetof(textured_vertex, texture_coords));
        glEnableVertexAttribArray(1);

    }

    glm::vec3 get_position() const {
        return position;
    }


};


struct normal_textured_vertex {//vertex that holds position normal and texture coordinates

    glm::vec3 position;
    glm::vec2 texture_coords;
    glm::vec3 normal;

    normal_textured_vertex(glm::vec3 pos, glm::vec2 text_coords, glm::vec3 n) {
        texture_coords = text_coords;
        position = pos;
        normal = n;
    }

    normal_textured_vertex() {
        texture_coords = glm::vec2(0, 0);
        position = glm::vec3(0, 0, 0);
        normal = glm::vec3(0, 0, 0);

    }

    static void enable_attributes() {
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(normal_textured_vertex),
                              (const GLvoid *) offsetof(normal_textured_vertex, position));
        glEnableVertexAttribArray(0);

        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(normal_textured_vertex),
                              (const GLvoid *) offsetof(normal_textured_vertex, texture_coords));
        glEnableVertexAttribArray(1);

        glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(normal_textured_vertex),
                              (const GLvoid *) offsetof(normal_textured_vertex, normal));
        glEnableVertexAttribArray(2);

    }

    glm::vec3 get_position() const {
        return position;
    }


};

【问题讨论】:

    标签: c++ opengl glm-math


    【解决方案1】:

    正确的解决方案是选项 3:不要有很多顶点格式完全不同的网格。 “顶点格式”是指网格提供的一组属性(包括它们在缓冲区中的编码方式)。

    一般来说,您应该选择一组相当有限的顶点格式并调整网格(离线)以适应这些格式。您可能有一种用于非蒙皮网格的格式、一种用于蒙皮网格的格式、一种用于 GUI 对象的格式、一种用于粒子的格式,可能还有一两个其他格式。

    如果您正在编写的应用程序无法控制所提供的数据形式并且必须处理任何内容,即使如此,我仍建议为数据未提供的属性创建无害的数据。例如,如果有人给您一个包含位置和 UV 但没有颜色的网格,则创建只是重复值 (1.0, 1.0, 1.0, 1.0) 的颜色数据。您的照明方程式应该可以很好地处理该颜色。如果有人给你一个有位置和颜色但没有纹理坐标的网格,创建只有 0 的 UV 值(并且应该给它一个小的白色纹理来采样)。等等。

    不要根据数据调整代码;将您的数据调整为您的代码。

    【讨论】:

      猜你喜欢
      • 2013-12-10
      • 2021-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-23
      相关资源
      最近更新 更多