Skybox
[opengl.git] / skybox.cpp
diff --git a/skybox.cpp b/skybox.cpp
new file mode 100644 (file)
index 0000000..bd097cb
--- /dev/null
@@ -0,0 +1,72 @@
+#include "shapes.hpp"
+#include "skybox.hpp"
+#include "image.hpp"
+#include <GL/glew.h>
+#include <glm/gtc/type_ptr.hpp>
+       
+Skybox::Skybox(const std::vector<std::string> faces): program("skyboxvert.glsl", "skyboxfrag.glsl") {
+       glUseProgram(program.progId);
+       glGenTextures(1, &texId);
+       glBindTexture(GL_TEXTURE_CUBE_MAP, texId);
+
+       int width, height, numChans;
+       for (int i = 0; i < faces.size(); i++) {
+               Image img(faces[i]);
+
+               glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, img.width(), img.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.data());
+       }
+
+       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_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);
+
+       glGenVertexArrays(1, &vao);
+       glBindVertexArray(vao);
+
+       GLuint vbo;
+       glGenBuffers(1, &vbo);
+
+       auto vertices = cube();
+
+       glBindBuffer(GL_ARRAY_BUFFER, vbo);
+       glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
+       
+       GLuint posLoc = glGetAttribLocation(program.progId, "pos");
+       glEnableVertexAttribArray(posLoc);
+       glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
+}
+void validatePrograms(GLuint progId) {
+       glValidateProgram(progId);
+       
+       GLint success;
+       glGetProgramiv(progId, GL_VALIDATE_STATUS, &success);
+       if (!success) {
+               GLchar log[1024];
+               glGetProgramInfoLog(progId, sizeof(log), NULL, log);
+               fprintf(stderr, "error: %s\n", log);
+               exit(1);
+       }
+}
+
+void Skybox::draw(glm::mat4 proj, glm::mat4 view) const {
+       glUseProgram(program.progId);
+
+       glDepthMask(GL_FALSE);
+       glDisable(GL_CULL_FACE);
+       glBindVertexArray(vao);
+       validatePrograms(program.progId);
+
+       GLuint projLoc = glGetUniformLocation(program.progId, "projection");
+       glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(proj));
+
+       GLuint viewLoc = glGetUniformLocation(program.progId, "view");
+       view = glm::mat4(glm::mat3(view));
+       glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
+
+       glBindTexture(GL_TEXTURE_CUBE_MAP, texId);
+       glDrawArrays(GL_TRIANGLES, 0, 36);
+       glEnable(GL_CULL_FACE);
+       glDepthMask(GL_TRUE);
+}