OpenGL(核心配置文件)纹理缺失或黑色
OpenGL (core profile) textures are missing or black
我正在使用带有模型 .obj 的 .mtl 文件中的引用加载纹理。我正在使用 Assimp 库来实现此目的。
问题是,正如标题中所述,纹理没有出现在模型上,或者(我不敢相信)它是黑色的。
以下是加载纹理的代码:
std::vector<texture> model::loadMaterialTextures(aiMaterial * mat, aiTextureType type, std::string typeName)
{
std::vector<texture> textures;
for (GLuint i = 0; i < mat->GetTextureCount(type); i++)
{
aiString str;
mat->GetTexture(type, i, &str);
GLboolean skip = false;
for (GLuint j = 0; j < textures_loaded.size(); j++)
{
if (textures_loaded[j].path == str)
{
skip = true;
break;
}
}
if (!skip)
{
texture tex;
tex.id = textureFromFile(str.C_Str(), this->directory);
tex.type = typeName;
tex.path = str;
textures.push_back(tex);
this->textures_loaded.push_back(tex);
}
}
return textures;
}
GLint model::textureFromFile(const char* path, std::string directory)
{
//Generate texture ID and load texture data
std::string filename = std::string(path);
filename = directory + '' + filename;
GLuint textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
int width, height;
unsigned char* image = SOIL_load_image(filename.c_str(), &width, &height, 0, SOIL_LOAD_RGB);
std::cout << SOIL_last_result() << std::endl;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
//auto e = glGetError();
// Parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
SOIL_free_image_data(image);
return textureID;
}
好的,这两个函数读取纹理名称的 .mtl 并从同一目录加载它们。我已经使用调试器逐步完成了代码,宽度和高度设置正确,图像指针指向字符数组。这让我觉得这部分很好。
进一步返回的纹理结构进入我的网格对象的构造函数:
mesh::mesh(std::vector<vertex> vertices, std::vector<GLuint> indices, std::vector<texture> textures)
: vertices(vertices), textures(textures), indices(indices)
{
this->setupMesh();
}
在 setupMesh 中,我执行基本属性设置、绑定到缓冲区等。在渲染循环期间,我调用 mesh->draw() 方法,如下所示:
void mesh::draw(shader* shader)
{
GLuint tex_diffNumber = 1;
GLuint tex_specNumber = 1;
for (GLuint i = 0; i < this->textures.size() ; i++)
{
//load target texture
glActiveTexture(GL_TEXTURE0 + 1);
std::stringstream sstream;
std::string number;
std::string name = this->textures[i].type;
if (name == TEX_DIFF_NAME)
sstream << tex_diffNumber++;
else if (name == TEX_SPEC_NAME)
sstream << tex_specNumber++;
number = sstream.str();
glBindTexture(GL_TEXTURE_2D, this->textures[i].id);
glUniform1i(glGetUniformLocation(shader->shaderProgID, (name + number).c_str()), i);
}
//set shininess
//glUniform1f(glGetUniformLocation(shader->shaderProgID, "material.shininess"), 16.0f);
//draw
glBindVertexArray(this->vao);
glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
//release
for (GLuint i = 0; i < this->textures.size(); i++)
{
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, 0);
}
}
这里重要的一点(恕我直言)是对统一更新的调用:
glUniform1i(glGetUniformLocation(shader->shaderProgID, (name + number).c_str()), i);
再说一次,这里没有问题,如果我打错了,着色器将无法编译,这是着色器:
#version 330 core
in vec2 TexCoords;
in vec4 customColor;
uniform sampler2D tex_diff1;
void main()
{
gl_FragColor = vec4(texture(tex_diff1, TexCoords));
}
名称"tex_diff1"是在 draw() 调用期间使用的确切成员名称。此外,我测试了纹理坐标是否良好,我根据texCoords的值在片段着色器中输出颜色。结果我得到了彩色模型,这意味着一切都很好。
所以问题是,缺少什么?
有什么想法在哪里挖掘和摇晃什么吗?
附言。
问题图像
特克斯科德作为颜色
在 for 循环中,您不断将活动纹理设置为 GL_TEXTURE0 + 1
,但您告诉着色器使用纹理单元 i。
最有可能的是,您想要这样的东西:
for (GLuint i = 0; i < this->textures.size() ; i++)
{
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, this->textures[i].id);
glUniform1i(glGetUniformLocation(shader->shaderProgID, (name + number).c_str()), i);
}
从不使用
glActiveTexture(GL_TEXTURE0 + i)
描述
glActiveTexture 选择哪个纹理单元后续纹理状态 呼叫会影响。实现的纹理单元数 支持取决于实现,但必须至少为 48。
glActiveTexture是纹理单元,用于加载相同类型的纹理,例如仅漫反射通道。
如果有漫反射贴图和法线贴图,则使用两个单位:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, this->tex_diffuse[i].id);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, this->tex_normal[i].id);
至于为什么它不起作用,我相信你把它绑定到 0。如果 i=0,则其
glBindTexture(GL_TEXTURE_2D, 0)
这是解除绑定的,你的对象是黑色的。
- 为什么我会得到黑色纹理?
- 黑色纹理,如果图片大小在第二个 OpenGL 线程中> 1 * 1
- 纹理显示为黑色
- 现代OpenGL 3.3核心黑色纹理
- 带有Clang的DirectX11显示黑色纹理(与Visual Studio配合使用)
- Direct3D11:在设备之间共享纹理:黑色纹理
- 使用着色器渲染时,OpenGL纹理都是黑色的
- 片段着色器中的 OpenGL 纹理黑色
- opengl-黑色纹理,如何在缓冲区上使用glm::vec*
- GLSL 150 GL 3.2黑色纹理
- GLSL纹理功能仅返回黑色的天空盒
- 从libpng加载的png纹理在OpenGL中显示为黑色
- OpenGL 3.3不会渲染任何纹理(黑色纹理、C++、GLFW/SOIL)
- OpenGL3两组着色器,纹理显示为黑色
- GLSL 将纹理渲染为黑色和蓝色
- OpenGL 3.30/GLSL 3.30-MRT输出黑色纹理
- SDL_CreateRGBSurface使用OpenGL纹理产生黑色纹理
- OpenGL CubeMapping黑色纹理
- OpenGL中纹理的采样是黑色的
- OpenGL纹理在3.3中都是黑色的-但在3.1中工作