我目前正在学习一些opengl的东西。在过去,我将顶点数据,纹理位置数据等存储在使用malloc创建的数组中。 现在我想用一些std :: vector来实现这个目的。我还使用本教程http://www.opengl-tutorial.org/beginners-tutorials/tutorial-7-model-loading创建了一个简单的.obj加载器。 但由于某种原因,我的纹理保持黑色。我把这些东西放在“对象”类中。
我会发布我认为重要的所有代码,但是如果你想查看整个源代码,我会发布它。
Object.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()不会抛出错误。 谢谢你的帮助!
大卫
答案 0 :(得分:0)
问题是你在将纹理加载到向量之前调用了glBufferData。对glBufferData的调用是将向量的内容复制到GPU内存中,但是你的向量还没有加载纹理,所以它可能充满了零(刚刚初始化)。
我建议等到SOIL_load_image返回调用glBufferData之后。
[编辑]
我的答案就在那里。我也没有看到你对你的问题的评论,你找到了根本原因。让我失望的是你在loadTexture方法中创建和加载你的顶点数组缓冲区。顶点数组缓冲区实际上与纹理无关或加载它。它可能更有意义,并使您的代码更易于处理顶点数组缓冲区,而不是在loadTexture中。在阅读你的代码时,它肯定会让我失望! :)