Текстурированные треугольные нагрузки сплошным цветом - PullRequest
1 голос
/ 14 июня 2019

Я пытаюсь визуализировать текстурированный треугольник.Я использую изображение STB для загрузки PNG.Треугольник отображается одним цветом для множества разных изображений, которые я пробовал.Цвет выглядит как среднее от общего количества цветов, отображаемых на изображении.

Я искал много решений для похожих вопросов и убедился (или я так думаю), что я не попал в общую'gotchas': glEnable(GL_TEXTURE_2D) называется.Мои звонки на glVertexAttribPoitners() настроены правильно.Я пытался сказать OpenGl, что я не хочу использовать mipmapping с glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR), и я включил соответствующие массивы вершин через glEnableVertexAttribArray().Мои шейдеры компилируются без ошибок.

#include <practice/practice.h>
#include <test_dep/stb_image.h>


void
initRenderer_practice()
{
    const char* vertex_shader = GLSL(450 core,

                                     layout (location = 0) in vec2 vCoords;
                                     layout (location = 1) in vec2 tCoords;

                                     out vec2 ftCoords;

                                     void main()
                                     {
                                         gl_Position = vec4(vCoords.x, vCoords.y, 0.0, 1.0);
                                         ftCoords = tCoords;
                                     }

        );

    const char* fragment_shader = GLSL(450 core,

                                       uniform sampler2D texture_data;
                                       in vec2 ftCoords;
                                       out vec4 fragColor;

                                       void main()
                                       {
                                           fragColor = texture(texture_data, ftCoords.st);
                                       }
        );


    GLfloat vCoordsLocal[] =
        {
            //
            // POSITION COORDS
            //
            // bottom left
            -0.5, -0.5,

            // bottom right
            0.5, -0.5,

            // top center
            0.0, 0.5,

            //
            // TEXTURE COORDS
            //
            // left bottom
            0.0, 0.0,

            // right bottom
            1.0, 0.0,

            // center top
            0.5, 1.0,
        };

    if (!practice_target)
    {
        practice_target = (uGLRenderTarget*)malloc(sizeof(uGLRenderTarget));
        practice_target->shader_program = 0;
        practice_target->vertex_array_object = (GLuint) -1;
        practice_target->vertex_buffer_object = (GLuint) -1;
    }

    practice_target->shader_program = uGLCreateShaderProgram_vf(&vertex_shader,
                                                                &fragment_shader);
    assert(practice_target->shader_program);
    glUseProgram(practice_target->shader_program);
    glError;

    glGenVertexArrays(1, &practice_target->vertex_array_object);
    glBindVertexArray(practice_target->vertex_array_object);
    glError;

    glGenBuffers(1, &practice_target->vertex_buffer_object);
    glBindBuffer(GL_ARRAY_BUFFER, practice_target->vertex_buffer_object);
    glBufferData(GL_ARRAY_BUFFER,
                 sizeof(vCoordsLocal),
                 vCoordsLocal,
                 GL_STATIC_DRAW);
    glError;

    glGenTextures(1, &practice_target->texture_id);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, practice_target->texture_id);
    practice_target->shdr_texture_2d_location = glGetUniformLocation(practice_target->shader_program, "texture_data");
    glUniform1i(practice_target->shdr_texture_2d_location, 0);
    assert(practice_target->shdr_texture_2d_location != -1);
    glError;

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glError;


    stbi_set_flip_vertically_on_load(true);
    u8* texture_data = NULL;
    GLint width, height, channels = 0;
    texture_data = stbi_load("./assets/index.png", &width, &height, &channels, 0);
    if (texture_data)
    {
        /*
        void glTexImage2D(GLenum target,
                          GLint level,
                          GLint internalFormat,
                          GLsizei width,
                          GLsizei height,
                          GLint border,
                          GLenum format,
                          GLenum type,
                          const GLvoid * data);
        */
        glTexImage2D(GL_TEXTURE_2D,
                     0,
                     GL_RGB,
                     width,
                     height,
                     0,
                     GL_RGB,
                     GL_UNSIGNED_BYTE,
                     texture_data);
        glGenerateMipmap(GL_TEXTURE_2D);
        glError;

        printf("\n\n numchannels: %d\n\n", channels);
    }
    else
    {
        puts("[ debug ] Load texture failed\n");
        assert(0);
    }

    stbi_image_free(texture_data);

    /*
      void glVertexAttribPointer(GLuint index,
      GLint size,
      GLenum type,
      GLboolean normalized,
      GLsizei stride,
      const GLvoid * pointer);
    */

    // Vertex coordinate attribute
    glVertexAttribPointer(0,
                          2,
                          GL_FLOAT,
                          GL_FALSE,
                          0,
                          (void*) 0);
    glEnableVertexAttribArray(0);

    // Texture coordinate attribute
    glVertexAttribPointer(1,
                          2,
                          GL_FLOAT,
                          GL_FALSE,
                          0,
                          (void*) 6);
    glEnableVertexAttribArray(1);
    glError;

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glUseProgram(0);
    glError;
}

void
render_practice()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(practice_target->shader_program);

    glEnable(GL_TEXTURE_2D);
    glBindVertexArray(practice_target->vertex_array_object);
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, practice_target->texture_id);
    glDrawArrays(GL_TRIANGLES, 0, 3);

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glUseProgram(0);
    glError;
}

Ожидаемый результат - отображение текстуры на треугольник, а не на один цвет.

1 Ответ

2 голосов
/ 14 июня 2019

Спецификация атрибута вершины для координат текстуры смещена.
Расположение в памяти атрибутов

x0 y0, x1, y1, x2, y2,   u0 v0, u1, v1, u2, v2

Итак, первая координата текстуры - это 6-й элемент в буфере.

Но последний параметр glVertexAttribPointer представляет собой смещение байт в хранилище данных буферного объекта.
Это означает, что смещение должно быть 6*sizeof(GLfloat), а не 6

glVertexAttribPointer(1,
                      2,
                      GL_FLOAT,
                      GL_FALSE,
                      0,
                      (void*)(6*sizeof(GLfloat)); // <-----

Я рекомендую изменить расположение атрибутов вершины на расширяемый макет:

x0 y0 u0 v0    x1 y1 u1 v1    x2 y2 u2 v2   ...

и использовать соответствующую спецификацию атрибута вершины:

GLsizei stride     = (GLsizei)(4*sizeof(GLfloat)); // 4 because of (x, y, u ,v)
void*   vertOffset = (void*)(0);                   // 0 because the vertex coords are 1st
void*   texOffset  = (void*)(2*sizeof(GLfloat));   // 2 because u, v are after x, y

// Vertex coordinate attribute
glVertexAttribPointer(0,
                      2,
                      GL_FLOAT,
                      GL_FALSE,
                      stride,
                      vertOffset);
glEnableVertexAttribArray(0);

// Texture coordinate attribute
glVertexAttribPointer(1,
                      2,
                      GL_FLOAT,
                      GL_FALSE,
                      stride,
                      texOffset;
glEnableVertexAttribArray(1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...