(OpenGL)没有绘制CubeMap

时间:2016-07-17 23:08:16

标签: opengl

我在OpenGL中遇到了立方体贴图的问题。当我尝试绘制立方体贴图时,它显示为黑色:

(我无法发布图片。它显示的是一个带有透视扭曲的黑色立方体)

着色器是可以的,因为立方体是用透视扭曲绘制的,当我使用这个片段着色器时,显然加载了着色器: (我无法发布图片。显示从黑色到红色的降级立方体)

#version 330 core

in vec3 direction;
out vec4 outcolor;

uniform samplerCube sampler;

void main() {
    outcolor = vec4(direction.x, 0.0, 0.0, 1.0);
}

立方体地图vao显然很好(显示了立方体)。

可能错误在加载的纹理立方体贴图中。这是代码:

GLboolean load_bmp_data(LPCSTR path, char **data, GLuint *datapos, GLuint *width, GLuint *height, GLuint *bitsperpixel) {
    GLuint size = 0;

    load_raw_file(path, data, &size); // It was correctly writen (100% ok)
    if(NULL == *data) {
        fprintf(stdout, "Error loading BMP image data from file '%s'.\n", path);
        return GL_FALSE;
    }

    if('B' != (*data)[0] || 'M' != (*data)[1]) {
        fprintf(stdout, "This image loader can only load BMP images.\n");
        free_raw_file(*data);
        return GL_FALSE;
    }

    *datapos       = *((GLuint *)(&(*data)[0x0A]));
    *width         = *((GLuint *)(&(*data)[0x12]));
    *height        = *((GLuint *)(&(*data)[0x16]));
    *bitsperpixel  = *((GLuint *)(&(*data)[0x1C])) & 0x0000FFFF;

    if(24 != *bitsperpixel) {
        fprintf(stdout, "This BMP image loader only supports loading 24 bits images.\n");
        free_raw_file(*data);
        return GL_FALSE;
    }

    return GL_TRUE;
}

void free_bmp_data(char *data) {
    free_raw_file(data);
}

GLboolean load_cube_map(cubemap_t *cubemap, LPCSTR dir, LPCSTR vertpath, LPCSTR fragpath) {
    vec3 vertices[36];
    GLuint vbo = 0;
    GLboolean noerror = GL_TRUE;
    char *path = NULL;
    char names[6][11] = {"right.bmp", "left.bmp", "top.bmp", "bottom.bmp", "front.bmp", "back.bmp"};
    unsigned int size = 0;
    GLuint i = 0;

    char *data = NULL;
    GLuint datapos = 0;
    GLuint width = 0;
    GLuint height = 0;
    GLuint bitsperpixel = 0;

    load_cube_positions(vertices, 1.0);

    // Generating buffer
    // ... Here I create the vertex buffer object and the vertex array object
    // ...

    // Loading shaders
    // Here I load the shaders from files

    // Loading faces
    glGenTextures(1, &cubemap->texture);
    if(0 == cubemap->texture) {
        fprintf(stdout, "Error creating a texture object for cube map.\n");
        return GL_FALSE;
    }
    glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap->texture);

    size = strlen(dir); // dir = "shaders/cubemap/"
    path = malloc(size + 10);
    if(NULL == path) {
        fprintf(stdout, "Error allocating dynamic memory for cube map paths.\n");
        return GL_FALSE;
    }
    strcpy(path, dir);

    for(i = 0; i < 6; i++) {
        strcpy(path + size, names[i]);
        if(GL_TRUE != load_bmp_data(path, &data, &datapos, &width, &height, &bitsperpixel)) {
            fprintf(stdout, "Error loading BMP data for cube map at '%s'.\n", path);
            return GL_FALSE;
        } // It doesn't fail, so data were loaded correctly
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data+datapos);
        free_bmp_data(data);
    }

    glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
    return GL_TRUE;
}

我认为可能的错误不在“load_bmp_data”中。功能,因为我可以使用此功能加载2D图像,并且它可以正常工作

绘制立方体贴图的代码:

void draw_cube_map(const cubemap_t *cubemap, const mat4 *rotate, const mat4 *projection) {
    mat4 matrix = *rotate;
    translate_mat4(&matrix, 0.0f, 0.0f, 2.0f); // Matrices functions are OK (100%)

    glCullFace(GL_FRONT);
    glUseProgram(cubemap->shader);
    glUniformMatrix4fv(cubemap->model_loc, 1, GL_FALSE, (GLfloat *)matrix.elements);
    glUniformMatrix4fv(cubemap->proj_loc, 1, GL_FALSE, (GLfloat *)projection->elements);

    glActiveTexture(GL_TEXTURE0);
    GLuint loc = glGetUniformLocation(cubemap->shader, "sampler");
    glUniform1i(loc, 0);
    glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap->texture);

    glBindVertexArray(cubemap->vao);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glCullFace(GL_BACK);
}

2 个答案:

答案 0 :(得分:0)

通常黑色纹理意味着没有纹理映射到缓冲区或不良UV。

如果没有花费详尽的阅读,很难确定,但看起来你在这里混合了两种不兼容的东西。你可以渲染一个大的立方体,它可以像那样工作,但是你应该只加载一个纹理并映射一个纹理。就像渲染一个常规立方体一样,除了你从里面做的。您还必须确保自己位于立方体内部而不是意外地在外面,因为您已经进行了面部剔除 - 并且您的缠绕顺序是正确的。

http://mbsoftworks.sk/index.php?page=tutorials&series=1&tutorial=13

本教程介绍如何快速轻松地获取立方体贴图。

答案 1 :(得分:0)

我找到了答案(但我不明白):

我必须设置过滤方法:

glTerParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTerParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

它可以是GL_NEAREST或其他什么。谢谢