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

时间:2014-02-22 15:49:50

标签: c++ opengl-3 glm-math

我目前正在学习一些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()不会抛出错误。 谢谢你的帮助!

大卫

1 个答案:

答案 0 :(得分:0)

问题是你在将纹理加载到向量之前调用了glBufferData。对glBufferData的调用是将向量的内容复制到GPU内存中,但是你的向量还没有加载纹理,所以它可能充满了零(刚刚初始化)。

< S>

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

[编辑]
我的答案就在那里。我也没有看到你对你的问题的评论,你找到了根本原因。让我失望的是你在loadTexture方法中创建和加载你的顶点数组缓冲区。顶点数组缓冲区实际上与纹理无关或加载它。它可能更有意义,并使您的代码更易于处理顶点数组缓冲区,而不是在loadTexture中。在阅读你的代码时,它肯定会让我失望! :)