updated makefile for supporting different target architectures
use "ARCH=arch_name make" restructured project folder, implementations and headers together under sources/
This commit is contained in:
244
sources/GL_STUFF/SCENE/Camera.cpp
Executable file
244
sources/GL_STUFF/SCENE/Camera.cpp
Executable file
@@ -0,0 +1,244 @@
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
|
||||
#include "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::panX( float deltaX){
|
||||
/*
|
||||
deltaX *= M_PI / 180;
|
||||
*/
|
||||
|
||||
printf("deltaX of %f\n", deltaX);
|
||||
|
||||
/*
|
||||
mat4 global_y_rotation = glm::rotate(glm::mat4(), -deltaX, glm::vec3( 0.0, 1.0, 0.0) );
|
||||
|
||||
getCamera()->cameraUp = ( global_y_rotation * vec4( getCamera()->cameraUp, 1.0) );
|
||||
|
||||
getCamera()->cameraFront = ( global_y_rotation * vec4( getCamera()->cameraFront, 1.0) );
|
||||
|
||||
//vec3.rotateY(this.focalPoint,this.focalPoint, this.position, -deltaX);
|
||||
*/
|
||||
|
||||
PHI += 0;
|
||||
THETA += deltaX;
|
||||
|
||||
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::panY( float deltaY){
|
||||
|
||||
PHI += deltaY;
|
||||
THETA += 0;
|
||||
|
||||
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::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;
|
||||
}
|
||||
}
|
||||
42
sources/GL_STUFF/SCENE/Camera.hpp
Executable file
42
sources/GL_STUFF/SCENE/Camera.hpp
Executable file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
class Camera {
|
||||
|
||||
public:
|
||||
glm::vec3 cameraPos;
|
||||
glm::vec3 cameraFront;
|
||||
glm::vec3 cameraUp;
|
||||
|
||||
Camera();
|
||||
Camera( glm::vec3 position, glm::vec3 front, glm::vec3 up);
|
||||
glm::mat4 getViewMat();
|
||||
glm::vec3 getPosition();
|
||||
//exp
|
||||
void alignTo( glm::vec3 direction);
|
||||
void setPosition( glm::vec3 pos);
|
||||
};
|
||||
|
||||
class CameraController {
|
||||
|
||||
private:
|
||||
Camera *camera;
|
||||
float cameraSpeed = 0.5f;
|
||||
bool mouseUnlocked = true;
|
||||
float lastX;
|
||||
float lastY;
|
||||
float PHI = 0.0;
|
||||
float THETA = 270.0;
|
||||
unsigned int windowLeft;
|
||||
unsigned int windowTop;
|
||||
unsigned int windowWidth;
|
||||
unsigned int windowHeight;
|
||||
|
||||
public:
|
||||
CameraController(Camera *cam);
|
||||
Camera* getCamera();
|
||||
void setWindowData(int left, int width, int top, int height);
|
||||
void mouseMotion(int cursorX, int cursorY);
|
||||
void keyPress(unsigned char key);
|
||||
void panX( float deltaX);
|
||||
void panY( float deltaY);
|
||||
};
|
||||
203
sources/GL_STUFF/SCENE/Camera_OG.cpp
Normal file
203
sources/GL_STUFF/SCENE/Camera_OG.cpp
Normal file
@@ -0,0 +1,203 @@
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
|
||||
#include "../../../headers/GL_STUFF/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;
|
||||
}
|
||||
}
|
||||
40
sources/GL_STUFF/SCENE/Camera_OG.hpp
Executable file
40
sources/GL_STUFF/SCENE/Camera_OG.hpp
Executable file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
class Camera {
|
||||
|
||||
public:
|
||||
glm::vec3 cameraPos;
|
||||
glm::vec3 cameraFront;
|
||||
glm::vec3 cameraUp;
|
||||
|
||||
Camera();
|
||||
Camera( glm::vec3 position, glm::vec3 front, glm::vec3 up);
|
||||
glm::mat4 getViewMat();
|
||||
glm::vec3 getPosition();
|
||||
//exp
|
||||
void alignTo( glm::vec3 direction);
|
||||
void setPosition( glm::vec3 pos);
|
||||
};
|
||||
|
||||
class CameraController {
|
||||
|
||||
private:
|
||||
Camera *camera;
|
||||
float cameraSpeed = 0.5f;
|
||||
bool mouseUnlocked = true;
|
||||
float lastX;
|
||||
float lastY;
|
||||
float PHI = 0.0;
|
||||
float THETA = 270.0;
|
||||
unsigned int windowLeft;
|
||||
unsigned int windowTop;
|
||||
unsigned int windowWidth;
|
||||
unsigned int windowHeight;
|
||||
|
||||
public:
|
||||
CameraController(Camera *cam);
|
||||
Camera* getCamera();
|
||||
void setWindowData(int left, int width, int top, int height);
|
||||
void mouseMotion(int cursorX, int cursorY);
|
||||
void keyPress(unsigned char key);
|
||||
};
|
||||
21
sources/GL_STUFF/SCENE/Instance3D.cpp
Executable file
21
sources/GL_STUFF/SCENE/Instance3D.cpp
Executable file
@@ -0,0 +1,21 @@
|
||||
#include "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;
|
||||
}
|
||||
21
sources/GL_STUFF/SCENE/Instance3D.h
Executable file
21
sources/GL_STUFF/SCENE/Instance3D.h
Executable file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include <glm/glm.hpp>
|
||||
/*
|
||||
#include <GL/glew.h>
|
||||
*/
|
||||
#include <GLES2/gl2.h>
|
||||
#include "./Model3D.hpp"
|
||||
#include "../SCENE/ObjectInstance.hpp"
|
||||
|
||||
class Instance3D : public WorldInstanceable {
|
||||
|
||||
private:
|
||||
Model3D* mesh;
|
||||
|
||||
public:
|
||||
Instance3D(Model3D* mesh, vec3 position);
|
||||
Instance3D(Model3D* mesh, vec3 position, vec3 scale);
|
||||
Instance3D(Model3D* mesh, vec3 position, vec3 axis, float angle);
|
||||
Instance3D(Model3D* mesh, vec3 position, vec3 scale, vec3 axis, float angle);
|
||||
Model3D* getModel();
|
||||
};
|
||||
85
sources/GL_STUFF/SCENE/InstancesLoader.cpp
Executable file
85
sources/GL_STUFF/SCENE/InstancesLoader.cpp
Executable file
@@ -0,0 +1,85 @@
|
||||
#include <regex>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "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;
|
||||
}
|
||||
3
sources/GL_STUFF/SCENE/InstancesLoader.h
Executable file
3
sources/GL_STUFF/SCENE/InstancesLoader.h
Executable file
@@ -0,0 +1,3 @@
|
||||
#include "../SCENE/Instance3D.h"
|
||||
|
||||
bool loadInstances(std::string path, vector<Instance3D*>& instances, bool smoothNormals);
|
||||
159
sources/GL_STUFF/SCENE/Model3D.cpp
Executable file
159
sources/GL_STUFF/SCENE/Model3D.cpp
Executable file
@@ -0,0 +1,159 @@
|
||||
#include "Model3D.hpp"
|
||||
extern "C" {
|
||||
#include "../GLES_3_1_compatibility.h"
|
||||
}
|
||||
#include "../UTILS/OnlyOnce.hpp"
|
||||
#include "../UTILS/ShaderMaker.h"
|
||||
#include "objloader.hpp"
|
||||
#include "../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;
|
||||
}
|
||||
29
sources/GL_STUFF/SCENE/Model3D.hpp
Executable file
29
sources/GL_STUFF/SCENE/Model3D.hpp
Executable file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace std; //for vector
|
||||
using namespace glm; //vec3 and friends
|
||||
|
||||
class Model3D {
|
||||
|
||||
private:
|
||||
int nVertices;
|
||||
GLuint vao;
|
||||
vec3 boundingBoxLBN;
|
||||
vec3 boundingBoxRTF;
|
||||
vector<vec3> loadVertexData(const char* modelPath, bool smoothNormals);
|
||||
void computeBoundingBox(vector<vec3> points);
|
||||
|
||||
public:
|
||||
Model3D(const char* modelPath, bool smoothNormals);
|
||||
GLuint getVAO();
|
||||
int getTrisCount();
|
||||
void draw();
|
||||
vec3 getLBN();
|
||||
vec3 getRTF();
|
||||
};
|
||||
103
sources/GL_STUFF/SCENE/ObjectInstance.cpp
Executable file
103
sources/GL_STUFF/SCENE/ObjectInstance.cpp
Executable file
@@ -0,0 +1,103 @@
|
||||
#include "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);
|
||||
}
|
||||
30
sources/GL_STUFF/SCENE/ObjectInstance.hpp
Executable file
30
sources/GL_STUFF/SCENE/ObjectInstance.hpp
Executable file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include <glm/glm.hpp>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class WorldInstanceable {
|
||||
|
||||
private:
|
||||
glm::vec3 localFront, localUp;
|
||||
void setup(glm::vec3 position);
|
||||
|
||||
public:
|
||||
glm::mat4 scaleMat;
|
||||
glm::mat4 rotation;
|
||||
glm::vec3 position;
|
||||
WorldInstanceable(glm::vec3 position);
|
||||
WorldInstanceable(glm::vec3 position, glm::vec3 scale);
|
||||
WorldInstanceable(glm::vec3 position, glm::vec3 axis, float angle);
|
||||
WorldInstanceable(glm::vec3 position, glm::vec3 scale, glm::vec3 axis, float angle);
|
||||
void setPosition(glm::vec3 position);
|
||||
void rotate(glm::vec3 axis, float angle);
|
||||
void scale(float factor);
|
||||
void scale(glm::vec3 factors);
|
||||
glm::mat4 getLocalTransform();
|
||||
glm::mat4 getGlobalTransform();
|
||||
void alignTo(glm::vec3 direction);
|
||||
|
||||
};
|
||||
40
sources/GL_STUFF/SCENE/ShadingHelper.cpp
Executable file
40
sources/GL_STUFF/SCENE/ShadingHelper.cpp
Executable file
@@ -0,0 +1,40 @@
|
||||
#include "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));
|
||||
}
|
||||
26
sources/GL_STUFF/SCENE/ShadingHelper.h
Executable file
26
sources/GL_STUFF/SCENE/ShadingHelper.h
Executable file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include <glm/glm.hpp>
|
||||
/*
|
||||
#include <GL/glew.h>
|
||||
*/
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
class ShadingHelper {
|
||||
GLuint program;
|
||||
public:
|
||||
ShadingHelper(GLuint program);
|
||||
void useProgram();
|
||||
GLuint getProgram();
|
||||
void bindTexture2D(GLuint texUnitIndex, GLuint texture, std::string uniform);
|
||||
void bindViewUniforms(glm::mat4 projection, glm::mat4 view);
|
||||
void bindLightUniforms(glm::vec3 lightPos, glm::vec3 lightCol, glm::vec3 eyePos);
|
||||
void bindModelUniforms(glm::mat4 locRotScl, glm::mat4 rotScl);
|
||||
};
|
||||
|
||||
class TextureHelper {
|
||||
public:
|
||||
GLuint texture;
|
||||
std::string uniformName;
|
||||
};
|
||||
136
sources/GL_STUFF/SCENE/objloader.cpp
Executable file
136
sources/GL_STUFF/SCENE/objloader.cpp
Executable file
@@ -0,0 +1,136 @@
|
||||
extern "C" {
|
||||
#include <stdio.h>
|
||||
}
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "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;
|
||||
}
|
||||
20
sources/GL_STUFF/SCENE/objloader.hpp
Executable file
20
sources/GL_STUFF/SCENE/objloader.hpp
Executable file
@@ -0,0 +1,20 @@
|
||||
#ifndef OBJLOADER_H
|
||||
#define OBJLOADER_H
|
||||
|
||||
bool loadOBJ(
|
||||
const char* path,
|
||||
std::vector<glm::vec3>& out_vertices,
|
||||
std::vector<glm::vec2>& out_uvs,
|
||||
std::vector<glm::vec3>& out_normals,
|
||||
bool smoothNormals
|
||||
);
|
||||
|
||||
bool loadAssImp(
|
||||
const char* path,
|
||||
std::vector<unsigned short>& indices,
|
||||
std::vector<glm::vec3>& vertices,
|
||||
std::vector<glm::vec2>& uvs,
|
||||
std::vector<glm::vec3>& normals
|
||||
);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user