Some classes
This commit is contained in:
parent
b1a5bf2fe4
commit
4c0a3d37d7
|
@ -1,4 +1,5 @@
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
#include "util/Log.h"
|
||||||
|
|
||||||
Application::Application()
|
Application::Application()
|
||||||
{
|
{
|
||||||
|
@ -14,7 +15,6 @@ void Application::Initialize()
|
||||||
{
|
{
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||||
{
|
{
|
||||||
std::cout << "Failed to init SDL\n";
|
|
||||||
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
|
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -37,13 +37,13 @@ void Application::Initialize()
|
||||||
|
|
||||||
// Set GL Attributes
|
// Set GL Attributes
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
||||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||||
|
|
||||||
SDL_GLContext glContext = SDL_GL_CreateContext(m_window);
|
m_glContext = SDL_GL_CreateContext(m_window);
|
||||||
|
|
||||||
if(glContext == NULL)
|
if(m_glContext == NULL)
|
||||||
{
|
{
|
||||||
printf("OpenGL context could not be created! SDL Error: %s\n", SDL_GetError());
|
printf("OpenGL context could not be created! SDL Error: %s\n", SDL_GetError());
|
||||||
return;
|
return;
|
||||||
|
@ -59,20 +59,27 @@ void Application::Initialize()
|
||||||
void Application::Run()
|
void Application::Run()
|
||||||
{
|
{
|
||||||
m_run = true;
|
m_run = true;
|
||||||
|
now_ = SDL_GetPerformanceCounter();
|
||||||
|
last_ = 0;
|
||||||
|
|
||||||
while (m_run)
|
while(m_run)
|
||||||
{
|
{
|
||||||
|
last_ = now_;
|
||||||
|
now_ = SDL_GetPerformanceCounter();
|
||||||
while(SDL_PollEvent(&m_event) != 0)
|
while(SDL_PollEvent(&m_event) != 0)
|
||||||
{
|
{
|
||||||
// Close button is pressed
|
// Close button is pressed
|
||||||
if(m_event.type == SDL_QUIT)
|
if(m_event.type == SDL_QUIT)
|
||||||
{
|
{
|
||||||
m_run = false;
|
Exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Render();
|
deltaTime_ = ((now_ - last_) / (double)SDL_GetPerformanceFrequency());
|
||||||
|
|
||||||
|
Update(deltaTime_);
|
||||||
|
Render();
|
||||||
|
|
||||||
// Set background color as cornflower blue
|
// Set background color as cornflower blue
|
||||||
glClearColor(0.39f, 0.58f, 0.93f, 1.f);
|
glClearColor(0.39f, 0.58f, 0.93f, 1.f);
|
||||||
|
|
||||||
|
@ -83,17 +90,22 @@ void Application::Run()
|
||||||
SDL_GL_SwapWindow(m_window);
|
SDL_GL_SwapWindow(m_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Destroy window
|
// After loop exits
|
||||||
|
|
||||||
|
// Destroy window
|
||||||
SDL_DestroyWindow(m_window);
|
SDL_DestroyWindow(m_window);
|
||||||
m_window = NULL;
|
m_window = NULL;
|
||||||
|
|
||||||
//Quit SDL subsystems
|
// Destroy context
|
||||||
|
SDL_GL_DeleteContext(m_glContext);
|
||||||
|
|
||||||
|
// Quit SDL subsystems
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::Update(GLfloat dtime)
|
void Application::Update(GLfloat dtime)
|
||||||
{
|
{
|
||||||
|
log_info(std::to_string(dtime));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::Render()
|
void Application::Render()
|
||||||
|
|
|
@ -1,17 +1,27 @@
|
||||||
#ifndef __APPLICATION_H__
|
#ifndef __APPLICATION_H__
|
||||||
#define __APPLICATION_H__
|
#define __APPLICATION_H__
|
||||||
#include "Common.h"
|
#include "util/Common.h"
|
||||||
|
#include "util/Singleton.h"
|
||||||
|
|
||||||
class Application
|
class Application : public Singleton<Application>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Application();
|
Application();
|
||||||
~Application();
|
~Application();
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
void Exit() { m_run = false; }
|
||||||
|
|
||||||
|
friend class Singleton<Application>;
|
||||||
private:
|
private:
|
||||||
SDL_Window* m_window;
|
SDL_Window* m_window;
|
||||||
SDL_Event m_event;
|
SDL_Event m_event;
|
||||||
|
SDL_GLContext m_glContext;
|
||||||
|
|
||||||
|
GLuint now_;
|
||||||
|
GLuint last_;
|
||||||
|
double deltaTime_;
|
||||||
|
|
||||||
bool m_run;
|
bool m_run;
|
||||||
|
|
||||||
void Run();
|
void Run();
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
int main(int argc, char const *argv[])
|
int main(int argc, char const *argv[])
|
||||||
{
|
{
|
||||||
Application app;
|
Application::getInstance().Initialize();
|
||||||
app.Initialize();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,200 @@
|
||||||
|
#include "Shader.h"
|
||||||
|
|
||||||
|
/** Compile a shader from file */
|
||||||
|
void Shader::compileShader(const string& filePath, GLuint& id)
|
||||||
|
{
|
||||||
|
// Load shader file
|
||||||
|
std::ifstream shaderFile(filePath);
|
||||||
|
if(shaderFile.fail())
|
||||||
|
{
|
||||||
|
fatalError("Failed to open file @"+filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
string fileContents = "";
|
||||||
|
string line;
|
||||||
|
|
||||||
|
while(std::getline(shaderFile, line))
|
||||||
|
{
|
||||||
|
fileContents += line + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
shaderFile.close();
|
||||||
|
|
||||||
|
const char* contentsPointer = fileContents.c_str();
|
||||||
|
|
||||||
|
// Create the shader with the contents of the file
|
||||||
|
glShaderSource(id, 1, &contentsPointer, nullptr);
|
||||||
|
glCompileShader(id);
|
||||||
|
|
||||||
|
GLint isCompiled = 0;
|
||||||
|
glGetShaderiv(id, GL_COMPILE_STATUS, &isCompiled);
|
||||||
|
if(isCompiled == GL_FALSE)
|
||||||
|
{
|
||||||
|
GLint maxLength = 0;
|
||||||
|
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &maxLength);
|
||||||
|
|
||||||
|
// The maxLength includes the NULL character
|
||||||
|
std::vector<GLchar> errorLog(maxLength);
|
||||||
|
glGetShaderInfoLog(id, maxLength, &maxLength, &errorLog[0]);
|
||||||
|
|
||||||
|
glDeleteShader(id);
|
||||||
|
|
||||||
|
// Exit with failure.
|
||||||
|
std::printf("%s\n", &(errorLog[0]));
|
||||||
|
fatalError("Shader " + filePath + " failed to compile");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create new shader from vertex and fragment files */
|
||||||
|
Shader& Shader::createShader(const string& vertexShaderFilePath, const string& fragmentShaderFilePath)
|
||||||
|
{
|
||||||
|
Shader* shader = new Shader();
|
||||||
|
|
||||||
|
shader->m_programID = glCreateProgram();
|
||||||
|
shader->m_vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
if(shader->m_vertexShaderID == 0)
|
||||||
|
{
|
||||||
|
fatalError("Vertex shader failed to be created!");
|
||||||
|
}
|
||||||
|
|
||||||
|
shader->m_fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
if(shader->m_fragmentShaderID == 0)
|
||||||
|
{
|
||||||
|
fatalError("Fragment shader failed to be created!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader::compileShader(vertexShaderFilePath, shader->m_vertexShaderID);
|
||||||
|
Shader::compileShader(fragmentShaderFilePath, shader->m_fragmentShaderID);
|
||||||
|
|
||||||
|
return *shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get uniform location */
|
||||||
|
GLuint Shader::getUniformLocation(const string& uniformName)
|
||||||
|
{
|
||||||
|
auto it = m_uniforms.find(uniformName);
|
||||||
|
if (it == m_uniforms.end())
|
||||||
|
{
|
||||||
|
// Get uniform location
|
||||||
|
GLint r = glGetUniformLocation(m_programID, uniformName.c_str());
|
||||||
|
if ( r == GL_INVALID_OPERATION || r < 0 )
|
||||||
|
log_warn("Uniform " + uniformName + " doesn't exist in program.");
|
||||||
|
|
||||||
|
// Add it to the cache
|
||||||
|
m_uniforms[uniformName] = r;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Link the shaders together */
|
||||||
|
void Shader::linkShaders()
|
||||||
|
{
|
||||||
|
// Attach our shaders to our program
|
||||||
|
glAttachShader(m_programID, m_vertexShaderID);
|
||||||
|
glAttachShader(m_programID, m_fragmentShaderID);
|
||||||
|
|
||||||
|
// Link our program
|
||||||
|
glLinkProgram(m_programID);
|
||||||
|
|
||||||
|
// Note the different functions here: glGetProgram* instead of glGetShader*.
|
||||||
|
GLint isLinked = 0;
|
||||||
|
glGetProgramiv(m_programID, GL_LINK_STATUS, (int *)&isLinked);
|
||||||
|
if(isLinked == GL_FALSE)
|
||||||
|
{
|
||||||
|
GLint maxLength = 0;
|
||||||
|
glGetProgramiv(m_programID, GL_INFO_LOG_LENGTH, &maxLength);
|
||||||
|
|
||||||
|
// The maxLength includes the NULL character
|
||||||
|
std::vector<GLchar> infoLog(maxLength);
|
||||||
|
glGetProgramInfoLog(m_programID, maxLength, &maxLength, &infoLog[0]);
|
||||||
|
|
||||||
|
// We don't need the program anymore.
|
||||||
|
glDeleteProgram(m_programID);
|
||||||
|
|
||||||
|
// Don't leak shaders either.
|
||||||
|
glDeleteShader(m_vertexShaderID);
|
||||||
|
glDeleteShader(m_fragmentShaderID);
|
||||||
|
|
||||||
|
fatalError("Shader linking failed!");
|
||||||
|
std::printf("%s\n", &(infoLog[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always detach shaders after a successful link.
|
||||||
|
glDetachShader(m_programID, m_vertexShaderID);
|
||||||
|
glDetachShader(m_programID, m_fragmentShaderID);
|
||||||
|
glDeleteShader(m_vertexShaderID);
|
||||||
|
glDeleteShader(m_fragmentShaderID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Bind attribute location */
|
||||||
|
void Shader::addAttribute(const string& attribName)
|
||||||
|
{
|
||||||
|
glBindAttribLocation(m_programID, m_attributes++, attribName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Bind the shader for usage */
|
||||||
|
void Shader::start()
|
||||||
|
{
|
||||||
|
glUseProgram(m_programID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Unbind the shader */
|
||||||
|
void Shader::stop()
|
||||||
|
{
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniform(const string& name, float x, float y, float z)
|
||||||
|
{
|
||||||
|
glUniform3f(getUniformLocation(name), x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniform(const string& name, const vec3& v)
|
||||||
|
{
|
||||||
|
glUniform3fv(getUniformLocation(name), 1, value_ptr(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniform(const string& name, const dvec3& v)
|
||||||
|
{
|
||||||
|
glUniform3dv(getUniformLocation(name), 1, value_ptr(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniform(const string& name, const vec4& v)
|
||||||
|
{
|
||||||
|
glUniform4fv(getUniformLocation(name), 1, value_ptr(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniform(const string& name, const dvec4& v)
|
||||||
|
{
|
||||||
|
glUniform4dv(getUniformLocation(name), 1, value_ptr(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniform(const string& name, const dmat4& m)
|
||||||
|
{
|
||||||
|
glUniformMatrix4dv(getUniformLocation(name), 1, GL_FALSE, value_ptr(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniform(const string& name, const mat4& m)
|
||||||
|
{
|
||||||
|
glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, value_ptr(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniform(const string& name, const mat3& m)
|
||||||
|
{
|
||||||
|
glUniformMatrix3fv(getUniformLocation(name), 1, GL_FALSE, value_ptr(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniform(const string& name, float val)
|
||||||
|
{
|
||||||
|
glUniform1f(getUniformLocation(name), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniform(const string& name, int val)
|
||||||
|
{
|
||||||
|
glUniform1i(getUniformLocation(name), val);
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef __SHADER_H__
|
||||||
|
#define __SHADER_H__
|
||||||
|
#include <fstream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "util/Common.h"
|
||||||
|
#include "util/Log.h"
|
||||||
|
|
||||||
|
class Shader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static Shader& createShader(const string& vertexShaderFilePath, const string& fragmentShaderFilePath);
|
||||||
|
|
||||||
|
void linkShaders();
|
||||||
|
|
||||||
|
void addAttribute(const string& attribName);
|
||||||
|
|
||||||
|
GLuint getUniformLocation(const string& uniformName);
|
||||||
|
|
||||||
|
void setUniform(const string& name, float x, float y, float z);
|
||||||
|
void setUniform(const string& name, const vec3& v);
|
||||||
|
void setUniform(const string& name, const dvec3& v);
|
||||||
|
void setUniform(const string& name, const vec4& v);
|
||||||
|
void setUniform(const string& name, const dvec4& v);
|
||||||
|
void setUniform(const string& name, const dmat4& m);
|
||||||
|
void setUniform(const string& name, const mat4& m);
|
||||||
|
void setUniform(const string& name, const mat3& m);
|
||||||
|
void setUniform(const string& name, float val);
|
||||||
|
void setUniform(const string& name, int val);
|
||||||
|
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
private:
|
||||||
|
int m_attributes;
|
||||||
|
|
||||||
|
GLuint m_programID;
|
||||||
|
GLuint m_vertexShaderID;
|
||||||
|
GLuint m_fragmentShaderID;
|
||||||
|
|
||||||
|
map<string, GLint> m_uniforms;
|
||||||
|
|
||||||
|
static void compileShader(const string& filePath, GLuint& id);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __SHADER_H__
|
|
@ -13,6 +13,8 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include "util/Math3D.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#endif // __COMMON_H__
|
#endif // __COMMON_H__
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef __LOG_H__
|
||||||
|
#define __LOG_H__
|
||||||
|
|
||||||
|
#include "Application.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define FPRNT(io,tag,message) fprintf(io, "[%s] %s\n", tag, message.c_str());
|
||||||
|
|
||||||
|
inline void fatalError(const std::string message)
|
||||||
|
{
|
||||||
|
FPRNT(stderr, "FATAL ERROR", message);
|
||||||
|
Application::getInstance().Exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void log_info(const std::string& message)
|
||||||
|
{
|
||||||
|
FPRNT(stdout, "Info", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void log_warn(const std::string& message)
|
||||||
|
{
|
||||||
|
FPRNT(stdout, "Warning", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void log_error(const std::string& message)
|
||||||
|
{
|
||||||
|
FPRNT(stdout, "Error", message);
|
||||||
|
}
|
||||||
|
#endif // __LOG_H__
|
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef __MATH_H__
|
||||||
|
#define __MATH_H__
|
||||||
|
// TODO: Write custom math class
|
||||||
|
// Using GLM for now
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
using namespace glm;
|
||||||
|
|
||||||
|
#endif // __MATH_H__
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef __SINGLETON_H__
|
||||||
|
#define __SINGLETON_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Abstract class for singleton pattern
|
||||||
|
**/
|
||||||
|
template<typename C>
|
||||||
|
class Singleton {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* I think this could be could be set as private without
|
||||||
|
* any harm...
|
||||||
|
* @return The instance of C
|
||||||
|
**/
|
||||||
|
inline static C& getInstance() {
|
||||||
|
// Being declared as static, I will be consistant over the getInstance() calls
|
||||||
|
// and destroyed at the end of the program.
|
||||||
|
static C I;
|
||||||
|
return I;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Prevents construction...
|
||||||
|
Singleton() {}
|
||||||
|
// ...as well as copy construction...
|
||||||
|
Singleton(const C&) {}
|
||||||
|
Singleton& operator=(const C&) {}
|
||||||
|
// ...or premature destruction.
|
||||||
|
virtual ~Singleton() {}
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif // __SINGLETON_H__
|
Loading…
Reference in New Issue