所以我在OpenGL中对纹理应用纹理时遇到了一些麻烦。我的解决方案看起来很高很低,但在很多小时的研究中都找不到解决方案。
我希望另一双眼睛能够捕捉到我的代码中的错误。
当我在着色器中设置颜色时,一切都很有效,但如果我尝试将纹理传递给它,我就会得到
下面的代码绘制了一个简单的正方形,并且(应该)对其应用纹理。
Image Loader:
void Texture::loadTexture(const char* _filename)
{
char fn[255] = "assets/textures/";
strcat(fn, _filename);
std::cout << fn << std::endl;
FREE_IMAGE_FORMAT format = FreeImage_GetFileType(fn, 0);
FIBITMAP* bitmap = FreeImage_Load(format, fn);
FIBITMAP* bitmap32 = nullptr;
unsigned int bitsPerPixel = FreeImage_GetBPP(bitmap);
std::cout << "Image BPP: " << bitsPerPixel << std::endl;
int imageWidth = FreeImage_GetWidth(bitmap);
int imageHeight = FreeImage_GetHeight(bitmap);
std::cout << "Image size: " << imageWidth << " x " << imageHeight << std::endl;
if (bitsPerPixel != 32)
bitmap32 = FreeImage_ConvertTo32Bits(bitmap);
else
bitmap32 = bitmap;
BYTE* textureData = FreeImage_GetBits(bitmap32);
//for(int i = 0; i < imageWidth * imageHeight * 4; i += 4) {
// std::cout << (int)textureData[i] << ", " << (int)textureData[i+1] << ", " << (int)textureData[i+2] << ", " << (int)textureData[i+3] << std::endl;
//}
glBindTexture(GL_TEXTURE_2D, m_ID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imageWidth, imageHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, (void*)textureData);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
FreeImage_Unload(bitmap);
if (bitsPerPixel != 32)
FreeImage_Unload(bitmap32);
}
通过以可读格式输出图像数据,我确认图像文件已加载并且数据正确无误。结果如预期。
我的主循环:
int main()
{
const std::vector<sun::Vertex> vertices = {
sun::Vertex(sun::Vector3f(-4.0f, 4.0f, 0.0f), sun::Vector2f(0.0f, 1.0f)),
sun::Vertex(sun::Vector3f(4.0f, 4.0f, 0.0f), sun::Vector2f(1.0f, 1.0f)),
sun::Vertex(sun::Vector3f(-4.0f, -4.0f, 0.0f), sun::Vector2f(0.0f, 0.0f)),
sun::Vertex(sun::Vector3f(4.0f, -4.0f, 0.0f), sun::Vector2f(1.0f, 0.0f))
};
const std::vector<unsigned int> indices = {0, 1, 2, 1, 3, 2};
sun::Window window("My Game", 1280, 800);
sun::Shader shader("basic.vs", "basic.fs");
sun::Mesh mesh;
sun::Transform transform;
sun::Texture texture;
transform.setProjection(70.0f, window.getWidth(), window.getHeight(), 1.0f, -1000.0f);
mesh.addVertices(vertices, indices);
texture.loadTexture("test2.png");
shader.addUniform("transform");
shader.bind();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Start the main loop
while (!window.closeWindow()) {
// Render
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.3f, 0.8f, 1.0f, 1.0f);
transform.setTranslation(0.0f, 0.0f, 10.0f);
shader.setUniform("transform", transform.getProjectedTransformation());
texture.bind(); // { glBindTexture(GL_TEXTURE_2D, m_ID); }
glEnable(GL_TEXTURE_2D);
mesh.draw(); // See below for details.
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
window.update();
}
return 1;
}
mesh.draw()方法:
void Mesh::draw()
{
//std::cout << m_Index << std::endl;
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void*)sizeof(Vector3f));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO);
glDrawElements(GL_TRIANGLES, m_SizeIndices, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
}
最后,我的Vertex和Fragment着色器分别为:
#version 330 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec2 texCoord;
uniform mat4 transform;
out vec2 coords;
void main()
{
gl_Position = transform * vec4(position, 1.0f);
coords = texCoord;
}
#version 330 core
in vec2 coord;
uniform sampler2D sampler;
void main()
{
gl_FragColor = texture2D(sampler, coord.xy);//vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
作为补充信息,在初始化期间设置/启用以下OpenGL参数:
void Window::init()
{
// Set viewport size
glfwGetFramebufferSize(m_Window, &m_Width, &m_Height);
glViewport(0, 0, m_Width, m_Height);
// Set vsync
glfwSwapInterval(0);
// Set face culling and depth test.
glFrontFace(GL_CW);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
// Enable 2D textures
glEnable(GL_TEXTURE_2D);
// Enable gamma correction
glEnable(GL_FRAMEBUFFER_SRGB);
}
非常感谢任何帮助。
谢谢!
答案 0 :(得分:1)
Annnnd我发现了我的问题。这表明,长时间盯着自己的代码会让你错过最明显的事情。
问题出在我的着色器上。顶点着色器正在输出
vec2 coords
但片段着色器正在等待
vec2 coord
一旦我改变了变量名称以匹配,我就得到了我的纹理。