Изменить цвет выбранной вершины, используя OpenGL 4.5 - PullRequest
0 голосов
/ 12 октября 2018

Я пишу программу на 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, поэтому все помогает.

1 Ответ

0 голосов
/ 12 октября 2018

Нужно ли создавать второе VBO только для цветов?Если да, то как мне настроить код для использования их обоих?Я очень новичок в OpenGL, поэтому все помогает.

Да, вы можете.Но также возможно закодировать координаты вершины и цвета в одном VBO.

В любом случае вам необходимо создать вершинный шейдер, у которого есть 2-й атрибут, помимо координат вершины.Этот атрибут - цвет, связанный с координатой вершины.И должен быть передан фрагментному шейдеру (в следующем используются необработанные строковые литералы ):

Вершинный шейдер

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");

Если вы хотите использовать 2 Vertex Buffer Objects , где 1-йсодержит позиции вершин с координатами 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)
...