diff --git a/CMakeLists.txt b/CMakeLists.txt index ee80151..54558f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,5 +15,42 @@ set(CMAKE_CXX_STANDARD 14) find_package(OpenGL REQUIRED) find_package(GLUT REQUIRED) -add_subdirectory(src) -add_subdirectory(example) +if(NOT ${OPENGL_GLU_FOUND}) + message(FATAL_ERROR "Glu not installed!") +endif() + +add_executable(tests_opengl + src/main.cpp + src/displayers.h + src/displayers.cpp + src/DataHandling/Texture.cpp + src/DataHandling/Texture.h + src/DataHandling/Model3D.cpp + src/DataHandling/Model3D.h + src/Vectors.h + src/InputStatus.cpp + src/InputStatus.h + src/Camera.cpp + src/Camera.h + src/Quaternion.cpp + src/Quaternion.h) + +target_link_directories(tests_opengl PRIVATE + src) + +target_include_directories(tests_opengl PRIVATE + src) + +target_link_libraries(tests_opengl + ${OPENGL_LIBRARIES} + ${GLUT_LIBRARIES}) + +target_include_directories(tests_opengl PRIVATE + ${OPENGL_INCLUDE_DIR} + ${GLUT_INCLUDE_DIR}) + +if (CMAKE_COMPILER_IS_GNUCXX) + target_compile_options(tests_opengl PRIVATE -Wall -Wpedantic -Wextra) +elseif(MSVC) + target_compile_options(tests_opengl PRIVATE /W4) +endif() \ No newline at end of file diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt deleted file mode 100644 index ce63966..0000000 --- a/example/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -add_executable(tests_opengl - main.cpp - displayers.h - displayers.cpp) - -target_link_directories(tests_opengl PRIVATE - ${PROJECT_SOURCE_DIR}/src) - -target_include_directories(tests_opengl PRIVATE - ${PROJECT_SOURCE_DIR}/src) - -target_link_libraries(tests_opengl - ${OPENGL_LIBRARIES} - ${GLUT_LIBRARIES} - engine) - -target_include_directories(tests_opengl PRIVATE - ${OPENGL_INCLUDE_DIR} - ${GLUT_INCLUDE_DIR}) \ No newline at end of file diff --git a/example/resources/RAPTOR.off b/resources/RAPTOR.off similarity index 100% rename from example/resources/RAPTOR.off rename to resources/RAPTOR.off diff --git a/example/resources/RAPTOR.tga b/resources/RAPTOR.tga similarity index 100% rename from example/resources/RAPTOR.tga rename to resources/RAPTOR.tga diff --git a/example/resources/arbre.tga b/resources/arbre.tga similarity index 100% rename from example/resources/arbre.tga rename to resources/arbre.tga diff --git a/example/resources/arbre_masque.tga b/resources/arbre_masque.tga similarity index 100% rename from example/resources/arbre_masque.tga rename to resources/arbre_masque.tga diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index 5e5e5e1..0000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -add_library(engine - DataHandling/Texture.cpp - DataHandling/Texture.h - DataHandling/Model3D.cpp - DataHandling/Model3D.h - Math/Vectors.h - Math/Quaternion.cpp - Math/Quaternion.h - InputStatus.cpp - InputStatus.h - Camera.cpp - Camera.h - Engine.h) - -target_include_directories(engine PRIVATE - ${PROJECT_SOURCE_DIR}/src) - -target_link_directories(engine PRIVATE - ${PROJECT_SOURCE_DIR}/src) - -target_link_libraries(engine - ${OPENGL_LIBRARIES} - ${GLUT_LIBRARIES}) - -target_include_directories(engine PRIVATE - ${OPENGL_INCLUDE_DIR} - ${GLUT_INCLUDE_DIR}) - -if (CMAKE_COMPILER_IS_GNUCXX) - target_compile_options(engine PRIVATE -Wall -Wpedantic -Wextra) -elseif(MSVC) - target_compile_options(engine PRIVATE /W4) -endif() diff --git a/src/Camera.cpp b/src/Camera.cpp index 7c0aa16..f1d66b9 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -17,11 +17,7 @@ Camera::Camera(const Vec3d& eye_pos, const Vec3d& look_direction, const Vec3d& u compute_base_change(); } -void Camera::translate(const Vec3d &translation) { - eye = eye + translation; -} - -void Camera::local_translate(const Vec3d& translation) +void Camera::translate(const Vec3d& translation) { eye = eye + translation * rotation_quaternion; } @@ -39,7 +35,7 @@ void Camera::rotate(const Vec3d& rotation) gaze = z_rotation * gaze; gaze_up = z_rotation * gaze_up; - Quaternion y_rotation{0,sin(rotation.y/2),0,cos(rotation.y/2)}; + Quaternion y_rotation{0,sin(rotation.y),0,cos(rotation.y)}; y_rotation.normalize(); gaze = y_rotation * gaze; gaze_up = y_rotation * gaze_up; @@ -56,22 +52,7 @@ void Camera::look() void Camera::set_position(const Vec3d& eye_pos) { - eye = eye_pos; -} - -const Vec3d& Camera::get_eyepos() const -{ - return eye; -} - -const Vec3d& Camera::get_gaze() const -{ - return gaze; -} - -const Vec3d& Camera::get_gazeup() const -{ - return gaze_up; + gaze = eye_pos; } void Camera::compute_base_change() diff --git a/src/Camera.h b/src/Camera.h index d05cdc1..61c4089 100644 --- a/src/Camera.h +++ b/src/Camera.h @@ -8,19 +8,16 @@ #include #include -#include "Math/Quaternion.h" -#include "Math/Vectors.h" +#include "Quaternion.h" +#include "Vectors.h" class Camera { public: Camera(const Vec3d& eye_pos,const Vec3d& look_direction,const Vec3d& up_vector); - /// Translates the camera according to the world axises. - /// \param translation Translation in the world coordinates system. - void translate(const Vec3d& translation); /// Translates the camera relative to its current position and look direction. /// \param translation Translation where x is pointing in the direction of vision. - void local_translate(const Vec3d& translation); + void translate(const Vec3d& translation); /// Rotates the gaze around its local x and z but around global y, relatively to the current orientation. /// This is to provide a coherent movement in regards to mouse movement. /// \param rotation Angles are radians to rotate about each axis. @@ -30,10 +27,6 @@ public: void look(); void set_position(const Vec3d& eye_pos); - - const Vec3d& get_eyepos() const; - const Vec3d& get_gaze() const; - const Vec3d& get_gazeup() const; private: Vec3d eye; Vec3d gaze; diff --git a/src/DataHandling/Model3D.cpp b/src/DataHandling/Model3D.cpp index 638a7d5..bc9fafd 100644 --- a/src/DataHandling/Model3D.cpp +++ b/src/DataHandling/Model3D.cpp @@ -5,7 +5,7 @@ #include "Model3D.h" -Model3D::Model3D() :is_textured(false), vertex_count(0), face_count(0), texture_count(0) +Model3D::Model3D() : vertex_count(0), face_count(0), texture_count(0), is_textured(false) {} Model3D::Model3D(const std::string& file_name) : Model3D() @@ -30,23 +30,10 @@ Model3D::~Model3D() delete(face_textures); delete(normals); } - - if (has_displaylist) - { - glDeleteLists(display_list_index,1); - } } void Model3D::draw_model() { - if (has_displaylist) - { - glCallList(display_list_index); - return; // Executing the regular draw calls is unnecessary - } - - // If there is no display list available, draw each triangles and texture them if necessary. - if (is_textured) { glEnable(GL_ALPHA_TEST); @@ -97,17 +84,6 @@ void Model3D::draw_model() } } -void Model3D::prepare_displaylist() -{ - display_list_index = glGenLists(1); - - glNewList(display_list_index,GL_COMPILE); - draw_model(); - glEndList(); - - has_displaylist = true; -} - bool Model3D::load_ascii_off_file(const std::string& file_name) { std::fstream file_stream(file_name, std::ios_base::in); diff --git a/src/DataHandling/Model3D.h b/src/DataHandling/Model3D.h index d160a7a..94474a5 100644 --- a/src/DataHandling/Model3D.h +++ b/src/DataHandling/Model3D.h @@ -10,7 +10,7 @@ #include #include "GL/glut.h" -#include "Math/Vectors.h" +#include "Vectors.h" #include "Texture.h" class Model3D { @@ -26,13 +26,9 @@ public: void set_scaling(float x_scale, float y_scale, float z_scale); void set_rotation(float angle, float x, float y, float z); - /// Draws the model, using a display list if available. void draw_model(); - /// Sets up an OpenGL display list for the model - void prepare_displaylist(); bool is_textured; - bool has_displaylist = false; private: uint32_t vertex_count; uint32_t face_count; @@ -55,8 +51,6 @@ private: Vec3f scaling{}; Vec3f rotation_axis{}; float rotation_angle{}; - - GLuint display_list_index; }; diff --git a/src/DataHandling/Texture.cpp b/src/DataHandling/Texture.cpp index 4f64c7b..003d030 100644 --- a/src/DataHandling/Texture.cpp +++ b/src/DataHandling/Texture.cpp @@ -73,7 +73,6 @@ bool Texture::load_rgb_tga(const std::string& rgb_filename) { bool return_value = load_tga(rgb_filename,image_data); invert_channels(0,2); - generate_texture(); return return_value; } @@ -118,25 +117,9 @@ bool Texture::load_rgba_tga(const std::string& rgb_filename, const std::string& // Now we have an RGBA image, update color_bits color_bits = 32; - invert_channels(0,2); - generate_texture(); return true; } -void Texture::generate_texture() -{ - glGenTextures(1,opengl_id); - glBindTexture(GL_TEXTURE_2D,opengl_id[0]); - if (color_bits == 24) - { - gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGB8,width,height,GL_RGB,GL_UNSIGNED_BYTE,image_data); - } - else if (color_bits == 32) - { - gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8,width,height,GL_RGBA,GL_UNSIGNED_BYTE,image_data); - } -} - void Texture::invert_channels(uint8_t first_channel, uint8_t second_channel) { uint8_t increment = color_bits/8; diff --git a/src/DataHandling/Texture.h b/src/DataHandling/Texture.h index 0eed6d6..d0c791e 100644 --- a/src/DataHandling/Texture.h +++ b/src/DataHandling/Texture.h @@ -33,9 +33,6 @@ private: /// Load and RGB TGA image file to an array bool load_tga(const std::string& filename, uint8_t*& data_array); - /// Initialize the texture for OpenGL - void generate_texture(); - void invert_channels(uint8_t first_channel,uint8_t second_channel); }; diff --git a/src/Engine.h b/src/Engine.h deleted file mode 100644 index 13c7d84..0000000 --- a/src/Engine.h +++ /dev/null @@ -1,85 +0,0 @@ -// -// Created by trotFunky on 02/11/2019. -// - -#ifndef TESTS_OPENGL_ENGINE_H -#define TESTS_OPENGL_ENGINE_H - -#include -#include - -#include "InputStatus.h" -#include "Camera.h" - -/// OpenGL Engine -namespace OGLE -{ - /// Display function provided at setup. - void (*custom_display)(); - static double aspect_ratio; - static Camera camera({0,0,0},{1,0,0},{0,1,0}); - - void reshape(int new_x, int new_y) - { - glViewport(0,0,new_x,new_y); - - aspect_ratio = (double)new_x/new_y; - InputStatus::window_size.x = new_x; - InputStatus::window_size.y = new_y; - } - - /// Used for glutDisplay. Wraps the custom_display function with the required OpenGL calls. - void display_wrapper() - { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode(GL_PROJECTION); - // Prepare view - glLoadIdentity(); - gluPerspective(60,OGLE::aspect_ratio,0.1,30000); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - OGLE::camera.look(); - - custom_display(); - - glutSwapBuffers(); - } - - void setup(int& argc, char** argv, void (*display_callback)(), const std::string& window_name = "OpenGL custom engine") - { - glutInit(&argc,argv); - // Generate window with GLUT - glutInitDisplayMode(GLUT_RGB| GLUT_DEPTH | GLUT_DOUBLE); - glutCreateWindow(window_name.c_str()); - glutIgnoreKeyRepeat(true); - glutSetCursor(GLUT_CURSOR_NONE); - - // Init OpenGL - glClearColor(0,0,0,1); - glClearDepth(1.0); - glEnable(GL_DEPTH_TEST); - - // Setup OPenGL to use textures - glEnable(GL_TEXTURE_2D); - glAlphaFunc(GL_GREATER, 0.5); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT/GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT/GL_CLAMP); - glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - glViewport(0,0,glutGet(GLUT_WINDOW_WIDTH),glutGet(GLUT_WINDOW_HEIGHT)); - - custom_display = display_callback; - - glutDisplayFunc(display_wrapper); - glutIdleFunc(display_wrapper); - glutReshapeFunc(reshape); - InputStatus::register_glut_callbacks(); - } -} - -#endif //TESTS_OPENGL_ENGINE_H diff --git a/src/InputStatus.h b/src/InputStatus.h index ca7059e..f1db851 100644 --- a/src/InputStatus.h +++ b/src/InputStatus.h @@ -9,7 +9,7 @@ #include #include -#include "Math/Vectors.h" +#include "Vectors.h" /// Handles the key and mouse events from glut and keep their status up to date. diff --git a/src/Math/Quaternion.cpp b/src/Quaternion.cpp similarity index 100% rename from src/Math/Quaternion.cpp rename to src/Quaternion.cpp diff --git a/src/Math/Quaternion.h b/src/Quaternion.h similarity index 100% rename from src/Math/Quaternion.h rename to src/Quaternion.h diff --git a/src/Math/Vectors.h b/src/Vectors.h similarity index 100% rename from src/Math/Vectors.h rename to src/Vectors.h diff --git a/example/displayers.cpp b/src/displayers.cpp similarity index 100% rename from example/displayers.cpp rename to src/displayers.cpp diff --git a/example/displayers.h b/src/displayers.h similarity index 100% rename from example/displayers.h rename to src/displayers.h diff --git a/example/main.cpp b/src/main.cpp similarity index 51% rename from example/main.cpp rename to src/main.cpp index 087dfcc..5c7746f 100644 --- a/example/main.cpp +++ b/src/main.cpp @@ -1,7 +1,6 @@ #include #include -#include "Engine.h" #include "displayers.h" #include "DataHandling/Texture.h" #include "DataHandling/Model3D.h" @@ -9,9 +8,11 @@ #include "Camera.h" volatile unsigned long long int timer_ticks = 0; +static double aspect_ratio; static Texture tree_texture; static Model3D raptor; static Texture raptor_texture; +static Camera camera({10,0,10},{-10,0,-10},{0,1,0}); void manage_inputs() { @@ -36,30 +37,30 @@ void manage_inputs() if (InputStatus::is_special_key_pressed(GLUT_KEY_RIGHT)) { timer_ticks += 5; - OGLE::camera.local_translate({0, 0, 0.1}); + camera.translate({0,0,0.1}); } if (InputStatus::is_special_key_pressed(GLUT_KEY_LEFT)) { timer_ticks -= 5; - OGLE::camera.local_translate({0, 0, -0.1}); + camera.translate({0,0,-0.1}); } if (InputStatus::is_key_pressed(' ')) { - OGLE::camera.local_translate({0, 0.1, 0}); + camera.translate({0,0.1,0}); } if (InputStatus::is_special_key_pressed(GLUT_KEY_PAGE_DOWN)) { - OGLE::camera.local_translate({0, -0.1, 0}); + camera.translate({0,-0.1,0}); } if (InputStatus::is_special_key_pressed(GLUT_KEY_UP)) { - OGLE::camera.local_translate({0.1, 0, 0}); + camera.translate({0.1,0,0}); } if (InputStatus::is_special_key_pressed(GLUT_KEY_DOWN)) { - OGLE::camera.local_translate({-0.1, 0, 0}); + camera.translate({-0.1,0,0}); } // Get mouse delta since last frame @@ -67,7 +68,7 @@ void manage_inputs() mouse_delta = InputStatus::get_mouse_delta(true); if (mouse_delta.x != 0 || mouse_delta.y != 0) { - OGLE::camera.rotate({0, + camera.rotate({0, -mouse_delta.x / InputStatus::mouse_sensitivity.x, -mouse_delta.y / InputStatus::mouse_sensitivity.y}); } @@ -78,6 +79,16 @@ void display() manage_inputs(); float angleY = 1*timer_ticks; + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + // Prepare view + glLoadIdentity(); + gluPerspective(60,aspect_ratio,0.1,30000); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + camera.look(); display_rotating_pyramid(-5,-2,-5,2,4,angleY); display_rotating_pyramid(5,-2,0,1,5,angleY); @@ -89,6 +100,17 @@ void display() glRotatef(angleY,0,-1,0); raptor.draw_model(); glPopMatrix(); + + glutSwapBuffers(); +} + +void reshape(int new_x, int new_y) +{ + glViewport(0,0,new_x,new_y); + + aspect_ratio = (double)new_x/new_y; + InputStatus::window_size.x = new_x; + InputStatus::window_size.y = new_y; } void update_angle(int value) @@ -99,26 +121,55 @@ void update_angle(int value) int main(int argc, char** argv) { - OGLE::setup(argc,argv,display); + glutInit(&argc,argv); + // Generate window with GLUT + glutInitDisplayMode(GLUT_RGB| GLUT_DEPTH | GLUT_DOUBLE); + glutCreateWindow("OpenGL custom engine tests"); + glutIgnoreKeyRepeat(true); + glutSetCursor(GLUT_CURSOR_NONE); + + // Init OpenGL + glClearColor(0,0,0,1); + glClearDepth(1.0); + glEnable(GL_DEPTH_TEST); + + // Setup OPenGL to use textures + glEnable(GL_TEXTURE_2D); + glAlphaFunc(GL_GREATER, 0.5); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT/GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT/GL_CLAMP); + glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Load and generate tree texture tree_texture.load_rgba_tga("resources/arbre.tga","resources/arbre_masque.tga"); + glGenTextures(1,tree_texture.opengl_id); + // TODO : Put in the Texture class + glBindTexture(GL_TEXTURE_2D,tree_texture.opengl_id[0]); + gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8,tree_texture.width,tree_texture.height,GL_RGBA,GL_UNSIGNED_BYTE,tree_texture.image_data); // Load and generate raptor texture raptor_texture.load_rgb_tga("resources/RAPTOR.tga"); + glGenTextures(1, raptor_texture.opengl_id); + // TODO : Put in the Texture class + glBindTexture(GL_TEXTURE_2D, raptor_texture.opengl_id[0]); + gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB8, raptor_texture.width, raptor_texture.height, GL_RGB, GL_UNSIGNED_BYTE, raptor_texture.image_data); + - // Load raptor model raptor.load_ascii_off_file("resources/RAPTOR.off"); raptor.assign_texture(raptor_texture); raptor.set_scaling(0.01,0.01,0.01); raptor.set_rotation(-90,1,0,0); - raptor.prepare_displaylist(); + glViewport(0,0,glutGet(GLUT_WINDOW_WIDTH),glutGet(GLUT_WINDOW_HEIGHT)); + glutDisplayFunc(display); + glutIdleFunc(display); + glutReshapeFunc(reshape); glutTimerFunc(50,update_angle,0); - - OGLE::camera.set_position({10,0,10}); - OGLE::camera.rotate({0,1.5*M_PI_4,0}); + InputStatus::register_glut_callbacks(); // Enters main loop, managed by GLUT glutMainLoop();