Serket
Serket

Reputation: 4475

OpenGL texture barely visible (very dark)

I've started messing around with textures in opengl, and when rendering my first texture, I saw a black screen. Then I realized that the screen in't black, rather the texture was very dim. Why is this happening? Here is the code:

Texture 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;
}

Texture class declaration (if you need it):

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);
};

Shaders: Vertex Shader:

#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;
}

Fragment Shader:

#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;
}

Renderer class declaration (you won't need the implementation although if you want it, I'll be happy to add it, just ask):

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 
};

Main Application (simplified):

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;
}

Upvotes: 1

Views: 316

Answers (1)

Rabbid76
Rabbid76

Reputation: 211166

Each color channel of the texture is coded in a byte. Hence, the color values are in range [0, 255]. Change the values of t[16]:

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

Note that when specifying the two-dimensional texture image, the data type of the pixel data is specified by GL_UNSIGNED_BYTE:

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

Upvotes: 3

Related Questions