Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: black texture in opengl 330 core

  1. #1
    Intern Newbie
    Join Date
    Aug 2012
    Posts
    48

    black texture in opengl 330 core

    I am trying to get texturing to work on this quad but now all I am getting is a black quad.

    This is the code to load the image
    Code :
    GLuint create_texture(const char* filename) {
        SDL_Surface* surface;
        GLenum tex_format;
        GLint num_colors;
        GLuint tex_id;
        char* file_path;
     
    file_path = get_resource(filename);
    surface = IMG_Load(file_path);
    if (!surface) {
        SDL_Log("failed to create surface\n");
        SDL_Quit();
        return -1;
    } else {
        if ((surface->w & (surface->w - 1)) != 0) {
            SDL_Log("image { %s } width is not power of 2\n", filename);
        }
        if ((surface->h & (surface->h - 1)) != 0) {
            SDL_Log("image { %s } height is not power of 2\n", filename);
        }
     
        num_colors = surface->format->BytesPerPixel;
        if (num_colors == 4) {
            if (surface->format->Rmask == 0x000000ff)
                tex_format = GL_RGBA;
            else
                tex_format = GL_BGRA;
        }
        if (num_colors == 3) {
            if (surface->format->Rmask == 0x000000ff)
                tex_format = GL_RGB;
            else
                tex_format = GL_BGR;
     
        } else {
            SDL_Log("pixel image format shouldn't get here! Quitting\n");
            SDL_Quit();
        };
     
        glGenTextures(1, &tex_id);
        glBindTexture(GL_TEXTURE_2D, tex_id);
     
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     
        glTexImage2D(GL_TEXTURE_2D, 0, tex_format, surface->w, surface->h, 0,
                     tex_format, GL_UNSIGNED_BYTE, surface->pixels);
    }
    if (surface) SDL_FreeSurface(surface);
    free(file_path);
     
    return tex_id;
    }

    vertex shader
    Code :
    #version 330 core
     
    layout (location = 0) in vec3 a_pos;
    layout (location = 1) in vec4 a_col;
    layout (location = 2) in vec2 a_tex;
     
    uniform mat4 u_mvp_mat;
    uniform mat4 u_mod_mat;
    uniform mat4 u_view_mat;
    uniform mat4 u_proj_mat;
     
    out vec4 f_color;
    out vec2 f_tex;
     
    void main()
    {
        gl_Position =   u_mvp_mat * vec4(a_pos, 1.0);
        f_tex = a_tex;
        f_color = a_col;
    }

    fragment shader
    Code :
    #version 330 core
     
    in vec4 f_color;
    out vec4 o_color;
     
    in vec2 f_tex;
    uniform sampler2D u_sprite_tex;
     
    void main (void)
    {
        o_color = f_color;
        o_color = texture(u_sprite_tex, f_tex);
    }

    setup vbo
    Code :
    quad = ren2d_new(); //just a wrapper around a quad or two tri.
    ren2d_set_tint(quad, 0, 1, 0, 1); //setting the color to green
     
    pos_loc = get_attrib_location(ce_get_default_shader(), "a_pos");
    col_loc = get_attrib_location(ce_get_default_shader(), "a_col");
    mvp_matrix_loc = get_uniform_location(ce_get_default_shader(), "u_mvp_mat");
    model_mat_loc = get_uniform_location(ce_get_default_shader(), "u_mod_mat");
    view_mat_loc = get_uniform_location(ce_get_default_shader(), "u_view_mat");
    proj_matrix_loc =
        get_uniform_location(ce_get_default_shader(), "u_proj_mat");
     
    tex_loc = get_uniform_location(ce_get_default_shader(), "u_sprite_tex");
     
    camera = cam_2d_new(ce_get_width(), ce_get_height());
     
    model_mat = mat4_identity();
    mat4_scale(model_mat, 128, 128, 1);
     
    tex_id = create_texture("test.png");
     
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
     
    glGenBuffers(1, &vert_buff);
    glBindBuffer(GL_ARRAY_BUFFER, vert_buff);
    glBufferData(GL_ARRAY_BUFFER, sizeof(quad->vertices), quad->vertices,
                 GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
     
    glGenBuffers(1, &col_buff);
    glBindBuffer(GL_ARRAY_BUFFER, col_buff);
    glBufferData(GL_ARRAY_BUFFER, sizeof(quad->colors), quad->colors,
                 GL_STATIC_DRAW);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(1);
     
    glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(quad->tex_coords),
                          quad->tex_coords);
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
     
    glGenBuffers(1, &ind_buff);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ind_buff);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quad->indices), quad->indices,
                 GL_STATIC_DRAW);
     
    glBindVertexArray(0);

    rendering function
    Code :
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
     
    //could my texturing problems be here?
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, tex_id);
    glUniform1i(tex_loc, 0);
     
    glUseProgram(ce_get_default_shader()->shader_program);
    glBindVertexArray(vao);
     
    //excuse the silly names
    ce_get_view_matrices(&vview_mat, &pproj_mat, &mmvp_mat);
     
    mat4_multi(&mmvp_mat, &vview_mat, model_mat);
    mat4_multi(&mmvp_mat, &pproj_mat, &mmvp_mat);
    glUniformMatrix4fv(mvp_matrix_loc, 1, GL_FALSE, mat4_get_data(&mmvp_mat));
     
    glUniformMatrix4fv(model_mat_loc, 1, GL_FALSE, mat4_get_data(model_mat));
    glUniformMatrix4fv(view_mat_loc, 1, GL_FALSE, mat4_get_data(&vview_mat));
    glUniformMatrix4fv(proj_matrix_loc, 1, GL_FALSE, mat4_get_data(&pproj_mat));
     
    glDrawElements(GL_TRIANGLES, quad->vertex_count, GL_UNSIGNED_SHORT, 0);
    glBindVertexArray(0);

    the last piece is the quad structure
    Code :
    #include "headers/renderable_2D.h"
    #include <stdlib.h>
     
     
     
    static void init_vertices(struct renderable_2D* out) {
        //2, 0, 1 - 3, 0, 2
        out->vertices[0] = 1.0f;
        out->vertices[1] = 1.0f;
        out->vertices[2] = 0.0f;
     
        out->vertices[3] = -1.0f;
        out->vertices[4] = 1.0f;
        out->vertices[5] = 0.0f;
     
        out->vertices[6] = -1.0f;
        out->vertices[7] = -1.0f;
        out->vertices[8] = 0.0f;
     
        out->vertices[9] = 1.0f;
        out->vertices[10] = -1.0f;
        out->vertices[11] = 0.0f;
    }
     
    static void init_colors(struct renderable_2D* out) {
        out->colors[0] = 1.0f;
        out->colors[1] = 1.0f;
        out->colors[2] = 1.0f;
        out->colors[3] = 1.0f;
     
        out->colors[4] = 1.0f;
        out->colors[5] = 1.0f;
        out->colors[6] = 1.0f;
        out->colors[7] = 1.0f;
     
        out->colors[8] = 1.0f;
        out->colors[9] = 1.0f;
        out->colors[10] = 1.0f;
        out->colors[11] = 1.0f;
     
        out->colors[12] = 1.0f;
        out->colors[13] = 1.0f;
        out->colors[14] = 1.0f;
        out->colors[15] = 1.0f;
    }
     
    static void init_texture_coords(struct renderable_2D* out) {
        out->tex_coords[0] = 0.0f;  // u1
        out->tex_coords[1] = 0.0f;  // v1
     
        out->tex_coords[2] = 1.0f;  // u2
        out->tex_coords[3] = 0.0f;  // v2
     
        out->tex_coords[4] = 1.0f;  // u3
        out->tex_coords[5] = 1.0f;  // v3
     
        out->tex_coords[6] = 0.0f;  // u4
        out->tex_coords[7] = 1.0f;  // v4
    }
     
    static void init_indices(struct renderable_2D* out) {
        out->indices[0] = 2;
        out->indices[1] = 0;
        out->indices[2] = 1;
     
        out->indices[3] = 3;
        out->indices[4] = 0;
        out->indices[5] = 2;
    }
     
    struct renderable_2D* ren2d_new(void) {
        struct renderable_2D* m_ren =
            (struct renderable_2D*)calloc(1, sizeof(struct renderable_2D));
        init_vertices(m_ren);
        init_indices(m_ren);
        init_texture_coords(m_ren);
        init_colors(m_ren);
        m_ren->vertex_count = 6;
        return m_ren;
    }
    struct renderable_2D* ren2d_set_uv(struct renderable_2D* out,
                                       const float uv[]) {
        out->tex_coords[0] = uv[0];  // u1
        out->tex_coords[1] = uv[1];  // v1
     
        out->tex_coords[2] = uv[2];  // u2
        out->tex_coords[3] = uv[3];  // v2
     
        out->tex_coords[4] = uv[4];  // u3
        out->tex_coords[5] = uv[5];  // v3
     
        out->tex_coords[6] = uv[6];  // u4
        out->tex_coords[7] = uv[7];  // v4
     
        return out;
    }
    struct renderable_2D* ren2d_set_tint(struct renderable_2D* out, const float r,
                                         const float g, const float b,
                                         const float a) {
        out->colors[0] = r;
        out->colors[1] = g;
        out->colors[2] = b;
        out->colors[3] = a;
     
        out->colors[4] = r;
        out->colors[5] = g;
        out->colors[6] = b;
        out->colors[7] = a;
     
        out->colors[8] = r;
        out->colors[9] = g;
        out->colors[10] = b;
        out->colors[11] = a;
     
        out->colors[12] = r;
        out->colors[13] = g;
        out->colors[14] = b;
        out->colors[15] = a;
     
        return out;
    }
    struct renderable_2D* ren2d_set_alpha(struct renderable_2D* out,
                                          const float a) {
        out->colors[3] = a;
        out->colors[7] = a;
        out->colors[11] = a;
        out->colors[15] = a;
     
        return out;
    }
    struct renderable_2D* rend2d_set_z_index(struct renderable_2D* out,
                                             const int index) {
        out->vertices[2] = index;
        out->vertices[5] = index;
        out->vertices[8] = index;
        out->vertices[11] = index;
     
        return out;
    }
    struct renderable_2D* rend2d_set_rotation(struct renderable_2D* out,
                                              const float angle) {
        out->rotation = angle;
     
        return out;
    }

    doing some basic testing in the fragment shader like this
    Code :
    #version 330 core
     
    in vec4 f_color;
    out vec4 o_color;
     
    in vec2 f_tex;
    uniform sampler2D u_sprite_tex;
     
    void main (void)
    {
        //o_color = f_color;
        vec4 c;
        if(f_tex.y == 1.0) { c = vec4(1.0, 0.0, 0.0, 1.0); }
        if(f_tex.y == 0.0) { c = vec4(0.0, 0.0, 1.0, 1.0); }
        o_color = c;
        o_color = texture(u_sprite_tex, f_tex);
    }

    the quad turns out blue, so it seems that I am not passing in the correct information to the shader but I am not exactly sure where I am making my mistake?

    Anyone can see what am I doing wrong here?

    initially the function to create texture was this
    Code :
    glTexImage2D( GL_TEXTURE_2D, 0, num_colors, surface->w, surface->h, 0,
                          texture_format, GL_UNSIGNED_BYTE, surface->pixels );

    but changed that to this
    Code :
    glTexImage2D( GL_TEXTURE_2D, 0, texture_format, surface->w, surface->h, 0,
                          texture_format, GL_UNSIGNED_BYTE, surface->pixels );
    because of this article on the opengl documentation: https://www.khronos.org/opengles/sdk...TexImage2D.xml
    where it says that the 3rd 7th elements should be the same but still I get a black texture.
    Last edited by blubee; 12-02-2015 at 12:05 PM. Reason: added some more info.

  2. #2
    Newbie Newbie
    Join Date
    Dec 2015
    Posts
    3
    Apologies for not testing this, but from looking at your code, I think the problem is this line:

    Code :
    glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(quad->tex_coords),
                          quad->tex_coords);

    I think the second parameter should be 2.

  3. #3
    Intern Newbie
    Join Date
    Aug 2012
    Posts
    48
    this was a really bad oversight on my part

    Code :
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
     
    glGenBuffers(1, &vert_buff);
    glBindBuffer(GL_ARRAY_BUFFER, vert_buff);
    glBufferData(GL_ARRAY_BUFFER, sizeof(quad->vertices), quad->vertices,
                 GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
     
    glGenBuffers(1, &col_buff);
    glBindBuffer(GL_ARRAY_BUFFER, col_buff);
    glBufferData(GL_ARRAY_BUFFER, sizeof(quad->colors), quad->colors,
                 GL_STATIC_DRAW);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(1);
     
    glGenBuffers(1, &tex_coord_buff); //first mistake I didn't generate a texture coordinate buffer
    glBindBuffer(GL_ARRAY_BUFFER, &tex_coord_loc); //after making the buffer actually bind it
    glBufferData(GL_ARRAY_BUFFER, sizeof(quad->tex), quad->tex,  //third mistake I didn't send any data to the GPU!
                 GL_STATIC_DRAW);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(quad->tex_coords),  //fourth mistake, the second variable should be 2 as I am only passing in 2 floats not 4
                          quad->tex_coords);
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
     
    glGenBuffers(1, &ind_buff);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ind_buff);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quad->indices), quad->indices,
                 GL_STATIC_DRAW);
     
    glBindVertexArray(0);

    I'm surprised it rendered and just didn't plain out explode my video card.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •