opengl-黑色纹理,如何在缓冲区上使用glm::vec*

opengl - black textures, how to use glm::vec* on buffers?

本文关键字:glm vec 缓冲区 纹理 黑色 opengl-      更新时间:2023-10-16

我目前正在学习一些opengl的东西。过去,我将顶点数据、纹理位置数据等存储在使用malloc创建的数组中。现在我正试图通过一些std::vector来实现这一点。我还用本教程创建了一个简单的.obj加载程序http://www.opengl-tutorial.org/beginners-tutorials/tutorial-7-model-loading.但由于某种原因,我的纹理一直是黑色的。我在"对象"类中有这些东西。

我会发布所有我认为重要的代码,但如果你想看到整个源代码,我会发布它。

对象.hpp:

class Object {
public:
Object(std::string objName);
~Object(void);
bool loadTexture(std::string textureName);
void setPos(glm::vec3 pos);
void setDir(glm::vec3 dir);
void draw(GLfloat time);
private:
std::vector<glm::vec3> vertexData;
std::vector<glm::vec3> elementData;
std::vector<glm::vec2> texturePosData;
std::vector<glm::vec3> vertexNormalData;
GLuint vertexArrayObject;
GLuint vertexBufferObject;
GLuint elementBufferObject;
GLuint texturePosBufferObject;
ShaderProgram *shader;
GLuint shaderProgram ;
GLuint textureObject;
GLuint textureUnit;
static GLuint globalTextureCount;
glm::vec3 position;
glm::vec3 direction;
//Uniforms
GLint model, uniView, uniProj, overrideColor;
};

目前有一些未使用的东西,我会在纹理工作后立即使用(如setPos()或setDir())

Object.cpp:我知道构造函数和对象加载器工作正常,因为顶点数据和纹理位置数据在向量中

bool Object::loadTexture(std::string textureName) {
textureUnit = globalTextureCount;
globalTextureCount++;
glBindVertexArray(vertexArrayObject);
//Create texuture Pos Buffer
glGenBuffers(1, &texturePosBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, texturePosBufferObject);
glBufferData(GL_ARRAY_BUFFER, texturePosData.size() * sizeof(glm::vec2), &texturePosData[0], GL_STATIC_DRAW);
glGenTextures(1, &textureObject);
glActiveTexture(GL_TEXTURE0 + textureUnit);
glBindTexture(GL_TEXTURE_2D, textureObject);
int width, height;
unsigned char *image = NULL;
image = SOIL_load_image(textureName.c_str(), &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glUniform1i(glGetUniformLocation(shaderProgram, "texKitten"), textureUnit);
GLint texAttrib = glGetAttribLocation(shaderProgram, "texcoord");
glEnableVertexAttribArray(texAttrib);
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
return true;
}

这是正确的方式吗,我将glBufferData与这些向量一起使用?纹理可能有什么问题?glError()不会引发错误。谢谢你的帮助!

David

问题是在将纹理加载到向量中之前调用了glBufferData。对glBufferData的调用是将向量的内容复制到GPU内存中,但向量中尚未加载纹理,因此可能充满了零(刚刚初始化)。

我建议等到SOIL_load_image返回后再调用glBufferData

[编辑]
我的回答太离谱了。我也没有看到你对你的问题的评论,你找到了根本原因。让我失望的是,您正在loadTexture方法中创建并加载顶点数组缓冲区。顶点数组缓冲区实际上与纹理或加载纹理无关。在loadTexture之外的其他地方处理顶点数组缓冲区时,可能会更有意义,并使代码更可读。当我阅读你的代码时,它确实让我大吃一惊!:)