2023-03-21 20:42:47 +01:00
# define APPNAMEVERSION "EnginPasTangible (alpha 0.4.2)"
2023-02-13 23:46:07 +01:00
# include "./Libraries/glad/glad.h"
# include <stdio.h>
# include <math.h>
2023-02-14 22:13:27 +01:00
# include <stdbool.h>
2023-02-13 23:46:07 +01:00
# include "./Libraries/GLFW/glfw3.h"
# define STB_IMAGE_IMPLEMENTATION
# include "./Libraries/stb/stb_image.h"
# include "headers/shader.h"
2023-03-21 20:42:47 +01:00
/* SCENE LIST
shaders / default . fs
shaders / immeublesparisiens . fs
2023-04-08 21:50:43 +02:00
shaders / couleurs . fs
shaders / sierp . fs
2023-04-05 11:48:37 +02:00
shaders / joliesformes . fs
2023-04-12 11:13:09 +02:00
shaders / orthogonalView . fs
2023-03-21 20:42:47 +01:00
*/
2023-04-12 14:20:41 +02:00
# define SCENE "shaders / default.fs"
2023-02-13 23:46:07 +01:00
# define FULLSCREEN 0
2023-03-15 11:50:52 +01:00
# define EXPERIMENTAL_FEATURES 0
2023-02-14 22:13:27 +01:00
/* ## DEBUG MODE ##
* 0 for all
* 1 for nothing
* 2 for FPS
* 3 for cursor position
2023-03-15 11:45:48 +01:00
* 5 for scroll level and precision
2023-04-12 14:20:41 +02:00
* 7 for orthogonal information
2023-02-14 22:13:27 +01:00
*
* For instance if you want fps and position set the value to 2 * 3 = 6
*/
2023-04-12 14:20:41 +02:00
# define DEBUG_MODE 7
2023-02-13 23:46:07 +01:00
GLuint screenWidth = 720 , screenHeight = 480 ;
const GLFWvidmode * mode ;
GLFWwindow * window ;
2023-02-14 22:13:27 +01:00
bool pause ;
2023-02-13 23:46:07 +01:00
void setupVAO ( ) ;
//GLuint getTextureHandle(char* path);
unsigned int VAO ;
float currentTime , deltaTime , lastFrame , startTime ;
2023-03-16 12:15:46 +01:00
float mousePosX , mousePosY ;
2023-03-21 20:42:47 +01:00
float speedlevel = 4. ;
2023-03-16 12:15:46 +01:00
float camPosX = 2.5 ;
float camPosY = 0.5 ;
float camPosZ = 2.5 ;
2023-03-21 20:42:47 +01:00
float speed = .04 ;
2023-03-16 12:15:46 +01:00
float pan = 0. ;
float multiplicatorFov = 1. ;
float tilt = 0. ;
float ez [ 3 ] = { 0 } ;
float ex [ 3 ] = { 0 } ;
float ey [ 3 ] = { 0 } ;
2023-03-20 09:55:36 +01:00
bool upar = false ;
bool downar = false ;
bool leftar = false ;
bool rightar = false ;
bool forwardar = false ;
bool backwardar = false ;
2023-04-12 14:20:41 +02:00
int orthoView = 0 ;
2023-03-20 09:55:36 +01:00
2023-03-15 11:45:48 +01:00
float fovValue = 1.0 ;
2023-03-21 14:11:04 +01:00
//281=3.13/2 * 180
const int maxYmouse = 281 ;
2023-03-15 09:37:44 +01:00
// more precision means less speed
2023-03-15 11:45:48 +01:00
float camPrecision = 2. ;
2023-02-13 23:46:07 +01:00
2023-03-16 09:32:30 +01:00
/*float[3] crossProduct(float vect_A[3], float vect_B[3])
{
float cross_P [ 3 ] ;
cross_P [ 0 ] = vect_A [ 1 ] * vect_B [ 2 ] - vect_A [ 2 ] * vect_B [ 1 ] ;
cross_P [ 1 ] = vect_A [ 2 ] * vect_B [ 0 ] - vect_A [ 0 ] * vect_B [ 2 ] ;
cross_P [ 2 ] = vect_A [ 0 ] * vect_B [ 1 ] - vect_A [ 1 ] * vect_B [ 0 ] ;
return cross_P ;
} */
2023-02-14 22:13:27 +01:00
static void key_callback ( GLFWwindow * window , int key , int scancode , int action , int mods )
{
2023-03-16 12:15:46 +01:00
int stateShift = glfwGetKey ( window , GLFW_KEY_LEFT_SHIFT ) ;
int stateControl = glfwGetKey ( window , GLFW_KEY_LEFT_CONTROL ) ;
if ( stateShift = = GLFW_PRESS ) {
2023-03-21 20:42:47 +01:00
speed = .08 * speedlevel ;
2023-03-16 12:15:46 +01:00
multiplicatorFov = 0.8 ;
}
else {
2023-03-21 20:42:47 +01:00
speed = .02 * speedlevel ;
2023-03-16 12:15:46 +01:00
multiplicatorFov = 1. ;
}
2023-03-20 09:55:36 +01:00
if ( action = = GLFW_PRESS ) {
if ( key = = GLFW_KEY_ESCAPE )
2023-02-14 22:13:27 +01:00
{
2023-03-20 09:55:36 +01:00
//glfwSetWindowShouldClose(window, GLFW_TRUE);
pause = ! pause ;
printf ( pause ? " En pause \n " : " En fonctionnement \n " ) ;
if ( pause )
{
glfwSetWindowTitle ( window , " EnginPasTangible (En pause) " ) ;
glfwSetInputMode ( window , GLFW_CURSOR , GLFW_CURSOR_NORMAL ) ;
}
else
{
glfwSetWindowTitle ( window , APPNAMEVERSION ) ;
glfwSetInputMode ( window , GLFW_CURSOR , GLFW_CURSOR_DISABLED ) ;
}
2023-02-14 22:13:27 +01:00
}
2023-04-12 14:20:41 +02:00
if ( key = = GLFW_KEY_TAB ) {
orthoView = ( orthoView + 1 ) % 2 ;
if ( DEBUG_MODE % 7 = = 0 ) {
printf ( " Orthogonal view : " ) ;
printf ( ( orthoView = = 1 ) ? " on " : " off " ) ;
printf ( " \n " ) ;
}
}
2023-03-20 09:55:36 +01:00
if ( key = = GLFW_KEY_BACKSPACE )
glfwSetWindowShouldClose ( window , GLFW_TRUE ) ;
if ( key = = GLFW_KEY_SPACE )
upar = true ;
if ( key = = GLFW_KEY_LEFT_CONTROL )
downar = true ;
if ( key = = GLFW_KEY_UP | | key = = GLFW_KEY_W ) {
forwardar = true ;
}
if ( key = = GLFW_KEY_DOWN | | key = = GLFW_KEY_S ) {
backwardar = true ;
}
if ( key = = GLFW_KEY_RIGHT | | key = = GLFW_KEY_D ) {
rightar = true ;
}
if ( key = = GLFW_KEY_LEFT | | key = = GLFW_KEY_A ) {
leftar = true ;
2023-02-14 22:13:27 +01:00
}
}
2023-03-20 09:55:36 +01:00
else if ( action = = GLFW_RELEASE ) {
if ( key = = GLFW_KEY_SPACE )
upar = false ;
if ( key = = GLFW_KEY_LEFT_CONTROL )
downar = false ;
if ( key = = GLFW_KEY_UP | | key = = GLFW_KEY_W ) {
forwardar = false ;
}
if ( key = = GLFW_KEY_DOWN | | key = = GLFW_KEY_S ) {
backwardar = false ;
}
if ( key = = GLFW_KEY_RIGHT | | key = = GLFW_KEY_D ) {
rightar = false ;
}
if ( key = = GLFW_KEY_LEFT | | key = = GLFW_KEY_A ) {
leftar = false ;
}
2023-03-16 12:15:46 +01:00
}
2023-02-14 22:13:27 +01:00
}
2023-03-15 11:45:48 +01:00
void scroll_callback ( GLFWwindow * window , double xoffset , double yoffset )
{
int stateControl = glfwGetKey ( window , GLFW_KEY_LEFT_CONTROL ) ;
// we only use yoffset as it is present on normal mice
2023-03-21 14:06:13 +01:00
if ( DEBUG_MODE % 5 = = 0 ) {
2023-03-15 11:45:48 +01:00
printf ( " scroll value : %f | precision : %f | " , yoffset , camPrecision ) ;
printf ( ( stateControl = = GLFW_PRESS ) ? " ctrl -> speed " : " Zooming " ) ;
printf ( " \n " ) ;
2023-03-21 14:06:13 +01:00
}
2023-03-15 11:45:48 +01:00
if ( stateControl = = GLFW_PRESS ) {
camPrecision + = yoffset / 2 ;
if ( camPrecision < = 1 )
camPrecision = 1 ;
}
else {
fovValue + = yoffset / 5 ;
if ( fovValue < = 0.2 & & EXPERIMENTAL_FEATURES = = 0 )
fovValue = 0.2 ;
}
}
2023-02-14 22:13:27 +01:00
static void cursor_position_callback ( GLFWwindow * window , double xpos , double ypos )
{
2023-03-15 08:40:50 +01:00
/*
//if (xpos>283){ //////283=3.14/2 * 180
// //xpos=283
//}
//if (xpos<-283){
// //xpos=-283
2023-03-15 09:37:44 +01:00
//}*/
int maxYcorrected = maxYmouse * camPrecision ;
if ( ypos > maxYcorrected ) {
glfwSetCursorPos ( window , xpos , maxYcorrected ) ;
2023-03-15 08:40:50 +01:00
}
2023-03-15 09:37:44 +01:00
if ( ypos < - maxYcorrected ) {
glfwSetCursorPos ( window , xpos , - maxYcorrected ) ;
2023-03-15 08:40:50 +01:00
}
2023-03-15 09:37:44 +01:00
2023-02-14 22:13:27 +01:00
if ( DEBUG_MODE % 3 = = 0 )
printf ( " x:%f | y:%f \n " , xpos , ypos ) ;
2023-03-15 09:37:44 +01:00
mousePosX = xpos / camPrecision ;
mousePosY = ypos / camPrecision ;
2023-02-14 22:13:27 +01:00
}
2023-02-13 23:46:07 +01:00
int main ( ) {
// Window setup
GLint glfwStatus = glfwInit ( ) ;
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
//glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
//glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//// glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint ( GLFW_RESIZABLE , GL_FALSE ) ; //#####
//glfwWindowHint(GLFW_DECORATED,GL_FALSE);
//glfwWindowHint(GLFW_CONTEXT_NO_ERROR,GL_FALSE);
2023-02-14 22:13:27 +01:00
pause = false ;
window = glfwCreateWindow ( screenWidth , screenHeight , APPNAMEVERSION , NULL , NULL ) ;
2023-02-13 23:46:07 +01:00
if ( window = = NULL )
{
printf ( " Window failed to create " ) ;
glfwTerminate ( ) ;
}
glfwMakeContextCurrent ( window ) ;
//glfwSwapInterval(1); // To my knowledge, this turns on vsync on macOS
// If Windows or Linux: load all OpenGL function pointers with GLAD
if ( ! gladLoadGLLoader ( ( GLADloadproc ) glfwGetProcAddress ) )
{
printf ( " Failed to initialize GLAD " ) ;
return - 1 ;
}
// END Window setup
// set up Vertex Array Object that contains our vertices and bind it
setupVAO ( ) ;
glBindVertexArray ( VAO ) ; // seeing as we only have a single VAO there's no need to unbind in the setupVertexArray function and then bind here, but we'll do so for clarity, organization, and avoiding possible bugs in future
GLuint quad_shader = glCreateProgram ( ) ;
2023-03-21 14:06:13 +01:00
int compilerInfo = buildShaders ( quad_shader , " shaders/generic.vs " , SCENE ) ;
2023-02-13 23:46:07 +01:00
if ( compilerInfo > 0 ) {
return compilerInfo ;
}
glUseProgram ( quad_shader ) ;
//GLuint channel_logo = getTextureHandle("assets/logo.png");
//glBindTexture(GL_TEXTURE_2D, channel_logo);
// for alpha (opacity)
//glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2023-02-14 22:13:27 +01:00
glfwSetKeyCallback ( window , key_callback ) ;
glfwSetCursorPosCallback ( window , cursor_position_callback ) ;
glfwSetInputMode ( window , GLFW_CURSOR , GLFW_CURSOR_DISABLED ) ;
2023-03-15 11:45:48 +01:00
glfwSetScrollCallback ( window , scroll_callback ) ;
2023-02-13 23:46:07 +01:00
GLFWimage images [ 1 ] ;
images [ 0 ] . pixels = stbi_load ( " ./assets/icon.png " , & images [ 0 ] . width , & images [ 0 ] . height , 0 , 4 ) ; //rgba channels
glfwSetWindowIcon ( window , 1 , images ) ;
stbi_image_free ( images [ 0 ] . pixels ) ;
int window_width , window_height ;
char FPS [ 20 ] ;
startTime = glfwGetTime ( ) ;
while ( ! glfwWindowShouldClose ( window ) )
{
2023-02-14 22:13:27 +01:00
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers ( window ) ;
glfwPollEvents ( ) ;
2023-02-13 23:46:07 +01:00
2023-02-14 22:13:27 +01:00
if ( pause )
{
glClearColor ( .1f , .2f , 0.3f , 1.0f ) ;
glClear ( GL_COLOR_BUFFER_BIT ) ;
continue ;
}
2023-03-16 09:32:30 +01:00
2023-03-16 12:15:46 +01:00
pan = - mousePosX / 180. ;
tilt = - mousePosY / 180. ;
//ez
ez [ 0 ] = cos ( tilt ) * sin ( pan ) ;
ez [ 1 ] = sin ( tilt ) ;
ez [ 2 ] = cos ( tilt ) * cos ( pan ) ; //normalize(lookingAt-posCam);////base orthonormée
//ex
ex [ 0 ] = - ez [ 2 ] ; //crossProduct(ez,{0.,1.,0.});
ex [ 2 ] = ez [ 0 ] ;
// ey
ey [ 0 ] = ex [ 1 ] * ez [ 2 ] - ex [ 2 ] * ez [ 1 ] ;
ey [ 1 ] = ex [ 2 ] * ez [ 0 ] - ex [ 0 ] * ez [ 2 ] ;
ey [ 2 ] = ex [ 0 ] * ez [ 1 ] - ex [ 1 ] * ez [ 0 ] ;
//crossProduct(ex,ez);
2023-03-16 09:32:30 +01:00
2023-03-20 09:55:36 +01:00
if ( upar )
camPosY + = speed ;
if ( downar )
camPosY - = speed ;
if ( forwardar ) {
camPosX + = speed * ez [ 0 ] ;
camPosY + = speed * ez [ 1 ] ;
camPosZ + = speed * ez [ 2 ] ;
}
if ( backwardar ) {
camPosX - = speed * ez [ 0 ] ;
camPosY - = speed * ez [ 1 ] ;
camPosZ - = speed * ez [ 2 ] ;
}
if ( rightar ) {
camPosX + = speed * ex [ 0 ] ;
camPosY + = speed * ex [ 1 ] ;
camPosZ + = speed * ex [ 2 ] ;
}
if ( leftar ) {
camPosX - = speed * ex [ 0 ] ;
camPosY - = speed * ex [ 1 ] ;
camPosZ - = speed * ex [ 2 ] ;
}
2023-02-13 23:46:07 +01:00
currentTime = glfwGetTime ( ) ;
deltaTime = currentTime - lastFrame ;
lastFrame = currentTime ;
gcvt ( 1 / deltaTime , 4 , FPS ) ;
2023-02-14 22:13:27 +01:00
if ( DEBUG_MODE % 2 = = 0 )
printf ( " FPS : %s \n " , FPS ) ;
2023-02-13 23:46:07 +01:00
glfwGetWindowSize ( window , & window_width , & window_height ) ;
glViewport ( 0 , 0 , window_width , window_height ) ;
// printf("%d\n", window_width);
glClearColor ( 0.9f , 0.9f , 0.2f , 1.0f ) ;
glClear ( GL_COLOR_BUFFER_BIT ) ;
//glDrawArrays(GL_TRIANGLES, 0, 6);
glDrawElements ( GL_TRIANGLES , 6 , GL_UNSIGNED_INT , 0 ) ;
glUniform1f ( glGetUniformLocation ( quad_shader , " iTime " ) , currentTime - startTime ) ;
2023-03-16 09:32:30 +01:00
glUniform3f ( glGetUniformLocation ( quad_shader , " iEx " ) , ex [ 0 ] , ex [ 1 ] , ex [ 2 ] ) ;
glUniform3f ( glGetUniformLocation ( quad_shader , " iEy " ) , ey [ 0 ] , ey [ 1 ] , ey [ 2 ] ) ;
glUniform3f ( glGetUniformLocation ( quad_shader , " iEz " ) , ez [ 0 ] , ez [ 1 ] , ez [ 2 ] ) ;
2023-02-13 23:46:07 +01:00
glUniform3f ( glGetUniformLocation ( quad_shader , " iCamPos " ) , camPosX , camPosY , camPosZ ) ;
2023-04-12 14:20:41 +02:00
glUniform1f ( glGetUniformLocation ( quad_shader , " iFovValue " ) , ( orthoView = = 1 ) ? 2 / ( fovValue * fovValue * multiplicatorFov ) : fovValue * fovValue * multiplicatorFov ) ;
glUniform1i ( glGetUniformLocation ( quad_shader , " iOrthoView " ) , orthoView ) ;
2023-02-13 23:46:07 +01:00
// glBindVertexArray(0); // no need to unbind it every time
}
// Optional cleaning up bc OS will likely do it for us, but is a good practice. Note that shaders are deleted in shader.h
glDeleteProgram ( quad_shader ) ;
// glfw: terminate, clearing all previously allocated GLFW resources.
glfwTerminate ( ) ;
return 0 ;
}
void setupVAO ( ) {
// set up vertex data (and buffer(s)) and configure vertex attributes
// ------------------------------------------------------------------
float vertices [ ] = {
// positions // textures
1.f , 1.0f , 0.0f , 1.5f , 1.0f , // top right
1.f , - 1.f , 0.0f , 1.5f , - 1.0f , // bottom right/////-1 => 0.
- 1.f , - 1.f , 0.0f , - 1.5f , - 1.0f , // bottom left
- 1.f , 1.f , 0.0f , - 1.5f , 1.0f // top left
} ;
unsigned int indices [ ] = {
0 , 1 , 3 , // first Triangle
1 , 2 , 3 // second Triangle
} ;
unsigned int VBO , EBO ;
glGenVertexArrays ( 1 , & VAO ) ;
glGenBuffers ( 1 , & VBO ) ;
glGenBuffers ( 1 , & EBO ) ;
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
glBindVertexArray ( VAO ) ;
glBindBuffer ( GL_ARRAY_BUFFER , VBO ) ;
glBufferData ( GL_ARRAY_BUFFER , sizeof ( vertices ) , vertices , GL_STATIC_DRAW ) ;
glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER , EBO ) ;
glBufferData ( GL_ELEMENT_ARRAY_BUFFER , sizeof ( indices ) , indices , GL_STATIC_DRAW ) ;
// Position attribute
glVertexAttribPointer ( 0 , 3 , GL_FLOAT , GL_FALSE , 5 * sizeof ( GLfloat ) , ( GLvoid * ) 0 ) ;
glEnableVertexAttribArray ( 0 ) ;
// TexCoord attribute
glVertexAttribPointer ( 2 , 2 , GL_FLOAT , GL_TRUE , 5 * sizeof ( GLfloat ) , ( GLvoid * ) ( 3 * sizeof ( GLfloat ) ) ) ;
glEnableVertexAttribArray ( 2 ) ;
// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
glBindBuffer ( GL_ARRAY_BUFFER , 0 ) ;
// remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
glBindVertexArray ( 0 ) ;
}
2023-03-16 12:15:46 +01:00
2023-02-13 23:46:07 +01:00