Попытка отобразить текстуру, но получить только сплошной цвет с OpenGL - PullRequest
0 голосов
/ 15 февраля 2019

Моя цель - отобразить куб с текстурой, взятой из файла png (DarkDirt.png).Проблема в том, что я получаю только сплошной коричневый цвет, и мое освещение меняется для каждого треугольника, образующего куб.

Теперь я читаю и думаю, что это может быть связано с установкой индекса на1 но я не добился успеха с этим.Я попытался поиграть со значениями UV, но это только изменит поведение освещения и ничего не исправит.Так что теперь я думаю, что мои вершины (вершины в коде) неверны?

код c ++, массивы:

const GLuint NumVertices = 24;
const GLuint NumTriCubes = 12;
const GLuint NumNormals = 6;
const GLuint NumUvs = 4;

GLfloat uvs[NumUvs][2] = {
    { 0, 0 },
    { 1, 0 },
    { 0, 1 },
    { 1, 1 },
};

GLfloat vertices[NumVertices][3] = {
    //Front
    { -0.5f, -0.5f, 0.5f }, //0
    { 0.5f, -0.5f, 0.5f }, //1
    { 0.5f, 0.5f, 0.5f }, //2
    { -0.5f, 0.5f, 0.5f }, //3

    //Right
    { 0.5f, -0.5f, 0.5f }, //4
    { 0.5f, -0.5f, -0.5f }, //5
    { 0.5f, 0.5f, -0.5f }, //6
    { 0.5f, 0.5f, 0.5f }, //7

    //Back
    { -0.5f, -0.5f, -0.5f },  //8
    { -0.5f, 0.5f, -0.5f }, //9
    { 0.5f, 0.5f, -0.5f }, //10
    { 0.5f, -0.5f, -0.5f }, //11

    //Left
    { -0.5f, -0.5f, 0.5f }, //12
    { -0.5f, 0.5f, 0.5f }, //13
    { -0.5f, 0.5f, -0.5f }, //14
    { -0.5f, -0.5f, -0.5f }, //15

    //Upper
    { -0.5f, 0.5f, 0.5f }, //16
    { 0.5f, 0.5f, 0.5f }, //17
    { 0.5f, 0.5f, -0.5f }, //18
    { -0.5f, 0.5f, -0.5f }, //19

    //Bottom
    { -0.5f, -0.5f, 0.5f }, //20
    { -0.5f, -0.5f, -0.5f }, //21
    { 0.5f, -0.5f, -0.5f }, //22
    { 0.5f, -0.5f, 0.5f }, //23

};

GLuint vertexIndices[NumTriCubes][3] = {
    //Front
    { 0, 1, 2 },
    { 0, 2, 3 },

    //Right
    { 4, 5, 6 },
    { 4, 6, 7 },

    //Back
    { 8, 9, 10 },
    { 8, 10, 11 },

    //Left
    { 12, 13, 14 },
    { 12, 14, 15 },

    //Upper
    { 16, 17, 18 },
    { 16, 18, 19 },

    //Bottom
    { 20, 21, 22 },
    { 20, 22, 23 }
};

GLfloat normals[NumVertices][3] = {

    //Front
    { 0.0f, 0.0f, 1.0f},
    { 0.0f, 0.0f, 1.0f},
    { 0.0f, 0.0f, 1.0f},
    { 0.0f, 0.0f, 1.0f},

    //Right
    { 1.0f, 0.0f, 0.0f},
    { 1.0f, 0.0f, 0.0f},
    { 1.0f, 0.0f, 0.0f},
    { 1.0f, 0.0f, 0.0f},

    //Back
    { 0.0f, 0.0f, -1.0f},
    { 0.0f, 0.0f, -1.0f},
    { 0.0f, 0.0f, -1.0f},
    { 0.0f, 0.0f, -1.0f},

    //Left
    { -1.0f, 0.0f, 0.0f},
    { -1.0f, 0.0f, 0.0f},
    { -1.0f, 0.0f, 0.0f},
    { -1.0f, 0.0f, 0.0f},

    //Upper
    { 0.0f, 1.0f, 0.0f},
    { 0.0f, 1.0f, 0.0f},
    { 0.0f, 1.0f, 0.0f},
    { 0.0f, 1.0f, 0.0f},

    //Bottom
    { 0.0f, -1.0f, 0.0f},
    { 0.0f, -1.0f, 0.0f},
    { 0.0f, -1.0f, 0.0f},
    { 0.0f, -1.0f, 0.0f}

};


код c ++, я связываю текстуру в функции draw ():

    m_texture->bind();

код c ++, инициализация:

    glGenBuffers(NumBuffers, m_Buffers);
    glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[VBO_Cube]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices)+ sizeof(uvs) + sizeof(normals), nullptr, GL_STATIC_DRAW);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
    glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices), sizeof(uvs), uvs);
    glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices) + sizeof(uvs), sizeof(normals), normals);

...

    glEnableVertexAttribArray(GLuint(m_vNormalLocation));
    glVertexAttribPointer(GLuint(m_vNormalLocation), 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(vertices)));

    glVertexAttribPointer(GLuint(m_vUVLocation), 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(vertices)));
    glEnableVertexAttribArray(GLuint(m_vUVLocation));

...
    m_texture = new QOpenGLTexture(QImage("DarkDirt.png").mirrored());
    m_texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear);
    m_texture->setMagnificationFilter(QOpenGLTexture::Linear);

Я пытаюсь заставить текстуру отображаться на каждой стороне куба.Так что это даст мне «грязный куб», как, например, в Minecraft.Но да, сейчас он проявляется только в виде твердого коричневого куба с освещением повсюду.Любая помощь будет оценена.Спасибо!

1 Ответ

0 голосов
/ 15 февраля 2019

Вам нужен один атрибут координаты текстуры для каждой координаты вершины.Поскольку у вас 24 (4 * 6) координат вершин, вам также понадобятся 24 атрибута текстурных координат:

const GLuint NumUvs = 24;
GLfloat uvs[NumUvs][2] = {
    { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 },
    { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 },
    { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 },
    { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 },
    { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 },
    { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 }
};

Расчет смещения нормальных векторов неверен:

glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices), sizeof(uvs), uvs);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices) + sizeof(uvs), sizeof(normals), normals);

glVertexAttribPointer(GLuint(m_vNormalLocation), 3, GL_FLOAT, GL_FALSE, 0,
      BUFFER_OFFSET(sizeof(vertices)));

Это должно быть:

glVertexAttribPointer(GLuint(m_vNormalLocation), 3, GL_FLOAT, GL_FALSE, 0, 
    BUFFER_OFFSET(sizeof(vertices) + sizeof(uvs)));

Кажется, что индекс атрибута координат текстуры (m_vUVLocation) никогда не устанавливается в вашей программе.

Вы можете получить индекс атрибута атрибута по QOpenGLShaderProgram::attributeLocation:

m_vUVLocation = m_programRender->attributeLocation("vUV");

или собственный OpenGL по glGetAttribLocation:

m_vUVLocation = glGetAttribLocation(m_programRender->programId(), "vUV");

Обратите внимание, также можно использовать GLSL Layout Qualifiers для определения местоположения атрибута в коде шейдера:

например, Vertex shader:

#version 400 core

layout(location = 0) in vec4 vPosition;
layout(location = 1) in vec4 vColor;
layout(location = 2) in vec3 vNormal;
layout(location = 3) in vec2 vUV;

Iв этом случае значение для m_vUVLocation будет равно 3.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...