diff --git a/core/Shaders/SkyboxShader.cpp b/core/Shaders/SkyboxShader.cpp new file mode 100644 index 0000000..b2c2352 --- /dev/null +++ b/core/Shaders/SkyboxShader.cpp @@ -0,0 +1,12 @@ +#include "SkyboxShader.h" +#include "skybox.vert.h" +#include "skybox.frag.h" + +SkyboxShader::SkyboxShader() : Shader(skybox_vert, skybox_frag) {} + +void SkyboxShader::UpdateSkybox(Skybox skybox) { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_CUBE_MAP, skybox.id); +} + +Name SkyboxShader::GetName() const { return "Skybox Shader"; } diff --git a/core/Shaders/SkyboxShader.h b/core/Shaders/SkyboxShader.h new file mode 100644 index 0000000..2c7ec29 --- /dev/null +++ b/core/Shaders/SkyboxShader.h @@ -0,0 +1,14 @@ +#ifndef SKYBOXSHADER_H +#define SKYBOXSHADER_H + +#include "Shader.h" +#include "Skybox.h" + +class SkyboxShader : public Shader { +public: + SkyboxShader(); + Name GetName() const; + void UpdateSkybox(Skybox skybox); +}; + +#endif /* SKYBOXSHADER_H */ diff --git a/core/Skybox.cpp b/core/Skybox.cpp new file mode 100644 index 0000000..a04894e --- /dev/null +++ b/core/Skybox.cpp @@ -0,0 +1,94 @@ +#include "Skybox.h" + +cfloat vertices[] = { + // positions + -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 +}; + +Skybox::Skybox() { + glGenVertexArrays(1, &cube); + glBindVertexArray(cube); + + Id vbo; + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + // We're just going to use position data + // UV data is the same + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * (sizeof(cfloat)), (void*) 0); + glBindVertexArray(0); +} + +Name Skybox::GetType() const { return "Skybox"; } + +Skybox *Skybox::FromFiles(const char *right, const char* left, const char* top, const char* bottom, const char* front, const char* back) { + // HOCUS: https://learnopengl.com/Advanced-OpenGL/Cubemaps + Skybox *sb = new Skybox(); + glGenTextures(1, &sb->id); + glBindTexture(GL_TEXTURE_CUBE_MAP, sb->id); + + int width, height, nrChannels; + unsigned char* data; + const char* files[] = {right, left, top, bottom, front, back}; + for (int i = 0; i < 6; i++) { + data = stbi_load(files[i], &width, &height, &nrChannels, 3); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, + 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + stbi_image_free(data); + } + 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_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); + + return sb; +} + +void Skybox::DrawSkybox() { + glBindVertexArray(cube); + glDrawArrays(GL_TRIANGLES, 0, 36); + glBindVertexArray(0); +} diff --git a/core/Skybox.h b/core/Skybox.h new file mode 100644 index 0000000..89f4ae4 --- /dev/null +++ b/core/Skybox.h @@ -0,0 +1,21 @@ +#ifndef SKYBOX_H +#define SKYBOX_H + +#include + +#include "types.h" +#include "Node.h" +#include "Material.h" + +class Skybox : public Node { +public: + Skybox(); + virtual Name GetType() const; + static Skybox *FromFiles(const char *right, const char* left, const char* top, const char* bottom, const char* front, const char* back); + void DrawSkybox(); + Id id; +private: + Id cube; +}; + +#endif /* SKYBOX_H */ diff --git a/core/couch.cpp b/core/couch.cpp index ac5ca5c..0dea082 100644 --- a/core/couch.cpp +++ b/core/couch.cpp @@ -12,6 +12,7 @@ #include "Shaders/FlatShader.h" #include "Shaders/ScreenShader.h" +#include "Shaders/SkyboxShader.h" #include "Screen.h" @@ -20,6 +21,8 @@ #include "Node.h" #include "Mesh.h" #include "Light.h" +#include "Skybox.h" + #include "Scripting/Lua.h" // Thirdparty Includes @@ -87,6 +90,8 @@ int main() { Screen screen; ScreenShader *screenShader = new ScreenShader(); + + SkyboxShader *skyboxShader = new SkyboxShader(); FlatShader *shader = new FlatShader(); @@ -127,6 +132,18 @@ int main() { // Render the scene tree render(root, shader, Matrix(1.0f)); + // Render the skybox + Skybox *skybox = Util::FindNodeByType(root, "Skybox"); + if (skybox) { + glDepthFunc(GL_LEQUAL); + skyboxShader->Use(); + skyboxShader->UpdateView(glm::mat4(glm::mat3(view))); + skyboxShader->UpdateProjection(projection); + skyboxShader->UpdateSkybox(*skybox); + skybox->DrawSkybox(); + glDepthFunc(GL_LESS); + } + // Stop rendering to texture screen.Disable(); // // Render the screen diff --git a/demo/main.lua b/demo/main.lua index b9bdcda..cefbca9 100644 --- a/demo/main.lua +++ b/demo/main.lua @@ -35,6 +35,16 @@ function init() light.diffuse = 1.0 light.specular = 0.1 couch.Node.GetRoot().children:Append(light) + + skybox = couch.Skybox.FromFiles( + "skybox/right.jpg", + "skybox/left.jpg", + "skybox/top.jpg", + "skybox/bottom.jpg", + "skybox/front.jpg", + "skybox/back.jpg" + ) + couch.Node.GetRoot().children:Append(skybox) ball = couch.Mesh.FromFile("cube.obj") material = ball:GetMaterial(0) @@ -44,6 +54,7 @@ function init() couch.Node.GetRoot().children:Append(ball) ball1 = couch.Mesh.FromFile("ball.obj") + print(material.diffuse.b) material = ball1:GetMaterial(0) ball1:SetMaterial(0, material) diff --git a/demo/skybox/back.jpg b/demo/skybox/back.jpg new file mode 100644 index 0000000..470a679 Binary files /dev/null and b/demo/skybox/back.jpg differ diff --git a/demo/skybox/bottom.jpg b/demo/skybox/bottom.jpg new file mode 100644 index 0000000..893f394 Binary files /dev/null and b/demo/skybox/bottom.jpg differ diff --git a/demo/skybox/front.jpg b/demo/skybox/front.jpg new file mode 100644 index 0000000..4e17b77 Binary files /dev/null and b/demo/skybox/front.jpg differ diff --git a/demo/skybox/left.jpg b/demo/skybox/left.jpg new file mode 100644 index 0000000..5750b91 Binary files /dev/null and b/demo/skybox/left.jpg differ diff --git a/demo/skybox/right.jpg b/demo/skybox/right.jpg new file mode 100644 index 0000000..8963037 Binary files /dev/null and b/demo/skybox/right.jpg differ diff --git a/demo/skybox/top.jpg b/demo/skybox/top.jpg new file mode 100644 index 0000000..4db3c2a Binary files /dev/null and b/demo/skybox/top.jpg differ diff --git a/scripting/couch.i b/scripting/couch.i index bb23ad2..7803e6e 100644 --- a/scripting/couch.i +++ b/scripting/couch.i @@ -15,6 +15,7 @@ #include "Material.h" #include "Camera.h" #include "Light.h" +#include "Skybox.h" %} %rename("%(strip:[script_])s") ""; @@ -45,7 +46,6 @@ public: } } - %include "types.h" %include "constants.h" %include "Node.h" @@ -55,4 +55,4 @@ public: %include "Material.h" %include "Camera.h" %include "Light.h" - +%include "Skybox.h" diff --git a/shaders/CMakeLists.txt b/shaders/CMakeLists.txt index 09ee23a..d0ea83c 100644 --- a/shaders/CMakeLists.txt +++ b/shaders/CMakeLists.txt @@ -12,7 +12,9 @@ add_shader(flat.vert) add_shader(flat.frag) add_shader(screen.vert) add_shader(screen.frag) +add_shader(skybox.vert) +add_shader(skybox.frag) add_custom_target(shader_headers - DEPENDS flat.vert.h flat.frag.h screen.vert.h screen.frag.h + DEPENDS flat.vert.h flat.frag.h screen.vert.h screen.frag.h skybox.vert.h skybox.frag.h COMMENT "Generated shaders headers.") diff --git a/shaders/skybox.frag b/shaders/skybox.frag new file mode 100644 index 0000000..12b013a --- /dev/null +++ b/shaders/skybox.frag @@ -0,0 +1,11 @@ +#version 330 core + +out vec4 FragColor; + +in vec3 UV; + +uniform samplerCube skybox; + +void main() { + FragColor = texture(skybox, UV); +} diff --git a/shaders/skybox.vert b/shaders/skybox.vert new file mode 100644 index 0000000..618ef3d --- /dev/null +++ b/shaders/skybox.vert @@ -0,0 +1,14 @@ +#version 330 core + +layout (location = 0) in vec3 pos; + +out vec3 UV; + +uniform mat4 VIEW; // Assuming this is free of translation +uniform mat4 PROJECTION; + +void main() { + UV = pos; + vec4 projectedPos = PROJECTION * VIEW * vec4(pos, 1.0); + gl_Position = projectedPos.xyww; +}