Some classes
This commit is contained in:
parent
b1a5bf2fe4
commit
4c0a3d37d7
|
@ -1,4 +1,5 @@
|
|||
#include "Application.h"
|
||||
#include "util/Log.h"
|
||||
|
||||
Application::Application()
|
||||
{
|
||||
|
@ -14,7 +15,6 @@ void Application::Initialize()
|
|||
{
|
||||
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());
|
||||
return;
|
||||
}
|
||||
|
@ -37,13 +37,13 @@ void Application::Initialize()
|
|||
|
||||
// Set GL Attributes
|
||||
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_MINOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 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());
|
||||
return;
|
||||
|
@ -59,20 +59,27 @@ void Application::Initialize()
|
|||
void Application::Run()
|
||||
{
|
||||
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)
|
||||
{
|
||||
// Close button is pressed
|
||||
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
|
||||
glClearColor(0.39f, 0.58f, 0.93f, 1.f);
|
||||
|
||||
|
@ -83,17 +90,22 @@ void Application::Run()
|
|||
SDL_GL_SwapWindow(m_window);
|
||||
}
|
||||
|
||||
//Destroy window
|
||||
// After loop exits
|
||||
|
||||
// Destroy window
|
||||
SDL_DestroyWindow(m_window);
|
||||
m_window = NULL;
|
||||
|
||||
//Quit SDL subsystems
|
||||
// Destroy context
|
||||
SDL_GL_DeleteContext(m_glContext);
|
||||
|
||||
// Quit SDL subsystems
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
void Application::Update(GLfloat dtime)
|
||||
{
|
||||
|
||||
log_info(std::to_string(dtime));
|
||||
}
|
||||
|
||||
void Application::Render()
|
||||
|
|
|
@ -1,17 +1,27 @@
|
|||
#ifndef __APPLICATION_H__
|
||||
#define __APPLICATION_H__
|
||||
#include "Common.h"
|
||||
#include "util/Common.h"
|
||||
#include "util/Singleton.h"
|
||||
|
||||
class Application
|
||||
class Application : public Singleton<Application>
|
||||
{
|
||||
public:
|
||||
Application();
|
||||
~Application();
|
||||
|
||||
void Initialize();
|
||||
void Exit() { m_run = false; }
|
||||
|
||||
friend class Singleton<Application>;
|
||||
private:
|
||||
SDL_Window* m_window;
|
||||
SDL_Event m_event;
|
||||
SDL_GLContext m_glContext;
|
||||
|
||||
GLuint now_;
|
||||
GLuint last_;
|
||||
double deltaTime_;
|
||||
|
||||
bool m_run;
|
||||
|
||||
void Run();
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
Application app;
|
||||
app.Initialize();
|
||||
Application::getInstance().Initialize();
|
||||
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 <map>
|
||||
|
||||
#include "util/Math3D.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#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