aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/engine.cpp6
-rw-r--r--src/render.cpp159
-rw-r--r--src/render.hpp79
-rw-r--r--src/shader.cpp146
-rw-r--r--src/shader.hpp107
-rw-r--r--src/window.hpp95
6 files changed, 494 insertions, 98 deletions
diff --git a/src/engine.cpp b/src/engine.cpp
index 317e116..a89a876 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -22,8 +22,8 @@
#include "engine.hpp"
#include "gamerun.hpp"
#include "input.hpp"
-#include "window.hpp"
#include "script.hpp"
+#include "render.hpp"
#include "components/Script.hpp"
#include "components/Position.hpp"
@@ -32,7 +32,7 @@ int Engine::init(void)
{
systems.add<GameRunSystem>();
systems.add<InputSystem>();
- systems.add<WindowSystem>();
+ systems.add<RenderSystem>();
systems.add<ScriptSystem>();
systems.configure();
@@ -62,7 +62,7 @@ void Engine::logicLoop(void)
void Engine::renderLoop(void)
{
while (shouldRun()) {
- systems.update<WindowSystem>(0);
+ systems.update<RenderSystem>(0);
std::this_thread::yield();
}
}
diff --git a/src/render.cpp b/src/render.cpp
new file mode 100644
index 0000000..30fd396
--- /dev/null
+++ b/src/render.cpp
@@ -0,0 +1,159 @@
+/**
+ * @file render.cpp
+ *
+ * Copyright (C) 2019 Clyne Sullivan
+ * Copyright (C) 2019 Belle-Isle, Andrew <drumsetmonkey@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <render.hpp>
+
+void RenderSystem::configure([[maybe_unused]]entityx::EntityManager& entities,
+ [[maybe_unused]]entityx::EventManager& events)
+{
+ init();
+}
+
+void RenderSystem::update([[maybe_unused]] entityx::EntityManager& entites,
+ [[maybe_unused]] entityx::EventManager& events,
+ [[maybe_unused]] entityx::TimeDelta dt)
+{
+ static GLfloat tri_data[] = {
+ -1.0, -1.0, 0.0,
+ 1.0, -1.0, 0.0,
+ 0.0, 1.0, 0.0,
+ };
+
+ GLuint s = worldShader.getProgram();
+ GLuint v = worldShader.getUniform("view");
+ GLuint p = worldShader.getUniform("projection");
+ GLuint m = worldShader.getUniform("model");
+ GLuint a = worldShader.getAttribute("vertex");
+
+ /***********
+ * SETUP *
+ ***********/
+
+ glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, 5.0f), // Pos
+ glm::vec3(0.0f, 0.0f, 0.0f), // Facing
+ glm::vec3(0.0f, 1.0f, 0.0f)); // Up
+
+ glm::mat4 projection = glm::perspective(45.0f,
+ ((float)width/(float)height),
+ 0.01f,
+ 2048.0f);
+
+ glm::mat4 model = glm::mat4(1.0f);
+
+ glUseProgram(s);
+
+ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+ glEnable(GL_DEPTH_TEST);
+
+ glUniformMatrix4fv(v, 1, GL_FALSE, glm::value_ptr(view));
+ glUniformMatrix4fv(p, 1, GL_FALSE, glm::value_ptr(projection));
+ glUniformMatrix4fv(m, 1, GL_FALSE, glm::value_ptr(model));
+
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_POLYGON_OFFSET_FILL);
+
+ glEnableVertexAttribArray(a);
+
+ /*************
+ * DRAWING *
+ *************/
+
+ GLuint tri_vbo;
+
+ glGenBuffers(1, &tri_vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, tri_vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(tri_data), tri_data, GL_STREAM_DRAW);
+
+ glVertexAttribPointer(a, 3, GL_FLOAT, GL_FALSE, 0, 0);
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+
+
+ /*************
+ * CLEANUP *
+ *************/
+ glDisableVertexAttribArray(a);
+
+ glDisable(GL_POLYGON_OFFSET_FILL);
+ glDisable(GL_CULL_FACE);
+
+ glUseProgram(0);
+
+ SDL_GL_SwapWindow(window.get());
+}
+
+int RenderSystem::init(void)
+{
+ // Select an OpenGL 4.3 profile.
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
+
+ if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) {
+ std::cerr << "SDL video failed to initialize: "
+ << SDL_GetError() << std::endl;
+ return -1;
+ }
+
+ // Create window, managed by the unique_ptr
+ window.reset(SDL_CreateWindow(title,
+ SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
+ width, height,
+ SDL_WINDOW_OPENGL));
+
+ if (window.get() == nullptr) {
+ std::cerr << "SDL window creation failed: "
+ << SDL_GetError() << std::endl;
+ return -1;
+ }
+
+ context = SDL_GL_CreateContext(window.get());
+
+ GLenum err;
+ glewExperimental = GL_TRUE;
+ if((err=glewInit()) != GLEW_OK){
+ std::cerr << "GLEW was not able to initialize! Error: " <<
+ glewGetErrorString(err) << std::endl;
+ return -1;
+ }
+
+ SDL_GL_SetSwapInterval(0);
+
+ glEnable(GL_BLEND);
+ glEnable(GL_DEPTH_TEST);
+ //glDepthFunc(GL_LESS);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ worldShader.createProgram("Shaders/world.vert", "Shaders/world.frag");
+
+ worldShader.addUniform("projection");
+ worldShader.addUniform("view");
+ worldShader.addUniform("model");
+
+ worldShader.addAttribute("vertex");
+
+ glEnableVertexAttribArray(worldShader.getAttribute("vertex"));
+ glUseProgram(worldShader.getProgram());
+
+ // TODO
+ //glPolygonOffset(1.0, 1.0);
+
+ glClearColor(0.6, 0.8, 1.0, 0.0);
+
+ return 0;
+}
diff --git a/src/render.hpp b/src/render.hpp
new file mode 100644
index 0000000..fa609a3
--- /dev/null
+++ b/src/render.hpp
@@ -0,0 +1,79 @@
+/**
+ * @file render.hpp
+ * Handles all in game rendering
+ *
+ * Copyright (C) 2019 Clyne Sullivan
+ * Copyright (C) 2019 Belle-Isle, Andrew <drumsetmonkey@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef RENDER_HPP_
+#define RENDER_HPP_
+
+#include <entityx/entityx.h>
+
+#include <shader.hpp>
+
+#include <SDL2/SDL.h>
+
+#define GLM_FORCE_RADIANS
+#include <glm/glm.hpp>
+#include <glm/gtc/matrix_transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+#include <glm/gtc/noise.hpp>
+
+class RenderSystem : public entityx::System<RenderSystem>
+{
+private:
+ constexpr static const char *title = "gamedev2";
+ constexpr static int width = 640;
+ constexpr static int height = 480;
+
+ std::unique_ptr<SDL_Window, void (*)(SDL_Window *)> window;
+ SDL_GLContext context;
+
+ Shader worldShader;
+public:
+ RenderSystem(void):
+ window(nullptr, SDL_DestroyWindow)
+ {}
+
+ ~RenderSystem(void)
+ {
+ SDL_GL_DeleteContext(context);
+ SDL_Quit();
+ }
+
+ /**
+ * Prepares the system for running.
+ */
+ void configure([[maybe_unused]]entityx::EntityManager& entities,
+ [[maybe_unused]]entityx::EventManager& events) final;
+
+ /**
+ * Updates the render system.
+ */
+ void update([[maybe_unused]] entityx::EntityManager& entites,
+ [[maybe_unused]] entityx::EventManager& events,
+ [[maybe_unused]] entityx::TimeDelta dt) final;
+
+ /**
+ * Initializes the rendering system
+ * @return Zero on success, non-zero on error
+ */
+ int init(void);
+};
+
+#endif//RENDER_HPP_
diff --git a/src/shader.cpp b/src/shader.cpp
new file mode 100644
index 0000000..bb62ac9
--- /dev/null
+++ b/src/shader.cpp
@@ -0,0 +1,146 @@
+/**
+ * @file shader.cpp
+ *
+ * Copyright (C) 2019 Belle-Isle, Andrew <drumsetmonkey@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <shader.hpp>
+
+#include <fstream>
+#include <iostream>
+#include <vector>
+
+#include <SDL2/SDL.h>
+
+/*************
+* PRIVATE *
+*************/
+
+std::string Shader::readShader(std::string filepath)
+{
+ std::string contents = "";
+ std::ifstream file(filepath, std::ios::in);
+
+ if (!file.is_open()) {
+ std::cerr << "Could not read shader " << filepath <<
+ ". Shader doesn't exist" << std::endl;
+ return "";
+ }
+
+ std::string line = "";
+ while (!file.eof()) {
+ std::getline(file, line);
+ contents.append(line + "\n");
+ }
+
+ file.close();
+ return contents;
+}
+
+GLuint Shader::createShader(std::string filepath, GLenum shaderType)
+{
+ GLuint shader = glCreateShader(shaderType);
+
+ std::string shaderStr = readShader(filepath);
+ const char* shaderSrc = shaderStr.c_str();
+
+ GLint result = GL_FALSE;
+ int logLength;
+
+ glShaderSource(shader, 1, &shaderSrc, NULL);
+ glCompileShader(shader);
+
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
+ std::vector<char> shaderError((logLength > 1) ? logLength : 1);
+ glGetShaderInfoLog(shader, logLength, NULL, &shaderError[0]);
+ std::cerr << &shaderError[0] << std::endl;
+
+ return shader;
+}
+
+/************
+* PUBLIC *
+************/
+
+GLuint Shader::createProgram(std::string vertexPath, std::string fragmentPath)
+{
+ GLuint vertex = createShader(vertexPath, GL_VERTEX_SHADER);
+ GLuint fragment = createShader(fragmentPath, GL_FRAGMENT_SHADER);
+
+ GLuint program = glCreateProgram();
+ glAttachShader(program, vertex);
+ glAttachShader(program, fragment);
+ glLinkProgram(program);
+
+ GLint result = GL_FALSE;
+ int logLength;
+
+ glGetProgramiv(program, GL_COMPILE_STATUS, &result);
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
+ std::vector<char> programError((logLength > 1) ? logLength : 1);
+ glGetProgramInfoLog(program, logLength, NULL, &programError[0]);
+ std::cerr << &programError[0] << std::endl;
+
+ glDeleteShader(vertex);
+ glDeleteShader(fragment);
+
+ this->program = program;
+
+ return program;
+}
+
+// TODO exceptions
+GLint Shader::addAttribute(std::string attrib)
+{
+ GLint attribute = glGetAttribLocation(program, attrib.c_str());
+
+ if (attribute == -1)
+ SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR,
+ "Could not bind attribute %s", attrib.c_str());
+
+ attributes.emplace(attrib, attribute);
+ return attribute;
+}
+
+GLint Shader::addUniform(std::string unfi)
+{
+ GLint uniform = glGetUniformLocation(program, unfi.c_str());
+
+ if (uniform == -1)
+ SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR,
+ "Could not bind uniform %s", unfi.c_str());
+
+ uniforms.emplace(unfi, uniform);
+ return uniform;
+}
+
+// TODO exceptions
+GLint Shader::getAttribute(std::string attrib)
+{
+ return attributes.at(attrib);
+}
+
+GLint Shader::getUniform(std::string unfi)
+{
+ return uniforms.at(unfi);
+}
+
+GLuint Shader::getProgram()
+{
+ return program;
+}
+
diff --git a/src/shader.hpp b/src/shader.hpp
new file mode 100644
index 0000000..e67a4a0
--- /dev/null
+++ b/src/shader.hpp
@@ -0,0 +1,107 @@
+/**
+ * @file shader.hpp
+ *
+ * Copyright (C) 2019 Belle-Isle, Andrew <drumsetmonkey@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SHADER_HPP
+#define SHADER_HPP
+
+#include <string>
+#include <unordered_map>
+
+#include <GL/glew.h>
+
+class Shader
+{
+ private:
+ /**
+ * Reads the contents of a shader file and returns a c++ string
+ * object representing the contents
+ * @param The file path
+ * @return The shader contents
+ */
+ std::string readShader(std::string);
+
+ /**
+ * Creates a shader from a filename and a shader type
+ * @param The file path containing the shader data
+ * @param What type of shader to create
+ * @return Memory address of shader location
+ */
+ GLuint createShader(std::string, GLenum);
+
+ GLuint program; /**< GPU Memory address of shader program */
+
+ /**
+ * Name of shader attributes and their corresponding memory
+ * locations in which the data exists
+ */
+ std::unordered_map<std::string, GLuint> attributes;
+
+ /**
+ * Name of shader uniforms in and their corresponding memory
+ * locations in which the data exists
+ */
+ std::unordered_map<std::string, GLuint> uniforms;
+ public:
+ Shader(): program(-1) {}
+ /**
+ * Given the file paths of two shaders, create a shader program.
+ * @param v The file path of the vertex shader file.
+ * @param f The file path of the fragment shader file.
+ * @return The GPU Memory location of the shader program
+ */
+ GLuint createProgram(std::string v, std::string f);
+
+ /**
+ * Finds and binds an attribute to the current shader if possible
+ * @param The attribute to bind in the shader
+ * @return The memory address of the new attribute, or -1 if the
+ * attribute doesn't exist in the shader
+ */
+ GLint addAttribute(std::string);
+ /**
+ * Finds and binds a uniform to the current shader if possible
+ * @param The uniform to bind in the shader
+ * @return The memory address of the new uniform, or -1 if the
+ * uniform doesn't exist in the shader
+ */
+ GLint addUniform(std::string);
+
+ /**
+ * Finds the GPU memory address of the given attribute in the shader
+ * program
+ * @param The attribute to find
+ * @return The attribute memory location, or -1 if it doesn't exist
+ */
+ GLint getAttribute(std::string);
+ /**
+ * Finds the GPU memory address of the given uniform in the shader
+ * program
+ * @param The uniform to find
+ * @return The uniform memory location, or -1 if it doesn't exist
+ */
+ GLint getUniform(std::string);
+
+ /**
+ * Gets the memory address of the program stored in this object
+ * @return The GPU memory address of the shader program stored
+ */
+ GLuint getProgram();
+};
+
+#endif // SHADER_HPP
diff --git a/src/window.hpp b/src/window.hpp
deleted file mode 100644
index ef6632a..0000000
--- a/src/window.hpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * @file window.hpp
- * Manages window creation.
- *
- * Copyright (C) 2019 Clyne Sullivan
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-#ifndef WINDOW_HPP_
-#define WINDOW_HPP_
-
-#include <entityx/entityx.h>
-#include <SDL2/SDL.h>
-
-/**
- * @class WindowSystem
- * Handles the game's window.
- */
-class WindowSystem : public entityx::System<WindowSystem> {
-private:
- constexpr static const char *title = "gamedev2";
- constexpr static int width = 640;
- constexpr static int height = 480;
-
- std::unique_ptr<SDL_Window, void (*)(SDL_Window *)> window;
- SDL_GLContext context;
-
-public:
- WindowSystem(void) :
- window(nullptr, SDL_DestroyWindow) {}
-
- ~WindowSystem(void) {
- SDL_GL_DeleteContext(context);
- }
-
- /**
- * Creates and initializes the window.
- * @return Zero on success, non-zero on error
- */
- int init(void) {
- if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) {
- std::cerr << "SDL video failed to initialize: "
- << SDL_GetError() << std::endl;
- return -1;
- }
-
- // Create window, managed by the unique_ptr
- window.reset(SDL_CreateWindow(title,
- SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
- width, height,
- SDL_WINDOW_OPENGL));
-
- if (window.get() == nullptr) {
- std::cerr << "SDL window creation failed: "
- << SDL_GetError() << std::endl;
- return -1;
- }
-
- context = SDL_GL_CreateContext(window.get());
-
- return 0;
- }
-
- /**
- * Prepares the system for running.
- */
- void configure([[maybe_unused]] entityx::EntityManager& entities,
- [[maybe_unused]] entityx::EventManager& events) final {
- init();
- }
-
- /**
- * Updates/refreshes the window.
- */
- void update([[maybe_unused]] entityx::EntityManager& entities,
- [[maybe_unused]] entityx::EventManager& events,
- [[maybe_unused]] entityx::TimeDelta dt) final {
- SDL_GL_SwapWindow(window.get());
- }
-};
-
-#endif // WINDOW_HPP_
-