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:
80
GL_STUFF/SOURCES/CURVES/Bezier.cpp
Executable file
80
GL_STUFF/SOURCES/CURVES/Bezier.cpp
Executable 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();
|
||||
}
|
||||
34
GL_STUFF/SOURCES/CURVES/Curve.cpp
Executable file
34
GL_STUFF/SOURCES/CURVES/Curve.cpp
Executable 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();
|
||||
}
|
||||
|
||||
110
GL_STUFF/SOURCES/CURVES/CurveIterator.cpp
Executable file
110
GL_STUFF/SOURCES/CURVES/CurveIterator.cpp
Executable 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;
|
||||
}
|
||||
203
GL_STUFF/SOURCES/CURVES/CurvesLoader.cpp
Executable file
203
GL_STUFF/SOURCES/CURVES/CurvesLoader.cpp
Executable 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;
|
||||
}
|
||||
|
||||
124
GL_STUFF/SOURCES/CURVES/Hermite.cpp
Executable file
124
GL_STUFF/SOURCES/CURVES/Hermite.cpp
Executable 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
128
GL_STUFF/SOURCES/CURVES/NURBS.cpp
Executable 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);
|
||||
}
|
||||
71
GL_STUFF/SOURCES/EFFECTS/CRT_SHADER/computeShader_particles.glsl
Executable file
71
GL_STUFF/SOURCES/EFFECTS/CRT_SHADER/computeShader_particles.glsl
Executable 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);
|
||||
}
|
||||
24
GL_STUFF/SOURCES/EFFECTS/CRT_SHADER/fragmentShader_particles.glsl
Executable file
24
GL_STUFF/SOURCES/EFFECTS/CRT_SHADER/fragmentShader_particles.glsl
Executable 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;
|
||||
}
|
||||
17
GL_STUFF/SOURCES/EFFECTS/CRT_SHADER/vertexShader_particles.glsl
Executable file
17
GL_STUFF/SOURCES/EFFECTS/CRT_SHADER/vertexShader_particles.glsl
Executable 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;
|
||||
}
|
||||
275
GL_STUFF/SOURCES/EFFECTS/CRT_shader.cpp
Executable file
275
GL_STUFF/SOURCES/EFFECTS/CRT_shader.cpp
Executable 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);
|
||||
}
|
||||
22
GL_STUFF/SOURCES/EFFECTS/PseudoContext.cpp
Executable file
22
GL_STUFF/SOURCES/EFFECTS/PseudoContext.cpp
Executable 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;
|
||||
}
|
||||
54
GL_STUFF/SOURCES/EFFECTS/ReelManager.cpp
Executable file
54
GL_STUFF/SOURCES/EFFECTS/ReelManager.cpp
Executable 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;
|
||||
}
|
||||
18
GL_STUFF/SOURCES/EFFECTS/SCREEN/fragmentShader_2.glsl
Executable file
18
GL_STUFF/SOURCES/EFFECTS/SCREEN/fragmentShader_2.glsl
Executable 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);
|
||||
}
|
||||
21
GL_STUFF/SOURCES/EFFECTS/SCREEN/vertexShader_2.glsl
Executable file
21
GL_STUFF/SOURCES/EFFECTS/SCREEN/vertexShader_2.glsl
Executable 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);
|
||||
}
|
||||
56
GL_STUFF/SOURCES/EFFECTS/Scene.cpp
Executable file
56
GL_STUFF/SOURCES/EFFECTS/Scene.cpp
Executable 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;
|
||||
}
|
||||
48
GL_STUFF/SOURCES/EFFECTS/Screen.cpp
Executable file
48
GL_STUFF/SOURCES/EFFECTS/Screen.cpp
Executable 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();
|
||||
}
|
||||
27
GL_STUFF/SOURCES/EFFECTS/TEX_MERGER/fragmentShader_merger.glsl
Executable file
27
GL_STUFF/SOURCES/EFFECTS/TEX_MERGER/fragmentShader_merger.glsl
Executable 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));
|
||||
}
|
||||
20
GL_STUFF/SOURCES/EFFECTS/TEX_MERGER/vertexShader_merger.glsl
Executable file
20
GL_STUFF/SOURCES/EFFECTS/TEX_MERGER/vertexShader_merger.glsl
Executable 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);
|
||||
}
|
||||
134
GL_STUFF/SOURCES/EFFECTS/TexMerger.cpp
Executable file
134
GL_STUFF/SOURCES/EFFECTS/TexMerger.cpp
Executable 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
203
GL_STUFF/SOURCES/SCENE/Camera.cpp
Executable 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;
|
||||
}
|
||||
}
|
||||
21
GL_STUFF/SOURCES/SCENE/Instance3D.cpp
Executable file
21
GL_STUFF/SOURCES/SCENE/Instance3D.cpp
Executable 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;
|
||||
}
|
||||
85
GL_STUFF/SOURCES/SCENE/InstancesLoader.cpp
Executable file
85
GL_STUFF/SOURCES/SCENE/InstancesLoader.cpp
Executable 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;
|
||||
}
|
||||
159
GL_STUFF/SOURCES/SCENE/Model3D.cpp
Executable file
159
GL_STUFF/SOURCES/SCENE/Model3D.cpp
Executable 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;
|
||||
}
|
||||
103
GL_STUFF/SOURCES/SCENE/ObjectInstance.cpp
Executable file
103
GL_STUFF/SOURCES/SCENE/ObjectInstance.cpp
Executable 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);
|
||||
}
|
||||
40
GL_STUFF/SOURCES/SCENE/ShadingHelper.cpp
Executable file
40
GL_STUFF/SOURCES/SCENE/ShadingHelper.cpp
Executable 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));
|
||||
}
|
||||
134
GL_STUFF/SOURCES/SCENE/objloader.cpp
Executable file
134
GL_STUFF/SOURCES/SCENE/objloader.cpp
Executable 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;
|
||||
}
|
||||
28
GL_STUFF/SOURCES/UTILS/ClockIterator.cpp
Executable file
28
GL_STUFF/SOURCES/UTILS/ClockIterator.cpp
Executable 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;
|
||||
}
|
||||
50
GL_STUFF/SOURCES/UTILS/OnlyOnce.cpp
Executable file
50
GL_STUFF/SOURCES/UTILS/OnlyOnce.cpp
Executable 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;
|
||||
}
|
||||
22
GL_STUFF/SOURCES/UTILS/ResourceCache.cpp
Executable file
22
GL_STUFF/SOURCES/UTILS/ResourceCache.cpp
Executable 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;
|
||||
}
|
||||
100
GL_STUFF/SOURCES/UTILS/ShaderMaker.cpp
Executable file
100
GL_STUFF/SOURCES/UTILS/ShaderMaker.cpp
Executable 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;
|
||||
}
|
||||
Reference in New Issue
Block a user