使用一个立方体纹理,由六张图片拼成一个天空盒,然后让它做沿Y轴逆时针转动。
#include "TEST_Skybox.h"
#include
using namespace std;
static GLint skybox_rotate_loc = 0;
TEST_FUNC_INIT(Skybox)
{
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
const GLfloat cube_vertices[] =
{
-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
};
const GLushort cube_indices[] =
{
0, 1, 2, 3, 6, 7, 4, 5, // First strip
2, 6, 0, 4, 1, 5, 3, 7 // Second strip
};
GLuint cube_vbo;
glGenBuffers(1, &cube_vbo);
glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
GLuint cube_element_buffer;
glGenBuffers(1, &cube_element_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cube_element_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cube_indices), cube_indices, GL_STATIC_DRAW);
GLuint skybox_prog = createShader("TEST_Skybox.vert", "TEST_Skybox.frag");
skybox_rotate_loc = glGetUniformLocation(skybox_prog, "tc_rotate");
// 加载立方体纹理
TextureInfo infoPX = getRawTextureFromFile("lf1.png");
TextureInfo infoNX = getRawTextureFromFile("rt1.png");
TextureInfo infoPY = getRawTextureFromFile("up1.png");
TextureInfo infoNY = getRawTextureFromFile("dn1.png");
TextureInfo infoPZ = getRawTextureFromFile("ft1.png");
TextureInfo infoNZ = getRawTextureFromFile("bk1.png");
GLuint cubTex;
glGenTextures(1, &cubTex);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubTex);
glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, (GLsizei)infoPX.width, (GLsizei)infoPX.height);
glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, (GLsizei)infoPX.width, (GLsizei)infoPX.height, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)infoPX.data);
glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, (GLsizei)infoNX.width, (GLsizei)infoNX.height, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)infoNX.data);
glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, (GLsizei)infoPY.width, (GLsizei)infoPY.height, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)infoPY.data);
glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, (GLsizei)infoNY.width, (GLsizei)infoNY.height, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)infoNY.data);
glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, (GLsizei)infoPZ.width, (GLsizei)infoPZ.height, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)infoPZ.data);
glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, (GLsizei)infoNZ.width, (GLsizei)infoNZ.height, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)infoNZ.data);
free(infoPX.data);
free(infoNX.data);
free(infoPY.data);
free(infoNY.data);
free(infoPZ.data);
free(infoNZ.data);
cout << glGetError() << endl;
}
TEST_FUNC_LOOP(Skybox)
{
static const unsigned int start_time = getCurTime();
float t = float(getCurTime() - start_time) / float(0x3FFF);
static const vmath::vec3 X(1.0f, 0.0f, 0.0f);
static const vmath::vec3 Y(0.0f, 1.0f, 0.0f);
static const vmath::vec3 Z(0.0f, 0.0f, 1.0f);
vmath::mat4 tc_matrix(vmath::mat4::identity());
glClearColor(0.0f, 0.25f, 0.3f, 1.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDisable(GL_CULL_FACE);
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
float aspect = float(480) / 640.0f;
tc_matrix = vmath::rotate(80.0f * 3.0f * t, Y);
// cout << getCurTime() - start_time <
tc_matrix = vmath::perspective(35.0f, 1.0f / aspect, 0.1f, 100.0f) * tc_matrix;
glUniformMatrix4fv(skybox_rotate_loc, 1, GL_FALSE, tc_matrix);
glDrawElements(GL_TRIANGLE_STRIP, 8, GL_UNSIGNED_SHORT, NULL);
glDrawElements(GL_TRIANGLE_STRIP, 8, GL_UNSIGNED_SHORT, (GLvoid*)(8 * sizeof(GLushort)));
// cout << glGetError() << endl;
return false;
}