Browse Source
OpenGL boilerplate by Benoit Ozell Packets code taken from https://github.com/jeschke/water-wave-packetsmaster
commit
b57310b38c
10 changed files with 5856 additions and 0 deletions
File diff suppressed because it is too large
@ -0,0 +1,147 @@ |
|||||
|
// Taken from https://github.com/jeschke/water-wave-packets
|
||||
|
#pragma once |
||||
|
|
||||
|
#include "constants.h" |
||||
|
|
||||
|
#include <iostream> |
||||
|
#include <Eigen/Dense> |
||||
|
|
||||
|
using namespace Eigen; |
||||
|
using namespace std; |
||||
|
|
||||
|
|
||||
|
// simulation parameters
|
||||
|
#define PACKET_SPLIT_ANGLE 0.95105f // direction angle variation threshold: 0.95105=18 degree
|
||||
|
#define PACKET_SPLIT_DISPERSION 0.3f // if the fastest wave in a packet traveled PACKET_SPLIT_DISPERSION*Envelopesize ahead, or the slowest by the same amount behind, subdivide this packet into two wavelength intervals
|
||||
|
#define PACKET_KILL_AMPLITUDE_DERIV 0.0001f // waves below this maximum amplitude derivative gets killed
|
||||
|
#define PACKET_BLEND_TRAVEL_FACTOR 1.0f // in order to be fully blended (appear or disappear), any wave must travel PACKET_BLEND_TRAVEL_FACTOR times "envelope size" in space (1.0 is standard)
|
||||
|
#define PACKET_ENVELOPE_SIZE_FACTOR 3.0f // size of the envelope relative to wavelength (determines how many "bumps" appear)
|
||||
|
#define PACKET_ENVELOPE_MINSIZE 0.02f // minimum envelope size in meters (smallest expected feature)
|
||||
|
#define PACKET_ENVELOPE_MAXSIZE 10.0f // maximum envelope size in meters (largest expected feature)
|
||||
|
#define PACKET_BOUNCE_FREQSPLIT true // (boolean) should a wave packet produce smaller waves at a bounce/reflection (->widen the wavelength interval of this packet)?
|
||||
|
#define PACKET_BOUNCE_FREQSPLIT_K 31.4f // if k_L is smaller than this value (lambda = 20cm), the wave is (potentially) split after a bounce
|
||||
|
#define MAX_SPEEDNESS 0.07f // all wave amplitudes a are limited to a <= MAX_SPEEDNESS*2.0*M_PI/k
|
||||
|
|
||||
|
// physical parameters
|
||||
|
#define SIGMA 0.074f // surface tension N/m at 20 grad celsius
|
||||
|
#define GRAVITY 9.81f // GRAVITY m/s^2
|
||||
|
#define DENSITY 998.2071f // water density at 20 degree celsius
|
||||
|
#define KINEMATIC_VISCOSITY 0.0000089f // kinematic viscosity
|
||||
|
#define PACKET_SLOWAVE_K 143.1405792f // k of the slowest possible wave packet
|
||||
|
#define PACKET_SLOWAVE_W0 40.2646141f // w_0 of the slowest possible wave packet
|
||||
|
|
||||
|
// memory management
|
||||
|
#define PACKET_BUFFER_DELTA 500000 // initial number of vertices, packet memory will be increased on demand by this stepsize
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
struct WAVE_PACKET |
||||
|
{ |
||||
|
// positions, directions, speed of the tracked vertices
|
||||
|
Vector2f pos1,pos2,pos3; // 2D position
|
||||
|
Vector2f dir1,dir2,dir3; // current movement direction
|
||||
|
float speed1,speed2,speed3; // speed of the particle
|
||||
|
Vector2f pOld1,pOld2,pOld3; // position in last timestep (needed to handle bouncing)
|
||||
|
Vector2f dOld1,dOld2,dOld3; // direction in last timestep (needed to handle bouncing)
|
||||
|
float sOld1,sOld2,sOld3; // speed in last timestep (needed to handle bouncing)
|
||||
|
Vector2f midPos; // middle position (tracked each timestep, used for rendering)
|
||||
|
Vector2f travelDir; // travel direction (tracked each timestep, used for rendering)
|
||||
|
float bending; // point used for circular arc bending of the wave function inside envelope
|
||||
|
|
||||
|
// bouncing and sliding
|
||||
|
bool bounced1, bounced2, bounced3; // indicates if this vertex bounced in this timestep
|
||||
|
bool sliding3; // indicates if the 3rd vertex is "sliding" (used for diffraction)
|
||||
|
bool use3rd; // indicates if the third vertex is present (it marks a (potential) sliding point)
|
||||
|
// wave function related
|
||||
|
float phase; // phase of the representative wave inside the envelope, phase speed vs. group speed
|
||||
|
float phOld; // old phase
|
||||
|
float E; // wave energy flux for this packet (determines amplitude)
|
||||
|
float envelope; // envelope size for this packet
|
||||
|
float k,w0; // w0 = angular frequency, k = current wavenumber
|
||||
|
float k_L,w0_L,k_H,w0_H; // w0 = angular frequency, k = current wavenumber, L/H are for lower/upper boundary
|
||||
|
float d_L,d_H; // d = travel distance to reference wave (gets accumulated over time), L/H are for lower/upper boundary
|
||||
|
float ampOld; // amplitude from last timestep, will be smoothly adjusted in each timestep to meet current desired amplitude
|
||||
|
float dAmp; // amplitude change in each timestep (depends on desired waveheight so all waves (dis)appear with same speed)
|
||||
|
// serial deletion step variable
|
||||
|
bool toDelete; // used internally for parallel deletion criterion computation
|
||||
|
public: |
||||
|
EIGEN_MAKE_ALIGNED_OPERATOR_NEW |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
|
||||
|
struct GHOST_PACKET |
||||
|
{ |
||||
|
Vector2f pos; // 2D position
|
||||
|
Vector2f dir; // current movement direction
|
||||
|
float speed; // speed of the packet
|
||||
|
float envelope; // envelope size for this packet
|
||||
|
float bending; // point used for circular arc bending of the wave function inside envelope
|
||||
|
float k; // k = current (representative) wavenumber(s)
|
||||
|
float phase; // phase of the representative wave inside the envelope
|
||||
|
float dPhase; // phase speed relative to group speed inside the envelope
|
||||
|
float ampOld; // amplitude from last timestep, will be smoothly adjusted in each timestep to meet current desired amplitude
|
||||
|
float dAmp; // change in amplitude in each timestep (waves travel PACKET_BLEND_TRAVEL_FACTOR*envelopesize in space until they disappear)
|
||||
|
public: |
||||
|
EIGEN_MAKE_ALIGNED_OPERATOR_NEW |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
class Packets |
||||
|
{ |
||||
|
public: |
||||
|
// scene
|
||||
|
int m_groundSizeX, m_groundSizeY; // pixel size of the ground texture
|
||||
|
float *m_ground; // texture containing the water depth and land (0.95)
|
||||
|
float *m_distMap; // distance map of the boundary map
|
||||
|
Vector2f *m_gndDeriv; |
||||
|
Vector2f *m_bndDeriv; |
||||
|
|
||||
|
// packet managing
|
||||
|
WAVE_PACKET *m_packet; // wave packet data
|
||||
|
GHOST_PACKET*m_ghostPacket; // ghost packet data
|
||||
|
int m_packetBudget; // this can be changed any time (soft budget)
|
||||
|
int m_packetNum; // current size of the buffer used for packets / ghosts
|
||||
|
float m_softDampFactor; |
||||
|
int *m_usedPacket; |
||||
|
int m_usedPackets; |
||||
|
int *m_freePacket; |
||||
|
int m_freePackets; |
||||
|
int *m_usedGhost; |
||||
|
int m_usedGhosts; |
||||
|
int *m_freeGhost; |
||||
|
int m_freeGhosts; |
||||
|
|
||||
|
// simulation
|
||||
|
float m_time; |
||||
|
float m_oldTime; |
||||
|
float m_elapsedTime; |
||||
|
|
||||
|
public: |
||||
|
EIGEN_MAKE_ALIGNED_OPERATOR_NEW |
||||
|
Packets(int packetBudget); |
||||
|
~Packets(void); |
||||
|
void Reset(); |
||||
|
float GetBoundaryDist(Vector2f &p); |
||||
|
Vector2f GetBoundaryNormal(Vector2f &p); |
||||
|
float GetGroundVal(Vector2f &p); |
||||
|
Vector2f GetGroundNormal(Vector2f &p); |
||||
|
float GetWaterDepth(Vector2f &p); |
||||
|
void UpdateTime(float dTime); |
||||
|
void ExpandWavePacketMemory(int targetNum); |
||||
|
int GetFreePackedID(); |
||||
|
void DeletePacket(int id); |
||||
|
int GetFreeGhostID(); |
||||
|
void DeleteGhost(int id); |
||||
|
void CreatePacket(float pos1x, float pos1y, float pos2x, float pos2y, float dir1x, float dir1y, float dir2x, float dir2y, float k_L, float k_H, float E); |
||||
|
void CreateLinearWavefront(float xPos, float yPos, float dirx, float diry, float crestlength, float lambda_L, float lambda_H, float E); |
||||
|
void CreateSpreadingPacket(float xPos, float yPos, float dirx, float diry, float spreadFactor, float crestlength, float lambda_L, float lambda_H, float E); |
||||
|
void CreateCircularWavefront(float xPos, float yPos, float radius, float lambda_L, float lambda_H, float E); |
||||
|
void GetWaveParameters(float waterDepth, float w0, float kIn, float &k_out, float &speed_out); |
||||
|
float GetPhaseSpeed(float w_0, float kIn); |
||||
|
float GetWaveAmplitude(float area, float E, float k); |
||||
|
float GetIntersectionDistance(Vector2f pos1, Vector2f dir1, Vector2f pos2, Vector2f dir2); |
||||
|
bool AdvectPacketVertex(float elapsedTime, Vector2f &posIn, Vector2f &dirIn, float w0, float &kIn, float &speedIn, Vector2f &posOut, Vector2f &dirOut, float &speedOut); |
||||
|
void AdvectWavePackets(float dTime); |
||||
|
}; |
||||
@ -0,0 +1,44 @@ |
|||||
|
// Taken from https://github.com/jeschke/water-wave-packets
|
||||
|
// Originally GlobalDefs.h
|
||||
|
|
||||
|
// Global definitions needed for packet simulation and rendering
|
||||
|
|
||||
|
// scene parameters
|
||||
|
#define SCENE_EXTENT 100.0f // extent of the entire scene (packets traveling outside are removed)
|
||||
|
#define MIN_WATER_DEPTH 0.1f // minimum water depth (meters)
|
||||
|
#define MAX_WATER_DEPTH 5.0f // maximum water depth (meters)
|
||||
|
#define WATER_TERRAIN_FILE "TestIsland.bmp"// Contains water depth and land height in different channels
|
||||
|
|
||||
|
|
||||
|
// rendering parameters
|
||||
|
#define PACKET_GPU_BUFFER_SIZE 1000000 // maximum number of wave packets to be displayed in one draw call
|
||||
|
|
||||
|
|
||||
|
/*
|
||||
|
// Fast rendering setup
|
||||
|
#define WAVETEX_WIDTH_FACTOR 0.5 // the wavemesh texture compared to screen resolution
|
||||
|
#define WAVETEX_HEIGHT_FACTOR 1 // the wavemesh texture compared to screen resolution
|
||||
|
#define WAVEMESH_WIDTH_FACTOR 0.1 // the fine wave mesh compared to screen resolution
|
||||
|
#define WAVEMESH_HEIGHT_FACTOR 0.25 // the fine wave mesh compared to screen resolution
|
||||
|
#define AA_OVERSAMPLE_FACTOR 2 // anti aliasing applied in BOTH X and Y directions {1,2,4,8}
|
||||
|
*/ |
||||
|
|
||||
|
/*
|
||||
|
// Balanced rendering setup
|
||||
|
#define WAVETEX_WIDTH_FACTOR 1 // the wavemesh texture compared to screen resolution
|
||||
|
#define WAVETEX_HEIGHT_FACTOR 2 // the wavemesh texture compared to screen resolution
|
||||
|
#define WAVEMESH_WIDTH_FACTOR 1 // the fine wave mesh compared to screen resolution
|
||||
|
#define WAVEMESH_HEIGHT_FACTOR 2 // the fine wave mesh compared to screen resolution
|
||||
|
#define AA_OVERSAMPLE_FACTOR 2 // anti aliasing applied in BOTH X and Y directions {1,2,4,8}
|
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
// High quality rendering setup
|
||||
|
#define WAVETEX_WIDTH_FACTOR 2 // the wavemesh texture compared to screen resolution
|
||||
|
#define WAVETEX_HEIGHT_FACTOR 4 // the wavemesh texture compared to screen resolution
|
||||
|
#define WAVEMESH_WIDTH_FACTOR 2 // the fine wave mesh compared to screen resolution
|
||||
|
#define WAVEMESH_HEIGHT_FACTOR 4 // the fine wave mesh compared to screen resolution
|
||||
|
#define AA_OVERSAMPLE_FACTOR 4 // anti aliasing applied in BOTH X and Y directions {1,2,4,8}
|
||||
|
|
||||
|
|
||||
|
|
||||
File diff suppressed because it is too large
@ -0,0 +1,33 @@ |
|||||
|
CONTEXT=sdl2 |
||||
|
ifeq "$(shell uname)" "Darwin" |
||||
|
CONTEXT=glfw3 |
||||
|
LDFLAGS += -lobjc -framework Foundation -framework OpenGL -framework Cocoa |
||||
|
endif |
||||
|
|
||||
|
CXXFLAGS += -g -W -Wall -Wno-unused-parameter -Wno-deprecated-declarations |
||||
|
CXXFLAGS += $(shell pkg-config --cflags glew) |
||||
|
CXXFLAGS += $(shell pkg-config --cflags $(CONTEXT)) |
||||
|
|
||||
|
LDFLAGS += -g |
||||
|
LDFLAGS += $(shell pkg-config --libs glew) |
||||
|
LDFLAGS += $(shell pkg-config --libs $(CONTEXT)) |
||||
|
|
||||
|
TP="tp3" |
||||
|
SRC=ripple |
||||
|
|
||||
|
exe : $(SRC).exe |
||||
|
run : exe |
||||
|
optirun ./$(SRC).exe |
||||
|
$(SRC).exe : $(SRC).cpp *.h |
||||
|
$(CXX) $(CXXFLAGS) -o$@ $(SRC).cpp $(LDFLAGS) |
||||
|
|
||||
|
sol : ; make SRC=$(SRC)Solution exe |
||||
|
runs : ; make SRC=$(SRC)Solution run |
||||
|
|
||||
|
clean : |
||||
|
rm -rf *.o *.exe *.exe.dSYM |
||||
|
|
||||
|
remise zip : |
||||
|
make clean |
||||
|
rm -f remise_$(TP).zip |
||||
|
zip -r remise_$(TP).zip *.cpp *.h *.glsl makefile *.txt textures |
||||
@ -0,0 +1,141 @@ |
|||||
|
#version 410 |
||||
|
|
||||
|
// Définition des paramètres des sources de lumière |
||||
|
layout (std140) uniform LightSourceParameters |
||||
|
{ |
||||
|
vec4 ambient; |
||||
|
vec4 diffuse; |
||||
|
vec4 specular; |
||||
|
vec4 position; |
||||
|
vec3 spotDirection; |
||||
|
float spotExponent; |
||||
|
float spotCutoff; // ([0.0,90.0] ou 180.0) |
||||
|
float constantAttenuation; |
||||
|
float linearAttenuation; |
||||
|
float quadraticAttenuation; |
||||
|
} LightSource[1]; |
||||
|
|
||||
|
// Définition des paramètres des matériaux |
||||
|
layout (std140) uniform MaterialParameters |
||||
|
{ |
||||
|
vec4 emission; |
||||
|
vec4 ambient; |
||||
|
vec4 diffuse; |
||||
|
vec4 specular; |
||||
|
float shininess; |
||||
|
} FrontMaterial; |
||||
|
|
||||
|
// Définition des paramètres globaux du modèle de lumière |
||||
|
layout (std140) uniform LightModelParameters |
||||
|
{ |
||||
|
vec4 ambient; // couleur ambiante |
||||
|
bool localViewer; // observateur local ou à l'infini? |
||||
|
bool twoSide; // éclairage sur les deux côtés ou un seul? |
||||
|
} LightModel; |
||||
|
|
||||
|
layout (std140) uniform varsUnif |
||||
|
{ |
||||
|
// partie 1: illumination |
||||
|
int typeIllumination; // 0:Lambert, 1:Gouraud, 2:Phong |
||||
|
bool utiliseBlinn; // indique si on veut utiliser modèle spéculaire de Blinn ou Phong |
||||
|
bool utiliseDirect; // indique si on utilise un spot style Direct3D ou OpenGL |
||||
|
bool afficheNormales; // indique si on utilise les normales comme couleurs (utile pour le débogage) |
||||
|
// partie 3: texture |
||||
|
int texnumero; // numéro de la texture appliquée |
||||
|
bool utiliseCouleur; // doit-on utiliser la couleur de base de l'objet en plus de celle de la texture? |
||||
|
int afficheTexelNoir; // un texel noir doit-il être affiché 0:noir, 1:mi-coloré, 2:transparent? |
||||
|
}; |
||||
|
|
||||
|
uniform sampler2D laTexture; |
||||
|
|
||||
|
///////////////////////////////////////////////////////////////// |
||||
|
|
||||
|
in Attribs { |
||||
|
vec3 lumiDir, spotDir; |
||||
|
vec3 normale, obsVec; |
||||
|
vec2 texCoord; |
||||
|
vec4 couleur; |
||||
|
} AttribsIn; |
||||
|
|
||||
|
out vec4 FragColor; |
||||
|
|
||||
|
float calculerSpot( in vec3 spotDir, in vec3 L ) |
||||
|
{ |
||||
|
float spotFacteur; |
||||
|
float spotDot = dot( L, normalize( spotDir ) ); |
||||
|
if ( utiliseDirect ) // modèle Direct3D |
||||
|
{ |
||||
|
float cosAngleInterne = cos(radians(LightSource[0].spotCutoff)); |
||||
|
float exposant = 1.01 + LightSource[0].spotExponent / 2.0; |
||||
|
float cosAngleExterne = pow( cos(radians(LightSource[0].spotCutoff)), exposant ); |
||||
|
// calculer le facteur spot avec la fonction smoothstep() |
||||
|
spotFacteur = smoothstep( cosAngleExterne, cosAngleInterne, spotDot ); |
||||
|
} |
||||
|
else // modèle OpenGL |
||||
|
{ |
||||
|
spotFacteur = ( spotDot > cos(radians(LightSource[0].spotCutoff)) ) ? pow( spotDot, LightSource[0].spotExponent ) : 0.0; |
||||
|
} |
||||
|
return( spotFacteur ); |
||||
|
} |
||||
|
|
||||
|
vec4 calculerReflexion( in vec3 L, in vec3 N, in vec3 O ) |
||||
|
{ |
||||
|
vec4 coul = FrontMaterial.emission + FrontMaterial.ambient * LightModel.ambient; |
||||
|
|
||||
|
// calcul de la composante ambiante |
||||
|
coul += FrontMaterial.ambient * LightSource[0].ambient; |
||||
|
|
||||
|
// calcul de l'éclairage seulement si le produit scalaire est positif |
||||
|
float NdotL = max( 0.0, dot( N, L ) ); |
||||
|
if ( NdotL > 0.0 ) |
||||
|
{ |
||||
|
// calcul de la composante diffuse |
||||
|
//coul += ( utiliseCouleur ? FrontMaterial.diffuse : vec4(1.0) ) * LightSource[0].diffuse * NdotL; |
||||
|
coul += FrontMaterial.diffuse * LightSource[0].diffuse * NdotL; |
||||
|
|
||||
|
// calcul de la composante spéculaire (Blinn ou Phong) |
||||
|
float NdotHV = max( 0.0, ( utiliseBlinn ) ? dot( normalize( L + O ), N ) : dot( reflect( -L, N ), O ) ); |
||||
|
coul += FrontMaterial.specular * LightSource[0].specular * ( ( NdotHV == 0.0 ) ? 0.0 : pow( NdotHV, FrontMaterial.shininess ) ); |
||||
|
} |
||||
|
return( coul ); |
||||
|
} |
||||
|
|
||||
|
void main( void ) |
||||
|
{ |
||||
|
vec3 L = normalize( AttribsIn.lumiDir ); // vecteur vers la source lumineuse |
||||
|
vec3 N = normalize( AttribsIn.normale ); // vecteur normal |
||||
|
//vec3 N = normalize( gl_FrontFacing ? AttribsIn.normale : -AttribsIn.normale ); |
||||
|
vec3 O = normalize( AttribsIn.obsVec ); // position de l'observateur |
||||
|
|
||||
|
// calculer la réflexion: |
||||
|
// si illumination de 1:Gouraud, prendre la couleur interpolée qui a été reçue |
||||
|
// si illumination de 2:Phong, le faire! |
||||
|
// si illumination de 0:Lambert, faire comme Phong, même si les normales sont les mêmes pour tous les fragments |
||||
|
vec4 coul = ( typeIllumination == 1 ) ? AttribsIn.couleur : calculerReflexion( L, N, O ); |
||||
|
|
||||
|
// calculer l'influence du spot |
||||
|
float spotFacteur = calculerSpot( AttribsIn.spotDir, L ); |
||||
|
coul *= spotFacteur; |
||||
|
//if ( spotFacteur <= 0.0 ) discard; // pour éliminer tout ce qui n'est pas dans le cône |
||||
|
// calcul de la composante ambiante |
||||
|
//coul += FrontMaterial.ambient * LightSource[0].ambient; |
||||
|
|
||||
|
// appliquer la texture s'il y a lieu |
||||
|
if ( texnumero != 0 ) |
||||
|
{ |
||||
|
vec4 couleurTexture = texture( laTexture, AttribsIn.texCoord ); |
||||
|
// comment afficher un texel noir? |
||||
|
if ( couleurTexture.r < 0.1 && couleurTexture.g < 0.1 && couleurTexture.b < 0.1 && |
||||
|
spotFacteur > 0.0 ) |
||||
|
if ( afficheTexelNoir == 1 ) |
||||
|
couleurTexture = coul / 2.0; |
||||
|
else if ( afficheTexelNoir == 2 ) |
||||
|
discard; |
||||
|
coul *= couleurTexture; |
||||
|
} |
||||
|
|
||||
|
// assigner la couleur finale |
||||
|
FragColor = clamp( coul, 0.0, 1.0 ); |
||||
|
|
||||
|
if ( afficheNormales ) FragColor = vec4(N,1.0); |
||||
|
} |
||||
@ -0,0 +1,73 @@ |
|||||
|
#version 410 |
||||
|
|
||||
|
layout(triangles) in; |
||||
|
layout(triangle_strip, max_vertices = 3) out; |
||||
|
|
||||
|
uniform mat4 matrModel; |
||||
|
uniform mat4 matrVisu; |
||||
|
uniform mat4 matrProj; |
||||
|
uniform mat3 matrNormale; |
||||
|
|
||||
|
layout (std140) uniform varsUnif |
||||
|
{ |
||||
|
// partie 1: illumination |
||||
|
int typeIllumination; // 0:Lambert, 1:Gouraud, 2:Phong |
||||
|
bool utiliseBlinn; // indique si on veut utiliser modèle spéculaire de Blinn ou Phong |
||||
|
bool utiliseDirect; // indique si on utilise un spot style Direct3D ou OpenGL |
||||
|
bool afficheNormales; // indique si on utilise les normales comme couleurs (utile pour le débogage) |
||||
|
// partie 3: texture |
||||
|
int texnumero; // numéro de la texture appliquée |
||||
|
bool utiliseCouleur; // doit-on utiliser la couleur de base de l'objet en plus de celle de la texture? |
||||
|
int afficheTexelNoir; // un texel noir doit-il être affiché 0:noir, 1:mi-coloré, 2:transparent? |
||||
|
}; |
||||
|
|
||||
|
in Attribs { |
||||
|
vec3 lumiDir, spotDir; |
||||
|
vec3 normale, obsVec; |
||||
|
vec2 texCoord; |
||||
|
vec4 couleur; |
||||
|
} AttribsIn[]; |
||||
|
|
||||
|
out Attribs { |
||||
|
vec3 lumiDir, spotDir; |
||||
|
vec3 normale, obsVec; |
||||
|
vec2 texCoord; |
||||
|
vec4 couleur; |
||||
|
} AttribsOut; |
||||
|
|
||||
|
void main() |
||||
|
{ |
||||
|
// si illumination est Lambert, calculer une nouvelle normale |
||||
|
vec3 n = vec3(0.0); |
||||
|
if ( typeIllumination == 0 ) |
||||
|
{ |
||||
|
vec3 p0 = gl_in[0].gl_Position.xyz; |
||||
|
vec3 p1 = gl_in[1].gl_Position.xyz; |
||||
|
vec3 p2 = gl_in[2].gl_Position.xyz; |
||||
|
n = cross( p1-p0, p2-p0 ); // cette nouvelle normale est déjà dans le repère de la caméra |
||||
|
// il n'est pas nécessaire de la multiplier par matrNormale |
||||
|
} |
||||
|
// ou faire une moyenne, MAIS CE N'EST PAS CE QU'ON VEUT! |
||||
|
// if ( typeIllumination == 0 ) |
||||
|
// { |
||||
|
// // calculer le centre |
||||
|
// for ( int i = 0 ; i < gl_in.length() ; ++i ) |
||||
|
// { |
||||
|
// n += AttribsIn[i].normale; |
||||
|
// } |
||||
|
// n /= gl_in.length(); |
||||
|
// } |
||||
|
|
||||
|
// émettre les sommets |
||||
|
for ( int i = 0 ; i < gl_in.length() ; ++i ) |
||||
|
{ |
||||
|
gl_Position = matrProj * gl_in[i].gl_Position; // on termine la transformation débutée dans le nuanceur de sommets |
||||
|
AttribsOut.lumiDir = AttribsIn[i].lumiDir; |
||||
|
AttribsOut.spotDir = AttribsIn[i].spotDir; |
||||
|
AttribsOut.normale = ( typeIllumination == 0 ) ? n : AttribsIn[i].normale; |
||||
|
AttribsOut.obsVec = AttribsIn[i].obsVec; |
||||
|
AttribsOut.texCoord = AttribsIn[i].texCoord; |
||||
|
AttribsOut.couleur = AttribsIn[i].couleur; |
||||
|
EmitVertex(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,130 @@ |
|||||
|
#version 410 |
||||
|
|
||||
|
// Définition des paramètres des sources de lumière |
||||
|
layout (std140) uniform LightSourceParameters |
||||
|
{ |
||||
|
vec4 ambient; |
||||
|
vec4 diffuse; |
||||
|
vec4 specular; |
||||
|
vec4 position; |
||||
|
vec3 spotDirection; |
||||
|
float spotExponent; |
||||
|
float spotCutoff; // ([0.0,90.0] ou 180.0) |
||||
|
float constantAttenuation; |
||||
|
float linearAttenuation; |
||||
|
float quadraticAttenuation; |
||||
|
} LightSource[1]; |
||||
|
|
||||
|
// Définition des paramètres des matériaux |
||||
|
layout (std140) uniform MaterialParameters |
||||
|
{ |
||||
|
vec4 emission; |
||||
|
vec4 ambient; |
||||
|
vec4 diffuse; |
||||
|
vec4 specular; |
||||
|
float shininess; |
||||
|
} FrontMaterial; |
||||
|
|
||||
|
// Définition des paramètres globaux du modèle de lumière |
||||
|
layout (std140) uniform LightModelParameters |
||||
|
{ |
||||
|
vec4 ambient; // couleur ambiante |
||||
|
bool localViewer; // observateur local ou à l'infini? |
||||
|
bool twoSide; // éclairage sur les deux côtés ou un seul? |
||||
|
} LightModel; |
||||
|
|
||||
|
layout (std140) uniform varsUnif |
||||
|
{ |
||||
|
// partie 1: illumination |
||||
|
int typeIllumination; // 0:Lambert, 1:Gouraud, 2:Phong |
||||
|
bool utiliseBlinn; // indique si on veut utiliser modèle spéculaire de Blinn ou Phong |
||||
|
bool utiliseDirect; // indique si on utilise un spot style Direct3D ou OpenGL |
||||
|
bool afficheNormales; // indique si on utilise les normales comme couleurs (utile pour le débogage) |
||||
|
// partie 3: texture |
||||
|
int texnumero; // numéro de la texture appliquée |
||||
|
bool utiliseCouleur; // doit-on utiliser la couleur de base de l'objet en plus de celle de la texture? |
||||
|
int afficheTexelNoir; // un texel noir doit-il être affiché 0:noir, 1:mi-coloré, 2:transparent? |
||||
|
}; |
||||
|
|
||||
|
uniform mat4 matrModel; |
||||
|
uniform mat4 matrVisu; |
||||
|
uniform mat4 matrProj; |
||||
|
uniform mat3 matrNormale; |
||||
|
|
||||
|
///////////////////////////////////////////////////////////////// |
||||
|
|
||||
|
layout(location=0) in vec4 Vertex; |
||||
|
layout(location=2) in vec3 Normal; |
||||
|
layout(location=3) in vec4 Color; |
||||
|
layout(location=8) in vec4 TexCoord; |
||||
|
|
||||
|
out Attribs { |
||||
|
vec3 lumiDir, spotDir; |
||||
|
vec3 normale, obsVec; |
||||
|
vec2 texCoord; |
||||
|
vec4 couleur; |
||||
|
} AttribsOut; |
||||
|
|
||||
|
vec4 calculerReflexion( in vec3 L, in vec3 N, in vec3 O ) |
||||
|
{ |
||||
|
vec4 coul = FrontMaterial.emission + FrontMaterial.ambient * LightModel.ambient; |
||||
|
|
||||
|
// calcul de la composante ambiante |
||||
|
coul += FrontMaterial.ambient * LightSource[0].ambient; |
||||
|
|
||||
|
// calcul de l'éclairage seulement si le produit scalaire est positif |
||||
|
float NdotL = max( 0.0, dot( N, L ) ); |
||||
|
if ( NdotL > 0.0 ) |
||||
|
{ |
||||
|
// calcul de la composante diffuse |
||||
|
//coul += ( utiliseCouleur ? FrontMaterial.diffuse : vec4(1.0) ) * LightSource[0].diffuse * NdotL; |
||||
|
coul += FrontMaterial.diffuse * LightSource[0].diffuse * NdotL; |
||||
|
|
||||
|
// calcul de la composante spéculaire (Blinn ou Phong) |
||||
|
float NdotHV = max( 0.0, ( utiliseBlinn ) ? dot( normalize( L + O ), N ) : dot( reflect( -L, N ), O ) ); |
||||
|
coul += FrontMaterial.specular * LightSource[0].specular * ( ( NdotHV == 0.0 ) ? 0.0 : pow( NdotHV, FrontMaterial.shininess ) ); |
||||
|
} |
||||
|
return( coul ); |
||||
|
} |
||||
|
|
||||
|
void main( void ) |
||||
|
{ |
||||
|
// transformation standard du sommet, ** sans la projection ** |
||||
|
gl_Position = matrVisu * matrModel * Vertex; |
||||
|
|
||||
|
// calculer la normale qui sera interpolée pour le nuanceur de fragment |
||||
|
AttribsOut.normale = matrNormale * Normal; |
||||
|
|
||||
|
// calculer la position du sommet (dans le repère de la caméra) |
||||
|
vec3 pos = vec3( matrVisu * matrModel * Vertex ); |
||||
|
|
||||
|
// vecteur de la direction de la lumière (dans le repère de la caméra) |
||||
|
AttribsOut.lumiDir = vec3( ( matrVisu * LightSource[0].position ).xyz - pos ); |
||||
|
|
||||
|
// vecteur de la direction vers l'observateur (dans le repère de la caméra) |
||||
|
AttribsOut.obsVec = ( LightModel.localViewer ? |
||||
|
normalize(-pos) : // =(0-pos) un vecteur qui pointe vers le (0,0,0), c'est-à-dire vers la caméra |
||||
|
vec3( 0.0, 0.0, 1.0 ) ); // on considère que l'observateur (la caméra) est à l'infini dans la direction (0,0,1) |
||||
|
// vecteur de la direction du spot (en tenant compte seulement des rotations de la caméra) |
||||
|
AttribsOut.spotDir = inverse(mat3(matrVisu)) * -LightSource[0].spotDirection; |
||||
|
// On accepte aussi: (si on suppose que .spotDirection est déjà dans le repère de la caméra) |
||||
|
//AttribsOut.spotDir = -LightSource[0].spotDirection; |
||||
|
// On accepte aussi: (car matrVisu a seulement une translation et pas de rotation => "mat3(matrVisu) == I" ) |
||||
|
//AttribsOut.spotDir = -LightSource[0].spotDirection; |
||||
|
// On accepte aussi: (car c'était le calcul qui était dans la solution précédente présentée dans le lab!) |
||||
|
//AttribsOut.spotDir = -( matrVisu * vec4(LightSource[0].spotDirection,1.0) ).xyz; |
||||
|
|
||||
|
// si illumination est 1:Gouraud, calculer la réflexion ici, sinon ne rien faire de plus |
||||
|
if ( typeIllumination == 1 ) |
||||
|
{ |
||||
|
vec3 L = normalize( AttribsOut.lumiDir ); // calcul du vecteur de la surface vers la source lumineuse |
||||
|
vec3 N = normalize( AttribsOut.normale ); // vecteur normal |
||||
|
vec3 O = normalize( AttribsOut.obsVec ); // position de l'observateur |
||||
|
AttribsOut.couleur = calculerReflexion( L, N, O ); |
||||
|
} |
||||
|
//else |
||||
|
// couleur = vec4(0.0); // inutile |
||||
|
|
||||
|
// assigner les coordonnées de texture |
||||
|
AttribsOut.texCoord = TexCoord.st; |
||||
|
} |
||||
@ -0,0 +1,954 @@ |
|||||
|
// Prénoms, noms et matricule des membres de l'équipe:
|
||||
|
// - Prénom1 NOM1 (matricule1)
|
||||
|
// - Prénom2 NOM2 (matricule2)
|
||||
|
|
||||
|
#include <stdlib.h> |
||||
|
#include <iostream> |
||||
|
#include "inf2705.h" |
||||
|
|
||||
|
#define SOL 1 |
||||
|
|
||||
|
// variables pour l'utilisation des nuanceurs
|
||||
|
GLuint prog; // votre programme de nuanceurs
|
||||
|
GLint locVertex = -1; |
||||
|
GLint locNormal = -1; |
||||
|
GLint locTexCoord = -1; |
||||
|
GLint locmatrModel = -1; |
||||
|
GLint locmatrVisu = -1; |
||||
|
GLint locmatrProj = -1; |
||||
|
GLint locmatrNormale = -1; |
||||
|
GLint loclaTexture = -1; |
||||
|
GLuint indLightSource; |
||||
|
GLuint indFrontMaterial; |
||||
|
GLuint indLightModel; |
||||
|
GLuint indvarsUnif; |
||||
|
GLuint progBase; // le programme de nuanceurs de base
|
||||
|
GLint locVertexBase = -1; |
||||
|
GLint locColorBase = -1; |
||||
|
GLint locmatrModelBase = -1; |
||||
|
GLint locmatrVisuBase = -1; |
||||
|
GLint locmatrProjBase = -1; |
||||
|
|
||||
|
GLuint vao[2]; |
||||
|
GLuint vbo[5]; |
||||
|
GLuint ubo[4]; |
||||
|
|
||||
|
// matrices de du pipeline graphique
|
||||
|
MatricePipeline matrModel; |
||||
|
MatricePipeline matrVisu; |
||||
|
MatricePipeline matrProj; |
||||
|
|
||||
|
// les formes
|
||||
|
FormeSphere *sphere = NULL, *sphereLumi = NULL; |
||||
|
FormeTheiere *theiere = NULL; |
||||
|
FormeTore *tore = NULL; |
||||
|
FormeCylindre *cylindre = NULL; |
||||
|
FormeCylindre *cone = NULL; |
||||
|
|
||||
|
// variables pour définir le point de vue
|
||||
|
double thetaCam = 0.0; // angle de rotation de la caméra (coord. sphériques)
|
||||
|
double phiCam = 0.0; // angle de rotation de la caméra (coord. sphériques)
|
||||
|
double distCam = 0.0; // distance (coord. sphériques)
|
||||
|
|
||||
|
// variables d'état
|
||||
|
bool enPerspective = false; // indique si on est en mode Perspective (true) ou Ortho (false)
|
||||
|
bool enmouvement = false; // le modèle est en mouvement/rotation automatique ou non
|
||||
|
bool afficheAxes = true; // indique si on affiche les axes
|
||||
|
GLenum modePolygone = GL_FILL; // comment afficher les polygones
|
||||
|
|
||||
|
////////////////////////////////////////
|
||||
|
// déclaration des variables globales //
|
||||
|
////////////////////////////////////////
|
||||
|
|
||||
|
// partie 1: illumination
|
||||
|
int modele = 1; // le modèle à afficher
|
||||
|
|
||||
|
// partie 3: texture
|
||||
|
GLuint textureDE = 0; |
||||
|
GLuint textureECHIQUIER = 0; |
||||
|
|
||||
|
// définition des lumières
|
||||
|
struct LightSourceParameters |
||||
|
{ |
||||
|
glm::vec4 ambient; |
||||
|
glm::vec4 diffuse; |
||||
|
glm::vec4 specular; |
||||
|
glm::vec4 position; |
||||
|
glm::vec3 spotDirection; |
||||
|
float spotExposant; |
||||
|
float spotAngle; // ([0.0,90.0] ou 180.0)
|
||||
|
float constantAttenuation; |
||||
|
float linearAttenuation; |
||||
|
float quadraticAttenuation; |
||||
|
} LightSource[1] = { { glm::vec4( 1.0, 1.0, 1.0, 1.0 ), |
||||
|
glm::vec4( 1.0, 1.0, 1.0, 1.0 ), |
||||
|
glm::vec4( 1.0, 1.0, 1.0, 1.0 ), |
||||
|
glm::vec4( 4, 1, 15, 1.0 ), |
||||
|
glm::vec3( -5.0, -2.0, -10.0 ), |
||||
|
1.0, // l'exposant du cône
|
||||
|
15.0, // l'angle du cône du spot
|
||||
|
1., 0., 0. } }; |
||||
|
|
||||
|
// définition du matériau
|
||||
|
struct MaterialParameters |
||||
|
{ |
||||
|
glm::vec4 emission; |
||||
|
glm::vec4 ambient; |
||||
|
glm::vec4 diffuse; |
||||
|
glm::vec4 specular; |
||||
|
float shininess; |
||||
|
} FrontMaterial = { glm::vec4( 0.0, 0.0, 0.0, 1.0 ), |
||||
|
glm::vec4( 0.1, 0.1, 0.1, 1.0 ), |
||||
|
glm::vec4( 1.0, 0.1, 1.0, 1.0 ), |
||||
|
glm::vec4( 1.0, 1.0, 1.0, 1.0 ), |
||||
|
100.0 }; |
||||
|
|
||||
|
struct LightModelParameters |
||||
|
{ |
||||
|
glm::vec4 ambient; // couleur ambiante
|
||||
|
int localViewer; // doit-on prendre en compte la position de l'observateur? (local ou à l'infini)
|
||||
|
int twoSide; // éclairage sur les deux côtés ou un seul?
|
||||
|
} LightModel = { glm::vec4(0,0,0,1), false, false }; |
||||
|
|
||||
|
struct |
||||
|
{ |
||||
|
// partie 1: illumination
|
||||
|
int typeIllumination; // 0:Lambert, 1:Gouraud, 2:Phong
|
||||
|
int utiliseBlinn; // indique si on veut utiliser modèle spéculaire de Blinn ou Phong
|
||||
|
int utiliseDirect; // indique si on utilise un spot style Direct3D ou OpenGL
|
||||
|
int afficheNormales; // indique si on utilise les normales comme couleurs (utile pour le débogage)
|
||||
|
// partie 3: texture
|
||||
|
int texnumero; // numéro de la texture appliquée
|
||||
|
int utiliseCouleur; // doit-on utiliser la couleur de base de l'objet en plus de celle de la texture?
|
||||
|
int afficheTexelNoir; // un texel noir doit-il être affiché 0:noir, 1:mi-coloré, 2:transparent?
|
||||
|
} varsUnif = { 2, false, false, false, |
||||
|
0, true, 0 }; |
||||
|
// ( En glsl, les types 'bool' et 'int' sont de la même taille, ce qui n'est pas le cas en C++.
|
||||
|
// Ci-dessus, on triche donc un peu en déclarant les 'bool' comme des 'int', mais ça facilite la
|
||||
|
// copie directe vers le nuanceur où les variables seront bien de type 'bool'. )
|
||||
|
|
||||
|
|
||||
|
void verifierAngles() |
||||
|
{ |
||||
|
if ( thetaCam > 360.0 ) |
||||
|
thetaCam -= 360.0; |
||||
|
else if ( thetaCam < 0.0 ) |
||||
|
thetaCam += 360.0; |
||||
|
|
||||
|
const GLdouble MINPHI = -90.0, MAXPHI = 90.0; |
||||
|
if ( phiCam > MAXPHI ) |
||||
|
phiCam = MAXPHI; |
||||
|
else if ( phiCam < MINPHI ) |
||||
|
phiCam = MINPHI; |
||||
|
} |
||||
|
|
||||
|
void calculerPhysique( ) |
||||
|
{ |
||||
|
if ( enmouvement ) |
||||
|
{ |
||||
|
static int sensTheta = 1; |
||||
|
static int sensPhi = 1; |
||||
|
thetaCam += 0.3 * sensTheta; |
||||
|
phiCam += 0.5 * sensPhi; |
||||
|
//if ( thetaCam <= 0. || thetaCam >= 360.0 ) sensTheta = -sensTheta;
|
||||
|
if ( phiCam < -90.0 || phiCam > 90.0 ) sensPhi = -sensPhi; |
||||
|
|
||||
|
static int sensAngle = 1; |
||||
|
LightSource[0].spotAngle += sensAngle * 0.3; |
||||
|
if ( LightSource[0].spotAngle < 5.0 ) sensAngle = -sensAngle; |
||||
|
if ( LightSource[0].spotAngle > 60.0 ) sensAngle = -sensAngle; |
||||
|
|
||||
|
#if 0 |
||||
|
static int sensExposant = 1; |
||||
|
LightSource[0].spotExposant += sensExposant * 0.3; |
||||
|
if ( LightSource[0].spotExposant < 1.0 ) sensExposant = -sensExposant; |
||||
|
if ( LightSource[0].spotExposant > 10.0 ) sensExposant = -sensExposant; |
||||
|
#endif |
||||
|
|
||||
|
// De temps à autre, alterner entre le modèle d'illumination: Lambert, Gouraud, Phong
|
||||
|
static float type = 0; |
||||
|
type += 0.005; |
||||
|
varsUnif.typeIllumination = fmod(type,3); |
||||
|
} |
||||
|
|
||||
|
verifierAngles(); |
||||
|
} |
||||
|
|
||||
|
void chargerTextures() |
||||
|
{ |
||||
|
unsigned char *pixels; |
||||
|
GLsizei largeur, hauteur; |
||||
|
if ( ( pixels = ChargerImage( "textures/de.bmp", largeur, hauteur ) ) != NULL ) |
||||
|
{ |
||||
|
glGenTextures( 1, &textureDE ); |
||||
|
glBindTexture( GL_TEXTURE_2D, textureDE ); |
||||
|
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, largeur, hauteur, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels ); |
||||
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); |
||||
|
glBindTexture( GL_TEXTURE_2D, 0 ); |
||||
|
delete[] pixels; |
||||
|
} |
||||
|
if ( ( pixels = ChargerImage( "textures/echiquier.bmp", largeur, hauteur ) ) != NULL ) |
||||
|
{ |
||||
|
glGenTextures( 1, &textureECHIQUIER ); |
||||
|
glBindTexture( GL_TEXTURE_2D, textureECHIQUIER ); |
||||
|
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, largeur, hauteur, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels ); |
||||
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); |
||||
|
glBindTexture( GL_TEXTURE_2D, 0 ); |
||||
|
delete[] pixels; |
||||
|
} |
||||
|
|
||||
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); |
||||
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); |
||||
|
} |
||||
|
|
||||
|
void chargerNuanceurs() |
||||
|
{ |
||||
|
// charger le nuanceur de base
|
||||
|
{ |
||||
|
// créer le programme
|
||||
|
progBase = glCreateProgram(); |
||||
|
|
||||
|
// attacher le nuanceur de sommets
|
||||
|
{ |
||||
|
GLuint nuanceurObj = glCreateShader( GL_VERTEX_SHADER ); |
||||
|
glShaderSource( nuanceurObj, 1, &ProgNuanceur::chainesSommetsMinimal, NULL ); |
||||
|
glCompileShader( nuanceurObj ); |
||||
|
glAttachShader( progBase, nuanceurObj ); |
||||
|
ProgNuanceur::afficherLogCompile( nuanceurObj ); |
||||
|
} |
||||
|
// attacher le nuanceur de fragments
|
||||
|
{ |
||||
|
GLuint nuanceurObj = glCreateShader( GL_FRAGMENT_SHADER ); |
||||
|
glShaderSource( nuanceurObj, 1, &ProgNuanceur::chainesFragmentsMinimal, NULL ); |
||||
|
glCompileShader( nuanceurObj ); |
||||
|
glAttachShader( progBase, nuanceurObj ); |
||||
|
ProgNuanceur::afficherLogCompile( nuanceurObj ); |
||||
|
} |
||||
|
|
||||
|
// faire l'édition des liens du programme
|
||||
|
glLinkProgram( progBase ); |
||||
|
|
||||
|
ProgNuanceur::afficherLogLink( progBase ); |
||||
|
// demander la "Location" des variables
|
||||
|
if ( ( locVertexBase = glGetAttribLocation( progBase, "Vertex" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de Vertex" << std::endl; |
||||
|
if ( ( locColorBase = glGetAttribLocation( progBase, "Color" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de Color" << std::endl; |
||||
|
if ( ( locmatrModelBase = glGetUniformLocation( progBase, "matrModel" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de matrModel" << std::endl; |
||||
|
if ( ( locmatrVisuBase = glGetUniformLocation( progBase, "matrVisu" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de matrVisu" << std::endl; |
||||
|
if ( ( locmatrProjBase = glGetUniformLocation( progBase, "matrProj" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de matrProj" << std::endl; |
||||
|
} |
||||
|
|
||||
|
// charger le nuanceur de ce TP
|
||||
|
{ |
||||
|
// créer le programme
|
||||
|
prog = glCreateProgram(); |
||||
|
|
||||
|
// attacher le nuanceur de sommets
|
||||
|
#if !defined(SOL) |
||||
|
const GLchar *chainesSommets = ProgNuanceur::lireNuanceur( "nuanceurSommets.glsl" ); |
||||
|
#else |
||||
|
const GLchar *chainesSommets = ProgNuanceur::lireNuanceur( "nuanceurSommetsSolution.glsl" ); |
||||
|
#endif |
||||
|
if ( chainesSommets != NULL ) |
||||
|
{ |
||||
|
GLuint nuanceurObj = glCreateShader( GL_VERTEX_SHADER ); |
||||
|
glShaderSource( nuanceurObj, 1, &chainesSommets, NULL ); |
||||
|
glCompileShader( nuanceurObj ); |
||||
|
glAttachShader( prog, nuanceurObj ); |
||||
|
ProgNuanceur::afficherLogCompile( nuanceurObj ); |
||||
|
delete [] chainesSommets; |
||||
|
} |
||||
|
#if !defined(SOL) |
||||
|
const GLchar *chainesGeometrie = ProgNuanceur::lireNuanceur( "nuanceurGeometrie.glsl" ); |
||||
|
#else |
||||
|
const GLchar *chainesGeometrie = ProgNuanceur::lireNuanceur( "nuanceurGeometrieSolution.glsl" ); |
||||
|
#endif |
||||
|
if ( chainesGeometrie != NULL ) |
||||
|
{ |
||||
|
GLuint nuanceurObj = glCreateShader( GL_GEOMETRY_SHADER ); |
||||
|
glShaderSource( nuanceurObj, 1, &chainesGeometrie, NULL ); |
||||
|
glCompileShader( nuanceurObj ); |
||||
|
glAttachShader( prog, nuanceurObj ); |
||||
|
ProgNuanceur::afficherLogCompile( nuanceurObj ); |
||||
|
delete [] chainesGeometrie; |
||||
|
} |
||||
|
// attacher le nuanceur de fragments
|
||||
|
#if !defined(SOL) |
||||
|
const GLchar *chainesFragments = ProgNuanceur::lireNuanceur( "nuanceurFragments.glsl" ); |
||||
|
#else |
||||
|
const GLchar *chainesFragments = ProgNuanceur::lireNuanceur( "nuanceurFragmentsSolution.glsl" ); |
||||
|
#endif |
||||
|
if ( chainesFragments != NULL ) |
||||
|
{ |
||||
|
GLuint nuanceurObj = glCreateShader( GL_FRAGMENT_SHADER ); |
||||
|
glShaderSource( nuanceurObj, 1, &chainesFragments, NULL ); |
||||
|
glCompileShader( nuanceurObj ); |
||||
|
glAttachShader( prog, nuanceurObj ); |
||||
|
ProgNuanceur::afficherLogCompile( nuanceurObj ); |
||||
|
delete [] chainesFragments; |
||||
|
} |
||||
|
|
||||
|
// faire l'édition des liens du programme
|
||||
|
glLinkProgram( prog ); |
||||
|
|
||||
|
ProgNuanceur::afficherLogLink( prog ); |
||||
|
// demander la "Location" des variables
|
||||
|
if ( ( locVertex = glGetAttribLocation( prog, "Vertex" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de Vertex" << std::endl; |
||||
|
if ( ( locNormal = glGetAttribLocation( prog, "Normal" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de Normal (partie 1)" << std::endl; |
||||
|
if ( ( locTexCoord = glGetAttribLocation( prog, "TexCoord" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de TexCoord (partie 3)" << std::endl; |
||||
|
if ( ( locmatrModel = glGetUniformLocation( prog, "matrModel" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de matrModel" << std::endl; |
||||
|
if ( ( locmatrVisu = glGetUniformLocation( prog, "matrVisu" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de matrVisu" << std::endl; |
||||
|
if ( ( locmatrProj = glGetUniformLocation( prog, "matrProj" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de matrProj" << std::endl; |
||||
|
if ( ( locmatrNormale = glGetUniformLocation( prog, "matrNormale" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de matrNormale (partie 1)" << std::endl; |
||||
|
if ( ( loclaTexture = glGetUniformLocation( prog, "laTexture" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de laTexture (partie 3)" << std::endl; |
||||
|
if ( ( indLightSource = glGetUniformBlockIndex( prog, "LightSourceParameters" ) ) == GL_INVALID_INDEX ) std::cerr << "!!! pas trouvé l'\"index\" de LightSource" << std::endl; |
||||
|
if ( ( indFrontMaterial = glGetUniformBlockIndex( prog, "MaterialParameters" ) ) == GL_INVALID_INDEX ) std::cerr << "!!! pas trouvé l'\"index\" de FrontMaterial" << std::endl; |
||||
|
if ( ( indLightModel = glGetUniformBlockIndex( prog, "LightModelParameters" ) ) == GL_INVALID_INDEX ) std::cerr << "!!! pas trouvé l'\"index\" de LightModel" << std::endl; |
||||
|
if ( ( indvarsUnif = glGetUniformBlockIndex( prog, "varsUnif" ) ) == GL_INVALID_INDEX ) std::cerr << "!!! pas trouvé l'\"index\" de varsUnif" << std::endl; |
||||
|
|
||||
|
// charger les ubo
|
||||
|
{ |
||||
|
glBindBuffer( GL_UNIFORM_BUFFER, ubo[0] ); |
||||
|
glBufferData( GL_UNIFORM_BUFFER, sizeof(LightSource), &LightSource, GL_DYNAMIC_COPY ); |
||||
|
glBindBuffer( GL_UNIFORM_BUFFER, 0 ); |
||||
|
const GLuint bindingIndex = 0; |
||||
|
glBindBufferBase( GL_UNIFORM_BUFFER, bindingIndex, ubo[0] ); |
||||
|
glUniformBlockBinding( prog, indLightSource, bindingIndex ); |
||||
|
} |
||||
|
{ |
||||
|
glBindBuffer( GL_UNIFORM_BUFFER, ubo[1] ); |
||||
|
glBufferData( GL_UNIFORM_BUFFER, sizeof(FrontMaterial), &FrontMaterial, GL_DYNAMIC_COPY ); |
||||
|
glBindBuffer( GL_UNIFORM_BUFFER, 0 ); |
||||
|
const GLuint bindingIndex = 1; |
||||
|
glBindBufferBase( GL_UNIFORM_BUFFER, bindingIndex, ubo[1] ); |
||||
|
glUniformBlockBinding( prog, indFrontMaterial, bindingIndex ); |
||||
|
} |
||||
|
{ |
||||
|
glBindBuffer( GL_UNIFORM_BUFFER, ubo[2] ); |
||||
|
glBufferData( GL_UNIFORM_BUFFER, sizeof(LightModel), &LightModel, GL_DYNAMIC_COPY ); |
||||
|
glBindBuffer( GL_UNIFORM_BUFFER, 0 ); |
||||
|
const GLuint bindingIndex = 2; |
||||
|
glBindBufferBase( GL_UNIFORM_BUFFER, bindingIndex, ubo[2] ); |
||||
|
glUniformBlockBinding( prog, indLightModel, bindingIndex ); |
||||
|
} |
||||
|
{ |
||||
|
glBindBuffer( GL_UNIFORM_BUFFER, ubo[3] ); |
||||
|
glBufferData( GL_UNIFORM_BUFFER, sizeof(varsUnif), &varsUnif, GL_DYNAMIC_COPY ); |
||||
|
glBindBuffer( GL_UNIFORM_BUFFER, 0 ); |
||||
|
const GLuint bindingIndex = 3; |
||||
|
glBindBufferBase( GL_UNIFORM_BUFFER, bindingIndex, ubo[3] ); |
||||
|
glUniformBlockBinding( prog, indvarsUnif, bindingIndex ); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// initialisation d'openGL
|
||||
|
void initialiser() |
||||
|
{ |
||||
|
// donner l'orientation du modèle
|
||||
|
thetaCam = 0.0; |
||||
|
phiCam = 0.0; |
||||
|
distCam = 30.0; |
||||
|
|
||||
|
// couleur de l'arrière-plan
|
||||
|
glClearColor( 0.4, 0.2, 0.0, 1.0 ); |
||||
|
|
||||
|
// activer les etats openGL
|
||||
|
glEnable( GL_DEPTH_TEST ); |
||||
|
|
||||
|
// charger les textures
|
||||
|
chargerTextures(); |
||||
|
|
||||
|
// allouer les UBO pour les variables uniformes
|
||||
|
glGenBuffers( 4, ubo ); |
||||
|
|
||||
|
// charger les nuanceurs
|
||||
|
chargerNuanceurs(); |
||||
|
glUseProgram( prog ); |
||||
|
|
||||
|
// (partie 1) créer le cube
|
||||
|
/* +Y */ |
||||
|
/* 3+-----------+2 */ |
||||
|
/* |\ |\ */ |
||||
|
/* | \ | \ */ |
||||
|
/* | \ | \ */ |
||||
|
/* | 7+-----------+6 */ |
||||
|
/* | | | | */ |
||||
|
/* | | | | */ |
||||
|
/* 0+---|-------+1 | */ |
||||
|
/* \ | \ | +X */ |
||||
|
/* \ | \ | */ |
||||
|
/* \| \| */ |
||||
|
/* 4+-----------+5 */ |
||||
|
/* +Z */ |
||||
|
|
||||
|
GLfloat sommets[3*4*6] = |
||||
|
{ |
||||
|
-1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, // P3,P2,P0,P1
|
||||
|
1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, // P5,P4,P1,P0
|
||||
|
1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, // P6,P5,P2,P1
|
||||
|
-1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, // P7,P6,P3,P2
|
||||
|
-1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, // P4,P7,P0,P3
|
||||
|
-1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0 // P4,P5,P7,P6
|
||||
|
}; |
||||
|
GLfloat normales[3*4*6] = |
||||
|
{ |
||||
|
0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, |
||||
|
0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, |
||||
|
1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, |
||||
|
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, |
||||
|
-1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, |
||||
|
0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, |
||||
|
}; |
||||
|
GLfloat texcoordsDe[2*4*6] = |
||||
|
{ |
||||
|
1.000000,0.000000, 0.666666,0.000000, 1.000000,0.333333, 0.666666,0.333333, |
||||
|
0.000000,0.666666, 0.333333,0.666666, 0.000000,0.333333, 0.333333,0.333333, |
||||
|
0.666666,1.000000, 0.666666,0.666666, 0.333333,1.000000, 0.333333,0.666666, |
||||
|
1.000000,0.333333, 0.666666,0.333333, 1.000000,0.666666, 0.666666,0.666666, |
||||
|
0.333333,0.000000, 0.333333,0.333333, 0.666666,0.000000, 0.666666,0.333333, |
||||
|
0.666666,0.333333, 0.333333,0.333333, 0.666666,0.666666, 0.333333,0.666666 |
||||
|
}; |
||||
|
GLfloat texcoordsEchiquier[2*4*6] = |
||||
|
{ |
||||
|
-1.0, -1.0, -1.0, 2.0, 2.0, -1.0, 2.0, 2.0, |
||||
|
2.0, -1.0, -1.0, -1.0, 2.0, 2.0, -1.0, 2.0, |
||||
|
-1.0, -1.0, -1.0, 2.0, 2.0, -1.0, 2.0, 2.0, |
||||
|
-1.0, 2.0, 2.0, 2.0, -1.0, -1.0, 2.0, -1.0, |
||||
|
2.0, 2.0, 2.0, -1.0, -1.0, 2.0, -1.0, -1.0, |
||||
|
-1.0, -1.0, -1.0, 2.0, 2.0, -1.0, 2.0, 2.0 |
||||
|
}; |
||||
|
|
||||
|
// allouer les objets OpenGL
|
||||
|
glGenVertexArrays( 2, vao ); |
||||
|
glGenBuffers( 5, vbo ); |
||||
|
// initialiser le VAO
|
||||
|
glBindVertexArray( vao[0] ); |
||||
|
|
||||
|
// charger le VBO pour les sommets
|
||||
|
glBindBuffer( GL_ARRAY_BUFFER, vbo[0] ); |
||||
|
glBufferData( GL_ARRAY_BUFFER, sizeof(sommets), sommets, GL_STATIC_DRAW ); |
||||
|
glVertexAttribPointer( locVertex, 3, GL_FLOAT, GL_FALSE, 0, 0 ); |
||||
|
glEnableVertexAttribArray(locVertex); |
||||
|
// (partie 1) charger le VBO pour les normales
|
||||
|
glBindBuffer( GL_ARRAY_BUFFER, vbo[1] ); |
||||
|
glBufferData( GL_ARRAY_BUFFER, sizeof(normales), normales, GL_STATIC_DRAW ); |
||||
|
glVertexAttribPointer( locNormal, 3, GL_FLOAT, GL_FALSE, 0, 0 ); |
||||
|
glEnableVertexAttribArray(locNormal); |
||||
|
// (partie 3) charger le VBO pour les coordonnées de texture du dé
|
||||
|
glBindBuffer( GL_ARRAY_BUFFER, vbo[2] ); |
||||
|
glBufferData( GL_ARRAY_BUFFER, sizeof(texcoordsDe), texcoordsDe, GL_STATIC_DRAW ); |
||||
|
glVertexAttribPointer( locTexCoord, 2, GL_FLOAT, GL_FALSE, 0, 0 ); |
||||
|
glEnableVertexAttribArray(locTexCoord); |
||||
|
// (partie 3) charger le VBO pour les coordonnées de texture de l'échiquier
|
||||
|
glBindBuffer( GL_ARRAY_BUFFER, vbo[3] ); |
||||
|
glBufferData( GL_ARRAY_BUFFER, sizeof(texcoordsEchiquier), texcoordsEchiquier, GL_STATIC_DRAW ); |
||||
|
glVertexAttribPointer( locTexCoord, 2, GL_FLOAT, GL_FALSE, 0, 0 ); |
||||
|
glEnableVertexAttribArray(locTexCoord); |
||||
|
|
||||
|
glBindVertexArray(0); |
||||
|
|
||||
|
// initialiser le VAO pour une ligne (montrant la direction du spot)
|
||||
|
glBindVertexArray( vao[1] ); |
||||
|
GLfloat coords[] = { 0., 0., 0., 0., 0., 1. }; |
||||
|
glBindBuffer( GL_ARRAY_BUFFER, vbo[4] ); |
||||
|
glBufferData( GL_ARRAY_BUFFER, sizeof(coords), coords, GL_STATIC_DRAW ); |
||||
|
glVertexAttribPointer( locVertexBase, 3, GL_FLOAT, GL_FALSE, 0, 0 ); |
||||
|
glEnableVertexAttribArray(locVertexBase); |
||||
|
glBindVertexArray(0); |
||||
|
|
||||
|
// créer quelques autres formes
|
||||
|
sphere = new FormeSphere( 1.0, 32, 32 ); |
||||
|
sphereLumi = new FormeSphere( 0.5, 10, 10 ); |
||||
|
theiere = new FormeTheiere( ); |
||||
|
tore = new FormeTore( 0.4, 0.8, 32, 32 ); |
||||
|
cylindre = new FormeCylindre( 0.3, 0.3, 3.0, 32, 32 ); |
||||
|
cone = new FormeCylindre( 0.0, 0.5, 3.0, 32, 32 ); |
||||
|
} |
||||
|
|
||||
|
void conclure() |
||||
|
{ |
||||
|
glUseProgram( 0 ); |
||||
|
glDeleteVertexArrays( 2, vao ); |
||||
|
glDeleteBuffers( 4, vbo ); |
||||
|
glDeleteBuffers( 4, ubo ); |
||||
|
delete sphere; |
||||
|
delete sphereLumi; |
||||
|
delete theiere; |
||||
|
delete tore; |
||||
|
delete cylindre; |
||||
|
delete cone; |
||||
|
} |
||||
|
|
||||
|
void afficherModele() |
||||
|
{ |
||||
|
// partie 3: paramètres de texture
|
||||
|
switch ( varsUnif.texnumero ) |
||||
|
{ |
||||
|
default: |
||||
|
//std::cout << "Sans texture" << std::endl;
|
||||
|
glBindTexture( GL_TEXTURE_2D, 0 ); |
||||
|
break; |
||||
|
case 1: |
||||
|
//std::cout << "Texture DE" << std::endl;
|
||||
|
glBindTexture( GL_TEXTURE_2D, textureDE ); |
||||
|
break; |
||||
|
case 2: |
||||
|
//std::cout << "Texture ECHIQUIER" << std::endl;
|
||||
|
glBindTexture( GL_TEXTURE_2D, textureECHIQUIER ); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
// Dessiner le modèle
|
||||
|
matrModel.PushMatrix(); { |
||||
|
|
||||
|
// appliquer les rotations
|
||||
|
matrModel.Rotate( phiCam, -1.0, 0.0, 0.0 ); |
||||
|
matrModel.Rotate( thetaCam, 0.0, -1.0, 0.0 ); |
||||
|
|
||||
|
// mise à l'échelle
|
||||
|
matrModel.Scale( 5.0, 5.0, 5.0 ); |
||||
|
|
||||
|
glUniformMatrix4fv( locmatrModel, 1, GL_FALSE, matrModel ); |
||||
|
// (partie 1: ne pas oublier de calculer et donner une matrice pour les transformations des normales)
|
||||
|
glUniformMatrix3fv( locmatrNormale, 1, GL_TRUE, glm::value_ptr( glm::inverse( glm::mat3( matrVisu.getMatr() * matrModel.getMatr() ) ) ) ); |
||||
|
|
||||
|
switch ( modele ) |
||||
|
{ |
||||
|
default: |
||||
|
case 1: |
||||
|
// afficher le cube
|
||||
|
glBindVertexArray( vao[0] ); |
||||
|
glBindBuffer( GL_ARRAY_BUFFER, varsUnif.texnumero == 1 ? vbo[2] : vbo[3] ); |
||||
|
glVertexAttribPointer( locTexCoord, 2, GL_FLOAT, GL_FALSE, 0, 0 ); |
||||
|
glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 ); |
||||
|
glDrawArrays( GL_TRIANGLE_STRIP, 4, 4 ); |
||||
|
glDrawArrays( GL_TRIANGLE_STRIP, 8, 4 ); |
||||
|
glDrawArrays( GL_TRIANGLE_STRIP, 12, 4 ); |
||||
|
glDrawArrays( GL_TRIANGLE_STRIP, 16, 4 ); |
||||
|
glDrawArrays( GL_TRIANGLE_STRIP, 20, 4 ); |
||||
|
glBindVertexArray( 0 ); |
||||
|
break; |
||||
|
case 2: |
||||
|
tore->afficher(); |
||||
|
break; |
||||
|
case 3: |
||||
|
sphere->afficher(); |
||||
|
break; |
||||
|
case 4: |
||||
|
matrModel.Rotate( -90.0, 1.0, 0.0, 0.0 ); |
||||
|
matrModel.Translate( 0.0, 0.0, -0.5 ); |
||||
|
matrModel.Scale( 0.5, 0.5, 0.5 ); |
||||
|
glUniformMatrix4fv( locmatrModel, 1, GL_FALSE, matrModel ); |
||||
|
glUniformMatrix3fv( locmatrNormale, 1, GL_TRUE, glm::value_ptr( glm::inverse( glm::mat3( matrVisu.getMatr() * matrModel.getMatr() ) ) ) ); |
||||
|
theiere->afficher( ); |
||||
|
break; |
||||
|
case 5: |
||||
|
matrModel.PushMatrix(); { |
||||
|
matrModel.Translate( 0.0, 0.0, -1.5 ); |
||||
|
glUniformMatrix4fv( locmatrModel, 1, GL_FALSE, matrModel ); |
||||
|
glUniformMatrix3fv( locmatrNormale, 1, GL_TRUE, glm::value_ptr( glm::inverse( glm::mat3( matrVisu.getMatr() * matrModel.getMatr() ) ) ) ); |
||||
|
cylindre->afficher(); |
||||
|
} matrModel.PopMatrix(); |
||||
|
break; |
||||
|
case 6: |
||||
|
matrModel.PushMatrix(); { |
||||
|
matrModel.Translate( 0.0, 0.0, -1.5 ); |
||||
|
glUniformMatrix4fv( locmatrModel, 1, GL_FALSE, matrModel ); |
||||
|
glUniformMatrix3fv( locmatrNormale, 1, GL_TRUE, glm::value_ptr( glm::inverse( glm::mat3( matrVisu.getMatr() * matrModel.getMatr() ) ) ) ); |
||||
|
cone->afficher(); |
||||
|
} matrModel.PopMatrix(); |
||||
|
break; |
||||
|
} |
||||
|
} matrModel.PopMatrix(); glUniformMatrix4fv( locmatrModel, 1, GL_FALSE, matrModel ); |
||||
|
} |
||||
|
|
||||
|
void afficherLumiere() |
||||
|
{ |
||||
|
// Dessiner la lumiere
|
||||
|
|
||||
|
// tracer une ligne vers la source lumineuse
|
||||
|
const GLfloat fact = 5.; |
||||
|
GLfloat coords[] = |
||||
|
{ |
||||
|
LightSource[0].position.x , LightSource[0].position.y , LightSource[0].position.z, |
||||
|
LightSource[0].position.x+LightSource[0].spotDirection.x/fact, LightSource[0].position.y+LightSource[0].spotDirection.y/fact, LightSource[0].position.z+LightSource[0].spotDirection.z/fact |
||||
|
}; |
||||
|
glLineWidth( 3.0 ); |
||||
|
glVertexAttrib3f( locColorBase, 1.0, 1.0, 0.5 ); // jaune
|
||||
|
glBindVertexArray( vao[1] ); |
||||
|
matrModel.PushMatrix(); { |
||||
|
glBindBuffer( GL_ARRAY_BUFFER, vbo[4] ); |
||||
|
glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(coords), coords ); |
||||
|
glDrawArrays( GL_LINES, 0, 2 ); |
||||
|
} matrModel.PopMatrix(); glUniformMatrix4fv( locmatrModelBase, 1, GL_FALSE, matrModel ); |
||||
|
glBindVertexArray( 0 ); |
||||
|
glLineWidth( 1.0 ); |
||||
|
|
||||
|
// tracer la source lumineuse
|
||||
|
matrModel.PushMatrix(); { |
||||
|
matrModel.Translate( LightSource[0].position.x, LightSource[0].position.y, LightSource[0].position.z ); |
||||
|
glUniformMatrix4fv( locmatrModelBase, 1, GL_FALSE, matrModel ); |
||||
|
sphereLumi->afficher(); |
||||
|
} matrModel.PopMatrix(); glUniformMatrix4fv( locmatrModelBase, 1, GL_FALSE, matrModel ); |
||||
|
} |
||||
|
|
||||
|
// fonction d'affichage
|
||||
|
void FenetreTP::afficherScene() |
||||
|
{ |
||||
|
// effacer l'ecran et le tampon de profondeur
|
||||
|
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); |
||||
|
|
||||
|
glUseProgram( progBase ); |
||||
|
|
||||
|
// définir le pipeline graphique
|
||||
|
if ( enPerspective ) |
||||
|
{ |
||||
|
matrProj.Perspective( 35.0, (GLdouble)largeur_ / (GLdouble)hauteur_, |
||||
|
0.1, 60.0 ); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
const GLfloat d = 8.0; |
||||
|
if ( largeur_ <= hauteur_ ) |
||||
|
{ |
||||
|
matrProj.Ortho( -d, d, |
||||
|
-d*(GLdouble)hauteur_ / (GLdouble)largeur_, |
||||
|
d*(GLdouble)hauteur_ / (GLdouble)largeur_, |
||||
|
0.1, 60.0 ); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
matrProj.Ortho( -d*(GLdouble)largeur_ / (GLdouble)hauteur_, |
||||
|
d*(GLdouble)largeur_ / (GLdouble)hauteur_, |
||||
|
-d, d, |
||||
|
0.1, 60.0 ); |
||||
|
} |
||||
|
} |
||||
|
glUniformMatrix4fv( locmatrProjBase, 1, GL_FALSE, matrProj ); |
||||
|
|
||||
|
matrVisu.LookAt( 0.0, 0.0, distCam, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ); |
||||
|
glUniformMatrix4fv( locmatrVisuBase, 1, GL_FALSE, matrVisu ); |
||||
|
|
||||
|
matrModel.LoadIdentity(); |
||||
|
glUniformMatrix4fv( locmatrModelBase, 1, GL_FALSE, matrModel ); |
||||
|
|
||||
|
// afficher les axes
|
||||
|
if ( afficheAxes ) FenetreTP::afficherAxes( 8.0 ); |
||||
|
|
||||
|
// dessiner la scène
|
||||
|
afficherLumiere(); |
||||
|
|
||||
|
glUseProgram( prog ); |
||||
|
|
||||
|
// mettre à jour les blocs de variables uniformes
|
||||
|
{ |
||||
|
glBindBuffer( GL_UNIFORM_BUFFER, ubo[0] ); |
||||
|
GLvoid *p = glMapBuffer( GL_UNIFORM_BUFFER, GL_WRITE_ONLY ); |
||||
|
memcpy( p, &LightSource, sizeof(LightSource) ); |
||||
|
glUnmapBuffer( GL_UNIFORM_BUFFER ); |
||||
|
} |
||||
|
{ |
||||
|
glBindBuffer( GL_UNIFORM_BUFFER, ubo[1] ); |
||||
|
GLvoid *p = glMapBuffer( GL_UNIFORM_BUFFER, GL_WRITE_ONLY ); |
||||
|
memcpy( p, &FrontMaterial, sizeof(FrontMaterial) ); |
||||
|
glUnmapBuffer( GL_UNIFORM_BUFFER ); |
||||
|
} |
||||
|
{ |
||||
|
glBindBuffer( GL_UNIFORM_BUFFER, ubo[2] ); |
||||
|
GLvoid *p = glMapBuffer( GL_UNIFORM_BUFFER, GL_WRITE_ONLY ); |
||||
|
memcpy( p, &LightModel, sizeof(LightModel) ); |
||||
|
glUnmapBuffer( GL_UNIFORM_BUFFER ); |
||||
|
} |
||||
|
{ |
||||
|
glBindBuffer( GL_UNIFORM_BUFFER, ubo[3] ); |
||||
|
GLvoid *p = glMapBuffer( GL_UNIFORM_BUFFER, GL_WRITE_ONLY ); |
||||
|
memcpy( p, &varsUnif, sizeof(varsUnif) ); |
||||
|
glUnmapBuffer( GL_UNIFORM_BUFFER ); |
||||
|
} |
||||
|
|
||||
|
// mettre à jour les matrices et autres uniformes
|
||||
|
glUniformMatrix4fv( locmatrProj, 1, GL_FALSE, matrProj ); |
||||
|
glUniformMatrix4fv( locmatrVisu, 1, GL_FALSE, matrVisu ); |
||||
|
glUniformMatrix4fv( locmatrModel, 1, GL_FALSE, matrModel ); |
||||
|
//glActiveTexture( GL_TEXTURE0 ); // activer la texture '0' (valeur de défaut)
|
||||
|
glUniform1i( loclaTexture, 0 ); // '0' => utilisation de GL_TEXTURE0
|
||||
|
|
||||
|
afficherModele(); |
||||
|
} |
||||
|
|
||||
|
// fonction de redimensionnement de la fenêtre graphique
|
||||
|
void FenetreTP::redimensionner( GLsizei w, GLsizei h ) |
||||
|
{ |
||||
|
glViewport( 0, 0, w, h ); |
||||
|
} |
||||
|
|
||||
|
static void echoEtats( ) |
||||
|
{ |
||||
|
static std::string illuminationStr[] = { "0:Lambert", "1:Gouraud", "2:Phong" }; |
||||
|
static std::string reflexionStr[] = { "0:Phong", "1:Blinn" }; |
||||
|
static std::string spotStr[] = { "0:OpenGL", "1:Direct3D" }; |
||||
|
std::cout << " modèle d'illumination= " << illuminationStr[varsUnif.typeIllumination] |
||||
|
<< ", refléxion spéculaire= " << reflexionStr[varsUnif.utiliseBlinn] |
||||
|
<< ", spot= " << spotStr[varsUnif.utiliseDirect] |
||||
|
<< std::endl; |
||||
|
} |
||||
|
|
||||
|
// fonction de gestion du clavier
|
||||
|
void FenetreTP::clavier( TP_touche touche ) |
||||
|
{ |
||||
|
// traitement des touches q et echap
|
||||
|
switch ( touche ) |
||||
|
{ |
||||
|
case TP_ECHAP: |
||||
|
case TP_q: // Quitter l'application
|
||||
|
quit(); |
||||
|
break; |
||||
|
|
||||
|
case TP_x: // Activer/désactiver l'affichage des axes
|
||||
|
afficheAxes = !afficheAxes; |
||||
|
std::cout << "// Affichage des axes ? " << ( afficheAxes ? "OUI" : "NON" ) << std::endl; |
||||
|
break; |
||||
|
|
||||
|
case TP_v: // Recharger les fichiers des nuanceurs et recréer le programme
|
||||
|
chargerNuanceurs(); |
||||
|
std::cout << "// Recharger nuanceurs" << std::endl; |
||||
|
break; |
||||
|
|
||||
|
case TP_p: // Permuter la projection: perspective ou orthogonale
|
||||
|
enPerspective = !enPerspective; |
||||
|
break; |
||||
|
|
||||
|
case TP_i: // Alterner entre le modèle d'illumination: Lambert, Gouraud, Phong
|
||||
|
if ( ++varsUnif.typeIllumination > 2 ) varsUnif.typeIllumination = 0; |
||||
|
echoEtats( ); |
||||
|
break; |
||||
|
|
||||
|
case TP_r: // Alterner entre le modèle de réflexion spéculaire: Phong, Blinn
|
||||
|
varsUnif.utiliseBlinn = !varsUnif.utiliseBlinn; |
||||
|
echoEtats( ); |
||||
|
break; |
||||
|
|
||||
|
case TP_s: // Alterner entre le modèle de spot: OpenGL, Direct3D
|
||||
|
varsUnif.utiliseDirect = !varsUnif.utiliseDirect; |
||||
|
echoEtats( ); |
||||
|
break; |
||||
|
|
||||
|
//case TP_l: // Alterner entre une caméra locale à la scène ou distante (localViewer)
|
||||
|
// LightModel.localViewer = !LightModel.localViewer;
|
||||
|
// std::cout << " localViewer=" << LightModel.localViewer << std::endl;
|
||||
|
// break;
|
||||
|
|
||||
|
case TP_a: // Incrémenter l'angle du cône du spot
|
||||
|
case TP_EGAL: |
||||
|
case TP_PLUS: |
||||
|
LightSource[0].spotAngle += 2.0; |
||||
|
if ( LightSource[0].spotAngle > 90.0 ) LightSource[0].spotAngle = 90.0; |
||||
|
std::cout << " spotAngle=" << LightSource[0].spotAngle << std::endl; |
||||
|
break; |
||||
|
case TP_z: // Décrémenter l'angle du cône du spot
|
||||
|
case TP_MOINS: |
||||
|
case TP_SOULIGNE: |
||||
|
LightSource[0].spotAngle -= 2.0; |
||||
|
if ( LightSource[0].spotAngle < 0.0 ) LightSource[0].spotAngle = 0.0; |
||||
|
std::cout << " spotAngle=" << LightSource[0].spotAngle << std::endl; |
||||
|
break; |
||||
|
|
||||
|
case TP_d: // Incrémenter l'exposant du spot
|
||||
|
case TP_BARREOBLIQUE: |
||||
|
LightSource[0].spotExposant += 0.3; |
||||
|
if ( LightSource[0].spotExposant > 89.0 ) LightSource[0].spotExposant = 89.0; |
||||
|
std::cout << " spotExposant=" << LightSource[0].spotExposant << std::endl; |
||||
|
break; |
||||
|
case TP_e: // Décrémenter l'exposant du spot
|
||||
|
case TP_POINT: |
||||
|
LightSource[0].spotExposant -= 0.3; |
||||
|
if ( LightSource[0].spotExposant < 0.0 ) LightSource[0].spotExposant = 0.0; |
||||
|
std::cout << " spotExposant=" << LightSource[0].spotExposant << std::endl; |
||||
|
break; |
||||
|
|
||||
|
case TP_j: // Incrémenter le coefficient de brillance
|
||||
|
case TP_CROCHETDROIT: |
||||
|
FrontMaterial.shininess *= 1.1; |
||||
|
std::cout << " FrontMaterial.shininess=" << FrontMaterial.shininess << std::endl; |
||||
|
break; |
||||
|
case TP_u: // Décrémenter le coefficient de brillance
|
||||
|
case TP_CROCHETGAUCHE: |
||||
|
FrontMaterial.shininess /= 1.1; if ( FrontMaterial.shininess < 0.0 ) FrontMaterial.shininess = 0.0; |
||||
|
std::cout << " FrontMaterial.shininess=" << FrontMaterial.shininess << std::endl; |
||||
|
break; |
||||
|
|
||||
|
case TP_DROITE: |
||||
|
LightSource[0].position.x += 0.3; |
||||
|
break; |
||||
|
case TP_GAUCHE: |
||||
|
LightSource[0].position.x -= 0.3; |
||||
|
break; |
||||
|
case TP_BAS: |
||||
|
LightSource[0].position.y += 0.3; |
||||
|
break; |
||||
|
case TP_HAUT: |
||||
|
LightSource[0].position.y -= 0.3; |
||||
|
break; |
||||
|
|
||||
|
case TP_FIN: |
||||
|
LightSource[0].spotDirection.x += 0.6; |
||||
|
break; |
||||
|
case TP_DEBUT: |
||||
|
LightSource[0].spotDirection.x -= 0.6; |
||||
|
break; |
||||
|
case TP_PAGEPREC: |
||||
|
LightSource[0].spotDirection.y += 0.6; |
||||
|
break; |
||||
|
case TP_PAGESUIV: |
||||
|
LightSource[0].spotDirection.y -= 0.6; |
||||
|
break; |
||||
|
|
||||
|
case TP_m: // Choisir le modèle affiché: cube, tore, sphère, théière, cylindre, cône
|
||||
|
if ( ++modele > 6 ) modele = 1; |
||||
|
std::cout << " modele=" << modele << std::endl; |
||||
|
break; |
||||
|
|
||||
|
case TP_0: |
||||
|
thetaCam = 0.0; phiCam = 0.0; distCam = 30.0; // placer les choses afin d'avoir une belle vue
|
||||
|
break; |
||||
|
|
||||
|
case TP_t: // Choisir la texture utilisée: aucune, dé, échiquier
|
||||
|
varsUnif.texnumero++; |
||||
|
if ( varsUnif.texnumero > 2 ) varsUnif.texnumero = 0; |
||||
|
std::cout << " varsUnif.texnumero=" << varsUnif.texnumero << std::endl; |
||||
|
break; |
||||
|
|
||||
|
// case TP_c: // Changer l'affichage de l'objet texturé avec couleurs ou sans couleur
|
||||
|
// varsUnif.utiliseCouleur = !varsUnif.utiliseCouleur;
|
||||
|
// std::cout << " utiliseCouleur=" << varsUnif.utiliseCouleur << std::endl;
|
||||
|
// break;
|
||||
|
|
||||
|
case TP_o: // Changer l'affichage des texels noirs (noir, mi-coloré, transparent)
|
||||
|
varsUnif.afficheTexelNoir++; |
||||
|
if ( varsUnif.afficheTexelNoir > 2 ) varsUnif.afficheTexelNoir = 0; |
||||
|
std::cout << " afficheTexelNoir=" << varsUnif.afficheTexelNoir << std::endl; |
||||
|
break; |
||||
|
|
||||
|
case TP_g: // Permuter l'affichage en fil de fer ou plein
|
||||
|
modePolygone = ( modePolygone == GL_FILL ) ? GL_LINE : GL_FILL; |
||||
|
glPolygonMode( GL_FRONT_AND_BACK, modePolygone ); |
||||
|
break; |
||||
|
|
||||
|
case TP_n: // Utiliser ou non les normales calculées comme couleur (pour le débogage)
|
||||
|
varsUnif.afficheNormales = !varsUnif.afficheNormales; |
||||
|
break; |
||||
|
|
||||
|
case TP_ESPACE: // Permuter la rotation automatique du modèle
|
||||
|
enmouvement = !enmouvement; |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
std::cout << " touche inconnue : " << (char) touche << std::endl; |
||||
|
imprimerTouches(); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// fonction callback pour un clic de souris
|
||||
|
int dernierX = 0; // la dernière valeur en X de position de la souris
|
||||
|
int dernierY = 0; // la derniere valeur en Y de position de la souris
|
||||
|
static enum { deplaceCam, deplaceSpotDirection, deplaceSpotPosition } deplace = deplaceCam; |
||||
|
static bool pressed = false; |
||||
|
void FenetreTP::sourisClic( int button, int state, int x, int y ) |
||||
|
{ |
||||
|
pressed = ( state == TP_PRESSE ); |
||||
|
if ( pressed ) |
||||
|
{ |
||||
|
// on vient de presser la souris
|
||||
|
dernierX = x; |
||||
|
dernierY = y; |
||||
|
switch ( button ) |
||||
|
{ |
||||
|
case TP_BOUTON_GAUCHE: // Tourner l'objet
|
||||
|
deplace = deplaceCam; |
||||
|
break; |
||||
|
case TP_BOUTON_MILIEU: // Modifier l'orientation du spot
|
||||
|
deplace = deplaceSpotDirection; |
||||
|
break; |
||||
|
case TP_BOUTON_DROIT: // Déplacer la lumière
|
||||
|
deplace = deplaceSpotPosition; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
// on vient de relâcher la souris
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void FenetreTP::sourisWheel( int x, int y ) // Changer la taille du spot
|
||||
|
{ |
||||
|
const int sens = +1; |
||||
|
LightSource[0].spotAngle += sens*y; |
||||
|
if ( LightSource[0].spotAngle > 90.0 ) LightSource[0].spotAngle = 90.0; |
||||
|
if ( LightSource[0].spotAngle < 0.0 ) LightSource[0].spotAngle = 0.0; |
||||
|
std::cout << " spotAngle=" << LightSource[0].spotAngle << std::endl; |
||||
|
} |
||||
|
|
||||
|
// fonction de mouvement de la souris
|
||||
|
void FenetreTP::sourisMouvement( int x, int y ) |
||||
|
{ |
||||
|
if ( pressed ) |
||||
|
{ |
||||
|
int dx = x - dernierX; |
||||
|
int dy = y - dernierY; |
||||
|
switch ( deplace ) |
||||
|
{ |
||||
|
case deplaceCam: |
||||
|
thetaCam -= dx / 3.0; |
||||
|
phiCam -= dy / 3.0; |
||||
|
break; |
||||
|
case deplaceSpotDirection: |
||||
|
LightSource[0].spotDirection.x += 0.06 * dx; |
||||
|
LightSource[0].spotDirection.y -= 0.06 * dy; |
||||
|
// std::cout << " LightSource[0].spotDirection=" << glm::to_string(LightSource[0].spotDirection) << std::endl;
|
||||
|
break; |
||||
|
case deplaceSpotPosition: |
||||
|
LightSource[0].position.x += 0.03 * dx; |
||||
|
LightSource[0].position.y -= 0.03 * dy; |
||||
|
// std::cout << " LightSource[0].position=" << glm::to_string(LightSource[0].position) << std::endl;
|
||||
|
//glm::vec3 ecranPos( x, hauteur_-y, ecranLumi[2] );
|
||||
|
//LightSource[0].position = glm::vec4(glm::unProject( ecranPos, VM, P, cloture ), 1.0);
|
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
dernierX = x; |
||||
|
dernierY = y; |
||||
|
|
||||
|
verifierAngles(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
int main( int argc, char *argv[] ) |
||||
|
{ |
||||
|
// créer une fenêtre
|
||||
|
FenetreTP fenetre( "INF2705 TP" ); |
||||
|
|
||||
|
// allouer des ressources et définir le contexte OpenGL
|
||||
|
initialiser(); |
||||
|
|
||||
|
bool boucler = true; |
||||
|
while ( boucler ) |
||||
|
{ |
||||
|
// mettre à jour la physique
|
||||
|
calculerPhysique( ); |
||||
|
|
||||
|
// affichage
|
||||
|
fenetre.afficherScene(); |
||||
|
fenetre.swap(); |
||||
|
|
||||
|
// récupérer les événements et appeler la fonction de rappel
|
||||
|
boucler = fenetre.gererEvenement(); |
||||
|
} |
||||
|
|
||||
|
// détruire les ressources OpenGL allouées
|
||||
|
conclure(); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
After Width: | Height: | Size: 3.0 MiB |
Loading…
Reference in new issue