【问题标题】:Opengl 330 core creating and using a texture 2DOpengl 330 核心创建和使用纹理 2D
【发布时间】:2016-03-06 23:41:28
【问题描述】:

我已经有一段时间没有写过一些图形编程了,我已经盯着这个看了很长一段时间了,不知道我做错了什么。

这就是我创建纹理的方式。

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

上面的这段代码可以正常加载图像数据。

顶点着色器

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

片段着色器。

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

这就是我设置 VBO 的方式

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

这是我的渲染函数:

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

我只是得到一个黑色的四边形。我无法追踪它,我已经盯着它看了好几个小时了。

像这样在片段着色器中做一些非常基本的测试。

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

我的四边形在 x 和 y 轴上都是蓝色的。这似乎是在 0.0 中传入的唯一值没有意义。

【问题讨论】:

    标签: c opengl texture-mapping


    【解决方案1】:

    好的,这绝对是我自己创造的问题。我得到分段错误的原因是因为这段代码。

    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);
    glBindBuffer(GL_ARRAY_BUFFER, 0); //right here
    
    glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(quad->tex_coords),
                          quad->tex_coords);
    glEnableVertexAttribArray(2);
    
    
    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);
    

    在您将 vbo 缓冲区绑定为零后,尝试访问它会导致分段错误...

    然后确保我将正确的数据发送到 gpu 并且所有其他代码都按预期工作。

                 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);
    //glBindBuffer(GL_ARRAY_BUFFER, 0); //right here remove this
    
    //properly setup the local data to gpu data
    glBufferData(GL_ARRAY_BUFFER, rend2d_get_sizeof_tex_coord(quad),
                 rend2d_get_tex_coord_data(quad), GL_STATIC_DRAW);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(2);
    
    glBindBuffer(GL_ARRAY_BUFFER, 0); //put it here after finished with vbo
    

    在这两个更改之后,一切都按预期工作。希望这可以节省一些时间。

    【讨论】:

      【解决方案2】:

      至少有两件事可能是错误的:

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

      您确定 quad->tex_coords 包含 4 维向量吗?片段着色器需要vec2。如果每个顶点只提供两个浮点数,则必须将第二个参数更改为两个。当 OpenGL 尝试从太小的ARRAY_BUFFER 中读取时,这也可能导致分段错误。请注意,如果属性对最终颜色没有贡献,则将其设置为非活动状态,因此可能仅在使用纹理时才能读取纹理坐标。

      第二:在将数据上传到纹理之前调用glGenerateMipmap

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-25
        • 1970-01-01
        • 2014-03-12
        • 2021-03-19
        • 2012-03-13
        相关资源
        最近更新 更多