我正试着用草纹理地面。有人会介意通过我的步骤来获得2D纹理以显示在3D空间中吗?我对在线教程没有任何好运。
这是我的步骤:
1)调用sprite类初始化来设置顶点坐标和uv数据
void Sprite::init(vec3 bottomleft, vec3 topLeft, vec3 topRight, vec3 bottomRight, std::string texturePath)
{
_texture = ImageLoader::loadPNG(texturePath);
_points = { bottomleft.x, bottomleft.y, bottomleft.z, topLeft.x, topLeft.y, topLeft.z, topRight.x, topRight.y, topRight.z, topRight.x, topRight.y, topRight.z, bottomRight.x, bottomRight.y, bottomRight.z, bottomleft.x, bottomleft.y, bottomleft.z };
_uv = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };
}
我使用均匀采样器并激活纹理
//draw ground texture
glUniform1i(samplerLocation, 0);
glActiveTexture(GL_TEXTURE0);
_grassTexture.draw();
draw函数实现如下,它将数据放入缓冲区并绘制三角形:
void Sprite::draw()
{
if (_vboID == 0)
{
glGenBuffers(1, &_vboID);
}
glBindTexture(GL_TEXTURE_2D, _texture.id);
glBindBuffer(GL_ARRAY_BUFFER, _vboID);
glBufferData(GL_ARRAY_BUFFER, _points.size() * sizeof(float) + _uv.size() * sizeof(float), nullptr, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, _points.size() * sizeof(float), &_points.front());
glBufferSubData(GL_ARRAY_BUFFER, _points.size() * sizeof(float), _uv.size() * sizeof(float), &_uv.front());
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
//position attribute pointer
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, &_points.front());
//uv attribute pointer
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, &_uv.front());
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
顶点着色器:
#version 400
in vec4 vertexPosition;
in vec2 vertexUV;
out vec4 fragmentColor;
out vec2 fragmentUV;
uniform mat4 MVP;
uniform vec4 COLOR;
void main()
{
gl_Position = MVP * vertexPosition;
fragmentColor = COLOR;
fragmentUV = vec2(vertexUV.x, 1.0 - vertexUV.y);
}
和片段着色器:
#version 400
in vec4 fragmentColor;
in vec2 fragmentUV;
out vec4 fragColor;
uniform sampler2D SAMPLER;
void main()
{
vec4 textureColor = texture(SAMPLER, fragmentUV);
fragColor = textureColor * fragmentColor;
}
此时,屏幕上不显示任何内容。我知道片段着色器中的textureColor是绿色的,所以看起来正确设置了制服。我最好的猜测是我要么缺少纹理初始化步骤,要么没有正确填充缓冲区。
答案 0 :(得分:1)
我认为调用glVertexAttribPointer时指针参数存在问题。您正在传递_points和_uv数组的地址,但是您应该相对于vbo的基数传递偏移量。
尝试:
//position attribute pointer
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
//uv attribute pointer
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)(_points.size() * sizeof(float)));