Some classes

This commit is contained in:
Evert Prants 2018-04-14 09:53:15 +03:00
parent b1a5bf2fe4
commit 4c0a3d37d7
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
9 changed files with 358 additions and 15 deletions

View File

@ -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()

View File

@ -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();

View File

@ -2,7 +2,6 @@
int main(int argc, char const *argv[])
{
Application app;
app.Initialize();
Application::getInstance().Initialize();
return 0;
}

200
src/Shader.cpp Normal file
View File

@ -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);
}

45
src/Shader.h Normal file
View File

@ -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__

View File

@ -13,6 +13,8 @@
#include <vector>
#include <map>
#include "util/Math3D.h"
using namespace std;
#endif // __COMMON_H__

31
src/util/Log.h Normal file
View File

@ -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__

12
src/util/Math3D.h Normal file
View File

@ -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__

32
src/util/Singleton.h Normal file
View File

@ -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__