在某些情况下,多个 OpenGL 纹理不起作用?
Multiple OpenGL Textures not working in some instances?
我正在尝试加载OBJ文件以在OpenGL中使用它们。OBJ 文件中的每个对象都有自己的纹理。在我的代码中,我将文件的每个对象拆分为一个结构,该结构的防御方式如下:
struct ObjModelComponent {
std::vector<glm::vec3> vertices;
std::vector<glm::vec2> uvs;
std::vector<glm::vec3> normals;
Texture tex;
ArrayBuffer vertex, uv, normal;
GLuint VAO;
};
Texture
类是一个简单的类,用于更轻松地加载和处理纹理。
在模型的课堂上,我对我的ObjModelComponent
有std::vector
.
我像这样渲染对象:
void ObjModel::render() {
for(int i = 0; i < components.size(); i++) {
components[i].vertex.activate();
components[i].uv.activate();
components[i].normal.activate();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, components[i].tex.getTextureID());
shader->sendInt(0, components[i].tex.getTextureName());
glBindVertexArray(components[i].VAO);
shader->sendMat4(*data->projection, "projection");
shader->sendMat4(data->viewMat, "view");
shader->sendMat4(model, "model");
glDrawArrays(GL_TRIANGLES, 0, int(components[i].vertices.size()));
glBindVertexArray(0);
}
}
纹理类如下所示:
Texture::Texture(std::string fileName, TextureType type):
textureName("tex"), fileName(fileName), type(type) {
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
unsigned char *image = SOIL_load_image(fileName.c_str(), &texWidth, &texHeight, 0, SOIL_LOAD_RGBA);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
switch (type) {
case TEXTURE_GENERATE_MIPMAP:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glGenerateMipmap(GL_TEXTURE_2D);
break;
case TEXTURE_NO_MIP_MAP:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
default:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
break;
}
glBindTexture(GL_TEXTURE_2D, 0);
SOIL_free_image_data(image);
}
Texture::Texture() {
}
Texture& Texture::operator=(const Texture &other) {
this->fileName = other.fileName;
this->textureName = other.textureName;
this->type = other.type;
// glDeleteTextures(1, &tex);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
unsigned char *image = SOIL_load_image(fileName.c_str(), &texWidth, &texHeight, 0, SOIL_LOAD_RGBA);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
switch (type) {
case TEXTURE_GENERATE_MIPMAP:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glGenerateMipmap(GL_TEXTURE_2D);
break;
case TEXTURE_NO_MIP_MAP:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
default:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
break;
}
glBindTexture(GL_TEXTURE_2D, 0);
SOIL_free_image_data(image);
return *this;
}
Texture::~Texture() {
glDeleteTextures(1, &tex);
}
GLuint Texture::getTextureID() {
return tex;
}
void Texture::setTextureName(std::string name) {
textureName = name;
}
std::string Texture::getTextureName() {
return textureName;
}
glm::vec2 Texture::getTextureSize() {
return glm::vec2(texWidth, texHeight);
}
组件的生成方式如下:
for(int i = 0; i < fileLines.size(); i++) {
if(fileLines[i].substr(0, 2) == "o ") {
if(!first) {
tmpComp.tex = tmpTex;
components.emplace_back(tmpComp);
componentIndex++;
}
first = false;
tmpTex = Texture(hg::substr(path, 0, int(path.find_last_of("/"))) + "/" + hg::substr(fileLines[i], 2, int(fileLines[i].length())) + ".png");
}
}
以下是生成 VAO 和数组缓冲区的方式:
for(int i = 0; i < components.size(); i++) {
glGenVertexArrays(1, &components[i].VAO);
glBindVertexArray(components[i].VAO);
components[i].vertex.setData(components[i].vertices.data(), sizeof(glm::vec3) * components[i].vertices.size(), 0);
components[i].uv.setData(components[i].uvs.data(), sizeof(glm::vec2) * components[i].uvs.size(), 1);
components[i].normal.setData(components[i].normals.data(), sizeof(glm::vec3) * components[i].normals.size(), 2);
components[i].vertex.activate();
components[i].uv.activate();
components[i].normal.activate();
glBindVertexArray(0);
}
你可以在GitHub上找到我的完整代码:https://github.com/Kuechenzwiebel/SDL-OpenGL-Tests
问题是,我的对象上显示的纹理是最后一个渲染的对象使用的纹理。
更新:删除纹理析构函数中的glDeleteTextures
,结果是所有组件上显示的纹理是用于最后一个组件的纹理。
我真的不明白为什么这不起作用,我从其他只使用一种纹理的原语中复制了它。那里一切正常。
我找到了一个解决方法,而不是单独的 ArrayBuffer 和 VAO,我只使用其中一个,并且还存储新对象从哪个索引开始。在那里,我更改了使用的纹理。
相关文章:
- 如何显示具有 opengl 纹理的灰度图像
- 无法使 opengl 纹理正常工作
- 现代OpenGL纹理金字塔
- OpenGL:纹理渲染被卡住
- 如何使用Qt多媒体和C++将.mp4视频从OpenGL纹理中保存出来
- 在某些情况下,多个 OpenGL 纹理不起作用?
- 如何将硬编码图像加载到 OpenGL 纹理中
- OpenGL 纹理会导致 ImGUI 窗口永久失焦
- 我如何将Win32窗口渲染到OpenGL纹理
- 将Pixeldata渲染到OpenGL纹理四边形中
- OpenGL纹理闪烁/有时在窗口大小上移动
- OpenGL 纹理坐标不起作用
- OpenGL 纹理状态使用警告:
- OpenGL纹理未显示
- OpenGL纹理不呈现
- 获取 OpenGL 纹理中特定像素的颜色
- C++ / OpenGL:纹理到像素图示例 - 缩小转换误差
- OpenGl 纹理拉扯
- OpenGL纹理格式,为OpenGL创建图像/纹理数据
- 创建原始OpenGL纹理数据(C++)