Add Skybox
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,3 +2,4 @@ build
|
|||||||
.directory
|
.directory
|
||||||
lib/assimp/libassimp.so.5.0.0
|
lib/assimp/libassimp.so.5.0.0
|
||||||
res/models
|
res/models
|
||||||
|
res/textures
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Size=894,195
|
|||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][Debug Utils]
|
[Window][Debug Utils]
|
||||||
Pos=14,16
|
Pos=39,30
|
||||||
Size=908,204
|
Size=908,204
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
|
|||||||
13
res/shaders/skybox.frag
Normal file
13
res/shaders/skybox.frag
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 f_color;
|
||||||
|
|
||||||
|
in vec3 v_texCoord;
|
||||||
|
|
||||||
|
uniform samplerCube u_skybox;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
f_color = texture(u_skybox, v_texCoord);
|
||||||
|
|
||||||
|
}
|
||||||
17
res/shaders/skybox.vert
Normal file
17
res/shaders/skybox.vert
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 a_position;
|
||||||
|
|
||||||
|
out vec3 v_texCoord;
|
||||||
|
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 u_viewProjectionMatrix;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
gl_Position = u_viewProjectionMatrix * vec4(a_position, 1.0);
|
||||||
|
|
||||||
|
v_texCoord = a_position;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,6 +20,8 @@ public:
|
|||||||
void lookAtTarget(glm::vec3 target);
|
void lookAtTarget(glm::vec3 target);
|
||||||
void lookForward();
|
void lookForward();
|
||||||
|
|
||||||
|
glm::mat4 getView() { return viewMatrix; }
|
||||||
|
glm::mat4 getProj() { return projectionMatrix; }
|
||||||
glm::mat4 getViewProj() { return viewProjectionMatrix; }
|
glm::mat4 getViewProj() { return viewProjectionMatrix; }
|
||||||
glm::vec3 getPosition() { return position; }
|
glm::vec3 getPosition() { return position; }
|
||||||
glm::vec3 getDirection() { return frontVec; }
|
glm::vec3 getDirection() { return frontVec; }
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ void Controller::run() {
|
|||||||
|
|
||||||
ShaderProgram shaderProgram("res/shaders/basic.vert", "res/shaders/basic.frag");
|
ShaderProgram shaderProgram("res/shaders/basic.vert", "res/shaders/basic.frag");
|
||||||
ShaderProgram lightProgram("res/shaders/light.vert", "res/shaders/light.frag");
|
ShaderProgram lightProgram("res/shaders/light.vert", "res/shaders/light.frag");
|
||||||
|
ShaderProgram skyboxProgram("res/shaders/skybox.vert", "res/shaders/skybox.frag");
|
||||||
|
|
||||||
//Model model_backpack("res/models/backpack.ffo");
|
//Model model_backpack("res/models/backpack.ffo");
|
||||||
//Model model_plant("res/models/plant.ffo");
|
//Model model_plant("res/models/plant.ffo");
|
||||||
@@ -104,6 +105,8 @@ void Controller::run() {
|
|||||||
lightSource.setRotation(glm::vec3(0.f));
|
lightSource.setRotation(glm::vec3(0.f));
|
||||||
lightSource.setPosition(glm::vec3(-2.f, 1.5f, 2.f));
|
lightSource.setPosition(glm::vec3(-2.f, 1.5f, 2.f));
|
||||||
|
|
||||||
|
Skybox skybox(&model_cube, &skyboxProgram, "res/textures/skybox/");
|
||||||
|
|
||||||
World world(&shaderProgram);
|
World world(&shaderProgram);
|
||||||
world.addEntity(dragon);
|
world.addEntity(dragon);
|
||||||
world.addEntity(lightSource);
|
world.addEntity(lightSource);
|
||||||
@@ -137,6 +140,8 @@ void Controller::run() {
|
|||||||
camera->lookForward();
|
camera->lookForward();
|
||||||
camera->updateVPM();
|
camera->updateVPM();
|
||||||
|
|
||||||
|
skybox.draw(camera->getView(), camera->getProj());
|
||||||
|
|
||||||
world.draw(camera->getViewProj(), camera->getPosition());
|
world.draw(camera->getViewProj(), camera->getPosition());
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
|||||||
@@ -79,4 +79,45 @@ void Entity::updateModelMatrix() {
|
|||||||
|
|
||||||
modelMatrix = translationMatrix * rotationMatrix * scaleMatrix;
|
modelMatrix = translationMatrix * rotationMatrix * scaleMatrix;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Skybox::Skybox(Model *cubeModel, ShaderProgram *shaderProgram, const char *texturePseudoPath)
|
||||||
|
: cubeModel(cubeModel),
|
||||||
|
shaderProgram(shaderProgram),
|
||||||
|
cubeMap(texturePseudoPath),
|
||||||
|
vertexArray(cubeModel->getMesh(0)->getVertexArray()) {
|
||||||
|
|
||||||
|
// Empty
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Skybox::draw(glm::mat4 viewMatrix, glm::mat4 projectionMatrix) {
|
||||||
|
|
||||||
|
// To disable face culling first get current state
|
||||||
|
GLboolean active;
|
||||||
|
glGetBooleanv(GL_CULL_FACE_MODE, &active);
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
glDepthMask(GL_FALSE);
|
||||||
|
shaderProgram->bind();
|
||||||
|
|
||||||
|
glm::mat4 viewProjectionMatrix = projectionMatrix * glm::mat4(glm::mat3(viewMatrix));
|
||||||
|
|
||||||
|
shaderProgram->setUniform("u_viewProjectionMatrix", viewProjectionMatrix);
|
||||||
|
|
||||||
|
cubeMap.bind(shaderProgram);
|
||||||
|
cubeModel->getMesh(0)->drawWithoutTextures(shaderProgram);
|
||||||
|
cubeMap.unbind();
|
||||||
|
|
||||||
|
shaderProgram->unbind();
|
||||||
|
glDepthMask(GL_TRUE);
|
||||||
|
|
||||||
|
// Restore face culling
|
||||||
|
if(active)
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
else
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
25
src/Entity.h
25
src/Entity.h
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
|
#include "Texture.h"
|
||||||
#include "ShaderProgram.h"
|
#include "ShaderProgram.h"
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
@@ -46,6 +47,26 @@ private:
|
|||||||
|
|
||||||
glm::mat4 modelMatrix = glm::mat4(1.0f);
|
glm::mat4 modelMatrix = glm::mat4(1.0f);
|
||||||
|
|
||||||
ShaderProgram* shaderProgram;
|
ShaderProgram *shaderProgram;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Skybox {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Skybox(Model *cubeModel, ShaderProgram *shaderProgram, const char *texturePseudoPath);
|
||||||
|
~Skybox() = default;
|
||||||
|
|
||||||
|
void draw(glm::mat4 viewMatrix, glm::mat4 projectionMatrix);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Model *cubeModel;
|
||||||
|
ShaderProgram *shaderProgram;
|
||||||
|
|
||||||
|
CubeMap cubeMap;
|
||||||
|
|
||||||
|
VertexArray *vertexArray;
|
||||||
|
|
||||||
|
};
|
||||||
|
|||||||
@@ -34,5 +34,12 @@ void Mesh::draw(ShaderProgram *shaderProgram) {
|
|||||||
(*it)->unbind();
|
(*it)->unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::drawWithoutTextures(ShaderProgram *shaderProgram) {
|
||||||
|
|
||||||
|
vertexArray.bind();
|
||||||
|
glDrawElements(GL_TRIANGLES, numElements, GL_UNSIGNED_INT, 0);
|
||||||
|
vertexArray.unbind();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ public:
|
|||||||
~Mesh() = default;
|
~Mesh() = default;
|
||||||
|
|
||||||
void draw(ShaderProgram *shaderProgram);
|
void draw(ShaderProgram *shaderProgram);
|
||||||
|
void drawWithoutTextures(ShaderProgram *shaderProgram);
|
||||||
|
|
||||||
|
VertexArray * getVertexArray() { return &vertexArray; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ public:
|
|||||||
|
|
||||||
void draw(ShaderProgram *shaderProgram);
|
void draw(ShaderProgram *shaderProgram);
|
||||||
|
|
||||||
|
Mesh * getMesh(unsigned int index) { return meshes[index]; }
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@@ -23,17 +23,14 @@ Texture::Texture(const char* texturePath, uint8_t textureType) {
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
|
||||||
|
|
||||||
if(textureBuffer) {
|
if(!textureBuffer) {
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer);
|
|
||||||
//glGenerateMipmap(GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
std::cout << "[Warning] Texture " << texturePath << " not found!" << std::endl;
|
std::cout << "[Warning] Texture " << texturePath << " not found!" << std::endl;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer);
|
||||||
|
//glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
|
||||||
stbi_image_free(textureBuffer);
|
stbi_image_free(textureBuffer);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
@@ -76,3 +73,72 @@ void Texture::bind(uint8_t textureUnit, ShaderProgram* shaderProgram, uint8_t te
|
|||||||
void Texture::unbind() {
|
void Texture::unbind() {
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CubeMap::CubeMap(const char* texturePseudoPath) {
|
||||||
|
|
||||||
|
// Reserve space in vector so that elements can be accessed explicitly.
|
||||||
|
texturePaths.resize(CUBEMAP_FACES_NUM_ITEMS);
|
||||||
|
fillTexturePathVector(texturePseudoPath);
|
||||||
|
|
||||||
|
stbi_set_flip_vertically_on_load(0);
|
||||||
|
|
||||||
|
glGenTextures(1, &textureId);
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 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(unsigned int i = 0; i < CUBEMAP_FACES_NUM_ITEMS; i++) {
|
||||||
|
|
||||||
|
auto *textureBuffer = stbi_load(texturePaths[i].c_str(), &textureWidth, &textureHeight, &bitsPerPixel, STBI_rgb_alpha);
|
||||||
|
|
||||||
|
if(!textureBuffer) {
|
||||||
|
std::cout << "[Warning] CubeMap Texture " << texturePaths[i].c_str() << " not found!" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer);
|
||||||
|
|
||||||
|
stbi_image_free(textureBuffer);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CubeMap::~CubeMap() {
|
||||||
|
glDeleteTextures(1, &textureId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CubeMap::bind(ShaderProgram *shaderProgram) {
|
||||||
|
std::string uniformName = "u_skybox";
|
||||||
|
|
||||||
|
shaderProgram->setUniform(uniformName.c_str(), 0);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, textureId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CubeMap::unbind() {
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CubeMap::fillTexturePathVector(const char* texturePseudoPath) {
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < CUBEMAP_FACES_NUM_ITEMS; i++) {
|
||||||
|
|
||||||
|
texturePaths[cm_front] = std::string(texturePseudoPath) + "front.png";
|
||||||
|
texturePaths[cm_back] = std::string(texturePseudoPath) + "back.png";
|
||||||
|
texturePaths[cm_top] = std::string(texturePseudoPath) + "top.png";
|
||||||
|
texturePaths[cm_bottom] = std::string(texturePseudoPath) + "bottom.png";
|
||||||
|
texturePaths[cm_left] = std::string(texturePseudoPath) + "left.png";
|
||||||
|
texturePaths[cm_right] = std::string(texturePseudoPath) + "right.png";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,9 +3,14 @@
|
|||||||
#include "ShaderProgram.h"
|
#include "ShaderProgram.h"
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// Order is important!
|
||||||
|
enum cubeMapFaces{cm_right, cm_left, cm_top, cm_bottom, cm_back, cm_front, CUBEMAP_FACES_NUM_ITEMS};
|
||||||
|
|
||||||
class Texture {
|
class Texture {
|
||||||
|
|
||||||
@@ -32,4 +37,28 @@ private:
|
|||||||
|
|
||||||
uint8_t textureType;
|
uint8_t textureType;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class CubeMap {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CubeMap(const char* texturePseudoPath);
|
||||||
|
~CubeMap();
|
||||||
|
|
||||||
|
void bind(ShaderProgram *shaderProgram);
|
||||||
|
void unbind();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void fillTexturePathVector(const char* texturePseudoPath);
|
||||||
|
|
||||||
|
std::vector<std::string> texturePaths;
|
||||||
|
|
||||||
|
GLuint textureId;
|
||||||
|
|
||||||
|
int32_t textureWidth;
|
||||||
|
int32_t textureHeight;
|
||||||
|
int32_t bitsPerPixel;
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
Window::Window() {
|
Window::Window() {
|
||||||
width = INIT_WINDOW_WIDTH; height = INIT_WINDOW_HEIGHT;
|
width = INIT_WINDOW_WIDTH; height = INIT_WINDOW_HEIGHT;
|
||||||
|
|
||||||
window = glfwCreateWindow(width, height, "Fall-Fever", NULL, NULL);
|
window = glfwCreateWindow(width, height, "OpenGL", NULL, NULL);
|
||||||
if(!window) {
|
if(!window) {
|
||||||
std::cout << "Failed to create window" << std::endl;
|
std::cout << "Failed to create window" << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user