opengl - 黑色纹理,如何在缓冲区上使用 glm::vec*?
Posted
技术标签:
【中文标题】opengl - 黑色纹理,如何在缓冲区上使用 glm::vec*?【英文标题】:opengl - black textures, how to use glm::vec* on buffers? 【发布时间】:2014-02-22 15:49:49 【问题描述】:我目前正在学习一些 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() 不会抛出错误。 感谢您的帮助!
大卫
【问题讨论】:
我解决了这个问题,问题出在 Object::draw() 中。我没有初始化制服。 【参考方案1】:问题是您在将纹理加载到矢量之前调用了 glBufferData。对 glBufferData 的调用正在将向量的内容复制到 GPU 内存中,但是您的向量尚未将纹理加载到其中,因此它可能充满了零(刚刚初始化)。
我的建议是等到 SOIL_load_image 返回后调用 glBufferData。
[编辑] 我在那里的回答太离谱了。我也没有看到您对您的问题的评论,您找到了根本原因。让我失望的是,您正在 loadTexture 方法中创建和加载顶点数组缓冲区。顶点数组缓冲区实际上与纹理或加载它没有任何关系。在 loadTexture 之外的某个地方处理顶点数组缓冲区可能更有意义,并使您的代码更具可读性。阅读您的代码时,它确实让我失望! :)
【讨论】:
以上是关于opengl - 黑色纹理,如何在缓冲区上使用 glm::vec*?的主要内容,如果未能解决你的问题,请参考以下文章