OpenGL 纹理几乎不可见(非常暗)

OpenGL texture barely visible (very dark)

我开始在 opengl 中摆弄纹理,在渲染我的第一个纹理时,我看到了黑屏。然后我意识到屏幕不是黑色的,而是纹理非常暗。为什么会这样?这是代码:

纹理class (.cpp):


Texture::Texture(void* data, unsigned int width, unsigned int height)
  :texture(0), curslot(32), width(width), height(height)
{
  glGenTextures(1, &texture);

  glBindTexture(GL_TEXTURE_2D, texture);

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR       );
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR       );
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     GL_CLAMP_TO_EDGE);

  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, this->width, this->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);

  glBindTexture(GL_TEXTURE_2D, 0);
}

Texture::~Texture(){
  glDeleteTextures(1, &texture);
}

void Texture::bind(unsigned char slot){
  glActiveTexture(GL_TEXTURE0 + slot);
  glBindTexture(GL_TEXTURE_2D, texture);

  curslot = slot;
}

纹理class声明(如果需要的话):

class Texture{
private:
  unsigned int texture;
  unsigned char curslot;
  unsigned int width;
  unsigned int height;
public:
  Texture(void* data, unsigned int width, unsigned int height);
  ~Texture();

  void bind(unsigned char slot=0);
};

着色器: 顶点着色器:

#version 330 core

layout(location = 0) in vec4 position;
layout(location = 1) in vec2 texpos;

out vec2 texCoord;

void main(){
  gl_Position = position;
  texCoord = texpos;
}

片段着色器:

#version 330 core

layout(location=0) out vec4 color;
uniform sampler2D u_Texture;

in vec2 texCoord;

void main(){
  vec4 texColor = texture(u_Texture, texCoord);
  color = texColor;
}

渲染器 class 声明(您不需要实现,但如果您需要它,我很乐意添加它,只需询问):

class Renderer{
private:
  Renderer(){}
public:
  static Renderer* renderer;

  Renderer(const Renderer& r) = delete;

  void draw(VertexArray* va, IndexBuffer* ib, Shader* shader,  void (*uniformCallback)(Shader*, void*), void* uniformCallbackParams) const; //Fourth parameter is a function pointer that executes every time the draw function is called. It enables the user of the class to declare their uniforms. First three parameters are abstracted classes. Final parameter is a void pointer that is passed into the uniform function 
};

主要应用(简体):

typedef struct{
  float x;
  float y;
  float texCoord_x;
  float texCoord_y;
} vertex_t;

static GLFWwindow* window;

static void uniformCallback(Shader* program, void* params){
  program->useUniform1i("u_Texture", 0); //Setting the sampler2D uniform for the texture slot
}

int main(){

  glfwInit();
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

  window = glfwCreateWindow(500, 500, "OpenGL", NULL, NULL);

  glfwMakeContextCurrent(window);
  glewInit();

  VertexArray* va = new VertexArray(); //Abstracted vertex array
  va->bind();

  VertexBuffer* vb = new VertexBuffer(); //Abstracted vertex buffer
  IndexBuffer* ib = new IndexBuffer(); //Abstracted index buffer

  unsigned char t[16] = { //Texture pixels, RGBA form. Made this simple 'image' just for testing purposes
    1, 0, 0, 1,
    1, 1, 1, 1,
    1, 1, 1, 1,
    1, 0, 0, 1
  };

  Texture* texture = new Texture(t, 2, 2); //Texture class (abstracted)
  texture->bind();

  Shader* program = new Shader(2, "vs.glsl", "fs.glsl"); //Abstracted shader

  vertex_t data[4] = {
    {-0.5,   0.5, 0.0f, 1.0f},
    { 0.5,   0.5, 1.0f, 1.0f},
    {-0.5,  -0.5, 0.0f, 0.0f},
    { 0.5,  -0.5, 1.0f, 0.0f}
  };

  unsigned int indicies[6] = {
    0, 1, 2,
    1, 2, 3
  };

  vb->setBufferData(data, 4*sizeof(vertex_t));
  ib->setBufferData(indicies, 6);

  vb->bind();
  ib->bind();

  va->addAttrib(GL_FLOAT, 2); //equivalent of glEnableAttribArray and glVertexAttribPointer
  va->addAttrib(GL_FLOAT, 2);
  while(!glfwWindowShouldClose(window)){
    glClear(GL_COLOR_BUFFER_BIT);

    Renderer::renderer->draw(va, ib, program, uniformCallback, NULL); //Refer to renderer class declaration

    glfwSwapBuffers(window);
    glfwPollEvents();
  }

  //Clean-up code (freeing pointers, etc.)

  glfwTerminate();
  return 0;
}

纹理的每个颜色通道都用一个字节编码。因此,颜色值在 [0, 255] 范围内。更改 t[16] 的值:

unsigned char t[16] = {
    255, 0,   0,   255,
    255, 255, 255, 255,
    255, 255, 255, 255,
    255, 0,   0,   255
  };

注意指定二维纹理图像时,像素数据的数据类型由GL_UNSIGNED_BYTE指定:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, this->width, this->height, 0,
             GL_RGBA, GL_UNSIGNED_BYTE, data);