ported the University CGI demo from WINDOWS + GLUT + GLEW + GLU + OpenGL 4 to LINUX WAYLAND + EGL + GLES 2 with minimal cuts

This commit is contained in:
beno
2025-07-03 01:26:25 +02:00
commit 6c125fb35e
85 changed files with 91688 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
#include "GLES_3_1_compatibility.h"
/* fails at link time,
resorting to eglGetProcAddress
#define GL_GLEXT_PROTOTYPES 1
#include <GLES2/gl2ext.h>
*/
#include <EGL/egl.h>
PFNGLGENVERTEXARRAYSOESPROC glGenVertexArraysOES;
PFNGLBINDVERTEXARRAYOESPROC glBindVertexArrayOES;
PFNGLDRAWBUFFERSEXTPROC glDrawBuffersEXT;
void glGenVertexArrays( GLuint n, GLuint *arrays_ptr) {
glGenVertexArraysOES( n, arrays_ptr);
}
void glBindVertexArray( GLuint array_ptr) {
glBindVertexArrayOES( array_ptr);
}
/* https://registry.khronos.org/OpenGL/extensions/OES/OES_framebuffer_object.txt */
void glDrawBuffers( GLsizei n,GLenum *buffers_ptr) {
glDrawBuffersEXT( n, buffers_ptr);
}
void GLES_3_1_compatibility_init(){
glGenVertexArraysOES = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES");
glBindVertexArrayOES = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES");
glDrawBuffersEXT = (PFNGLDRAWBUFFERSEXTPROC)eglGetProcAddress("glDrawBuffersEXT");
}

View File

@@ -0,0 +1,36 @@
#pragma once
#include <GLES2/gl2.h>
/* fails at link time,
resorting to eglGetProcAddress
#define GL_GLEXT_PROTOTYPES 1
*/
#include <GLES2/gl2ext.h>
/* aarch64-linux-gnu/include/math.h already defines it */
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288
#endif
/* GLES2 provides it as an extension */
#ifndef GL_DEPTH24_STENCIL8
#define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES
#endif
#ifndef GL_DEPTH_STENCIL_ATTACHMENT
#define GL_DEPTH_STENCIL_ATTACHMENT GL_DEPTH_STENCIL_OES
#endif
#ifndef GL_DRAW_FRAMEBUFFER
#define GL_DRAW_FRAMEBUFFER GL_DRAW_BUFFER0_EXT
#endif
void glGenVertexArrays( GLuint n, GLuint *arrays_ptr);
void glBindVertexArray( GLuint array_ptr);
void glDrawBuffers( GLsizei n,GLenum *buffers_ptr);
void GLES_3_1_compatibility_init();

9
GL_STUFF/GL_STUFF.cpp Executable file
View File

@@ -0,0 +1,9 @@
// GL_STUFF.cpp : Defines the functions for the static library.
//
#include "framework.h"
// TODO: This is an example of a library function
void fnGLSTUFF()
{
}

View File

@@ -0,0 +1,24 @@
#pragma once
#include "./Curve.hpp"
class Bezier : public Curve {
private:
unsigned int order;
protected:
float evaluateBasisFunction(float at, int number, int order, float intervalLeft, float intervalRight);
public:
Bezier(unsigned int order, vector<glm::vec3> *points, vector<float> *intervals);
glm::vec3 evaluate(float at);
glm::vec3 derivate(float at);
};
class Bezier3Segments : public Bezier {
public:
Bezier3Segments( vector<glm::vec3>* points, vector<float>* intervals);
glm::vec3 evaluate(float at);
glm::vec3 derivate(float at);
float getLeftBound();
float getRightBound();
};

View File

@@ -0,0 +1,22 @@
#pragma once
#include <vector>
#include <glm/glm.hpp>
using namespace std;
class Curve {
protected:
vector<glm::vec3> *controlPoints;
vector<float> *intervalBoundaries;
public:
Curve(vector<glm::vec3> *points, vector<float> *boundaries);
vector<glm::vec3>* getControlPoints();
void setControlPoints(vector<glm::vec3>* points);
vector<float>* getIntervalBoundaries();
void setIntervalBoundaries(vector<float>* boundaries);
virtual float getLeftBound();
virtual float getRightBound();
virtual glm::vec3 evaluate(float at) = 0;
virtual glm::vec3 derivate(float at) = 0;
};

View File

@@ -0,0 +1,35 @@
#pragma once
#include "./Curve.hpp"
enum class CurveIterationMode
{
BASIC,
LENGTH
};
class CurveIterator {
private:
Curve *curve;
unsigned int steps;
CurveIterationMode iterationMode;
float estimatedLength;
int basicStepCounter;
float lengthStepCounter;
float leftBound;
float rightBound;
float lastIncrement;
void resetIterator();
void computeLength();
public:
CurveIterator(Curve *curve, unsigned int steps, CurveIterationMode basicOrLength);
void nextStep();
float getStep();
void setProgress(float at);
glm::vec3 evaluation();
glm::vec3 derivation();
Curve* getCurve();
};

View File

@@ -0,0 +1,35 @@
#pragma once
#include <string>
#include <regex>
#include <iostream>
#include "./Curve.hpp"
#include "Bezier.hpp"
#include "NURBS.hpp"
class CurvesLoader {
static string currentCurveType;
static vector<glm::vec3>* pointsBuffer;
static vector<NURBS*> NURBSes;
static vector<Bezier3Segments*> beziers;
static unsigned int NURBSOrder;
static NURBSType NURBS_TYPE;
static vector<float>* NURBSWeights;
static char lineHeader[128];
static char* res;
static FILE* file;
static std::smatch pieces;
static void beginCurve(string str, std::smatch pieces, std::regex regex);
static NURBS* BasicNURBS();
static NURBS* ClampedNURBS();
static NURBS* CyclicNURBS();
static void closeNURBS();
static void closeBezier();
static void closePendingCurve();
static void parseVertexData(string str);
public:
static bool loadCurves(std::string path, vector<Curve*>& curves);
};

View File

@@ -0,0 +1,21 @@
#pragma once
#include "./Curve.hpp"
enum class HermiteModes {
Basic,
Direct,
Cardinal,
TBC
};
class Hermite : public Curve {
private:
vector<glm::vec3> derivatives;
glm::vec3 evaluateCubic(float t, float t1, float t2, glm::vec3 y1, glm::vec3 y2, glm::vec3 dy1, glm::vec3 dy2);
public:
void computeDerivatives(HermiteModes mode, vector<glm::vec3> auxData);
Hermite(vector<glm::vec3> *points, vector<float> *intervals);
glm::vec3 evaluate(float at);
glm::vec3 derivate(float at);
};

View File

@@ -0,0 +1,28 @@
#pragma once
#include "./Curve.hpp"
enum class NURBSType {
BASIC,
CLAMPED,
CYCLIC
};
class NURBS : public Curve {
private:
unsigned int order;
vector<float>* weights;
vector<unsigned int>* multiplicities;
vector<float>* derivativeBoundaries;
vector<glm::vec3>* derivativePoints;
vector<float>* derivativeWeghts;
glm::vec3 deBoor( float at, int index);
void preliminaryChecks();
public:
NURBS( unsigned int order, vector<glm::vec3>* points, vector<float>* weights, vector<float>* boundaries, vector<unsigned int>* multiplicities);
unsigned int getOrder();
vector<float>* getWeights();
glm::vec3 evaluate(float at);
glm::vec3 derivate(float at);
float getLeftBound();
float getRightBound();
};

View File

@@ -0,0 +1,92 @@
#pragma once
#include <glm/gtc/matrix_transform.hpp>
/*
ON MOBILE, GLES 3.1 WOULD BE REQUIRED (compute shader support)
*/
#include <GL/glew.h>
#include <string>
#include <iostream>
using namespace std;
using namespace glm;
enum SIM_PRECISION {
FINE,
REGULAR,
ROUGH
};
class CRT_Shader {
private:
static bool CRT_FLIP_Y;
string resourceRoot = "C:\\Users\\BoBoBoat\\Desktop\\SCUOLA\\CGI\\GL_STUFF\\GL_STUFF\\SOURCES\\EFFECTS\\CRT_SHADER\\";
const float CRT_PIXEL_LENGTH = 2e-3; //value of 1 gets only red (bad bug)
static const int CRT_PIXEL_SCALE = 1; //they work together
const float CRT_DEPTH = 1e0;
static int CRT_HORIZONTAL_PIXELS;
static int CRT_VERTICAL_PIXELS;
static int CRT_WIDTH;
static int CRT_HEIGHT;
static int PARTICLE_COUNT;
static const int GROUP_COUNT = 1024;
static int PARTICLE_GROUP_COUNT;
static const unsigned int COLOR_CHANNELS = 4;
static SIM_PRECISION resolution;
mat4 orthoMat;
vec3 CS_LTN, CS_RBN, CS_LTF, CS_RBF;
GLuint dt_location;
GLuint compute_prog;
GLuint render_prog;
GLuint render_vao;
GLuint end_position_buffer, start_position_buffer, velocity_buffer, color_buffer, magnets_buffer;
float magx;
float magy;
vec4 attractors[8];
GLuint velocity_tbo, start_position_tbo, end_position_tbo, color_tbo;
CRT_Shader();
vec3 scaleToZOne(vec3 vector);
vec3 crt_emission_angle(int index);
void createRenderShader();
void createComputeShader();
void buffersSetup();
void VAOsSetup();
public:
static void setup(int w, int h, bool flipY, SIM_PRECISION precision) {
CRT_FLIP_Y = flipY;
resolution = precision;
CRT_WIDTH = w;
CRT_HEIGHT = h;
CRT_HORIZONTAL_PIXELS = w / CRT_PIXEL_SCALE;
CRT_VERTICAL_PIXELS = h / CRT_PIXEL_SCALE;
PARTICLE_COUNT = CRT_HORIZONTAL_PIXELS * CRT_VERTICAL_PIXELS;
PARTICLE_GROUP_COUNT = (PARTICLE_COUNT / GROUP_COUNT) + ((PARTICLE_COUNT % GROUP_COUNT) ? 1 : 0);
cout << "HPIX " << CRT_HORIZONTAL_PIXELS << "\n";
cout << "VPIX " << CRT_VERTICAL_PIXELS << "\n";
}
static CRT_Shader& get() {
static CRT_Shader instance;
return instance;
}
void draw(unsigned int ONE_TICK_MS, unsigned int timePassed);
void setMagnet(int index, vec4 positionAndMass);
float getLeftBound();
float getRightBound();
float getBottomBound();
float getTopBound();
/*Copies H_PIXELS * V_PIXELS from FrameBuffer to internal VAO */
void loadColorFromFramebuffer(GLuint FBO);
};

View File

@@ -0,0 +1,18 @@
#ifndef PSEUDOCONTEXT
#define PSEUDOCONTEXT
#include <vector>
class PseudoContext {
protected:
//viewport
int width, height;
int top, left;
public:
PseudoContext(int left, int top, int width, int height);
virtual void draw() = 0;
std::vector<int> getBounds();
};
#endif

View File

@@ -0,0 +1,22 @@
#ifndef REELMANAGER_H
#define REELMANAGER_H
/*
#include <GL/glew.h>
*/
#include <GLES2/gl2.h>
#include <vector>
class ReelManager {
private:
unsigned int TEXTURE_NUM;
unsigned int currentIndex = 0;
GLuint* textures;
GLuint FBO;
public:
ReelManager(unsigned int textureNumber, unsigned int width, unsigned int height);
GLuint getFBO();
void clearTexture();
void nextTexture();
std::vector<GLuint> getTextures();
};
#endif

View File

@@ -0,0 +1,26 @@
#ifndef SCENE_H
#define SCENE_H
/*
#include <GL/glew.h>
*/
#include <GLES2/gl2.h>
#include "PseudoContext.h"
class Scene : public PseudoContext{
private:
//aux
GLuint FBO;
GLuint depthRBO;
GLuint outputTexture; /*FBO for communications with other bois*/
public:
Scene(int left, int top, int width, int height);
void setOutTexture(GLuint outTexture);
void draw();
void keyPress(unsigned char key, int x, int y);
GLuint getFrameBuffer();
};
#endif

View File

@@ -0,0 +1,31 @@
#ifndef SCREEN_H
#define SCREEN_H
#include "../SCENE/Model3D.hpp"
#include "PseudoContext.h"
class Screen: public PseudoContext {
private:
//aux
GLuint inputTexture = 0;
GLuint quadVAO, vertVBO;
GLuint program2;
GLuint shaderTexId;
GLfloat quadVerts[18] = {
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f
};
public:
Screen(int left, int top, int width, int height);
void setInputTexture(GLuint inputTexture);
void draw();
};
#endif

View File

@@ -0,0 +1,38 @@
#ifndef TEXMERGER_H
#define TEXMERGER_H
/*
#include <GL/glew.h>
*/
#include <GLES2/gl2.h>
#include <vector>
class TexMerger {
private:
GLuint program;
GLuint* mergeBuffers;
std::vector<bool> usageMap;
GLuint FBO;
GLuint quadVAO, vertVBO;
GLuint shaderTex1Id, shaderTex2Id;
int bufCount;
GLuint reserveBuffer();
bool isBuffer(GLuint number);
void freeBuffer(GLuint number);
GLfloat quadVerts[18] = {
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f
};
public:
TexMerger(GLuint texCount, unsigned int texWidth, unsigned int texHeight);
GLuint merge(std::vector<GLuint> inTextures, int startIndex, int endIndex);
};
#endif // !TEXMERGER_H

View File

@@ -0,0 +1,40 @@
#pragma once
#include <glm/gtc/type_ptr.hpp>
class Camera {
public:
glm::vec3 cameraPos;
glm::vec3 cameraFront;
glm::vec3 cameraUp;
Camera();
Camera( glm::vec3 position, glm::vec3 front, glm::vec3 up);
glm::mat4 getViewMat();
glm::vec3 getPosition();
//exp
void alignTo( glm::vec3 direction);
void setPosition( glm::vec3 pos);
};
class CameraController {
private:
Camera *camera;
float cameraSpeed = 0.5f;
bool mouseUnlocked = true;
float lastX;
float lastY;
float PHI = 0.0;
float THETA = 270.0;
unsigned int windowLeft;
unsigned int windowTop;
unsigned int windowWidth;
unsigned int windowHeight;
public:
CameraController(Camera *cam);
Camera* getCamera();
void setWindowData(int left, int width, int top, int height);
void mouseMotion(int cursorX, int cursorY);
void keyPress(unsigned char key);
};

View File

@@ -0,0 +1,21 @@
#pragma once
#include <glm/glm.hpp>
/*
#include <GL/glew.h>
*/
#include <GLES2/gl2.h>
#include "./Model3D.hpp"
#include "../SCENE/ObjectInstance.hpp"
class Instance3D : public WorldInstanceable {
private:
Model3D* mesh;
public:
Instance3D(Model3D* mesh, vec3 position);
Instance3D(Model3D* mesh, vec3 position, vec3 scale);
Instance3D(Model3D* mesh, vec3 position, vec3 axis, float angle);
Instance3D(Model3D* mesh, vec3 position, vec3 scale, vec3 axis, float angle);
Model3D* getModel();
};

View File

@@ -0,0 +1,3 @@
#include "../SCENE/Instance3D.h"
bool loadInstances(std::string path, vector<Instance3D*>& instances, bool smoothNormals);

View File

@@ -0,0 +1,29 @@
#pragma once
#include <glm/glm.hpp>
#include <GLES2/gl2.h>
#include <vector>
using namespace std; //for vector
using namespace glm; //vec3 and friends
class Model3D {
private:
int nVertices;
GLuint vao;
vec3 boundingBoxLBN;
vec3 boundingBoxRTF;
vector<vec3> loadVertexData(const char* modelPath, bool smoothNormals);
void computeBoundingBox(vector<vec3> points);
public:
Model3D(const char* modelPath, bool smoothNormals);
GLuint getVAO();
int getTrisCount();
void draw();
vec3 getLBN();
vec3 getRTF();
};

View File

@@ -0,0 +1,30 @@
#pragma once
#include <glm/glm.hpp>
#include <GLES2/gl2.h>
#include <string>
using namespace std;
class WorldInstanceable {
private:
glm::vec3 localFront, localUp;
void setup(glm::vec3 position);
public:
glm::mat4 scaleMat;
glm::mat4 rotation;
glm::vec3 position;
WorldInstanceable(glm::vec3 position);
WorldInstanceable(glm::vec3 position, glm::vec3 scale);
WorldInstanceable(glm::vec3 position, glm::vec3 axis, float angle);
WorldInstanceable(glm::vec3 position, glm::vec3 scale, glm::vec3 axis, float angle);
void setPosition(glm::vec3 position);
void rotate(glm::vec3 axis, float angle);
void scale(float factor);
void scale(glm::vec3 factors);
glm::mat4 getLocalTransform();
glm::mat4 getGlobalTransform();
void alignTo(glm::vec3 direction);
};

View File

@@ -0,0 +1,26 @@
#pragma once
#include <glm/glm.hpp>
/*
#include <GL/glew.h>
*/
#include <GLES2/gl2.h>
#include <string>
class ShadingHelper {
GLuint program;
public:
ShadingHelper(GLuint program);
void useProgram();
GLuint getProgram();
void bindTexture2D(GLuint texUnitIndex, GLuint texture, std::string uniform);
void bindViewUniforms(glm::mat4 projection, glm::mat4 view);
void bindLightUniforms(glm::vec3 lightPos, glm::vec3 lightCol, glm::vec3 eyePos);
void bindModelUniforms(glm::mat4 locRotScl, glm::mat4 rotScl);
};
class TextureHelper {
public:
GLuint texture;
std::string uniformName;
};

View File

@@ -0,0 +1,20 @@
#ifndef OBJLOADER_H
#define OBJLOADER_H
bool loadOBJ(
const char* path,
std::vector<glm::vec3>& out_vertices,
std::vector<glm::vec2>& out_uvs,
std::vector<glm::vec3>& out_normals,
bool smoothNormals
);
bool loadAssImp(
const char* path,
std::vector<unsigned short>& indices,
std::vector<glm::vec3>& vertices,
std::vector<glm::vec2>& uvs,
std::vector<glm::vec3>& normals
);
#endif

View File

@@ -0,0 +1,12 @@
#pragma once
class ClockIterator {
private:
unsigned int max;
unsigned int counter;
public:
ClockIterator(unsigned int loopMillis);
unsigned int step(unsigned int millis);
float getPercentage();
unsigned int getPosition();
void reset();
};

View File

@@ -0,0 +1,3 @@
#include <GLES2/gl2.h>
GLuint loadImg(const char* path);

View File

@@ -0,0 +1,21 @@
#pragma once
#include <string>
#include <vector>
#include <map>
#include "../UTILS/OnlyOnce.hpp"
using namespace std;
class ResourceCache {
private:
ResourceCache ();
map<string, GLuint> images;
map<string, GLuint> shaders;
public:
static ResourceCache& get() {
static ResourceCache instance;
return instance;
}
GLuint getImage(string path);
GLuint getShader(string vertPath, string fragPath);
};

View File

@@ -0,0 +1,12 @@
#pragma once
#include <GLES2/gl2.h>
class ShaderMaker
{
public:
static GLuint createProgram(char* vertexfilename, char *fragmentfilename);
static char* readShaderSource(const char* shaderFile);
private:
ShaderMaker() { }
};

7462
GL_STUFF/HEADERS/UTILS/stb_image.h Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

228
GL_STUFF/Makefile Normal file
View File

@@ -0,0 +1,228 @@
include ../external.mk
S=${PWD}GL_STUFF/SOURCES/
H=${PWD}GL_STUFF/HEADERS/
O=${PWD}GL_STUFF/OBJECTS/
_U=UTILS/
_S=SCENE/
_E=EFFECTS/
_C=CURVES/
COMPATIBILITY_OBJECT=GLES_3_1_compatibility.o
UTILS_OBJECTS=${O}${_U}ClockIterator.o ${O}${_U}OnlyOnce.o ${O}${_U}ResourceCache.o ${O}${_U}ShaderMaker.o
SCENE_OBJECTS=${O}${_S}Camera.o ${O}${_S}Instance3D.o ${O}${_S}InstancesLoader.o ${O}${_S}Model3D.o ${O}${_S}ObjectInstance.o ${O}${_S}objloader.o ${O}${_S}ShadingHelper.o
# THE PLATFORM SUPPORTS UP TO GLES2 AND COMPUTE SHADERS COME WITH GLES3.1
# REMOVED
# ${O}${_E}CRT_shader.o
EFFECTS_OBJECTS=${O}${_E}PseudoContext.o ${O}${_E}ReelManager.o ${O}${_E}Scene.o ${O}${_E}Screen.o ${O}${_E}TexMerger.o
CURVES_OBJECTS=${O}${_C}Bezier.o ${O}${_C}Curve.o ${O}${_C}CurveIterator.o ${O}${_C}CurvesLoader.o ${O}${_C}Hermite.o ${O}${_C}NURBS.o
OBJECTS=${COMPATIBILITY_OBJECT} ${UTILS_OBJECTS} ${SCENE_OBJECTS} ${EFFECTS_OBJECTS} ${CURVES_OBJECTS}
CFLAGS=-ansi -Wpedantic -Winline -Werror -std=c++11 # c11
all:
make ${OBJECTS}
# COMPATIBILITY OBJECT
GLES_3_1_compatibility.o : GLES_3_1_compatibility.c GLES_3_1_compatibility.h ${HEADERS}GLES2/gl2.h ${HEADERS}GLES2/gl2ext.h
${C_COMPILER} \
${I_GRAPHICS} \
-o GLES_3_1_compatibility.o \
-c -ansi -Wpedantic -Winline -Werror -std=c99 \
GLES_3_1_compatibility.c \
${GLOBAL_COMPILE_CONF}
# UTILS
${O}${_U}ClockIterator.o : ${S}${_U}ClockIterator.cpp ${H}${_U}ClockIterator.hpp
${CPP_COMPILER} \
-o ${O}${_U}ClockIterator.o \
-c ${CFLAGS} ${S}${_U}ClockIterator.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_U}OnlyOnce.o : ${S}${_U}OnlyOnce.cpp ${H}${_U}OnlyOnce.hpp ${H}${_U}stb_image.h
${CPP_COMPILER} \
${I_GRAPHICS} \
-o ${O}${_U}OnlyOnce.o \
-c ${CFLAGS} ${S}${_U}OnlyOnce.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_U}ResourceCache.o : ${S}${_U}ResourceCache.cpp ${H}${_U}ResourceCache.h ${H}${_U}ShaderMaker.h
${CPP_COMPILER} \
${I_GRAPHICS} \
-o ${O}${_U}ResourceCache.o \
-c ${CFLAGS} ${S}${_U}ResourceCache.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_U}ShaderMaker.o : ${S}${_U}ShaderMaker.cpp ${H}${_U}ShaderMaker.h
${CPP_COMPILER} \
${I_GRAPHICS} \
-o ${O}${_U}ShaderMaker.o \
-c ${CFLAGS} ${S}${_U}ShaderMaker.cpp \
${GLOBAL_COMPILE_CONF}
# SCENE
${O}${_S}Camera.o : ${S}${_S}Camera.cpp ${H}${_S}Camera.hpp
${CPP_COMPILER} \
${I_CGI_MATH} \
${I_MY_GLUT} \
-o ${O}${_S}Camera.o \
-c ${CFLAGS} ${S}${_S}Camera.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_S}Instance3D.o : ${S}${_S}Instance3D.cpp ${H}${_S}Instance3D.h
${CPP_COMPILER} \
${I_CGI_MATH} \
${I_GRAPHICS} \
-o ${O}${_S}Instance3D.o \
-c ${CFLAGS} ${S}${_S}Instance3D.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_S}InstancesLoader.o : ${S}${_S}InstancesLoader.cpp ${H}${_S}InstancesLoader.h
${CPP_COMPILER} \
${I_CGI_MATH} \
${I_GRAPHICS} \
-o ${O}${_S}InstancesLoader.o \
-c ${CFLAGS} ${S}${_S}InstancesLoader.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_S}ObjectInstance.o : ${S}${_S}ObjectInstance.cpp ${H}${_S}ObjectInstance.hpp
${CPP_COMPILER} \
${I_CGI_MATH} \
${I_GRAPHICS} \
-o ${O}${_S}ObjectInstance.o \
-c ${CFLAGS} ${S}${_S}ObjectInstance.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_S}objloader.o : ${S}${_S}objloader.cpp ${H}${_S}objloader.hpp
${CPP_COMPILER} \
${I_CGI_MATH} \
-o ${O}${_S}objloader.o \
-c ${CFLAGS} ${S}${_S}objloader.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_S}Model3D.o : ${S}${_S}Model3D.cpp ${H}${_S}Model3D.hpp \
${H}${_U}OnlyOnce.hpp ${H}${_U}ShaderMaker.h ${H}${_S}objloader.hpp \
${H}${_U}ResourceCache.h \
./GLES_3_1_compatibility.h
${CPP_COMPILER} \
${I_CGI_MATH} \
${I_GRAPHICS} \
-o ${O}${_S}Model3D.o \
-c ${CFLAGS} ${S}${_S}Model3D.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_S}ShadingHelper.o : ${S}${_S}ShadingHelper.cpp ${H}${_S}ShadingHelper.h
${CPP_COMPILER} \
${I_CGI_MATH} \
${I_GRAPHICS} \
-o ${O}${_S}ShadingHelper.o \
-c ${CFLAGS} ${S}${_S}ShadingHelper.cpp \
${GLOBAL_COMPILE_CONF}
#EFFECTS
# THE PLATFORM SUPPORTS UP TO GLES2 AND COMPUTE SHADERS COME WITH GLES3.1
#
# ${O}${_E}CRT_shader.o : ${S}${_E}CRT_shader.cpp ${H}${_E}CRT_shader.h ${H}${_U}ShaderMaker.h
# ${COMPILER} \
# ${I_CGI_MATH} \
# ${I_GRAPHICS} \
# -o ${O}${_E}CRT_shader.o \
# -c ${CFLAGS} ${S}${_E}CRT_shader.cpp \
# ${GLOBAL_COMPILE_CONF}
${O}${_E}PseudoContext.o : ${S}${_E}PseudoContext.cpp ${H}${_E}PseudoContext.h
${CPP_COMPILER} \
-o ${O}${_E}PseudoContext.o \
-c ${CFLAGS} ${S}${_E}PseudoContext.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_E}ReelManager.o : ${S}${_E}ReelManager.cpp ${H}${_E}ReelManager.h
${CPP_COMPILER} \
${I_GRAPHICS} \
-o ${O}${_E}ReelManager.o \
-c ${CFLAGS} ${S}${_E}ReelManager.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_E}Scene.o : ${S}${_E}Scene.cpp ${H}${_E}Scene.h ./GLES_3_1_compatibility.h
${CPP_COMPILER} \
${I_GRAPHICS} \
${I_MY_GLUT} \
${I_CGI_MATH} \
-o ${O}${_E}Scene.o \
-c ${CFLAGS} ${S}${_E}Scene.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_E}Screen.o : ${S}${_E}Screen.cpp ${H}${_E}Screen.h ${H}${_U}ShaderMaker.h
${CPP_COMPILER} \
${I_GRAPHICS} \
${I_MY_GLUT} \
${I_CGI_MATH} \
-o ${O}${_E}Screen.o \
-c ${CFLAGS} ${S}${_E}Screen.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_E}TexMerger.o : ${S}${_E}TexMerger.cpp ${H}${_E}TexMerger.h ${H}${_U}ShaderMaker.h
${CPP_COMPILER} \
${I_GRAPHICS} \
${I_CGI_MATH} \
-o ${O}${_E}TexMerger.o \
-c ${CFLAGS} ${S}${_E}TexMerger.cpp \
${GLOBAL_COMPILE_CONF}
#CURVES
${O}${_C}Bezier.o : ${S}${_C}Bezier.cpp ${H}${_C}Bezier.hpp
${CPP_COMPILER} \
${I_CGI_MATH} \
-o ${O}${_C}Bezier.o \
-c ${CFLAGS} ${S}${_C}Bezier.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_C}Curve.o : ${S}${_C}Curve.cpp ${H}${_C}Curve.hpp
${CPP_COMPILER} \
${I_CGI_MATH} \
-o ${O}${_C}Curve.o \
-c ${CFLAGS} ${S}${_C}Curve.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_C}CurveIterator.o : ${S}${_C}CurveIterator.cpp ${H}${_C}CurveIterator.hpp
${CPP_COMPILER} \
${I_CGI_MATH} \
-o ${O}${_C}CurveIterator.o \
-c ${CFLAGS} ${S}${_C}CurveIterator.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_C}CurvesLoader.o : ${S}${_C}CurvesLoader.cpp ${H}${_C}CurvesLoader.hpp
${CPP_COMPILER} \
${I_CGI_MATH} \
-o ${O}${_C}CurvesLoader.o \
-c ${CFLAGS} ${S}${_C}CurvesLoader.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_C}Hermite.o : ${S}${_C}Hermite.cpp ${H}${_C}Hermite.hpp
${CPP_COMPILER} \
${I_CGI_MATH} \
-o ${O}${_C}Hermite.o \
-c ${CFLAGS} ${S}${_C}Hermite.cpp \
${GLOBAL_COMPILE_CONF}
${O}${_C}NURBS.o : ${S}${_C}NURBS.cpp ${H}${_C}NURBS.hpp
${CPP_COMPILER} \
${I_CGI_MATH} \
-o ${O}${_C}NURBS.o \
-c ${CFLAGS} ${S}${_C}NURBS.cpp \
${GLOBAL_COMPILE_CONF}
.PHONY: clean
clean:
-rm ${OBJECTS} *~ core

View File

@@ -0,0 +1,80 @@
#include "../../HEADERS/CURVES/Bezier.hpp"
#include "iostream"
#define LERP(t,a,b) (1 - t) * a + t * b;
Bezier::Bezier(unsigned int order, vector<glm::vec3> *points, vector<float> *intervals) : Curve{ points, intervals } {
this->order = order;
}
/*might be useless (using lerp based evaluation)*/
float Bezier::evaluateBasisFunction(float at, int number, int order, float intervalLeft, float intervalRight) {
if (number < 0 || number > order) {
return 0;
}
else if (number == 0 && order == 0) {
return 1;
}
else {
return ((at - intervalLeft)/(intervalRight - intervalLeft)) * evaluateBasisFunction(at, number - 1, order - 1, intervalLeft, intervalRight) + ((intervalRight - at) / (intervalRight - intervalLeft)) * evaluateBasisFunction(at, number, order - 1, intervalLeft, intervalRight);
}
}
glm::vec3 Bezier::evaluate(float at) {
vector<glm::vec3>partials = vector<glm::vec3>();
for (const glm::vec3 point : *controlPoints)
partials.push_back(point);
int iter = partials.size() - 1;
while (iter > 0) {
for (int i = 0; i < iter; i++) {
partials[i] = LERP(at, partials[i], partials[i + 1]);
}
iter--;
}
return partials[0];
}
glm::vec3 Bezier::derivate(float at) {
return glm::vec3();
}
/*
* takes as input a sequence of points
* to be interpreted as conjoined bezier segments of order 3
*/
Bezier3Segments::Bezier3Segments( vector<glm::vec3>* points, vector<float>* intervals) : Bezier { ((unsigned int) points->size() - 1 ) , points , intervals } {
int nPoints = points->size();
assert((nPoints % 4) == 0);
}
glm::vec3 Bezier3Segments::evaluate(float at) {
for (int interval = 0; interval < intervalBoundaries->size() - 1; interval++) {
if ((intervalBoundaries->operator[](interval) <= at) && (intervalBoundaries->operator[](interval + 1) >= at)) {
float normalizedAt = (at - intervalBoundaries->operator[](interval)) / (intervalBoundaries->operator[](interval + 1) - intervalBoundaries->operator[](interval));
vector<glm::vec3> partials;
for (int j = 0; j <= 3; j++) {
partials.push_back(controlPoints->operator[](4 * interval + j));
}
int count = 3;
while (count > 0) {
for (int j = 0; j < count; j++) {
partials[j] = LERP(normalizedAt, partials[j], partials[j + 1]);
}
count--;
}
return partials[0];
}
}
throw "Bezier3Segment evaluation out of range";
}
glm::vec3 Bezier3Segments::derivate(float at) {
return glm::vec3();
}
float Bezier3Segments::getLeftBound() {
return intervalBoundaries->front();
}
float Bezier3Segments::getRightBound() {
return intervalBoundaries->back();
}

View File

@@ -0,0 +1,34 @@
#include "../../HEADERS/CURVES/Curve.hpp"
#include <iostream>
Curve::Curve(vector<glm::vec3> *points, vector<float> *boundaries) {
setControlPoints(points);
setIntervalBoundaries(boundaries);
}
vector<glm::vec3>* Curve::getControlPoints() {
return controlPoints;
}
vector<float>* Curve::getIntervalBoundaries() {
return intervalBoundaries;
}
void Curve::setControlPoints(vector<glm::vec3>* points) {
controlPoints = points;
}
void Curve::setIntervalBoundaries(vector<float> *boundaries) {
intervalBoundaries = boundaries;
}
float Curve::getLeftBound() {
return intervalBoundaries->front();
}
float Curve::getRightBound() {
return intervalBoundaries->back();
}

View File

@@ -0,0 +1,110 @@
#include "../../HEADERS/CURVES/CurveIterator.hpp"
#include <iostream>
#include <sstream>
CurveIterator::CurveIterator(Curve *curve, unsigned int steps, CurveIterationMode basicOrLength) {
this->curve = curve;
this->steps = steps;
this->iterationMode = basicOrLength;
leftBound = curve->getLeftBound();
rightBound = curve->getRightBound();
estimatedLength = 0;
resetIterator();
if (iterationMode == CurveIterationMode::LENGTH) {
computeLength();
}
}
void CurveIterator::resetIterator() {
basicStepCounter = 0;
lengthStepCounter = leftBound;
lastIncrement = (rightBound - leftBound) / steps;
//std::cout << "lastIncrement after reset is " << lastIncrement << std::endl;
}
void CurveIterator::computeLength() {
for (int i = 0; i < steps; i++) {
glm::vec3 startPoint = curve->evaluate(leftBound + (rightBound - leftBound) * i / steps);
glm::vec3 endPoint = curve->evaluate(leftBound + (rightBound - leftBound) * (i + 1) / steps);
estimatedLength += glm::length(endPoint - startPoint);
//std::cout << "segment length " << estimatedLength << std::endl;
}
}
float CurveIterator::getStep() {
if (iterationMode == CurveIterationMode::LENGTH) {
return lengthStepCounter;
}
else {
return leftBound + (rightBound - leftBound) * basicStepCounter / steps;
}
}
void CurveIterator::nextStep() {
if (iterationMode == CurveIterationMode::LENGTH) {
float increment = lastIncrement;
//std::cout << "lastInc is " << lastIncrement << std::endl;
//std::cout << "lstepCount is " << lengthStepCounter << std::endl;
if ((lengthStepCounter + increment) <= rightBound) {
glm::vec3 point1 = curve->evaluate(lengthStepCounter);
glm::vec3 point2 = curve->evaluate(lengthStepCounter + increment);
increment *= ((estimatedLength / steps) / glm::length(point2 - point1));
//std::cout << "segment length " << glm::length(curve->evaluate(lengthStepCounter + increment) - curve->evaluate(lengthStepCounter)) << std::endl;
lengthStepCounter += increment;
lastIncrement = increment;
}
else { //cycle
resetIterator();
}
}
else {
if(basicStepCounter < steps){
basicStepCounter++;
}
else {
resetIterator();
}
}
}
void CurveIterator::setProgress(float at) {
if (at < 0 || at > 1) {
std::stringstream err;
err << "CurveIterator : required progress (" << at << ") is out of range [ 0 , 1 ]";
throw std::invalid_argument(err.str());
}
else {
resetIterator();
int nSteps = at * steps;
for (int i = 0; i < nSteps; i++)
nextStep();
}
}
glm::vec3 CurveIterator::evaluation() {
float at;
if (iterationMode == CurveIterationMode::LENGTH) {
at = lengthStepCounter;
}
else {
at = leftBound + (rightBound - leftBound) * basicStepCounter / steps;
}
//std::cout << "iterator at is " << at << std::endl;
return curve->evaluate(at);
}
glm::vec3 CurveIterator::derivation() {
float at;
if (iterationMode == CurveIterationMode::LENGTH) {
at = lengthStepCounter;
}
else {
at = leftBound + (rightBound - leftBound) * basicStepCounter / steps;
}
return curve->derivate(at);
}
Curve* CurveIterator::getCurve() {
return curve;
}

View File

@@ -0,0 +1,203 @@
#include "../../HEADERS/CURVES/CurvesLoader.hpp"
string CurvesLoader::currentCurveType;
vector<glm::vec3>* CurvesLoader::pointsBuffer;
vector<NURBS*> CurvesLoader::NURBSes;
vector<Bezier3Segments*> CurvesLoader::beziers;
unsigned int CurvesLoader::NURBSOrder;
NURBSType CurvesLoader::NURBS_TYPE;
vector<float>* CurvesLoader::NURBSWeights;
char CurvesLoader::lineHeader[128];
char* CurvesLoader::res;
FILE* CurvesLoader::file;
std::smatch CurvesLoader::pieces;
void CurvesLoader::beginCurve(string str, std::smatch pieces, std::regex regex) {
pointsBuffer = new vector<glm::vec3>();
NURBSWeights = new vector<float>();
NURBS_TYPE = NURBSType::BASIC;
//si inizia una patch di BEZIER
if (pieces[1].str() == "BEZIER") {
//std::cout << "next is BEZIER" << std::endl;
currentCurveType = "BEZIER";
}
//si inizia una NURBS
else if (pieces[1].str() == "NURBS") {
//std::cout << "next is NURBS" << std::endl;
currentCurveType = "NURBS";
res = fgets(lineHeader, 128, file); // read curve multiplicity
str = lineHeader;
std::regex regex("\\s*order (\\d)\\s*(clamped|cyclic)?\\s*(\\n)?");
if (res == NULL || !std::regex_match(str, pieces, regex)) {
throw "expected NURBS order";
}
else {
NURBSOrder = stoi(pieces[1]);
if (pieces.length() > 2) {
if (pieces[2].str() == "clamped") {
NURBS_TYPE = NURBSType::CLAMPED;
}
else if (pieces[2].str() == "cyclic") {
NURBS_TYPE = NURBSType::CYCLIC;
}
}
else {
NURBS_TYPE = NURBSType::BASIC;
}
std::cout << res << std::endl;
}
//std::cout << "parsed order : " << NURBSOrder << std::endl;
}
}
NURBS* CurvesLoader::BasicNURBS() {
unsigned int nFunctions = pointsBuffer->size();
unsigned int totalElements = NURBSOrder + nFunctions;
vector<float>* intervals = new vector<float>();
for (int i = 0; i <= totalElements; i++)
intervals->push_back((float) i / totalElements);
vector<unsigned int>* multiplicities = new vector<unsigned int>;
for (int i = 0; i < pointsBuffer->size(); i++)
multiplicities->push_back(1);
return new NURBS(NURBSOrder, pointsBuffer, NURBSWeights, intervals, multiplicities);
}
NURBS* CurvesLoader::ClampedNURBS() {
unsigned int nFunctions = pointsBuffer->size();
vector<float>* intervals = new vector<float>();
for (int i = 0; i <= NURBSOrder; i++)
intervals->push_back(0);
for (int i = 1; i <= nFunctions - NURBSOrder; i++)
intervals->push_back((float)i / (nFunctions - NURBSOrder));
for (int i = 0; i < NURBSOrder; i++)
intervals->push_back(1);
vector<unsigned int>* multiplicities = new vector<unsigned int>;
for (int i = 0; i < pointsBuffer->size(); i++)
multiplicities->push_back(1);
return new NURBS(NURBSOrder, pointsBuffer, NURBSWeights, intervals, multiplicities);
}
NURBS* CurvesLoader::CyclicNURBS() {
for (int i = 0; i < NURBSOrder; i++) {
pointsBuffer->push_back(pointsBuffer->at(i));
NURBSWeights->push_back(NURBSWeights->at(i));
}
unsigned int nFunctions = pointsBuffer->size();
unsigned int totalElements = NURBSOrder + nFunctions;
vector<float>* intervals = new vector<float>();
for (int i = 0; i <= totalElements; i++)
intervals->push_back((float) i/ totalElements);
vector<unsigned int>* multiplicities = new vector<unsigned int>;
for (int i = 0; i < pointsBuffer->size(); i++)
multiplicities->push_back(1);
return new NURBS(NURBSOrder, pointsBuffer, NURBSWeights, intervals, multiplicities);
}
void CurvesLoader::closeNURBS(){
try {
switch (NURBS_TYPE) {
case NURBSType::BASIC :
std::cout << "NURBS was BASIC" << std::endl;
NURBSes.push_back(BasicNURBS());
break;
case NURBSType::CLAMPED :
std::cout << "NURBS was CLAMPED" << std::endl;
NURBSes.push_back(ClampedNURBS());
break;
case NURBSType::CYCLIC :
std::cout << "NURBS was CYCLIC" << std::endl;
NURBSes.push_back(CyclicNURBS());
break;
}
}
catch (std::invalid_argument e) {
std::cout << e.what() << std::endl;
}
}
void CurvesLoader::closeBezier() {
vector<float>* intervals = new vector<float>();
int nIntervals = pointsBuffer->size() / 4;
intervals->push_back(0);
for (int i = 1; i <= nIntervals; i++)
intervals->push_back((float)i / nIntervals);
beziers.push_back(new Bezier3Segments(pointsBuffer, intervals));
}
void CurvesLoader::closePendingCurve() {
if (currentCurveType == "BEZIER") {
closeBezier();
}
else if (currentCurveType == "NURBS") {
closeNURBS();
}
}
void CurvesLoader::parseVertexData(string str) {
vector<float> vecComponents = vector<float>();
std::regex regex("-?\\d+.\\d+");
while (std::regex_search(str, pieces, regex)) {
float entry = stof(pieces[0], NULL); //potevi evitare la regex
vecComponents.push_back(entry);
str = pieces.suffix().str();
}
glm::vec3 vec(vecComponents[0], vecComponents[1], vecComponents[2]);
pointsBuffer->push_back(vec);
if (currentCurveType == "NURBS") {
NURBSWeights->push_back(vecComponents[3]);
}
}
bool CurvesLoader::loadCurves(std::string path, vector<Curve*>& curves) {
currentCurveType = "NONE";
pointsBuffer = new vector<glm::vec3>();
NURBSWeights = new vector<float>();
file = fopen(&path[0], "r");
if (file == NULL) {
printf("Impossible to open the curve file ! Are you in the right path ?\n");
getchar();
return false;
}
while (1) {
res = fgets(lineHeader, 128, file); // read the first word of the line
// EOF = End Of File. Store pending curve and quit the loop.
if (res == NULL) {
closePendingCurve(); //what if there was no pending curve? (aka return false)
break;
}
string str = lineHeader;
std::regex regex("\\s*curve \\d+ : (BEZIER|NURBS)\\n");
//inizia una curva (la prima o una nuova)
if (std::regex_match(str, pieces, regex)) {
closePendingCurve();
beginCurve(str, pieces, regex);
}
//deve essere materiale inerente la curva in costruzione
else {
std::regex regex("\\s*(-?\\d+.\\d+)(( , -?\\d+.\\d+)+)\\s*(\\n)?");
//sono dati di un vertice
if (std::regex_match(str, pieces, regex)){
parseVertexData(str);
}
else {
std::cout << "unrecognized line : " << str << std::endl;
}
}
}
std::cout << "trovate " << beziers.size() << " curve di bezier" << std::endl << "e " << NURBSes.size() << " NURBS" << std::endl;
for (Bezier3Segments* el : beziers)
curves.push_back(el);
for (NURBS* el : NURBSes)
curves.push_back(el);
/* !!! only the file existence gets checked */
return true;
}

View File

@@ -0,0 +1,124 @@
#include "../../HEADERS/CURVES/Hermite.hpp"
#define PHI0(t) (2.0f*t*t*t - 3.0f*t*t + 1)
#define PHI1(t) (t*t*t - 2.0f*t*t + t)
#define PSI0(t) (-2.0f*t*t*t + 3.0f*t*t)
#define PSI1(t) (t*t*t - t*t)
Hermite::Hermite(vector<glm::vec3> *points, vector<float> *intervalBoundaries)
: Curve{ points, intervalBoundaries } {
}
void Hermite::computeDerivatives(HermiteModes mode, vector<glm::vec3> auxData) {
derivatives.clear();
int length = (*controlPoints).size();
switch (mode) {
case HermiteModes::Direct:
assert(controlPoints->size() == auxData.size());
derivatives.push_back(auxData[0]);
for (int i = 0; i < auxData.size() - 1; i++) {
derivatives.push_back(auxData[i]);
derivatives.push_back(auxData[i]);
}
derivatives.push_back(auxData[auxData.size() - 1]);
break;
case HermiteModes::Basic:
{
glm::vec3 result;
result = 0.5f * ((*controlPoints)[1] - (*controlPoints)[0]) / ((*intervalBoundaries)[1] - (*intervalBoundaries)[0]);
derivatives.push_back(result);
for (int i = 1; i < length - 1; i++) {
result = 0.5f *
(
(((*controlPoints)[i + 1] - (*controlPoints)[i])
/ ((*intervalBoundaries)[i + 1] - (*intervalBoundaries)[i]))
+ (((*controlPoints)[i] - (*controlPoints)[i - 1])
/ ((*intervalBoundaries)[i] - (*intervalBoundaries)[i - 1]))
);
derivatives.push_back(result);
derivatives.push_back(result);
}
result = 0.5f * ((*controlPoints)[length - 1] - (*controlPoints)[length - 2]) / ((*intervalBoundaries)[length - 1] - (*intervalBoundaries)[length - 2]);
derivatives.push_back(result);
}
break;
case HermiteModes::Cardinal:
{
assert(controlPoints->size() == auxData.size());
int last = controlPoints->size() - 1;
glm::vec3 delta1;
glm::vec3 delta2;
delta1 = (*controlPoints)[1] - (*controlPoints)[0];
float interval1;
float interval2;
interval1 = (*intervalBoundaries)[1] - (*intervalBoundaries)[0];
glm::vec3 result;
result = 0.5f * (1 - auxData[0].x) * delta1 / interval1;
derivatives.push_back(result);
for (int i = 1; i < last; i++) {
delta1 = (*controlPoints)[i + 1] - (*controlPoints)[i];
delta2 = (*controlPoints)[i] - (*controlPoints)[i - 1];
interval1 = (*intervalBoundaries)[i + 1] - (*intervalBoundaries)[i];
interval2 = (*intervalBoundaries)[i] - (*intervalBoundaries)[i - 1];
result = 0.5f * (1 - auxData[i].x) * (delta1 / interval1 + delta2 / interval2);
derivatives.push_back(result);
derivatives.push_back(result);
}
delta1 = (*controlPoints)[last] - (*controlPoints)[last - 1];
interval1 = (*intervalBoundaries)[last] - (*intervalBoundaries)[last - 1];
result = 0.5f * (1 - auxData[last].x) * (delta1 / interval1);
derivatives.push_back(result);
}
break;
case HermiteModes::TBC:
{
assert(controlPoints->size() == auxData.size());
int last = controlPoints->size() - 1;
glm::vec3 delta1;
glm::vec3 delta2;
delta1 = (*controlPoints)[1] - (*controlPoints)[0];
float interval1;
float interval2;
interval1 = (*intervalBoundaries)[1] - (*intervalBoundaries)[0];
glm::vec3 result;
//first
result = 0.5f * (1 - auxData[0].x) * (1 + auxData[0].y) * (1 + auxData[0].z) * delta1 / interval1;
derivatives.push_back(result);
for (int i = 1; i < last; i++) {
delta1 = (*controlPoints)[i + 1] - (*controlPoints)[i];
delta2 = (*controlPoints)[i] - (*controlPoints)[i - 1];
interval1 = (*intervalBoundaries)[i + 1] - (*intervalBoundaries)[i];
interval2 = (*intervalBoundaries)[i] - (*intervalBoundaries)[i - 1];
//last
result = 0.5f * ((1 - auxData[i].x) * (1 + auxData[i].y) * (1 - auxData[i].z) * (delta1 / interval1) + (1 - auxData[i].x) * (1 - auxData[i].y) * (1 - auxData[i].z) * (delta2 / interval2));
derivatives.push_back(result);
//first
result = 0.5f * ((1 - auxData[i].x) * (1 + auxData[i].y) * (1 + auxData[i].z) * (delta1 / interval1) + (1 - auxData[i].x) * (1 - auxData[i].y) * (1 - auxData[i].z) * (delta2 / interval2));
derivatives.push_back(result);
}
delta1 = (*controlPoints)[last] - (*controlPoints)[last - 1];
interval1 = (*intervalBoundaries)[last] - (*intervalBoundaries)[last - 1];
//last
result = 0.5f * ((1 - auxData[last].x) * (1 + auxData[last].y) * (1 - auxData[last].z) * (delta1 / interval1));
derivatives.push_back(result);
}
break;
}
}
glm::vec3 Hermite::evaluateCubic(float t, float t1, float t2, glm::vec3 y1, glm::vec3 y2, glm::vec3 dy1, glm::vec3 dy2) {
float interval = t2 - t1;
float newX = (t - t1) / interval;
return y1 * PHI0(newX) + dy1 * interval * PHI1(newX) + y2 * PSI0(newX) + dy2 * interval * PSI1(newX);
}
glm::vec3 Hermite::evaluate(float at) {
for (int i = 0; i < intervalBoundaries->size() - 1; i++)
if ((*intervalBoundaries)[i] <= at && at <= (*intervalBoundaries)[i + 1])
return evaluateCubic(at, (*intervalBoundaries)[i], (*intervalBoundaries)[i + 1], (*controlPoints)[i], (*controlPoints)[i + 1], derivatives[2 * i], derivatives[2 * i + 1]);
return glm::vec3();
}
glm::vec3 Hermite::derivate(float at) {
return glm::vec3();
}

128
GL_STUFF/SOURCES/CURVES/NURBS.cpp Executable file
View File

@@ -0,0 +1,128 @@
#include "../../HEADERS/CURVES/NURBS.hpp"
#include <stdexcept>
#include <sstream>
#include <iostream>
void NURBS::preliminaryChecks() {
int nPoints = controlPoints->size();
int nWeights = weights->size();
int nBoundaries = intervalBoundaries->size();
int nMultiplicities = multiplicities->size();
int requiredBoundaries = order + 1;
for (int i = 0; i < nMultiplicities; i++)
requiredBoundaries += multiplicities->operator[](i);
std::cout << "nPoints : " << nPoints << std::endl;
std::cout << "nWeights : " << nWeights << std::endl;
std::cout << "nBoundaries : " << nBoundaries << std::endl;
std::cout << "nMultiplicities : " << nMultiplicities << std::endl;
std::cout << "requiredBoundaries : " << requiredBoundaries << std::endl;
if (nWeights != nPoints)
throw std::invalid_argument("NURBS : nPoints <> nWeights");
if (nMultiplicities != (nPoints)) {
std::stringstream err;
err << "NURBS : nPoints (" << nPoints << ") <> nMultiplicities (" << nMultiplicities << ")";
throw std::invalid_argument(err.str());
}
if (nBoundaries != requiredBoundaries) {
std::stringstream err;
err << "NURBS : nBoundaries (" << nBoundaries << ") <> should be equal to Order + sum (multiplicities) (" << requiredBoundaries << ")";
throw std::invalid_argument(err.str());
}
}
NURBS::NURBS( unsigned int order, vector<glm::vec3>* points, vector<float>* weights, vector<float>* boundaries, vector<unsigned int>* multiplicities) : Curve{ points , boundaries} {
this->order = order;
this->weights = weights;
this->intervalBoundaries = boundaries;
this->multiplicities = multiplicities;
preliminaryChecks();
derivativePoints = new vector<glm::vec3>();
derivativeWeghts = new vector<float>();
derivativeBoundaries = new vector<float>();
for (int i = 0; i < controlPoints->size() - 1; i++) {
glm::vec3 point = ((float)order) * ((*controlPoints)[i + 1] - (*controlPoints)[i])
/ ((*intervalBoundaries)[i + order + 1] - (*intervalBoundaries)[i + 1]);
derivativePoints->push_back(point);
//not so sure about this
derivativeWeghts->push_back(weights->at(i));
}
for (int i = 1; i < intervalBoundaries->size() - 1; i++)
derivativeBoundaries->push_back(intervalBoundaries->operator[](i));
}
glm::vec3 NURBS::deBoor(float at, int index) {
if (order < 0) {
throw std::invalid_argument("NURBS : evaluateBasis order underflow");
}
else {
vector<glm::vec3> points = vector<glm::vec3>();
vector<float> wei = vector<float>(); //
int firstPointIndex = index - order;
for (int i = index - order; i <= index; i++) {
float w = weights->operator[](i);
points.push_back(controlPoints->operator[](i) * w);
wei.push_back(w); //
}
for (int j = 0; j < order; j++) {
for (int i = index - order + j + 1; i <= index; i++) {
int pointIndex = i - index + order;
float denominator = ((*intervalBoundaries)[i + order - j] - (*intervalBoundaries)[i]);
if (denominator != 0.0f){
points[pointIndex] = (points[pointIndex] * (at - (*intervalBoundaries)[i]) + ((*intervalBoundaries)[i + order - j] - at) * points[pointIndex - 1])
/ denominator;
wei[pointIndex] = (wei[pointIndex] * (at - (*intervalBoundaries)[i]) + ((*intervalBoundaries)[i + order - j] - at) * wei[pointIndex - 1])
/ denominator;
}
}
}
return points[order] / wei[order];
}
}
glm::vec3 NURBS::evaluate(float at) {
//std::cout << "eval at " << at << std::endl;
for(int i = order; i < intervalBoundaries->size() - order - 1; i++)
if ((intervalBoundaries->operator[](i) <= at) && (at < intervalBoundaries->operator[](i + 1))) {
return deBoor(at, i);
}
if (pow(at - getRightBound(), 2) < 1e-8)
return deBoor(at, intervalBoundaries->size() - order - 2);
throw std::invalid_argument("NURBS : evaluation out of range");
}
glm::vec3 NURBS::derivate(float at) {
vector<glm::vec3>* swapPoints = controlPoints;
vector<float>* swapWeights = weights;
vector<float>* swapBoundaries = intervalBoundaries;
controlPoints = derivativePoints;
weights = derivativeWeghts;
intervalBoundaries = derivativeBoundaries;
order--;
glm::vec3 result = evaluate(at);
order++;
controlPoints = swapPoints;
weights = swapWeights;
intervalBoundaries = swapBoundaries;
return result;
}
float NURBS::getLeftBound() {
return intervalBoundaries->at(order);
}
float NURBS::getRightBound() {
return intervalBoundaries->at(intervalBoundaries->size() - order - 1);
}

View File

@@ -0,0 +1,71 @@
#version 430 core
//Uniform block containing positions and masses of the attractors
layout (std140, binding = 0) uniform attractor_block
{
vec4 attractor[8]; //xyz = position, w = strength
};
//Process particles in blocks of 128
layout (local_size_x = 1024) in;
//buffers containing the positions and velocities of the particles
layout (rgba32f, binding = 0) uniform imageBuffer velocity_buffer;
layout (rgba32f, binding = 1) uniform imageBuffer start_position_buffer;
layout (rgba32f, binding = 2) uniform imageBuffer end_position_buffer;
//Delta time
uniform float dt;
uniform vec3 nearTopLeft;
uniform vec3 nearBottomRight;
uniform vec3 farTopLeft;
uniform vec3 farBottomRight;
bool insideFrustrum(vec4 point) {
//float zRelative = ((point.z - nearBottomRight.z) / (nearBottomRight.z - farBottomRight.z));
//bool moreLeft = (point.x >= (nearTopLeft.x + (nearTopLeft.x - farTopLeft.x) * zRelative)); // left plane
//bool lessRight = (point.x <= (nearBottomRight.x + (nearBottomRight.x - farBottomRight.x) * zRelative)); // left plane
//bool moreBottom = (point.y >= (nearBottomRight.y + (nearBottomRight.y - farBottomRight.y) * zRelative)); //top plane
//bool lessTop = (point.y <= (nearTopLeft.y + (nearTopLeft.y - farTopLeft.y) * zRelative)); //bottom plane
//return ( (zRelative >= -1.0f) && moreLeft && lessRight && lessTop && moreBottom);
return ((point.x < farBottomRight.x) && (point.x > farTopLeft.x) && (point.y < farTopLeft.y) && (point.y > farBottomRight.y) && (point.z > -1.0));
}
vec4 scaleToZZero(vec4 v){
vec4 newV = v / (1 + v.z);
return newV;
}
void main(void)
{
//read the current position and velocity from the buffers
vec4 vel = imageLoad(velocity_buffer, int(gl_GlobalInvocationID.x));
vec4 pos = imageLoad(start_position_buffer, int(gl_GlobalInvocationID.x));
int i;
bool inFrustrum = true;
float dt2 = dt * dt;
while( inFrustrum && pos.z < 0.0f){
//update position using current velocity * time
pos.xyz += vel.xyz * dt;
//for each attractor... BOTTLENECK
for(i = 0; i < 8; i++)
{
if(attractor[i].w > 0){
//calculate force and update velocity accordingly
vec3 dir = (attractor[i].xyz - pos.xyz);
float dist = dot(dir, dir);
vel.xyz += (dt2 * attractor[i].w * cross(dir, vel.xyz) / (pow(dist, 2)));
}
}
inFrustrum = insideFrustrum(pos);
}
pos = scaleToZZero(pos);
//store the new position back into the buffers
imageStore(end_position_buffer, int(gl_GlobalInvocationID.x), pos);
}

View File

@@ -0,0 +1,24 @@
#version 430 core
layout (location = 0) out vec4 color;
layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord;
in vec4 particleColor;
uniform uint pixelWidth;
void main(void)
{
color = vec4(particleColor.xyz, 1.0f);
/*
color.r *= ((mod(gl_FragCoord.x, 8) != 0) && (mod(gl_FragCoord.y, 8) != 0) && (mod(gl_FragCoord.x, 8) != 1) && (mod(gl_FragCoord.y, 8) != 1))? 0 : 1;
color.g *= ((mod(gl_FragCoord.x, 8) != 2) && (mod(gl_FragCoord.y, 8) != 2) && (mod(gl_FragCoord.x, 8) != 3) && (mod(gl_FragCoord.y, 8) != 3))? 0 : 1;
color.b *= ((mod(gl_FragCoord.x, 8) != 4) && (mod(gl_FragCoord.y, 8) != 4) && (mod(gl_FragCoord.x, 8) != 5) && (mod(gl_FragCoord.y, 8) != 5))? 0 : 1;
*/
float mx = mod(roundEven(gl_FragCoord.x), 4 * pixelWidth);
float my = mod(roundEven(gl_FragCoord.y), 4 * pixelWidth);
color.r *= ((mx < pixelWidth) && (my < pixelWidth * 3)) ? 0.8 : 0.3;
color.g *= ((mx > pixelWidth && mx < pixelWidth * 2) && (my < pixelWidth * 3)) ? 1 : 0.4;
color.b *= ((mx > pixelWidth * 2 && mx < pixelWidth * 3) && (my < pixelWidth * 3)) ? 1 : 0.4;
}

View File

@@ -0,0 +1,17 @@
#version 430 core
layout (location = 0) in vec4 particleData;
//////
layout (location = 2) in vec4 iparticleColor;
out float intensity;
//
out vec4 particleColor;
uniform mat4 mvp;
void main(void)
{
gl_Position = mvp * vec4( particleData.xy, 0, 1);
particleColor = iparticleColor;
}

View File

@@ -0,0 +1,275 @@
#include "../../HEADERS/EFFECTS/CRT_shader.h"
#include "../../HEADERS/UTILS/ShaderMaker.h"
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
int CRT_Shader::CRT_HORIZONTAL_PIXELS;
int CRT_Shader::CRT_VERTICAL_PIXELS;
int CRT_Shader::CRT_WIDTH;
int CRT_Shader::CRT_HEIGHT;
int CRT_Shader::PARTICLE_COUNT;
int CRT_Shader::PARTICLE_GROUP_COUNT;
bool CRT_Shader::CRT_FLIP_Y;
SIM_PRECISION CRT_Shader::resolution;
vec3 CRT_Shader::scaleToZOne(vec3 vector) {
return (1 / vector.z) * vector;
}
vec3 CRT_Shader::crt_emission_angle(int index) {
int xCoord = (index % CRT_HORIZONTAL_PIXELS) - (CRT_HORIZONTAL_PIXELS / 2);
int yCoord = (index / CRT_HORIZONTAL_PIXELS) - (CRT_VERTICAL_PIXELS / 2);
float longCat = CRT_DEPTH;
float shortCatX = CRT_PIXEL_LENGTH * xCoord;
float shortCatY = CRT_PIXEL_LENGTH * yCoord;
vec3 res = vec3(shortCatX, -shortCatY, 1.0);
return res;
}
void CRT_Shader::createRenderShader() {
string vertexSh = resourceRoot + "vertexShader_particles.glsl";
string fragmentSh = resourceRoot + "fragmentShader_particles.glsl";
render_prog = ShaderMaker::createProgram(&vertexSh[0], &fragmentSh[0]);
}
void CRT_Shader::createComputeShader() {
GLenum ErrorCheckValue = glGetError();
string compSh = resourceRoot + "computeShader_particles.glsl";
GLchar* VertexShader = ShaderMaker::readShaderSource(&compSh[0]);
//Visualizzo sulla console il CODICE VERTEX SHADER
std::cout << VertexShader;
//Generiamo un identificativo per il vertex shader
GLuint computeShaderId = glCreateShader(GL_COMPUTE_SHADER);
//Associamo all'identificativo il codice del vertex shader
glShaderSource(computeShaderId, 1, (const char**)&VertexShader, NULL);
//Compiliamo il Vertex SHader
glCompileShader(computeShaderId);
int success;
char infoLog[512];
glGetShaderiv(computeShaderId, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(computeShaderId, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
ErrorCheckValue = glGetError();
std::cout << ErrorCheckValue;
if (ErrorCheckValue != GL_NO_ERROR)
{
fprintf(
stderr,
"ERROR: Could not create the shaders: %s \n",
gluErrorString(ErrorCheckValue)
);
exit(-1);
}
//Creiamo un identificativo di un eseguibile e gli colleghiamo i due shader compilati
compute_prog = glCreateProgram();
glAttachShader(compute_prog, computeShaderId);
glLinkProgram(compute_prog);
dt_location = glGetUniformLocation(compute_prog, "dt");
}
void CRT_Shader::buffersSetup() {
GLuint buffers[5];
GLuint textures[3];
glGenBuffers(5, buffers);
start_position_buffer = buffers[0];
end_position_buffer = buffers[1];
velocity_buffer = buffers[2];
color_buffer = buffers[3];
magnets_buffer = buffers[4];
glBindBuffer(GL_ARRAY_BUFFER, magnets_buffer);
glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(vec4), NULL, GL_DYNAMIC_COPY); //dynamic copy ???
for (int i = 0; i < 8; i++) {
attractors[i] = vec4();
}
glBindBuffer(GL_ARRAY_BUFFER, start_position_buffer);
glBufferData(GL_ARRAY_BUFFER, PARTICLE_COUNT * sizeof(vec4), NULL, GL_DYNAMIC_COPY);
//Map the position buffer
vec4* positions = (vec4*)glMapNamedBufferRangeEXT(start_position_buffer, 0, PARTICLE_COUNT * sizeof(vec4), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
for (int i = 0; i < PARTICLE_COUNT; i++)
{
positions[i] = vec4(0, 0, -CRT_DEPTH, 0);
}
glUnmapNamedBufferEXT(start_position_buffer);
glBindBuffer(GL_ARRAY_BUFFER, end_position_buffer);
glBufferData(GL_ARRAY_BUFFER, PARTICLE_COUNT * sizeof(vec4), NULL, GL_DYNAMIC_COPY);
glUnmapNamedBufferEXT(end_position_buffer);
//initialization of the velocity buffer
glBindBuffer(GL_ARRAY_BUFFER, velocity_buffer);
glBufferData(GL_ARRAY_BUFFER, PARTICLE_COUNT * sizeof(vec4), NULL, GL_DYNAMIC_COPY);
vec4* velocities = (vec4*)glMapBufferRange(GL_ARRAY_BUFFER, 0, PARTICLE_COUNT * sizeof(vec4), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
for (int i = 0; i < CRT_VERTICAL_PIXELS * CRT_HORIZONTAL_PIXELS; i++)
{
velocities[i] = glm::vec4(crt_emission_angle(i), 0.0);
}
glUnmapBuffer(GL_ARRAY_BUFFER);
//////////////////////////////////////////////////////////
//initialization of the color buffer
glBindBuffer(GL_ARRAY_BUFFER, color_buffer);
glBufferData(GL_ARRAY_BUFFER, PARTICLE_COUNT * COLOR_CHANNELS * sizeof(unsigned char), NULL, GL_DYNAMIC_COPY);
glGenTextures(3, textures);
velocity_tbo = textures[0];
start_position_tbo = textures[1];
end_position_tbo = textures[2];
glBindTexture(GL_TEXTURE_BUFFER, velocity_tbo);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, velocity_buffer);
glBindTexture(GL_TEXTURE_BUFFER, start_position_tbo);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, start_position_buffer);
glBindTexture(GL_TEXTURE_BUFFER, end_position_tbo);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, end_position_buffer);
}
void CRT_Shader::VAOsSetup() {
glGenVertexArrays(1, &render_vao);
glBindVertexArray(render_vao);
glBindBuffer(GL_ARRAY_BUFFER, end_position_buffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
glBindBuffer(GL_ARRAY_BUFFER, velocity_buffer);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
/////////////////////
glBindBuffer(GL_ARRAY_BUFFER, color_buffer);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, 4 * sizeof(unsigned char), 0);
glBindBuffer(GL_ARRAY_BUFFER, magnets_buffer);
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
}
CRT_Shader::CRT_Shader() {
createRenderShader();
createComputeShader();
float top = crt_emission_angle(0).y;
float bottom = crt_emission_angle((PARTICLE_COUNT)-1).y;
if (CRT_FLIP_Y) {
float swap = top;
top = bottom;
bottom = swap;
}
orthoMat = ortho(crt_emission_angle(0).x,
crt_emission_angle((PARTICLE_COUNT) - 1).x,
bottom,
top,
-1.0f,
1.0f);
buffersSetup();
VAOsSetup();
CS_LTF = vec3(scaleToZOne(crt_emission_angle(0)).x, scaleToZOne(crt_emission_angle(0)).y, 0);
CS_RBF = vec3(scaleToZOne(crt_emission_angle((PARTICLE_COUNT) - 1)).x, scaleToZOne(crt_emission_angle((PARTICLE_COUNT) - 1)).y, 0);
CS_LTN = vec3(-0.1, 0.1, -1);
CS_RBN = vec3(0.1, -0.1, -1);
}
void CRT_Shader::draw(unsigned int ONE_TICK_MS, unsigned int timePassed) {
glBindBuffer(GL_ARRAY_BUFFER, magnets_buffer);
vec4* attractors = (vec4*)glMapNamedBufferRangeEXT(magnets_buffer, 0, 8 * sizeof(vec4), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
for (int i = 0; i < 8; i++)
attractors[i] = this->attractors[i];
glUnmapNamedBufferEXT(magnets_buffer);
//activate the compute program and bind the position
//and velocity buffers
glUseProgram(compute_prog);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, magnets_buffer);
glBindImageTexture(0, velocity_tbo, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
glBindImageTexture(1, start_position_tbo, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
glBindImageTexture(2, end_position_tbo, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
glUniform3f(glGetUniformLocation(compute_prog, "nearTopLeft"), CS_LTN.x, CS_LTN.y, CS_LTN.z);
glUniform3f(glGetUniformLocation(compute_prog, "nearBottomRight"), CS_RBN.x, CS_RBN.y, CS_RBN.z);
glUniform3f(glGetUniformLocation(compute_prog, "farTopLeft"), CS_LTF.x, CS_LTF.y, CS_LTF.z);
glUniform3f(glGetUniformLocation(compute_prog, "farBottomRight"), CS_RBF.x, CS_RBF.y, CS_RBF.z);
//set delta time
glUniform1f(dt_location, 1e-2 * pow(4, (int) resolution));
//dispatch the compute shader
glDispatchCompute(PARTICLE_GROUP_COUNT, 1, 1);
//ensure that writes by the compute shader have completed
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glUseProgram(render_prog);
glUniformMatrix4fv(glGetUniformLocation(render_prog, "mvp"), 1, GL_FALSE, value_ptr(orthoMat));
glUniform1ui(glGetUniformLocation(render_prog, "pixelWidth"), CRT_PIXEL_SCALE * 1000 * CRT_PIXEL_LENGTH);
glBindVertexArray(render_vao);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glPointSize(CRT_PIXEL_SCALE);
glDrawArrays(GL_POINTS, 0, PARTICLE_COUNT);
glDisable(GL_BLEND);
}
void CRT_Shader::setMagnet(int index, vec4 positionAndMass) {
float vieww = scaleToZOne(crt_emission_angle((PARTICLE_COUNT) - 1)).x - scaleToZOne(crt_emission_angle(0)).x;
float viewh = scaleToZOne(crt_emission_angle((PARTICLE_COUNT) - 1)).y - scaleToZOne(crt_emission_angle(0)).y;
magx = vieww * (positionAndMass.x - CRT_WIDTH / 2) / ((float)CRT_WIDTH);
magy = viewh * (positionAndMass.y - CRT_HEIGHT / 2) / ((float)CRT_HEIGHT);
attractors[index] = vec4(magx, magy, positionAndMass.z, positionAndMass.w * pow(4, (int)-resolution));
}
/*
DOES ANYTHING CHANGE WITH CRT_FLIP_Y ???
*/
float CRT_Shader::getLeftBound() {
return -CRT_WIDTH / 2;
}
float CRT_Shader::getRightBound() {
return CRT_WIDTH / 2;
}
float CRT_Shader::getBottomBound() {
return -(CRT_HEIGHT / 2);
}
float CRT_Shader::getTopBound() {
return (CRT_HEIGHT / 2);
}
void CRT_Shader::loadColorFromFramebuffer(GLuint FBO) {
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glBindBuffer(GL_PIXEL_PACK_BUFFER, color_buffer);
glReadPixels(0, 0, CRT_HORIZONTAL_PIXELS, CRT_VERTICAL_PIXELS, GL_RGBA, GL_UNSIGNED_BYTE, 0);
}

View File

@@ -0,0 +1,22 @@
#include "../../HEADERS/EFFECTS/PseudoContext.h"
#include <vector>
PseudoContext::PseudoContext(int left, int top, int width, int height) {
this->width = width;
this->height = height;
this->top = top;
this->left = left;
}
std::vector<int> PseudoContext::getBounds() {
int top = this->top;
int bottom = this->top + this->height;
int left = this->left;
int right = this->left + this->width;
std::vector<int> result = std::vector<int>();
result.push_back(top);
result.push_back(bottom);
result.push_back(left);
result.push_back(right);
return result;
}

View File

@@ -0,0 +1,54 @@
/*
#include <GL/glew.h>
*/
#include <GLES2/gl2.h>
#include "../../HEADERS/EFFECTS/ReelManager.h"
#include <vector>
/* equals stdlib.h from C */
#include <cstdlib>
ReelManager::ReelManager(unsigned int textureNumber, unsigned int width, unsigned int height) {
TEXTURE_NUM = textureNumber;
textures = (GLuint*) malloc(TEXTURE_NUM * sizeof(GLuint));
glGenFramebuffers(1, &FBO);
glGenTextures(TEXTURE_NUM, textures);
for (int i = 0; i < TEXTURE_NUM; i++) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
}
glBindTexture(GL_TEXTURE_2D, 0);
}
void ReelManager::nextTexture() {
currentIndex = ++currentIndex % TEXTURE_NUM;
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[currentIndex], 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void ReelManager::clearTexture() {
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[currentIndex], 0);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
GLuint ReelManager::getFBO() {
return FBO;
}
std::vector<GLuint> ReelManager::getTextures() {
std::vector<GLuint> vec = std::vector<GLuint>();
for (int i = currentIndex + 1 ; i < TEXTURE_NUM; i++) {
vec.push_back(textures[i]);
}
for (int i = 0; i <= currentIndex; i++) {
vec.push_back(textures[i]);
}
return vec;
}

View File

@@ -0,0 +1,18 @@
#version 300 es
/*this will affect all the float guys (float, vecN, matN )*/
precision mediump float;
in vec3 fragPos;
in vec2 frag_uv; //coordinate 2d di texure
uniform sampler2D inTex; //campionatore 2d
out vec4 FragColor;
void main()
{
//FragColor = vec4(1.0f, 1.0f, 0, 1);
FragColor = texture(inTex, frag_uv);
}

View File

@@ -0,0 +1,21 @@
#version 300 es
/*this will affect all the float guys (float, vecN, matN )*/
precision mediump float;
layout (location = 0) in vec3 vertPos; // Attributo Posizione
out vec3 fragPos;
out vec2 frag_uv;
void main()
{
float adjustedU = (vertPos.x + 1) / 2;
float adjustedV = (vertPos.y + 1) / 2;
frag_uv = vec2(adjustedU, adjustedV);
fragPos = vertPos;
gl_Position = vec4(fragPos, 1);
}

View File

@@ -0,0 +1,56 @@
#include "../../HEADERS/EFFECTS/Scene.h"
extern "C" {
#include "../../GLES_3_1_compatibility.h"
}
/* REPLACED
#include <GL/freeglut.h>
*/
#include <glut.h>
#include <glm/gtc/matrix_transform.hpp>
#include <string>
#include <iostream>
using namespace glm;
Scene::Scene(int left, int top, int width, int height)
: PseudoContext { left, top, width, height }
{
glGenFramebuffers(1, &FBO);
glGenRenderbuffers(1, &depthRBO);
glBindRenderbuffer(GL_RENDERBUFFER, depthRBO);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
void Scene::draw() {
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, outputTexture, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRBO);
GLenum DrawBuffers[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_STENCIL_ATTACHMENT };
glDrawBuffers(2, DrawBuffers);
}
void Scene::setOutTexture(GLuint outTexture) {
outputTexture = outTexture;
}
void Scene::keyPress(unsigned char key, int x, int y) {
switch (key)
{
case 27:
exit(0);
break;
default:
break;
}
}
GLuint Scene::getFrameBuffer() {
return this->FBO;
}

View File

@@ -0,0 +1,48 @@
#include "../../HEADERS/EFFECTS/Screen.h"
extern "C" {
#include "../../GLES_3_1_compatibility.h"
#include <glut.h>
}
#include <string>
#include "../../HEADERS/UTILS/ShaderMaker.h"
Screen::Screen(int left, int top, int width, int height)
: PseudoContext{ left, top, width, height }
{
glGenVertexArrays(1, &quadVAO);
glBindVertexArray(quadVAO);
glGenBuffers(1, &vertVBO);
glBindBuffer(GL_ARRAY_BUFFER, vertVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVerts), quadVerts, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float)/**/,(void*) 0);
glEnableVertexAttribArray(0);
string root = "C:\\Users\\BoBoBoat\\Desktop\\SCUOLA\\CGI\\GL_STUFF\\GL_STUFF\\SOURCES\\EFFECTS\\SCREEN";
string vertSh = root + "\\vertexShader_2.glsl";
string fragSh = root + "\\fragmentShader_2.glsl";
program2 = ShaderMaker::createProgram(&vertSh[0], &fragSh[0]);
shaderTexId = glGetUniformLocation(program2, "inTex");
}
void Screen::setInputTexture(GLuint inputTex) {
inputTexture = inputTex;
}
void Screen::draw() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
//glViewport(left, top, width, height);
//gluOrtho2D(0, width, height, 0);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(program2);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, inputTexture);
glUniform1i(shaderTexId, 0);
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glutSwapBuffers();
}

View File

@@ -0,0 +1,27 @@
#version 300 es
/*this will affect all the float guys (float, vecN, matN )*/
precision mediump float;
in vec3 fragPos;
in vec2 frag_uv; //coordinate 2d di texure
uniform sampler2D inTex1; //campionatore 2d
uniform sampler2D inTex2;
out vec4 FragColor;
vec4 max4(vec4 a, vec4 b){
return vec4( max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w));
}
void main()
{
float mergeFac = 0.6;
float adjFac = 1.5;
//FragColor = vec4(1.0f, 1.0f, 0, 1);
FragColor = mix(texture(inTex1, frag_uv), texture(inTex2, frag_uv), mergeFac);
FragColor = vec4( clamp( 0, 1, adjFac * FragColor.x), clamp( 0, 1, adjFac * FragColor.y), clamp( 0, 1, adjFac * FragColor.z), clamp( 0, 1, adjFac * FragColor.w));
//FragColor = 0.25 * texture(inTex1, frag_uv) + 0.75 * texture(inTex2, frag_uv);//max4(texture(inTex1, frag_uv) , texture(inTex2, frag_uv));
}

View File

@@ -0,0 +1,20 @@
#version 300 es
/*this will affect all the float guys (float, vecN, matN )*/
precision mediump float;
layout (location = 0) in vec3 vertPos; // Attributo Posizione
out vec3 fragPos;
out vec2 frag_uv;
void main()
{
float adjustedU = (vertPos.x + 1) / 2;
float adjustedV = (vertPos.y + 1) / 2;
frag_uv = vec2(adjustedU, adjustedV);
fragPos = vertPos;
gl_Position = vec4(fragPos, 1);
}

View File

@@ -0,0 +1,134 @@
#include "../../HEADERS/EFFECTS/TexMerger.h"
#include "../../HEADERS/UTILS/ShaderMaker.h"
#include <string>
#include <iostream>
#include <glm/glm.hpp>
extern "C" {
#include "../../GLES_3_1_compatibility.h"
}
TexMerger::TexMerger(GLuint texCount, unsigned int texWidth, unsigned int texHeight) {
glGenVertexArrays(1, &quadVAO);
glBindVertexArray(quadVAO);
glGenBuffers(1, &vertVBO);
glBindBuffer(GL_ARRAY_BUFFER, vertVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVerts), quadVerts, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float)/**/, (void*)0);
glEnableVertexAttribArray(0);
std::string root = "C:\\Users\\BoBoBoat\\Desktop\\SCUOLA\\CGI\\GL_STUFF\\GL_STUFF\\SOURCES\\EFFECTS\\TEX_MERGER";
std::string vertSh = root + "\\vertexShader_merger.glsl";
std::string fragSh = root + "\\fragmentShader_merger.glsl";
program = ShaderMaker::createProgram(&vertSh[0], &fragSh[0]);
shaderTex1Id = glGetUniformLocation(program, "inTex1");
shaderTex2Id = glGetUniformLocation(program, "inTex2");
bufCount = ceil(log2((float)texCount));
mergeBuffers = (GLuint*) malloc(bufCount * sizeof(GLuint));
glGenFramebuffers(1, &FBO);
glGenTextures(bufCount, mergeBuffers);
for (unsigned int i = 0; i < bufCount; i++) {
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, mergeBuffers[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); //RGB o RGBA?
usageMap.push_back(false);
}
}
GLuint TexMerger::reserveBuffer() {
unsigned int index = 0;
while (index < bufCount && usageMap[index]) {
index++;
}
if (index >= bufCount)
throw "TexMerger::reserveBuffer : free buffer not found";
return mergeBuffers[index];
}
bool TexMerger::isBuffer(GLuint number) {
bool found = false;
int index = -1;
while (!found && (++index < bufCount))
if (mergeBuffers[index] == number)
found = true;
return found;
}
void TexMerger::freeBuffer(GLuint number) {
bool found = false;
int index = -1;
while (!found && (++index < bufCount))
if (mergeBuffers[index] == number)
found = true;
if (found)
usageMap[index] = false;
else
throw "TexMerger::freeBuffer : index not found";
}
/*(BUFFER è in realtà un indice)
* MERGE (START,END)
* if (END - START) == 0
* leggi la texture
* ritorna texture
* else
* MID = (START + END) / 2
* B1 = MERGE(START, MID)
* B2 = MERGE(MID + 1, END )
* scegli un BUFFER libero (bloccante)
* somma B1, B2 nel BUFFER
* sblocca tra B1 e B2 quelli che sono BUFFER
* ritorna BUFFER
*/
GLuint TexMerger::merge(std::vector<GLuint> inTextures, int startIndex, int endIndex) {
if ((endIndex - startIndex) == 0) {
return inTextures[startIndex];
}
else {
int mid = (startIndex + endIndex) / 2;
GLuint buf1;
GLuint buf2;
GLuint result;
try{
buf1 = merge(inTextures, startIndex, mid);
buf2 = merge(inTextures, mid + 1, endIndex);
result = reserveBuffer();
}
catch( std::string ex){
std::cout << ex;
}
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, result, 0);
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
/* commented and not available
glDrawBuffers(1, DrawBuffers);
*/
//glClearColor(0, 0, 0, 0);
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(program);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, buf1);
glUniform1i(shaderTex1Id, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, buf2);
glUniform1i(shaderTex2Id, 1);
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
if (isBuffer(buf1))
freeBuffer(buf1);
if (isBuffer(buf2))
freeBuffer(buf2);
return result;
}
}

203
GL_STUFF/SOURCES/SCENE/Camera.cpp Executable file
View File

@@ -0,0 +1,203 @@
#define GLM_ENABLE_EXPERIMENTAL
#include "../../HEADERS/SCENE/Camera.hpp"
/* REPLACED
#include <GL/freeglut.h>
*/
extern "C" {
#include <glut.h>
}
#include <glm/gtc/matrix_transform.hpp>
#include <string>
#include <iostream>
#include <glm/gtx/transform.hpp>
#include <glm/gtx/norm.hpp>
/* don't know how it worked before */
#include <glm/gtx/quaternion.hpp>
/* aarch64-linux-gnu/include/math.h already defines it */
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288
#endif
using namespace glm;
Camera::Camera() {
this->cameraPos = vec3();
this->cameraFront = vec3(0.0f, 0.0f, -1.0f);
this->cameraUp = vec3(0.0f, 1.0f, 0.0f);
}
Camera::Camera(vec3 position, vec3 front, vec3 up) {
if (! glm::length(front))
throw std::invalid_argument("Camera : front vector has no length");
if (! glm::length(up))
throw std::invalid_argument("Camera : up vector has no length");
this->cameraPos = position;
this->cameraFront = front;
this->cameraUp = up;
}
glm::mat4 Camera::getViewMat() {
return lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
}
glm::vec3 Camera::getPosition() {
return cameraPos;
}
void Camera::setPosition(glm::vec3 pos) {
cameraPos = pos;
}
void Camera::alignTo(glm::vec3 direction) {
glm::vec3 localZ;
direction = glm::normalize(direction);
localZ = cameraFront;
glm::quat a = glm::rotation(localZ, direction);
cameraFront = glm::toMat4(a) * glm::vec4(cameraFront, 0.0f);
cameraUp = glm::toMat4(a) * glm::vec4(cameraUp, 0.0f); //temp
// ++++++++++++++++++++++++++ //
glm::vec3 right = glm::normalize(cross(cameraFront, cameraUp));
right.y = 0;
glm::vec3 stabilizedR = glm::normalize(right);
cameraUp = glm::cross(stabilizedR, cameraFront);
}
CameraController::CameraController(Camera *cam) {
lastX = 0;
lastY = 0;
windowHeight = 0;
windowWidth = 0;
windowTop = 0;
windowLeft = 0;
this->camera = cam;
}
Camera* CameraController::getCamera() {
return camera;
}
void CameraController::setWindowData(int left, int width, int top, int height) {
windowLeft = left;
windowWidth = width;
windowTop = top;
windowHeight = height;
lastX = left + width / 2;
lastY = top + height / 2;
}
void CameraController::mouseMotion(int cursorX, int cursorY) {
//return;
float alfa = 0.05; //serve ridimensionare l'offset tra due posizioni successive del mouse
//il mouse è appena entrato nella finestra
if (mouseUnlocked)
{
lastX = windowLeft + windowWidth / 2;
lastY = windowTop + windowHeight / 2;
mouseUnlocked = false;
}
//di quanto ci siamo mossi
float xoffset = (cursorX - lastX);
float yoffset = (lastY - cursorY);
glutWarpPointer(windowLeft + windowWidth / 2, windowTop + windowHeight / 2);
lastX = windowLeft + windowWidth / 2;
lastY = windowTop + windowHeight / 2;
xoffset *= alfa;
yoffset *= alfa;
PHI += yoffset;
THETA += xoffset;
//if (PHI >= 179.0)
// PHI = 179;
vec3 direction;
direction.x = cos(radians(PHI)) * cos(radians(THETA));
direction.y = sin(radians(PHI));
direction.z = cos(radians(PHI)) * sin(radians(THETA));
getCamera()->cameraFront = normalize(direction);
}
void CameraController::keyPress(unsigned char key) {
Camera *c = getCamera();
vec3 dir;
switch (key)
{
case 'a':
//Calcolo la direzione perpendicolare alla direzione della camera e l'alto della camera
dir = normalize(cross(getCamera()->cameraFront, getCamera()->cameraUp));
//Mi sposto a sinistra lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos - dir * cameraSpeed;
break;
case 'A':
//Calcolo la direzione perpendicolare alla direzione della camera e l'alto della camera
dir = normalize(cross(c->cameraFront, c->cameraUp));
//Mi sposto a sinistra lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos - dir * (cameraSpeed * 10);
break;
case 'd':
//Calcolo la irezione perpendicolare alla direzione della camera e l'alto della camera
dir = normalize(cross(c->cameraFront, c->cameraUp));//Mi sposto a destra lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos + dir * cameraSpeed;
break;
case 'D':
//Calcolo la irezione perpendicolare alla direzione della camera e l'alto della camera
dir = normalize(cross(c->cameraFront, c->cameraUp));//Mi sposto a destra lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos + dir * (cameraSpeed * 10);
break;
case 's':
//Mi sposto indietro lungo la direzione della camera
c->cameraPos = c->cameraPos - cameraSpeed * c->cameraFront;
break;
case 'S':
//Mi sposto indietro lungo la direzione della camera
c->cameraPos = c->cameraPos - (cameraSpeed * 10) * c->cameraFront;
break;
case 'w':
//Mi sposto avanti lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos + cameraSpeed * c->cameraFront;
break;
case 'W':
//Mi sposto avanti lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos + (cameraSpeed * 10) * c->cameraFront;
break;
case 'r':
//Mi sposto avanti lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos + cameraSpeed * c->cameraUp;
break;
case 'R':
//Mi sposto avanti lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos + (cameraSpeed * 10) * c->cameraUp;
break;
case 'f':
//Mi sposto avanti lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos - cameraSpeed * c->cameraUp;
break;
case 'F':
//Mi sposto avanti lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos - (cameraSpeed * 10) * c->cameraUp;
break;
default:
break;
}
}

View File

@@ -0,0 +1,21 @@
#include "../../HEADERS/SCENE/Instance3D.h"
Instance3D::Instance3D(Model3D* mesh, vec3 position) : WorldInstanceable{ position } {
this->mesh = mesh;
}
Instance3D::Instance3D(Model3D* mesh, vec3 position, vec3 scale) : WorldInstanceable{ position , scale } {
this->mesh = mesh;
}
Instance3D::Instance3D(Model3D* mesh, vec3 position, vec3 axis, float angle) : WorldInstanceable{ position, axis, angle } {
this->mesh = mesh;
}
Instance3D::Instance3D(Model3D* mesh, vec3 position, vec3 scale, vec3 axis, float angle) : WorldInstanceable { position, scale, axis, angle } {
this->mesh = mesh;
}
Model3D* Instance3D::getModel() {
return this->mesh;
}

View File

@@ -0,0 +1,85 @@
#include <regex>
#include <iostream>
#include <sstream>
#include "../../HEADERS/SCENE/InstancesLoader.h"
char lineHeader[128];
char* res;
FILE* file;
std::smatch pieces;
Instance3D* parseInstanceData(Model3D* model, string str) {
vector<float> vecComponents = vector<float>();
std::regex regex("-?\\d+.\\d+");
std::regex_search(str, pieces, regex);
float x = stof(pieces[0], NULL); //potevi evitare la regex
str = pieces.suffix().str();
std::regex_search(str, pieces, regex);
float y = stof(pieces[0], NULL); //potevi evitare la regex
str = pieces.suffix().str();
std::regex_search(str, pieces, regex);
float z = stof(pieces[0], NULL); //potevi evitare la regex
str = pieces.suffix().str();
std::regex_search(str, pieces, regex);
float rotx = stof(pieces[0], NULL); //potevi evitare la regex
str = pieces.suffix().str();
std::regex_search(str, pieces, regex);
float roty = stof(pieces[0], NULL); //potevi evitare la regex
str = pieces.suffix().str();
std::regex_search(str, pieces, regex);
float rotz = stof(pieces[0], NULL); //potevi evitare la regex
Instance3D* inst = new Instance3D(model, vec3(x, y, z), vec3(1));
inst->rotate(vec3(1, 0, 0), rotx);
inst->rotate(vec3(0, 1, 0), roty);
inst->rotate(vec3(0, 0, 1), rotz);
return inst;
}
/* TOFIX: broken */
bool loadInstances(std::string path, vector<Instance3D*>& instances, bool smoothNormals) {
bool modelLoaded = false;
std::stringstream fileName;
Model3D* currentModel = NULL;
/*on windows was last of \\ */
string root = path.substr(0, path.find_last_of("/") + 1);
file = fopen(&path[0], "r");
if (file == NULL) {
printf("Impossible to open the scene file ! Are you in the right path ?\n");
getchar();
return false;
}
while (1) {
res = fgets(lineHeader, 128, file); // read the first word of the line
// EOF = End Of File. Store pending curve and quit the loop.
if (res == NULL) {
break;
}
string str = lineHeader;
std::regex regex("\\w+\\n");
//inizia una serie di istanze(la prima o una nuova)
if (std::regex_match(str, pieces, regex)) {
std::regex regex("\\w+");
std::regex_search(str, pieces, regex);
fileName.str(std::string()); //clear
fileName << root << pieces[0].str() << ".obj";
string mdl = fileName.str();
currentModel = new Model3D(&mdl[0], smoothNormals);
modelLoaded = true;
}
//devono essere i dati di trasformazione di un istanza
else {
std::regex regex("\\s*(-?\\d+.\\d+)(( , -?\\d+.\\d+)+)\\s*(\\n)?");
//sono dati di un vertice
if (std::regex_match(str, pieces, regex) && modelLoaded) {
instances.push_back(parseInstanceData(currentModel, str));
}
else {
std::cout << "unrecognized scene line : " << str << std::endl;
}
}
}
std::cout << "trovati " << instances.size() << std::endl;
return true;
}

View File

@@ -0,0 +1,159 @@
#include "../../HEADERS/SCENE/Model3D.hpp"
extern "C" {
#include "../../GLES_3_1_compatibility.h"
}
#include "../../HEADERS/UTILS/OnlyOnce.hpp"
#include "../../HEADERS/UTILS/ShaderMaker.h"
#include "../../HEADERS/SCENE/objloader.hpp"
#include "../../HEADERS/UTILS/ResourceCache.h"
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
/* the gl**OES functions are calls which are not in the original OpenGL ES 2
OpenGL ES 3 would have supported them, ES 2 offers them as extensions
*/
Model3D::Model3D(const char* modelPath, bool smoothNormals) {
vector<vec3> points = loadVertexData(modelPath, smoothNormals);
computeBoundingBox(points);
}
void Model3D::computeBoundingBox(vector<vec3> points) {
boundingBoxLBN = points[0];
boundingBoxRTF = points[0];
for (const vec3& point : points) {
boundingBoxLBN.x = glm::min(boundingBoxLBN.x, point.x);
boundingBoxLBN.y = glm::min(boundingBoxLBN.y, point.y);
boundingBoxLBN.z = glm::max(boundingBoxLBN.z, point.z);
boundingBoxRTF.x = glm::max(boundingBoxRTF.x, point.x);
boundingBoxRTF.y = glm::max(boundingBoxRTF.y, point.y);
boundingBoxRTF.z = glm::min(boundingBoxRTF.z, point.z);
}
}
vector<vec3> Model3D::loadVertexData(const char* modelPath, bool smoothNormals) {
unsigned int vbo, vboUv, vboNor, vboTangent, vboBitangent;
vector<vec3> vertices;
vector<int> verticesIndex;
vector<vec2> verticesUv;
vector<vec3> verticesNor;
vector<vec3> verticesTangent;
vector<vec3> verticesBitangent;
loadOBJ(modelPath, vertices, verticesUv, verticesNor, smoothNormals);
/* the windows version was happy even with %d */
printf("Vertici : %ld\tUVcoord : %ld\tNormali : %ld\n", vertices.size(), verticesUv.size(), verticesNor.size() );
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// VBO vertici
{
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vec3), &vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0/* 3 * sizeof(float)*/, 0);
Model3D::nVertices = vertices.size();
}
// VBO coordinate UV
{
glGenBuffers(1, &vboUv);
glBindBuffer(GL_ARRAY_BUFFER, vboUv);
glBufferData(GL_ARRAY_BUFFER, verticesUv.size() * sizeof(vec2), &verticesUv[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,0 /*2 * sizeof(float)*/, 0);
}
// VBO normali
{
glGenBuffers(1, &vboNor);
glBindBuffer(GL_ARRAY_BUFFER, vboNor);
glBufferData(GL_ARRAY_BUFFER, verticesNor.size() * sizeof(vec3), &verticesNor[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0/* 3 * sizeof(float)*/,0);
}
// VBO tangenti e VBO bitangenti
{
for (int i = 0; i < vertices.size(); i += 3) {
//erano del tipo vec2& =
// Shortcuts for vertices
vec3 v0 = vertices[i + 0];
vec3 v1 = vertices[i + 1];
vec3 v2 = vertices[i + 2];
// Shortcuts for UVs
vec2 uv0 = verticesUv[i + 0];
vec2 uv1 = verticesUv[i + 1];
vec2 uv2 = verticesUv[i + 2];
// Edges of the triangle : position delta
vec3 deltaPos1 = v1 - v0;
vec3 deltaPos2 = v2 - v0;
// UV delta
vec2 deltaUV1 = uv1 - uv0;
vec2 deltaUV2 = uv2 - uv0;
float r = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV1.y * deltaUV2.x);
vec3 tangent = (deltaPos1 * deltaUV2.y - deltaPos2 * deltaUV1.y) * r;
vec3 bitangent = (deltaPos2 * deltaUV1.x - deltaPos1 * deltaUV2.x) * r;
// Set the same tangent for all three vertices of the triangle.
verticesTangent.push_back(tangent);
verticesTangent.push_back(tangent);
verticesTangent.push_back(tangent);
// Same thing for bitangents
verticesBitangent.push_back(bitangent);
verticesBitangent.push_back(bitangent);
verticesBitangent.push_back(bitangent);
}
glGenBuffers(1, &vboTangent);
glBindBuffer(GL_ARRAY_BUFFER, vboTangent);
glBufferData(GL_ARRAY_BUFFER, verticesTangent.size() * sizeof(vec3), &verticesTangent[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, 0);
glGenBuffers(1, &vboBitangent);
glBindBuffer(GL_ARRAY_BUFFER, vboBitangent);
glBufferData(GL_ARRAY_BUFFER, verticesBitangent.size() * sizeof(vec3), &verticesBitangent[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 0, 0);
}
return vertices;
}
void Model3D::draw() {
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, nVertices);
glBindVertexArray(0);
}
GLuint Model3D::getVAO() {
return this->vao;
}
int Model3D::getTrisCount() {
return this->nVertices;
}
vec3 Model3D::getLBN() {
return boundingBoxLBN;
}
vec3 Model3D::getRTF() {
return boundingBoxRTF;
}

View File

@@ -0,0 +1,103 @@
#include "../../HEADERS/SCENE/ObjectInstance.hpp"
#include <glm/gtc/matrix_transform.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/transform.hpp>
#include <glm/gtx/norm.hpp>
#include <iostream>
/*was glm/gtc/before */
#include <glm/gtx/quaternion.hpp>
/* aarch64-linux-gnu/include/math.h already defines it */
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288
#endif
glm::mat4 WorldInstanceable::getLocalTransform() {
glm::mat4 transform = glm::mat4(1.0);
transform *= scaleMat;
transform *= rotation;
return transform;
}
glm::mat4 WorldInstanceable::getGlobalTransform() {
glm::mat4 transform = getLocalTransform();
//transform = glm::translate(glm::mat4(transform), position);
return glm::translate(glm::mat4(1.0), position) * transform;
}
void WorldInstanceable::alignTo(glm::vec3 direction) {
glm::vec3 localZ;
direction = glm::normalize(direction);
localZ = localFront;
glm::quat a = glm::rotation(localZ, direction);
localFront = glm::toMat4(a) * glm::vec4(localFront, 0.0f);
glm::quat b = glm::rotation(localZ, direction);
localUp = glm::toMat4(b) * glm::vec4(localUp, 0.0f);
//++++++++++++++++++++++++++
//glm::vec3 right = glm::normalize(cross(localFront, localUp));
glm::vec3 right = glm::normalize(cross(localUp, localFront));
right.y = 0;
glm::vec3 stabilizedR = glm::normalize(right);
glm::quat c = glm::rotation(right, stabilizedR);
localUp = glm::toMat4(c) * glm::vec4(localUp, 0);
localUp = -glm::cross(stabilizedR, localFront);
rotation = glm::mat4(glm::mat3(stabilizedR, localUp, localFront));
}
void WorldInstanceable::setPosition(glm::vec3 position) {
this->position = position;
}
void WorldInstanceable::rotate(glm::vec3 axis, float angle) {
rotation *= glm::rotate(glm::radians(angle), axis);
}
void WorldInstanceable::scale(float factor) {
scaleMat *= glm::scale(glm::mat4(1.0), glm::vec3(factor));
}
void WorldInstanceable::scale(glm::vec3 factors) {
scaleMat *= glm::scale(glm::mat4(1.0), factors);
}
void WorldInstanceable::setup(glm::vec3 position) {
this->position = position;
localFront = glm::vec3( 0, 0, 1);
localUp = glm::vec3( 0, 1, 0);
rotation = glm::mat4(1.0f);
scaleMat = glm::mat4(1.0f);
}
WorldInstanceable::WorldInstanceable(glm::vec3 position) {
setup(position);
}
WorldInstanceable::WorldInstanceable(glm::vec3 position, glm::vec3 scale) {
setup(position);
this->scale(scale);
}
WorldInstanceable::WorldInstanceable(glm::vec3 position, glm::vec3 axis, float angle) {
setup(position);
this->rotate(axis, angle);
}
WorldInstanceable::WorldInstanceable(glm::vec3 position, glm::vec3 scale, glm::vec3 axis, float angle) {
setup(position);
this->scale(scale);
this->rotate(axis, angle);
}

View File

@@ -0,0 +1,40 @@
#include "../../HEADERS/SCENE/ShadingHelper.h"
#include <glm/gtc/type_ptr.hpp>
ShadingHelper::ShadingHelper(GLuint program) {
this->program = program;
}
void ShadingHelper::useProgram() {
glUseProgram(program);
}
GLuint ShadingHelper::getProgram() {
return program;
}
void ShadingHelper::bindTexture2D(GLuint texUnitIndex, GLuint texture, std::string uniform) {
glActiveTexture(GL_TEXTURE0 + texUnitIndex);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glGetUniformLocation(program, &uniform[0]), texUnitIndex);
}
void ShadingHelper::bindViewUniforms(glm::mat4 projection, glm::mat4 view) {
GLint projectionUniform = glGetUniformLocation(program, "Projection");
glUniformMatrix4fv(projectionUniform, 1, GL_FALSE, value_ptr(projection));
GLint viewUniform = glGetUniformLocation(program, "View");
glUniformMatrix4fv(viewUniform, 1, GL_FALSE, value_ptr(view));
}
void ShadingHelper::bindLightUniforms(glm::vec3 lightPos, glm::vec3 lightCol, glm::vec3 eyePos) {
glUniform3f(glGetUniformLocation(program, "lightPos"), lightPos.x, lightPos.y, lightPos.z);
glUniform3f(glGetUniformLocation(program, "lightCol"), lightCol.x, lightCol.y, lightCol.z);
glUniform3f(glGetUniformLocation(program, "eyePos"), eyePos.x, eyePos.y, eyePos.z);
}
void ShadingHelper::bindModelUniforms(glm::mat4 locRotScl, glm::mat4 rotScl) {
GLint localTransformUniform = glGetUniformLocation(program, "Model");
glUniformMatrix4fv(localTransformUniform, 1, GL_FALSE, value_ptr(locRotScl));
GLint onlyRotationUniform = glGetUniformLocation(program, "ModelRot");
glUniformMatrix4fv(onlyRotationUniform, 1, GL_FALSE, value_ptr(rotScl));
}

View File

@@ -0,0 +1,134 @@
#include <vector>
#include <stdio.h>
#include <string>
#include <cstring>
#include <glm/glm.hpp>
#include "../../HEADERS/SCENE/objloader.hpp"
// Very, VERY simple OBJ loader.
// Here is a short list of features a real function would provide :
// - Binary files. Reading a model should be just a few memcpy's away, not parsing a file at runtime. In short : OBJ is not very great.
// - Animations & bones (includes bones weights)
// - Multiple UVs
// - All attributes should be optional, not "forced"
// - More stable. Change a line in the OBJ file and it crashes.
// - More secure. Change another line and you can inject code.
// - Loading from memory, stream, etc
bool loadOBJ(
const char* path,
std::vector<glm::vec3>& out_vertices,
std::vector<glm::vec2>& out_uvs,
std::vector<glm::vec3>& out_normals,
bool smoothNormals
) {
printf("Loading OBJ file %s...\n", path);
std::vector<unsigned int> vertexIndices, uvIndices, normalIndices;
std::vector<glm::vec3> temp_vertices;
std::vector<glm::vec2> temp_uvs;
std::vector<glm::vec3> temp_normals;
FILE* file = fopen(path, "r");
if (file == NULL) {
printf("Impossible to open the file ! Are you in the right path ? See Tutorial 1 for details\n");
getchar();
return false;
}
while (1) {
char lineHeader[128];
// read the first word of the line
int res = fscanf(file, "%s", lineHeader);
if (res == EOF)
break; // EOF = End Of File. Quit the loop.
// else : parse lineHeader
if (strcmp(lineHeader, "v") == 0) {
glm::vec3 vertex;
fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z);
temp_vertices.push_back(vertex);
}
else if (strcmp(lineHeader, "vt") == 0) {
glm::vec2 uv;
fscanf(file, "%f %f\n", &uv.x, &uv.y);
uv.y = -uv.y; // Invert V coordinate since we will only use DDS texture, which are inverted. Remove if you want to use TGA or BMP loaders.
temp_uvs.push_back(uv);
}
else if (strcmp(lineHeader, "vn") == 0) {
glm::vec3 normal;
fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z);
temp_normals.push_back(normal);
}
else if (strcmp(lineHeader, "f") == 0) {
std::string vertex1, vertex2, vertex3;
unsigned int vertexIndex[3], uvIndex[3], normalIndex[3];
/* the Windows version accepted even the %d specifier, here is more strict */
int matches = fscanf(file, "%u/%u/%u %u/%u/%u %u/%u/%u\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2]);
if (matches != 9) {
printf("File can't be read by our simple parser :-( Try exporting with other options\n");
fclose(file);
return false;
}
vertexIndices.push_back(vertexIndex[0]);
vertexIndices.push_back(vertexIndex[1]);
vertexIndices.push_back(vertexIndex[2]);
uvIndices.push_back(uvIndex[0]);
uvIndices.push_back(uvIndex[1]);
uvIndices.push_back(uvIndex[2]);
normalIndices.push_back(normalIndex[0]);
normalIndices.push_back(normalIndex[1]);
normalIndices.push_back(normalIndex[2]);
}
else {
// Probably a comment, eat up the rest of the line
char stupidBuffer[1000];
fgets(stupidBuffer, 1000, file);
}
}
// For each vertex of each triangle
for (unsigned int i = 0; i < vertexIndices.size(); i++) {
// Get the indices of its attributes
unsigned int vertexIndex = vertexIndices[i];
unsigned int uvIndex = uvIndices[i];
unsigned int normalIndex = normalIndices[i];
// Get the attributes thanks to the index
glm::vec3 vertex = temp_vertices[vertexIndex - 1];
glm::vec2 uv = temp_uvs[uvIndex - 1];
glm::vec3 normal;
if (smoothNormals) {
normal = glm::vec3();
unsigned int count = 0;
for (int j = 0; j < vertexIndices.size(); j++) {
if (vertexIndices[i] == vertexIndices[j]) {
normal += temp_normals[normalIndices[j] - 1];
count++;
}
}
printf("averaging %d normals\n", count);
normal /= count; //count is always greater than 0
}
else {
normal = temp_normals[normalIndex - 1];
}
// Put the attributes in buffers
out_vertices.push_back(vertex);
out_uvs.push_back(uv);
out_normals.push_back(normal);
}
fclose(file);
return true;
}

View File

@@ -0,0 +1,28 @@
#include "../../HEADERS/UTILS/ClockIterator.hpp"
#include <stdexcept>
ClockIterator::ClockIterator(unsigned int loopMillis) {
if(loopMillis == 0)
throw std::invalid_argument("ClockIterator: loop period must be greater than zero");
reset();
max = loopMillis;
}
void ClockIterator::reset() {
counter = 0;
}
unsigned int ClockIterator::step(unsigned int millis) {
counter += millis;
unsigned int res = counter / max;
counter %= max;
return res;
}
float ClockIterator::getPercentage() {
return (100.0f * counter) / max;
}
unsigned int ClockIterator::getPosition() {
return counter;
}

View File

@@ -0,0 +1,50 @@
#include "../../HEADERS/UTILS/OnlyOnce.hpp"
/*
#include <GL/glew.h>
*/
#ifndef STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#endif // !STB_IMAGE_IMPLEMENTATION
#include "../../HEADERS/UTILS/stb_image.h"
GLuint loadImg(const char* path) {
GLuint texture;
int width, height, nrChannels;
GLenum format;
unsigned char* data;
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
//Gestione minification e magnification
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
data = stbi_load(path, &width, &height, &nrChannels, 0);
if (data)
{
if (nrChannels == 3)
format = GL_RGB;
if (nrChannels == 4)
format = GL_RGBA;
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
printf("Tutto OK %d %d \n", width, height);
}
else
{
printf("LoadImage Errore nel caricare la texture\n");
printf("%s\n", stbi_failure_reason());
}
stbi_image_free(data);
glBindTexture(GL_TEXTURE_2D, 0);
return texture;
}

View File

@@ -0,0 +1,22 @@
#include "../../HEADERS/UTILS/ResourceCache.h"
#include "../../HEADERS/UTILS/ShaderMaker.h"
ResourceCache::ResourceCache() {
images = map<string, GLuint>();
shaders = map<string, GLuint>();
}
GLuint ResourceCache::getImage(string path) {
if (images.count(path) == 0) {
images[path] = loadImg(&path[0]);
}
return images.find(path)->second;
}
GLuint ResourceCache::getShader(string vertPath, string fragPath) {
string mapName = string(vertPath).append(fragPath);
if (shaders.count(mapName) == 0) {
shaders[mapName] = ShaderMaker::createProgram(&vertPath[0], &fragPath[0]);
}
return shaders.find(mapName)->second;
}

View File

@@ -0,0 +1,100 @@
#include "../../HEADERS/UTILS/ShaderMaker.h"
#include <iostream>
#include <fstream>
/* PORCATA AGGIUNTA IN SEGUITO */
#include <stdlib.h>
using namespace std;
char* ShaderMaker::readShaderSource(const char* shaderFile)
{
FILE* fp = fopen(shaderFile, "rb");
if (fp == NULL) { return NULL; }
fseek(fp, 0L, SEEK_END);
long size = ftell(fp);
fseek(fp, 0L, SEEK_SET);
char* buf = new char[size + 1];
fread(buf, 1, size, fp);
buf[size] = '\0';
fclose(fp);
return buf;
}
GLuint ShaderMaker::createProgram(char* vertexfilename, char *fragmentfilename)
{
GLenum ErrorCheckValue = glGetError();
// Creiamo gli eseguibili degli shader
//Leggiamo il codice del Vertex Shader
GLchar* VertexShader = readShaderSource(vertexfilename);
//Visualizzo sulla console il CODICE VERTEX SHADER
std::cout << VertexShader;
std::cout << "MACHEOH\n\n\n\n" << std::endl;
//Generiamo un identificativo per il vertex shader
GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
//Associamo all'identificativo il codice del vertex shader
glShaderSource(vertexShaderId, 1, (const char**)&VertexShader, NULL);
//Compiliamo il Vertex SHader
glCompileShader(vertexShaderId);
int success;
GLchar infoLog[512];
int logLength;
glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &success);
if ( GL_TRUE != success) {
glGetShaderInfoLog(vertexShaderId, 512, &logLength, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
//Leggiamo il codice del Fragment Shader
const GLchar* FragmentShader = readShaderSource(fragmentfilename);
//Visualizzo sulla console il CODICE FRAGMENT SHADER
std::cout << FragmentShader;
//Generiamo un identificativo per il FRAGMENT shader
GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShaderId, 1, (const char**)&FragmentShader, NULL);
//Compiliamo il FRAGMENT SHader
glCompileShader(fragmentShaderId);
glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS, &success);
if ( GL_TRUE != success) {
glGetShaderInfoLog(fragmentShaderId, 512, &logLength, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
ErrorCheckValue = glGetError();
cout << ErrorCheckValue;
if (ErrorCheckValue != GL_NO_ERROR)
{
fprintf(
stderr,
"ERROR: Could not create the shaders: %s | %x\n",
"(FIX MY SOURCE)",
ErrorCheckValue
);
exit(-1);
}
//Creiamo un identificativo di un eseguibile e gli colleghiamo i due shader compilati
GLuint programId = glCreateProgram();
glAttachShader(programId, vertexShaderId);
glAttachShader(programId, fragmentShaderId);
glLinkProgram(programId);
return programId;
}