From 78dc21fee8e80a28bf06b6e0c2ac33c0653e538d Mon Sep 17 00:00:00 2001 From: MrDev023 Date: Sun, 31 Jul 2016 15:49:39 +0200 Subject: [PATCH] Add EulerAngles to Quaternion and Shaders System --- CMakeLists.txt | 2 + res/shaders/test.frag | 6 ++ res/shaders/test.vert | 6 ++ a.ogg => res/sounds/a.ogg | Bin a.wav => res/sounds/a.wav | Bin src/audio.cpp | 5 +- src/audio.h | 2 +- src/main.cpp | 16 ++-- src/math.cpp | 4 - src/math.h | 3 +- src/matrix4f.cpp | 1 + src/quaternion.cpp | 65 ++++++++++---- src/renderer.h | 38 +++++++++ src/shader.cpp | 174 ++++++++++++++++++++++++++++++++++++++ src/window.cpp | 1 - 15 files changed, 291 insertions(+), 32 deletions(-) create mode 100644 res/shaders/test.frag create mode 100644 res/shaders/test.vert rename a.ogg => res/sounds/a.ogg (100%) rename a.wav => res/sounds/a.wav (100%) create mode 100644 src/renderer.h create mode 100644 src/shader.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f9b504..b848253 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,7 @@ #require opengl,glew,glut,glu,al,alc,sndfile library +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + cmake_minimum_required(VERSION 2.6) cmake_policy(SET CMP0015 NEW) diff --git a/res/shaders/test.frag b/res/shaders/test.frag new file mode 100644 index 0000000..a979352 --- /dev/null +++ b/res/shaders/test.frag @@ -0,0 +1,6 @@ +uniform float a; + +void main(void){ + if(a >= 0)gl_FragColor = vec4(a,0,0,1); + else gl_FragColor = vec4(0,-a,0,1); +} \ No newline at end of file diff --git a/res/shaders/test.vert b/res/shaders/test.vert new file mode 100644 index 0000000..d2e96d4 --- /dev/null +++ b/res/shaders/test.vert @@ -0,0 +1,6 @@ + + +void main(void){ + gl_FrontColor = gl_Color; + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; +} \ No newline at end of file diff --git a/a.ogg b/res/sounds/a.ogg similarity index 100% rename from a.ogg rename to res/sounds/a.ogg diff --git a/a.wav b/res/sounds/a.wav similarity index 100% rename from a.wav rename to res/sounds/a.wav diff --git a/src/audio.cpp b/src/audio.cpp index 2981b06..2136aa9 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -3,8 +3,11 @@ ALCdevice* Audio::device; ALCcontext* Audio::context; -ALuint Audio::loadSound(const std::string Filename){ +ALuint Audio::loadSound(std::string Filename){ // Ouverture du fichier audio avec libsndfile + std::string* path = new std::string("res/sounds/"); + Filename = *path + Filename; + delete path; SF_INFO FileInfos; SNDFILE* File = sf_open(Filename.c_str(), SFM_READ, &FileInfos); if (File == NULL){ diff --git a/src/audio.h b/src/audio.h index 6245e08..614ac95 100644 --- a/src/audio.h +++ b/src/audio.h @@ -15,7 +15,7 @@ class Audio{ public: static void initOpenAL(); static void destroyOpenAL(); - static ALuint loadSound(const std::string); + static ALuint loadSound(std::string); static ALuint createSource(ALuint*); static ALuint createSource(const std::string); static void destroySound(ALuint*); diff --git a/src/main.cpp b/src/main.cpp index bc27acb..4fe05cf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,11 +1,10 @@ #include "window.h" #include "audio.h" +#include "renderer.h" #include #include -//43,2ko - void event(SDL_Event e){ } @@ -13,24 +12,29 @@ void event(SDL_Event e){ int main(int argc, char** argv){ Window::initWindow(800,600,"Test"); Audio::initOpenAL(); + GLuint s = Shader::createShader("test.vert","test.frag"); + float i = 0; + Shader::bindShader(&s); while(!Window::closeRequested){//main loop - + Shader::setUniform(&s,"a",cos(i)); Window::pollEvent(&event); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); - glBegin(GL_POINTS); + glBegin(GL_QUADS); glVertex2f(-1,-1); glVertex2f(-1,1); - glVertex2f(1,-1); + glVertex2f(1,1); glVertex2f(1,-1); glEnd(); Window::displayUpdate(); - + i+=1/5000.0f; } + Shader::destroyShader(&s); Audio::destroyOpenAL(); Window::destroyWindow(); + return 0; } diff --git a/src/math.cpp b/src/math.cpp index bac9bb9..1c96499 100644 --- a/src/math.cpp +++ b/src/math.cpp @@ -40,10 +40,6 @@ int norm(float v){ return (v>=0)?1:-1; } -float abs(float a){ - return (a<0)?-a:a; -} - float nearest(float a, float b, float v){ float absA = abs(a); float absB = abs(b); diff --git a/src/math.h b/src/math.h index c3c55ad..a6eb063 100644 --- a/src/math.h +++ b/src/math.h @@ -3,6 +3,7 @@ #include #include +#include extern const float PI; float lerp(float,float,float); @@ -15,7 +16,6 @@ float max(float,float); float toRadians(float); float toDegrees(float); int norm(float); -float abs(float); float nearest(float,float,float); class Vector4f; @@ -201,6 +201,7 @@ class Quaternion{ Matrix4f ToMatrix(); Quaternion NLerp(Quaternion,float,bool); Quaternion SLerp(Quaternion,float,bool); + Vector3f EulerAngles(); Vector3f GetForward(); Vector3f GetBackward(); Vector3f GetRight(); diff --git a/src/matrix4f.cpp b/src/matrix4f.cpp index c6595bd..b1554ee 100644 --- a/src/matrix4f.cpp +++ b/src/matrix4f.cpp @@ -220,3 +220,4 @@ float* Matrix4f::GetComponents(){ } return result; } + diff --git a/src/quaternion.cpp b/src/quaternion.cpp index 4bf4aa8..4c40d26 100644 --- a/src/quaternion.cpp +++ b/src/quaternion.cpp @@ -24,8 +24,8 @@ Quaternion::Quaternion(float x, float y, float z, float w){ } Quaternion::Quaternion(Vector3f axis,float angle){ - float s = (float) sin(angle / 2); - float c = (float) cos(angle / 2); + float s = (float) sin(angle / 2.0); + float c = (float) cos(angle / 2.0); this->x = axis.x * s; this->y = axis.y * s; @@ -44,22 +44,19 @@ Quaternion::Quaternion(const Quaternion& q,Vector3f axis,float angle){ } Quaternion::Quaternion(Vector3f euler){ - float c1 = (float) cos(euler.x / 2); - float s1 = (float) sin(euler.x / 2); - - float c2 = (float) cos(euler.y / 2); - float s2 = (float) sin(euler.y / 2); - - float c3 = (float) cos(euler.z / 2); - float s3 = (float) sin(euler.z / 2); - - float c1c2 = c1 * c2; - float s1s2 = s1 * s2; - - x = c1c2 * s3 + s1s2 * c3; - y = s1 * c2 * c3 + c1 * s2 * s3; - z = c1 * s2 * c3 - s1 * c2 * s3; - w = c1c2 * c3 - s1s2 * s3; + double h = euler.y * PI/360.0f; + double a = euler.z * PI/360.0f; + double b = euler.x * PI/360.0f; + double c1 = cos(h); + double c2 = cos(a); + double c3 = cos(b); + double s1 = sin(h); + double s2 = sin(a); + double s3 = sin(b); + w = round((c1*c2*c3 - s1*s2*s3)*100000.0)/100000.0; + x = round((s1*s2*c3 + c1*c2*s3)*100000.0)/100000.0; + y = round((s1*c2*c3 + c1*s2*s3)*100000.0)/100000.0; + z = round((c1*s2*c3 - s1*c2*s3)*100000.0)/100000.0; } Quaternion::Quaternion(Matrix4f rot){ @@ -276,3 +273,35 @@ Vector3f Quaternion::GetUp(){ Vector3f Quaternion::GetDown(){ return Vector3f(0, -1, 0).Rotate(*this); } + +Vector3f Quaternion::EulerAngles(){ + Vector3f euler = Vector3f(); + double qw = w; + double qx = x; + double qy = y; + double qz = z; + double qw2 = qw*qw; + double qx2 = qx*qx; + double qy2 = qy*qy; + double qz2 = qz*qz; + double test= qx*qy + qz*qw; + if (test > 0.499) { + euler.y = 360/PI*atan2(qx,qw); + euler.z = 90; + euler.x = 0; + return euler; + } + if (test < -0.499) { + euler.y = -360/PI*atan2(qx,qw); + euler.z = -90; + euler.x = 0; + return euler; + } + double h = atan2(2*qy*qw-2*qx*qz,1-2*qy2-2*qz2); + double a = asin(2*qx*qy+2*qz*qw); + double b = atan2(2*qx*qw-2*qy*qz,1-2*qx2-2*qz2); + euler.y = round(h*180/PI); + euler.z = round(a*180/PI); + euler.x = round(b*180/PI); + return euler; +} diff --git a/src/renderer.h b/src/renderer.h new file mode 100644 index 0000000..9d44877 --- /dev/null +++ b/src/renderer.h @@ -0,0 +1,38 @@ +#ifndef RENDERER_H +#define RENDERER_H + +#include "math.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +bool fileExists(const std::string&); + +class Shader{ + public: + static std::string LoadSource(const char*); + static GLuint createShader(const char*,const char*); + static void destroyShader(GLuint*); + static void bindShader(GLuint*); + static void unbindShader(); + static void setUniform(GLuint*,const char*,float); + static void setUniform(GLuint*,const char*,Vector3f); + static void setUniform(GLuint*,const char*,Vector2f); + static void setUniform(GLuint*,const char*,Vector4f); + static void setUniform(GLuint*,const char*,Quaternion); + static void setUniform(GLuint*,const char*,Matrix4f); +}; + +#endif \ No newline at end of file diff --git a/src/shader.cpp b/src/shader.cpp new file mode 100644 index 0000000..9d1efd8 --- /dev/null +++ b/src/shader.cpp @@ -0,0 +1,174 @@ +#include "renderer.h" + +std::string Shader::LoadSource(const char* filename){ + std::string file(""); + std::ifstream in_stream; + std::string line; + std::vector v; + + std::string* ff = new std::string(filename); + std::string* path = new std::string("res/shaders/"); + *ff = *path + *ff; + in_stream.open(ff->c_str()); + delete ff; + delete path; + + int l = 1; + for( std::string line; getline( in_stream, line ); ) + { + if(line.substr(0,8) != "#include"){ + file += line + "\n"; + }else{ + std::string str = line; + std::istringstream buf(str); + std::istream_iterator beg(buf), end; + + std::vector tokens(beg, end); // done! + if(tokens.size() == 2){ + std::string fileName = tokens.at(1).substr(1,tokens.at(1).size() - 2); + bool a = fileExists(fileName); + if (a){ + if(std::find(v.begin(), v.end(), fileName.c_str()) == v.end()){ + file = file + std::string(Shader::LoadSource(fileName.c_str())); + v.push_back(fileName.c_str()); + } + }else{printf("Syntax incorrect #%d : include file '%s' not exist",l,fileName.c_str());} + }else{ + printf("Syntax incorrect #%d : expected identifier after ‘include’ token",l); + } + } + l++; + } + in_stream.close(); + return file; +} + +void Shader::destroyShader(GLuint* s){ + glDeleteProgram(*s); +} + +GLuint Shader::createShader(const char* vertName,const char* fragName){ + std::string vert = Shader::LoadSource(vertName); + std::string frag = Shader::LoadSource(fragName); + GLuint vertShader; + GLuint fragShader; + + vertShader = glCreateShader(GL_VERTEX_SHADER); + fragShader = glCreateShader(GL_FRAGMENT_SHADER); + if(vertShader == 0 || fragShader == 0){ + printf("Shader not created !"); + if(vertShader != 0)glDeleteShader(vertShader); + if(fragShader != 0)glDeleteShader(fragShader); + return 0; + } + + const char* a = ((const char*)vert.c_str()); + const char* b = ((const char*)frag.c_str()); + + glShaderSource(vertShader,1,(const GLchar**)&a,NULL); + glShaderSource(fragShader,1,(const GLchar**)&b,NULL); + + glCompileShader(vertShader); + GLint compile_status = GL_TRUE; + glGetShaderiv(vertShader, GL_COMPILE_STATUS, &compile_status); + if(compile_status != GL_TRUE){ + char *log = NULL; + GLsizei logsize = 0; + glGetShaderiv(vertShader, GL_INFO_LOG_LENGTH, &logsize); + log = (char*)malloc(logsize + 1); + if(log == NULL) + { + fprintf(stderr, "impossible d'allouer de la memoire !\n"); + return 0; + } + memset(log, '\0', logsize + 1); + glGetShaderInfoLog(vertShader, logsize, &logsize, log); + fprintf(stderr, "impossible de compiler le shader '%s' :\n%s",vertName,log); + free(log); + glDeleteShader(vertShader); + glDeleteShader(fragShader); + return 0; + } + glCompileShader(fragShader); + compile_status = GL_TRUE; + glGetShaderiv(fragShader, GL_COMPILE_STATUS, &compile_status); + if(compile_status != GL_TRUE){ + char *log = NULL; + GLsizei logsize = 0; + glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logsize); + log = (char*)malloc(logsize + 1); + if(log == NULL) + { + fprintf(stderr, "impossible d'allouer de la memoire !\n"); + return 0; + } + memset(log, '\0', logsize + 1); + glGetShaderInfoLog(fragShader, logsize, &logsize, log); + fprintf(stderr, "impossible de compiler le shader '%s' :\n%s",fragName,log); + free(log); + glDeleteShader(vertShader); + glDeleteShader(fragShader); + return 0; + } + GLuint program; + program = glCreateProgram(); + glAttachShader(program,vertShader); + glAttachShader(program,fragShader); + glLinkProgram(program); + GLint linked; + glGetProgramiv(program, GL_LINK_STATUS, &linked); + if (!linked) + { + printf("Program not linked !"); + glDeleteShader(vertShader); + glDeleteShader(fragShader); + glDeleteProgram(program); + return 0; + } + glValidateProgram(program); + glDeleteShader(vertShader); + glDeleteShader(fragShader); + return program; +} + +void Shader::bindShader(GLuint* s){ + glUseProgram(*s); +} + +void Shader::unbindShader(){ + glUseProgram(0); +} + +bool fileExists(const std::string& filename) +{ + struct stat buf; + if (stat(filename.c_str(), &buf) != -1) + { + return true; + } + return false; +} + +void Shader::setUniform(GLuint* program,const char* varName,float value){ + glUniform1f(glGetUniformLocation(*program,varName),value); +} + +void Shader::setUniform(GLuint* program,const char* varName,Vector2f v){ + glUniform2f(glGetUniformLocation(*program,varName),v.x,v.y); +} + +void Shader::setUniform(GLuint* program,const char* varName,Vector3f v){ + glUniform3f(glGetUniformLocation(*program,varName),v.x,v.y,v.z); +} + +void Shader::setUniform(GLuint* program,const char* varName,Vector4f v){ + glUniform4f(glGetUniformLocation(*program,varName),v.x,v.y,v.z,v.w); +} + +void Shader::setUniform(GLuint* program,const char* varName,Quaternion v){ + glUniform4f(glGetUniformLocation(*program,varName),v.x,v.y,v.z,v.w); +} + +void Shader::setUniform(GLuint* program,const char* varName,Matrix4f ma){ + glUniformMatrix4fv(glGetUniformLocation(*program,varName),01,0,ma.GetComponents()); +} \ No newline at end of file diff --git a/src/window.cpp b/src/window.cpp index 96082d1..d56acd6 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -49,7 +49,6 @@ void Window::destroyWindow(){ SDL_GL_DeleteContext ( context ) ; SDL_DestroyWindow(pWindow); SDL_Quit(); - exit(0); } void Window::displayUpdate(){