0

It seems every time I try to get texturing working in my OpenGL apps I miss something obvious, and I end up spending many hours debugging. Well it happened again and even though I've been trying to compare my code with an older working app for quite some time, I'm still missing something because the texture just isn't displaying at all. The mesh shows up black. I'm not getting any OpenGL errors.

I would be very grateful for some help narrowing down the problem.

Here is part of my code, I'm pretty sure my mistake is in these areas of the code:

OpenGL.cpp:

bool OpenGL::enable_attribs_and_uniforms(GLuint program_id)
{
    glGenVertexArrays(1, &this->vao_id);
    glBindVertexArray(this->vao_id);

    this->pos_a_loc = glGetAttribLocation(program_id, "pos_a");
    this->uv_a_loc = glGetAttribLocation(program_id, "uv_a");
    if (this->pos_a_loc == -1 || /*this->color_a_loc == -1 ||*/ this->uv_a_loc == -1)
    {
        std::cerr << "OpenGL Warning: Failed to get attribute locations, probably because at least one attribute isn't being used in the shader program. Attributes get optimized out if they don't affect the output of the shader program in any way.\n\n";
    }

    glEnableVertexAttribArray(this->pos_a_loc);
    glEnableVertexAttribArray(this->uv_a_loc);

    this->p_mat_u_loc = glGetUniformLocation(program_id, "p_mat_u");
    this->v_mat_u_loc = glGetUniformLocation(program_id, "v_mat_u");
    this->m_mat_u_loc = glGetUniformLocation(program_id, "m_mat_u");
    this->mvp_mat_u_loc = glGetUniformLocation(program_id, "mvp_mat_u");
    this->tex_samp_u_loc = glGetUniformLocation(program_id, "tex_samp_u");
    if (this->p_mat_u_loc == -1 || this->v_mat_u_loc == -1 ||
        this->m_mat_u_loc == -1 || this->mvp_mat_u_loc == -1 ||
        this->tex_samp_u_loc == -1)
    {
        std::cerr << "OpenGL Warning: Failed to get all uniform locations, probably because at least one uniform isn't being used in the shader program. Uniforms get optimized out if they don't affect the output of the shader program in any way.\n\n";
    }

    check_gl_error();

    return true;
}

void OpenGL::fill_buffers(std::vector<Object*>& objs)
{
    std::vector<Object*>::iterator it;
    for (it = objs.begin(); it != objs.end(); ++it)
    {
        GLuint vb_pos_id;
        glGenBuffers(1, &vb_pos_id);
        glBindBuffer(GL_ARRAY_BUFFER, vb_pos_id);
        glBufferData(GL_ARRAY_BUFFER, (*it)->v_pos.size() * sizeof(glm::vec3), &(*it)->v_pos[0], GL_STATIC_DRAW);
        this->vb_pos_ids.push_back(vb_pos_id);

        (*it)->tex_filenames[0] = "some_texture.png";

        SDL_Surface* tex_surface = IMG_Load((*it)->tex_filenames[0].c_str());
        if (!tex_surface)
        {
            std::cerr << "Texture Error: Couldn't open texture file: " << (*it)->tex_filenames[0] << "\n\n";
            return;
        }

        GLuint tex_samp_id;
        glGenTextures(1, &tex_samp_id);
        glBindTexture(GL_TEXTURE_2D, tex_samp_id);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_surface->w, tex_surface->h, 0,
            GL_RGBA, GL_UNSIGNED_BYTE, tex_surface->pixels);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        this->tex_samp_ids.push_back(tex_samp_id);

        GLuint vb_uv_id;
        glGenBuffers(1, &vb_uv_id);
        glBindBuffer(GL_ARRAY_BUFFER, vb_uv_id);
        glBufferData(GL_ARRAY_BUFFER, (*it)->v_uv.size() * sizeof(glm::vec2), &(*it)->v_uv[0], GL_STATIC_DRAW);
        this->vb_uv_ids.push_back(vb_uv_id);
    }

    check_gl_error();

    return;
}


void OpenGL::draw(std::vector<Object*>& objs)   // draws GL_TRIANGLES
{
    std::vector<Object*>::iterator objs_it;
    std::vector<GLuint>::iterator vb_pos_it;
    std::vector<GLuint>::iterator vb_col_it;
    std::vector<GLuint>::iterator vb_uv_it;
    unsigned int i = 0;
    for (objs_it = objs.begin(), vb_pos_it = this->vb_pos_ids.begin(),
         vb_col_it = this->vb_col_ids.begin(), vb_uv_it = this->vb_uv_ids.begin();
         objs_it != objs.end(); ++objs_it, ++vb_pos_it, ++vb_col_it, ++vb_uv_it, ++i)
    {
        (*objs_it)->m_mat = glm::rotate((*objs_it)->m_mat, 1.0f, glm::vec3(0.0f, 1.0f, 0.0f));

        this->mvp_mat = this->p_mat * this->v_mat * (*objs_it)->m_mat;

        // send attribs to vertex shader
        glBindBuffer(GL_ARRAY_BUFFER, (*vb_pos_it));
        glVertexAttribPointer(this->pos_a_loc, 3, GL_FLOAT, GL_FALSE, 0, 0);

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, this->tex_samp_ids[i]);

        glBindBuffer(GL_ARRAY_BUFFER, (*vb_uv_it));
        glVertexAttribPointer(this->uv_a_loc, 2, GL_FLOAT, GL_FALSE, 0, 0);

        // send uniforms to vertex shader
        glUniformMatrix4fv(this->p_mat_u_loc, 1, GL_FALSE, &this->p_mat[0][0]);
        glUniformMatrix4fv(this->v_mat_u_loc, 1, GL_FALSE, &this->v_mat[0][0]);
        glUniformMatrix4fv(this->m_mat_u_loc, 1, GL_FALSE, &(*objs_it)->m_mat[0][0]);
        glUniformMatrix4fv(this->mvp_mat_u_loc, 1, GL_FALSE, &this->mvp_mat[0][0]);
        glUniform1i(this->tex_samp_u_loc, 0);

        // draw
        glDrawArrays(GL_TRIANGLES, 0, (*objs_it)->v_pos.size());

        check_gl_error();
        glGetError();   // clear GL error before next iteration
    }

    return;
}

simple.vsh:

#version 330 core

in vec3 pos_a;
in vec2 uv_a;

uniform mat4 p_mat_u;
uniform mat4 v_mat_u;
uniform mat4 m_mat_u;
uniform mat4 mvp_mat_u;

out vec2 uv_v;

void main()
{
    gl_Position = mvp_mat_u * vec4(pos_a, 1.0);
    uv_v = uv_a;
}

simple.fsh:

#version 330 core

smooth in vec2 uv_v;

uniform sampler2D tex_samp_u;

out vec4 color_o;

void main()
{
    color_o = texture2D(tex_samp_u, uv_v);
}
Defcronyke
  • 611
  • 1
  • 7
  • 21

1 Answers1

1

Well, it turned out the code wasn't the problem, I was exporting from Blender incorrectly. I guess the downvote was appropriate.

This code works to display the texture, but it shows up flipped the wrong way, so I'll have to flip it after loading the image, and I still have to figure out how to get Blender's collada exporter to export with -Z forward, Y up orientation... but that's not for this question.

Defcronyke
  • 611
  • 1
  • 7
  • 21