【发布时间】:2017-05-31 09:24:47
【问题描述】:
在此之前,很抱歉发布了很多代码。我会尽量直截了当。
我的纹理是 bmp 格式的 4x4 纹理图像(如果有人对此感兴趣,那就是 ->)。作为映射的结果,我得到了左上像素(0.0,1.0)的颜色(我检查了它,它总是左上像素的颜色),我的三角形颜色导致该像素的颜色,即白色。
我尝试在GL_TEXTURE_MAG_FILTER 中更改GL_NEARESTtoGL_LINEAR
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
我得到右下像素 (1.0, 0.0),这是某种绿色: 我正在使用 stb_image 加载纹理。所以在我的 Texture.cpp 中:
Texture::Texture(const std::string& fileName)
{
int width, height, numComponents;
unsigned char* imageData = stbi_load(fileName.c_str(), &width, &height, &numComponents, 4);
if (imageData == NULL)
{
std::cerr << "Error: Texture load failed for texture: " << fileName << std::endl;
}
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &_texture);
glBindTexture(GL_TEXTURE_2D, _texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
stbi_image_free(imageData);
}
Texture::~Texture(void)
{
glDeleteTextures(1, &_texture);
}
void Texture::Bind(unsigned int unit)
{
assert(unit >= 0 && unit <= 31);
glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(GL_TEXTURE_2D, _texture);
}
在我的顶点着色器中:
#version 150
in vec3 position;
in vec2 texCoord;
out vec2 texCoord0;
void main(void)
{
texCoord0 = texCoord;
gl_Position = vec4(position, 1.0);
}
在我的片段着色器中:
#version 150
in vec2 textCoord0;
uniform sampler2D texture;
void main(void)
{
gl_FragColor = texture2D(texture, textCoord0);
}
在我的 main.cpp
#include <iostream>
#include <GL/glew.h>
#include "Display.h"
#include "Shader.h"
#include "Mesh.h"
#include "Texture.h"
int main(int argc, char** argv)
{
Display display(800, 600, " ");
display.Clear(0.0f, 0.15f, 0.3f, 1.0f);
Vertex vertices[] = {
Vertex(glm::vec3(-1.0f, -1.0f, 0.0f), glm::vec2(0.0f, 0.0f)),
Vertex(glm::vec3( 0.0f, 1.0f, 0.0f), glm::vec2(0.5f, 1.0f)),
Vertex(glm::vec3( 1.0f, -1.0f, 0.0f), glm::vec2(1.0f, 0.0f))
};
Texture texture("./res/a.bmp");
Shader shader("./res/testShader");
Mesh mesh(vertices, sizeof(vertices) / sizeof(vertices[0]));
while (display.IsClosed() != true)
{
shader.Bind();
texture.Bind(0);
mesh.Draw();
display.Update();
}
return 0;
}
在 Mesh.cpp 中,我将顶点属性(glm::vec3 _position 和 glm::vec2 _texture)拆分为 2 个 stl 向量并使用 2 个缓冲区(“0” - 用于顶点位置和“1” - 纹理):
Mesh::Mesh(Vertex* vertices, unsigned int numVertices, GLenum usage)
{
_drawCount = numVertices;
glGenVertexArrays(1, &_vertexArrayObject);
glBindVertexArray(_vertexArrayObject);
std::vector<glm::vec3> positions;
std::vector<glm::vec2> texCoords;
positions.reserve(numVertices);
texCoords.reserve(numVertices);
for (unsigned int i = 0; i < numVertices; ++i)
{
positions.push_back(*vertices[i].Position());
texCoords.push_back(*vertices[i].TexCoord());
}
glGenBuffers(NUM_BUFFERS, _vertexArrayBuffers);
glBindBuffer(GL_ARRAY_BUFFER, _vertexArrayBuffers[POSITION_VB]);
glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(positions[0]), positions.data(), usage);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, _vertexArrayBuffers[TEXCOORD_VB]);
glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(texCoords[0]), texCoords.data(), usage);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
glBindVertexArray(0);
}
Mesh::~Mesh(void)
{
glDeleteVertexArrays(1, &_vertexArrayObject);
}
void Mesh::Draw(GLenum mode)
{
glBindVertexArray(_vertexArrayObject);
glDrawArrays(mode, 0, _drawCount);
glBindVertexArray(0);
}
在 Shader.cpp 我绑定了这样的属性:
glBindAttribLocation(_program, 0, "position");
glBindAttribLocation(_program, 1, "texCoord");
--------------编辑------------------ --------------- 将顶点着色器更改为:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoord;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(position, 1.0f);
TexCoord = texCoord;
}
和片段着色器:
#version 330 core
in vec2 TexCoord;
out vec4 color;
uniform sampler2D ourTexture;
void main()
{
color = texture(ourTexture, TexCoord);
}
纹理映射正确。
但我仍然想知道为什么我的第一个解决方案不起作用。
【问题讨论】:
-
在我看来,您的第二次
glVertexAttribPointer调用缺少偏移量(最后一个参数)UV 数据位于位置数据之后。如果我是对的,您正在将 posisiton.xy 读取为 UV。 (您可以尝试在 renderdoc 中运行它以查看顶点着色器的结果并确认/确认我的诊断) -
@Borgleader 我认为使用超过 1 个缓冲区的想法是拆分数据,然后按部分将其发送到 GPU?还是我错了,它不起作用?因为那时我不知道我应该设置什么偏移量。在您编辑后,我现在将尝试使用 renderdoc 并让您知道我的结果
-
哦,nvm,我错过了那部分,我看到了你的初始顶点数组,错过了两个 std::vector。 (根据this answer,您的 VAO 的初始化似乎是正确的)
-
如果使用 texcoord(
gl_FragColor=vec4(texcoord,0,0,1);) 给三角形上色会是什么样子? -
可能不相关,但您的
glTexParameterf应该是glTexParameteri。