[Shader] added. [GameState] OK.

This commit is contained in:
Quentin Bazin 2014-12-15 16:47:30 +01:00
parent dadddc93a9
commit fad91e840f
21 changed files with 990 additions and 2 deletions

View File

@ -20,7 +20,6 @@ LDFLAGS := -g
# Any extra libraries you wish to link with your project
#---------------------------------------------------------------------------------
LIBS := -lsfml-graphics -lsfml-audio -lsfml-window -lsfml-system
LIBS := -lSDL2_ttf -lSDL2_mixer -lSDL2_image -lSDL2
#---------------------------------------------------------------------------------
ifeq ($(shell uname), Darwin)
@ -29,7 +28,7 @@ LIBS += -framework OpenGL
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
LIBS += -lGL
LIBS += -lGLEW -lGL
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

View File

@ -0,0 +1,54 @@
/*
* =====================================================================================
*
* Filename: Application.hpp
*
* Description:
*
* Version: 1.0
* Created: 14/12/2014 05:09:11
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#ifndef APPLICATION_HPP_
#define APPLICATION_HPP_
#include <SFML/Graphics/RenderWindow.hpp>
#include "ApplicationStateStack.hpp"
#include "GameClock.hpp"
//#include "ResourceHandler.hpp"
class Application {
public:
Application();
~Application();
void handleEvents();
void run();
void resetView() { m_window.setView(m_defaultView); }
sf::RenderWindow &window() { return m_window; }
static Application &getInstance() {
static Application instance;
return instance;
}
private:
sf::RenderWindow m_window;
sf::View m_defaultView;
GameClock m_clock;
ApplicationStateStack *m_applicationStateStack;
};
#endif // APPLICATION_HPP_

View File

@ -0,0 +1,41 @@
/*
* =====================================================================================
*
* Filename: ApplicationStateStack.hpp
*
* Description:
*
* Version: 1.0
* Created: 14/12/2014 13:48:48
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#ifndef APPLICATIONSTATESTACK_HPP_
#define APPLICATIONSTATESTACK_HPP_
#include <memory>
#include <stack>
#include "ApplicationState.hpp"
class ApplicationStateStack {
public:
ApplicationStateStack();
~ApplicationStateStack();
ApplicationState &top() { return *m_stack.top().get(); }
void push(ApplicationState *state) { m_stack.push(std::unique_ptr<ApplicationState>(state)); }
void pop() { m_stack.pop(); }
static ApplicationStateStack &getInstance();
private:
std::stack<std::unique_ptr<ApplicationState>> m_stack;
};
#endif // APPLICATIONSTATESTACK_HPP_

28
include/core/Config.hpp Normal file
View File

@ -0,0 +1,28 @@
/*
* =====================================================================================
*
* Filename: Config.hpp
*
* Description:
*
* Version: 1.0
* Created: 14/12/2014 13:45:14
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#ifndef CONFIG_HPP_
#define CONFIG_HPP_
#include "Types.hpp"
const u16 SCREEN_WIDTH = 640;
const u16 SCREEN_HEIGHT = 480;
const char *APP_NAME = "KubKraft";
#endif // CONFIG_HPP_

27
include/gl/OpenGL.hpp Normal file
View File

@ -0,0 +1,27 @@
/*
* =====================================================================================
*
* Filename: OpenGL.hpp
*
* Description:
*
* Version: 1.0
* Created: 15/12/2014 04:18:34
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#ifndef OPENGL_HPP_
#define OPENGL_HPP_
#ifdef __APPLE__
#include <OpenGL/glew.h>
#else
#include <GL/glew.h>
#endif
#endif // OPENGL_HPP_

49
include/gl/Shader.hpp Normal file
View File

@ -0,0 +1,49 @@
/*
* =====================================================================================
*
* Filename: Shader.hpp
*
* Description:
*
* Version: 1.0
* Created: 15/12/2014 16:30:20
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#ifndef SHADER_HPP_
#define SHADER_HPP_
#include "OpenGL.hpp"
class Shader {
public:
Shader();
Shader(const char *vertexFilename, const char *fragementFilename);
~Shader();
void loadFromFile(const char *vertexFilename, const char *fragementFilename);
void compileShader(GLenum type, GLuint &shader, const char *filename);
GLint attrib(const char *attribName);
GLint uniform(const char *uniformName);
void enableVertexAttribArray(const char *attribName);
void disableVertexAttribArray(const char *attribName);
static void bind(const Shader *shader);
GLint program() const { return m_program; }
private:
GLuint m_vertexShader;
GLuint m_fragmentShader;
GLuint m_program;
};
#endif // SHADER_HPP_

View File

@ -0,0 +1,31 @@
/*
* =====================================================================================
*
* Filename: ApplicationState.hpp
*
* Description:
*
* Version: 1.0
* Created: 14/12/2014 13:49:55
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#ifndef APPLICATIONSTATE_HPP_
#define APPLICATIONSTATE_HPP_
class ApplicationState {
public:
ApplicationState();
virtual ~ApplicationState();
virtual void update() = 0;
virtual void draw() = 0;
};
#endif // APPLICATIONSTATE_HPP_

View File

@ -0,0 +1,40 @@
/*
* =====================================================================================
*
* Filename: GameState.hpp
*
* Description:
*
* Version: 1.0
* Created: 15/12/2014 03:51:32
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#ifndef GAMESTATE_HPP_
#define GAMESTATE_HPP_
#include "ApplicationState.hpp"
#include "OpenGL.hpp"
#include "Shader.hpp"
class GameState : public ApplicationState {
public:
GameState();
~GameState();
void update();
void draw();
private:
GLuint m_vbo;
Shader m_shader;
};
#endif // GAMESTATE_HPP_

74
include/system/Debug.hpp Normal file
View File

@ -0,0 +1,74 @@
/*
* =====================================================================================
*
* Filename: Debug.hpp
*
* Description:
*
* Version: 1.0
* Created: 14/12/2014 05:02:30
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#ifndef DEBUG_HPP_
#define DEBUG_HPP_
#include <cstring>
#include <iostream>
#include <sstream>
#include <string>
#include "Types.hpp"
#define DEBUG_ENABLED
#define DEBUG_COLOR
#define _FILE (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#ifdef DEBUG_ENABLED
#define DEBUG(args...) { std::cout << Debug::textColor(Debug::TextColor::Red, true) << _FILE << ":" << __LINE__ << ":" << Debug::textColor(); Debug::print(args); }
#else
#define DEBUG(args...) {}
#endif
namespace Debug {
enum TextColor {
White = 0,
Red = 31,
Blue = 36
};
inline std::string textColor(u8 color = TextColor::White, bool bold = false) {
#ifdef DEBUG_COLOR
return std::string("\33[0;") + ((color < 10) ? "0" : "") + std::to_string(color) + ";0" + ((bold) ? "1" : "0") + "m";
#else
return std::string("");
#endif
}
template<typename T>
std::string makeString(std::stringstream &stream, T value) {
stream << value;
return stream.str();
}
template<typename T, typename... Args>
std::string makeString(std::stringstream &stream, T value, Args... args) {
stream << value << " ";
return makeString(stream, args...);
}
template<typename... Args>
void print(Args... args) {
std::stringstream stream;
std::cout << textColor(0, true) << makeString(stream, args...) << textColor() << std::endl;
}
}
#endif // DEBUG_HPP_

View File

@ -0,0 +1,54 @@
/*
* =====================================================================================
*
* Filename: Exception.hpp
*
* Description:
*
* Version: 1.0
* Created: 14/12/2014 05:02:53
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#ifndef EXCEPTION_HPP_
#define EXCEPTION_HPP_
#include <exception>
#include <string>
#include "Debug.hpp"
#include "Types.hpp"
#define EXCEPTION(args...) (Exception(__LINE__, _FILE, args))
class Exception : public std::exception {
public:
template<typename... Args>
Exception(u16 line, std::string filename, Args... args) throw() {
m_line = line;
m_filename = filename;
std::stringstream stream;
m_errorMsg = Debug::makeString(stream, args...);
}
~Exception() throw() {
}
virtual const char *what() const throw() {
return (Debug::textColor(Debug::TextColor::Red, true) + "at " + m_filename + ":" + std::to_string(m_line) + ": " + Debug::textColor(0, true) + m_errorMsg.c_str() + Debug::textColor()).c_str();
}
private:
u16 m_line;
std::string m_filename;
std::string m_errorMsg;
};
#endif // EXCEPTION_HPP_

View File

@ -0,0 +1,53 @@
/*
* =====================================================================================
*
* Filename: GameClock.hpp
*
* Description:
*
* Version: 1.0
* Created: 14/12/2014 13:42:17
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#ifndef GAMECLOCK_HPP_
#define GAMECLOCK_HPP_
#include <functional>
#include <SFML/System.hpp>
#include "Types.hpp"
class GameClock {
public:
GameClock();
~GameClock();
static u32 getTicks(bool realTime = false);
void measureLastFrameDuration();
void updateGame(std::function<void(void)> updateFunc);
void drawGame(std::function<void(void)> drawFunc);
private:
static sf::Clock clock;
static u32 ticks;
u32 m_lastFrameDate;
u32 m_lag;
u32 m_timeDropped;
u32 m_now;
u32 m_lastFrameDuration;
u32 m_timestep;
u8 m_numUpdates;
};
#endif // GAMECLOCK_HPP_

28
include/system/Types.hpp Normal file
View File

@ -0,0 +1,28 @@
/*
* =====================================================================================
*
* Filename: Types.hpp
*
* Description:
*
* Version: 1.0
* Created: 14/12/2014 05:05:33
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#ifndef TYPES_HPP_
#define TYPES_HPP_
typedef unsigned char u8;
typedef signed char s8;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned long u32;
typedef signed long s32;
#endif // TYPES_HPP_

6
shaders/game.f.glsl Normal file
View File

@ -0,0 +1,6 @@
#version 120
void main() {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}

13
shaders/game.v.glsl Normal file
View File

@ -0,0 +1,13 @@
#version 120
attribute vec2 coord2d;
uniform mat4 u_projectionMatrix;
uniform mat4 u_viewMatrix;
void main() {
mat4 MVP = u_projectionMatrix * u_viewMatrix;
gl_Position = MVP * vec4(coord2d, 0.0, 1.0);
}

View File

@ -0,0 +1,74 @@
/*
* =====================================================================================
*
* Filename: Application.cpp
*
* Description:
*
* Version: 1.0
* Created: 14/12/2014 05:09:21
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#include <SFML/Window/Event.hpp>
#include "Application.hpp"
#include "Config.hpp"
#include "Exception.hpp"
#include "OpenGL.hpp"
Application::Application() {
if(glewInit() != GLEW_OK) {
EXCEPTION("glew init failed");
}
m_window.create(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT), APP_NAME, sf::Style::Close, sf::ContextSettings(24, 8, 2));
m_defaultView.reset(sf::FloatRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
//ResourceHandler::getInstance().loadResources();
m_applicationStateStack = &ApplicationStateStack::getInstance();
}
Application::~Application() {
}
void Application::handleEvents() {
sf::Event event;
while(m_window.pollEvent(event)) {
if(event.type == sf::Event::Closed) {
m_window.close();
}
if(event.type == sf::Event::KeyPressed
&& event.key.code == sf::Keyboard::Escape) {
m_window.close();
}
}
}
void Application::run() {
while(m_window.isOpen()) {
m_clock.measureLastFrameDuration();
handleEvents();
m_clock.updateGame([&]{
m_applicationStateStack->top().update();
});
m_clock.drawGame([&]{
m_window.clear();
m_window.setView(m_defaultView);
m_applicationStateStack->top().draw();
m_window.display();
});
}
}

View File

@ -0,0 +1,32 @@
/*
* =====================================================================================
*
* Filename: ApplicationStateStack.cpp
*
* Description:
*
* Version: 1.0
* Created: 14/12/2014 13:49:05
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#include "ApplicationStateStack.hpp"
#include "GameState.hpp"
ApplicationStateStack::ApplicationStateStack() {
push(new GameState);
}
ApplicationStateStack::~ApplicationStateStack() {
}
ApplicationStateStack &ApplicationStateStack::getInstance() {
static ApplicationStateStack instance;
return instance;
}

145
source/gl/Shader.cpp Normal file
View File

@ -0,0 +1,145 @@
/*
* =====================================================================================
*
* Filename: Shader.cpp
*
* Description:
*
* Version: 1.0
* Created: 15/12/2014 16:30:34
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#include <iostream>
#include <fstream>
#include "Exception.hpp"
#include "Shader.hpp"
Shader::Shader() {
}
Shader::Shader(const char *vertexFilename, const char *fragmentFilename) {
loadFromFile(vertexFilename, fragmentFilename);
}
Shader::~Shader() {
glDeleteShader(m_vertexShader);
glDeleteShader(m_fragmentShader);
glDeleteProgram(m_program);
}
void Shader::loadFromFile(const char *vertexFilename, const char *fragmentFilename) {
compileShader(GL_VERTEX_SHADER, m_vertexShader, vertexFilename);
compileShader(GL_FRAGMENT_SHADER, m_fragmentShader, fragmentFilename);
m_program = glCreateProgram();
glAttachShader(m_program, m_vertexShader);
glAttachShader(m_program, m_fragmentShader);
glLinkProgram(m_program);
GLint linkOK = GL_FALSE;
glGetProgramiv(m_program, GL_LINK_STATUS, &linkOK);
if(!linkOK){
GLint errorSize = 0;
glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &errorSize);
char *errorMsg = new char[errorSize + 1];
glGetProgramInfoLog(m_program, errorSize, &errorSize, errorMsg);
errorMsg[errorSize] = '\0';
std::string error = std::string(errorMsg);
delete[] errorMsg;
glDeleteProgram(m_program);
throw EXCEPTION("Program", m_program, "link failed:", error);
}
}
void Shader::compileShader(GLenum type, GLuint &shader, const char *filename) {
shader = glCreateShader(type);
std::ifstream file(filename);
if(!file) {
glDeleteShader(type);
throw EXCEPTION("Failed to open", filename);
}
std::string line;
std::string sourceCode;
while(getline(file, line)) sourceCode += line + '\n';
file.close();
const GLchar *sourceCodeString = sourceCode.c_str();
glShaderSource(shader, 1, &sourceCodeString, NULL);
glCompileShader(shader);
GLint compileOK = GL_FALSE;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileOK);
if(!compileOK) {
GLint errorSize = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &errorSize);
char *errorMsg = new char[errorSize + 1];
glGetShaderInfoLog(shader, errorSize, &errorSize, errorMsg);
errorMsg[errorSize] = '\0';
std::string error = std::string(errorMsg);
delete[] errorMsg;
glDeleteShader(shader);
throw EXCEPTION("Shader", filename, "compilation failed:", error);
}
}
GLint Shader::attrib(const char *attribName) {
GLint attrib = glGetAttribLocation(m_program, attribName);
if(attrib == -1) {
throw EXCEPTION("Could not bind attribute:", attribName);
}
return attrib;
}
GLint Shader::uniform(const char *uniformName) {
GLint uniform = glGetUniformLocation(m_program, uniformName);
if(uniform == -1) {
throw EXCEPTION("Could not bind uniform:", uniformName);
}
return uniform;
}
void Shader::enableVertexAttribArray(const char *attribName) {
glEnableVertexAttribArray(attrib(attribName));
}
void Shader::disableVertexAttribArray(const char *attribName) {
glDisableVertexAttribArray(attrib(attribName));
}
void Shader::bind(const Shader *shader) {
if(shader) {
glUseProgram(shader->m_program);
} else {
glUseProgram(0);
}
}

45
source/main.cpp Normal file
View File

@ -0,0 +1,45 @@
/*
* =====================================================================================
*
* Filename: main.cpp
*
* Description:
*
* Version: 1.0
* Created: 13/12/2014 20:49:00
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#include <iostream>
#include "Application.hpp"
#include "Debug.hpp"
#include "Exception.hpp"
int main(int argc, char *argv[]) {
try {
Application &app = Application::getInstance();
app.run();
}
catch(const Exception &err) {
std::cerr << Debug::textColor(Debug::TextColor::Red, true) << "Fatal error " << Debug::textColor() << err.what() << std::endl;
return 1;
}
catch(const std::exception &e) {
std::cerr << Debug::textColor(Debug::TextColor::Red, true) << "Exception caught: " << Debug::textColor(0, true) << e.what() << Debug::textColor() << std::endl;
return 1;
}
catch(...) {
std::cerr << "Fatal error: Unknown error." << std::endl;
return 1;
}
return 0;
}

View File

@ -0,0 +1,26 @@
/*
* =====================================================================================
*
* Filename: ApplicationState.cpp
*
* Description:
*
* Version: 1.0
* Created: 14/12/2014 13:50:04
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#include "ApplicationState.hpp"
ApplicationState::ApplicationState() {
}
ApplicationState::~ApplicationState() {
}

View File

@ -0,0 +1,84 @@
/*
* =====================================================================================
*
* Filename: GameState.cpp
*
* Description:
*
* Version: 1.0
* Created: 15/12/2014 03:51:55
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#define GLM_FORCE_RADIANS
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "GameState.hpp"
GameState::GameState() {
m_shader.loadFromFile("shaders/game.v.glsl", "shaders/game.f.glsl");
glGenBuffers(1, &m_vbo);
GLfloat vertices[2 * 4] = {
0.0, 1.0,
1.0, 0.0,
0.0, -1.0,
-1.0, 0.0
};
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
Shader::bind(&m_shader);
glm::mat4 projectionMatrix = glm::perspective(80.0f, 1.0f, 0.1f, 1000.0f);
glUniformMatrix4fv(m_shader.uniform("u_projectionMatrix"), 1, GL_FALSE, glm::value_ptr(projectionMatrix));
glm::mat4 viewMatrix = glm::lookAt(glm::vec3(0.0f, 1.0f, 1.0f),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f));
glUniformMatrix4fv(m_shader.uniform("u_viewMatrix"), 1, GL_FALSE, glm::value_ptr(viewMatrix));
Shader::bind(nullptr);
}
GameState::~GameState() {
glDeleteBuffers(1, &m_vbo);
}
void GameState::update() {
}
void GameState::draw() {
Shader::bind(&m_shader);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glVertexAttribPointer(m_shader.attrib("coord2d"), 2, GL_FLOAT, GL_FALSE, 0, 0);
m_shader.enableVertexAttribArray("coord2d");
GLubyte indices[6] = {
0, 1, 2,
2, 3, 0
};
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);
m_shader.disableVertexAttribArray("coord2d");
glBindBuffer(GL_ARRAY_BUFFER, 0);
Shader::bind(nullptr);
}

View File

@ -0,0 +1,85 @@
/*
* =====================================================================================
*
* Filename: GameClock.cpp
*
* Description:
*
* Version: 1.0
* Created: 14/12/2014 13:42:26
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#include "Application.hpp"
#include "GameClock.hpp"
sf::Clock GameClock::clock;
u32 GameClock::ticks = 0;
GameClock::GameClock() {
m_lastFrameDate = 0;
m_lag = 0;
m_timeDropped = 0;
m_now = 0;
m_lastFrameDuration = 0;
m_timestep = 6;
m_numUpdates = 0;
}
GameClock::~GameClock() {
}
u32 GameClock::getTicks(bool realTime) {
if(realTime) {
return clock.getElapsedTime().asMilliseconds();
} else {
return ticks;
}
}
void GameClock::measureLastFrameDuration() {
m_now = getTicks(true) - m_timeDropped;
m_lastFrameDuration = m_now - m_lastFrameDate;
m_lastFrameDate = m_now;
m_lag += m_lastFrameDuration;
if(m_lag >= 200) {
m_timeDropped += m_lag - m_timestep;
m_lag = m_timestep;
m_lastFrameDate = getTicks(true) - m_timeDropped;
}
}
void GameClock::updateGame(std::function<void(void)> updateFunc) {
m_numUpdates = 0;
while(m_lag >= m_timestep && m_numUpdates < 10 && Application::getInstance().window().isOpen()) {
ticks += m_timestep;
updateFunc();
m_lag -= m_timestep;
m_numUpdates++;
}
}
void GameClock::drawGame(std::function<void(void)> drawFunc) {
if(m_numUpdates > 0) {
drawFunc();
}
m_lastFrameDuration = getTicks(true) - m_timeDropped - m_lastFrameDate;
if(m_lastFrameDuration < m_timestep) {
sf::sleep(sf::milliseconds(m_timestep - m_lastFrameDuration));
}
m_now = 0;
m_lastFrameDuration = 0;
}