【问题标题】:Change color of chosen vertex using OpenGL 4.5使用 OpenGL 4.5 更改所选顶点的颜色
【发布时间】:2019-03-17 23:38:03
【问题描述】:

我正在用 C++ 编写一个程序,使用 OpenGL 根据用户输入插入和编辑三角形。在屏幕上显示一个三角形后,用户可以单击任何顶点并通过按数字键决定为其分配什么颜色。每个带编号的键代表一种颜色,1 可以是红色,2 可以是蓝色,以此类推到 9。

现在我有代码来识别他们点击了 VBO 中的哪个顶点,但我不明白一旦我识别了顶点该怎么做。我知道我可以使用我现在正在使用的 glUniform3f,但这会使场景中的每个三角形都具有相同的颜色。

顶点着色器和片段着色器:

Program program;
const GLchar* vertex_shader =
        "#version 150 core\n"
                "in vec2 position;"
                "void main()"
                "{"
                "   gl_Position = vec4(position, 0.0, 1.0);"
                "}";
const GLchar* fragment_shader =
        "#version 150 core\n"
                "out vec4 outColor;"
                "uniform vec3 triangleColor;"
                "void main()"
                "{"
                "    outColor = vec4(triangleColor, 1.0);"
                "}";

我是否需要为颜色创建第二个 VBO?如果是这样,我如何设置代码以同时使用它们?我对 OpenGL 很陌生,所以任何事情都有帮助。

【问题讨论】:

  • 使用 VBO 很容易。您可以只更新由glBufferSubData 更改的缓冲区部分。如果您只喜欢制服,那么您必须传递选定的顶点标识符(其 VBO 中的位置)并通过与 gl_VertexID 比较在顶点着色器中使用 if。

标签: c++ opengl colors glsl vertex-shader


【解决方案1】:

我需要为颜色创建第二个 VBO 吗?如果是这样,我如何设置代码以使用它们?我对 OpenGL 很陌生,所以有什么帮助。

是的,你可以。但也可以在一个 VBO 中编码顶点坐标和颜色。

无论如何,您必须创建一个顶点着色器,它除了顶点坐标之外还有第二个属性。该属性是与顶点坐标关联的颜色。并且必须传递给片段着色器(在下面使用Raw string literal):

顶点着色器

const GLchar* vertex_shader = R"(
#version 150 core

in vec2 position;
in vec3 color;

out vec3 vColor;

void main()
{
    vColor      = color;
    gl_Position = vec4(position, 0.0, 1.0);
}
)";

片段着色器

const GLchar* fragment_shader = R"(
#version 150 core

in vec3 vColor;

out vec4 outColor;

void main()
{
    outColor = vec4(vColor.rgb, 1.0);
}
)";

C++

GLuint program = ...;

glLinkProgram( program );
GLint position_inx = glGetAttribLocation(program, "position");
GLint color_inx    = glGetAttribLocation(program, "color");

如果你想使用 2Vertex Buffer Objects,其中第一个包含 x 和 y 坐标的顶点位置,第二个包含具有红色、绿色和蓝色通道的颜色,那么定义通用顶点数组属性可能如下所示:

GLuint VBOpos = ....; // x0, y0,     x1, y1, ...
GLuint VBOcol = ....; // r0, g0, b0, r1, g1, b1, ...

glBindBuffer( GL_ARRAY_BUFFER, VBOpos );
glEnableVertexAttribArray( position_inx );
glVertexAttribPointer( 
    position_inx,
    2, GL_FLOAT, GL_FALSE, // 2 floats per coordinate
    0, nullptr );          // tightly packed

glBindBuffer( GL_ARRAY_BUFFER, VBOcol );
glEnableVertexAttribArray( color_inx );
glVertexAttribPointer( 
    color_inx,
    3, GL_FLOAT, GL_FALSE, // 3 floats per color
    0, nullptr );          // tightly packed

如果要使用 1 Vertex Buffer Objects,其中包含 x 和 y 坐标,后跟红色、绿色和蓝色通道,则通用顶点属性数组的定义可能如下所示:

GLuint VBO = ....; // x0, y0, r0, g0, b0, x1, y1, r1, g1, b1, ...

glBindBuffer( GL_ARRAY_BUFFER, VBO );

glEnableVertexAttribArray( position_inx );
glVertexAttribPointer( 
    position_inx,
    2, GL_FLOAT, GL_FALSE,     // 2 floats per coordinate
    5 * sizeof(float),         // stride of 5 floats from one tuple to the next one
    (void*)0 );                // offset of the vertex coordinates is 0

glEnableVertexAttribArray( color_inx );
glVertexAttribPointer( 
    color_inx,
    3, GL_FLOAT, GL_FALSE,      // 3 floats per color
    5 * sizeof(float),          // stride of 5 floats from one tuple to the next one
    (void*)(2 * sizeof(float)); // offset of the color attribute is 2 * sizeof(float)

【讨论】:

  • GLuint程序的意义是什么= ...;在你的 C++ 部分?
  • @BenReilly 我不明白你的问题。 program 当然是命名的着色器程序对象。 program = glCreateProgram()
猜你喜欢
  • 2016-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-05
  • 1970-01-01
相关资源
最近更新 更多