纹理不显示,网格显示黑色

时间:2013-06-14 16:12:43

标签: opengl sdl textures opengl-3 sdl-image

似乎每当我尝试在我的OpenGL应用程序中运行纹理时,我都会错过一些明显的东西,最后我会花费很多时间进行调试。好吧它再次发生,即使我一直试图将我的代码与较旧的工作应用程序进行比较很长一段时间,我仍然缺少一些东西,因为纹理根本就没有显示。网格显示为黑色。我没有收到任何OpenGL错误。

我非常感谢帮助缩小问题范围。

以下是我的代码的一部分,我很确定我的错误在代码的这些方面:

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

1 个答案:

答案 0 :(得分:1)

嗯,事实证明代码不是问题,我从Blender输出错误。我想downvote是合适的。

此代码用于显示纹理,但它显示错误的方式,所以我必须在加载图像后翻转它,我仍然要弄清楚如何让Blender的collada导出器导出 - Z向前,Y向上......但这不适合这个问题。