176 lines
4.8 KiB
C++
176 lines
4.8 KiB
C++
#include "skybox.h"
|
|
|
|
SkyBox::SkyBox(GLsizei resolution): m_resolution(resolution)
|
|
{
|
|
|
|
}
|
|
|
|
SkyBox::~SkyBox()
|
|
{
|
|
glDeleteVertexArrays(1, &m_vao);
|
|
glDeleteBuffers(1, &m_vbo);
|
|
glDeleteTextures(1, &m_textureId);
|
|
}
|
|
|
|
void SkyBox::initGl(Shader* program)
|
|
{
|
|
initializeOpenGLFunctions();
|
|
|
|
m_program = program;
|
|
|
|
glGenBuffers(1, &m_vbo);
|
|
glGenVertexArrays(1, &m_vao);
|
|
|
|
int locationPos = m_program->attributeLocation("in_position");
|
|
|
|
loadMesh();
|
|
|
|
glBindVertexArray(m_vao);
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
|
glVertexAttribPointer(GLuint(locationPos), 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<void *>(0));
|
|
glEnableVertexAttribArray(GLuint(locationPos));
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
glBindVertexArray(0);
|
|
|
|
glGenTextures(1, &m_textureId);
|
|
|
|
QTime t;
|
|
t.start();
|
|
qDebug() << "Generating skybox...";
|
|
generateCubeMap();
|
|
qDebug() << "Skybox generated in" << t.elapsed() / 1000.f << "s";
|
|
}
|
|
|
|
void SkyBox::generateCubeMap() {
|
|
GLuint fbo;
|
|
glGenFramebuffers(1, &fbo);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
|
|
|
glBindTexture(GL_TEXTURE_CUBE_MAP, m_textureId);
|
|
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
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);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
|
|
|
for (GLuint i = 0; i < 6; i++) {
|
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, m_resolution, m_resolution, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
|
|
}
|
|
|
|
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_textureId, 0);
|
|
|
|
GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0};
|
|
glDrawBuffers(1, drawBuffers);
|
|
|
|
Shader skyboxShader("nightsky", true);
|
|
|
|
skyboxShader.bind();
|
|
|
|
QMatrix4x4 projection;
|
|
projection.perspective(90, 1, 0.01f, 100);
|
|
QMatrix4x4 viewProjection[6];
|
|
GLfloat matArray[6 * 16];
|
|
|
|
viewProjection[0].lookAt(QVector3D(0,0,0), QVector3D(1,0,0), QVector3D(0, -1, 0));
|
|
viewProjection[1].lookAt(QVector3D(0,0,0), QVector3D(-1, 0, 0), QVector3D(0, -1, 0));
|
|
viewProjection[2].lookAt(QVector3D(0,0,0), QVector3D(0, 1, 0), QVector3D(0, 0, 1));
|
|
viewProjection[3].lookAt(QVector3D(0,0,0), QVector3D(0, -1, 0), QVector3D(0, 0, -1));
|
|
viewProjection[4].lookAt(QVector3D(0,0,0), QVector3D(0, 0, 1), QVector3D(0, -1, 0));
|
|
viewProjection[5].lookAt(QVector3D(0,0,0), QVector3D(0, 0, -1), QVector3D(0, -1, 0));
|
|
|
|
for (int i = 0; i < 6; i++) {
|
|
viewProjection[i] = projection * viewProjection[i];
|
|
for (int j = 0; j < 16; j++) {
|
|
matArray[i * 16 + j] = viewProjection[i].data()[j];
|
|
}
|
|
}
|
|
|
|
glUniformMatrix4fv(skyboxShader.uniformLocation("u_viewProjection"), 6, false, matArray);
|
|
|
|
glViewport(0, 0, m_resolution, m_resolution);
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
glBindVertexArray(m_vao);
|
|
glDrawArrays(GL_TRIANGLES, 0, GLsizei(3 * 12));
|
|
glBindVertexArray(0);
|
|
skyboxShader.release();
|
|
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
glDeleteFramebuffers(1, &fbo);
|
|
}
|
|
|
|
void SkyBox::loadMesh()
|
|
{
|
|
GLfloat 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,
|
|
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,
|
|
|
|
};
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
|
glBufferData(GL_ARRAY_BUFFER,
|
|
GLsizei(9 * 12 * sizeof(GLfloat)),
|
|
vertices,
|
|
GL_STATIC_DRAW);
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
}
|
|
|
|
void SkyBox::render()
|
|
{
|
|
//glDisable(GL_DEPTH_TEST);
|
|
m_program->setTexture("skyTexture", GL_TEXTURE0, m_textureId, GL_TEXTURE_CUBE_MAP);
|
|
m_program->bind();
|
|
glBindVertexArray(m_vao);
|
|
glDrawArrays(GL_TRIANGLES, 0, GLsizei(3 * 12));
|
|
glBindVertexArray(0);
|
|
m_program->release();
|
|
//glEnable(GL_DEPTH_TEST);
|
|
}
|