3

ゲームにスカイボックスを実装しようとしています。私が使用している画像は次のとおりです。

ここに画像の説明を入力

残念ながら、これは非常に拡大されており、テクスチャのピクセルの一部しか表示されていません。次のようになります。

ここに画像の説明を入力

スカイボックスを作成するための私のコードは次のとおりです。

SkyBox::SkyBox()

{
    programID = LoadShaders("Resources/Shaders/skybox.vert", "Resources/Shaders/skybox.frag");

    pID = glGetUniformLocation(programID, "P");
    vID = glGetUniformLocation(programID, "V");

    float points[] =
    {
        -1.0f,  1.0f, -1.0f,
        -1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

        -1.0f,  1.0f, -1.0f,
        1.0f,  1.0f, -1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
        1.0f, -1.0f,  1.0f
    };
    glGenBuffers (1, &vbo);
    glBindBuffer (GL_ARRAY_BUFFER, vbo);
    glBufferData (GL_ARRAY_BUFFER, sizeof (points), points, GL_STATIC_DRAW);

    const char *pth = "/Users/uonibr/Documents/Programming/Space Shooter/Space Shooter/Space Shooter/Resources/space.jpg";

    createCubeMap(pth, pth, pth, pth, pth, pth);
}


bool load_cube_map_side (GLuint texture, GLenum side_target, const char* file_name)
{
    glBindTexture (GL_TEXTURE_CUBE_MAP, texture);

    int x, y;
    unsigned char*  image_data = SOIL_load_image(file_name, &x, &y, 0, SOIL_LOAD_RGBA);
    if (!image_data) {
        fprintf (stderr, "ERROR: could not load %s\n", file_name);
        return false;
    }
    // non-power-of-2 dimensions check
    if ((x & (x - 1)) != 0 || (y & (y - 1)) != 0) {
        fprintf (
                 stderr, "WARNING: image %s is not power-of-2 dimensions\n", file_name
                 );
    }

    // copy image data into 'target' side of cube map
    glTexImage2D (
                  side_target,
                  0,
                  GL_RGBA,
                  x,
                  y,
                  0,
                  GL_RGBA,
                  GL_UNSIGNED_BYTE,
                  image_data
                  );
    free (image_data);
    return true;
}


void SkyBox::createCubeMap ( const char* front, const char* back, const char* top, const char* bottom, const char* left,const char* right)
{
    // generate a cube-map texture to hold all the sides
    glActiveTexture (GL_TEXTURE0);
    glGenTextures (1, &cubeMap);

    // load each image and copy into a side of the cube-map texture
    assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, front));
    assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, back));
    assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, top));
    assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, bottom));
    assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, left));
    assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_POSITIVE_X, right));

    // format cube map texture
    glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}

スカイボックスのレンダリング コードは次のとおりです。

void SkyBox::render(const Camera &camera) const
{
    glDepthMask (GL_FALSE);
    glUseProgram (programID);
    glActiveTexture (GL_TEXTURE0);
    glBindTexture (GL_TEXTURE_CUBE_MAP, cubeMap);
    glUniformMatrix4fv(pID, 1, GL_FALSE, &camera.getProjectionMatrix()[0][0]);
    glm::mat4 view = camera.getRotationMatrix();
    glUniformMatrix4fv(vID, 1, GL_FALSE, &view[0][0]);
    glEnableVertexAttribArray (0);
    // 1st attribute buffer : vertices
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexAttribPointer(
                          0,                  // attribute. No particular reason for 0, but must match the layout in the shader.
                          3,                  // size
                          GL_FLOAT,           // type
                          GL_FALSE,           // normalized?
                          0,                  // stride
                          (void*)0            // array buffer offset
                          );

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glDrawArrays (GL_TRIANGLES, 0, 36);

    glDisableVertexAttribArray(0);
    glDepthMask (GL_TRUE);
    glCullFace(GL_BACK);

}

フラグメント シェーダーは単純です。

#version 330 core

in vec3 texcoords;
uniform samplerCube cube_texture;
out vec4 frag_color;

void main () {
    frag_color = texture (cube_texture, texcoords);
}

頂点シェーダーと同様:

#version 330 core

in vec3 vp;
uniform mat4 P, V;
out vec3 texcoords;

void main () {
    texcoords = vp;
    gl_Position = P * V * vec4 (vp, 1.0);

}

編集:射影行列を作成するための私のコードは次のとおりです。

glm::mat4 Camera::getProjectionMatrix() const
{
    return glm::perspective(FoV, 4.0f / 3.0f, 0.1f, 100.0f);
}

ここに私のFovがあります:

 float FoV = 3.14159 * 65. / 180;
4

1 に答える 1