Initial commit
							
								
								
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,3 +1,9 @@
 | 
				
			|||||||
 | 
					# CLion
 | 
				
			||||||
 | 
					**/.idea/**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# CMake build files
 | 
				
			||||||
 | 
					**/cmake-build-debug/**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# C++ objects and libs
 | 
					# C++ objects and libs
 | 
				
			||||||
*.slo
 | 
					*.slo
 | 
				
			||||||
*.lo
 | 
					*.lo
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										152
									
								
								CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,152 @@
 | 
				
			|||||||
 | 
					################################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed | Contact: shaunrd0@gmail.com | URL: www.shaunreed.com  ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Project for working with OpenGL and Qt5 widgets                            ##
 | 
				
			||||||
 | 
					################################################################################
 | 
				
			||||||
 | 
					cmake_minimum_required(VERSION 3.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					project(
 | 
				
			||||||
 | 
					    #[[NAME]]   Qtk
 | 
				
			||||||
 | 
					    VERSION     1.0
 | 
				
			||||||
 | 
					    DESCRIPTION "An example project using QT and OpenGL"
 | 
				
			||||||
 | 
					    LANGUAGES   CXX
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set(CMAKE_INCLUDE_CURRENT_DIR ON)
 | 
				
			||||||
 | 
					set(CMAKE_AUTOUIC ON)
 | 
				
			||||||
 | 
					set(CMAKE_AUTOMOC ON)
 | 
				
			||||||
 | 
					set(CMAKE_AUTORCC ON)
 | 
				
			||||||
 | 
					set(CMAKE_CXX_STANDARD 11)
 | 
				
			||||||
 | 
					set(CMAKE_CXX_STANDARD_REQUIRED ON)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Find all Qt package components required for this project
 | 
				
			||||||
 | 
					find_package(Qt5 COMPONENTS Core LinguistTools Gui Widgets REQUIRED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Add our Qt resources.qrc file to our application
 | 
				
			||||||
 | 
					set(SOURCES app/main.cpp)
 | 
				
			||||||
 | 
					qt5_add_resources(SOURCES resources.qrc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Set translation files
 | 
				
			||||||
 | 
					set(TS_FILES qtk_en_US.ts)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_executable(
 | 
				
			||||||
 | 
					    qtk             # Executable name
 | 
				
			||||||
 | 
					    ${SOURCES}      # Executable source code
 | 
				
			||||||
 | 
					    ${TS_FILES}     # Link translation files
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					################################################################################
 | 
				
			||||||
 | 
					# External Libraries
 | 
				
			||||||
 | 
					################################################################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Find and link GLUT package; Otherwise show an error
 | 
				
			||||||
 | 
					find_package(GLUT REQUIRED)
 | 
				
			||||||
 | 
					if (!GLUT_FOUND)
 | 
				
			||||||
 | 
					  message(
 | 
				
			||||||
 | 
					      "Error: CMake was unable to find the GLUT package\n"
 | 
				
			||||||
 | 
					      "Please install GLUT (freeglut3-dev) and try again\n"
 | 
				
			||||||
 | 
					      "sudo apt install freeglut3-dev\n"
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Find and link OpenGL package; Otherwise show an error
 | 
				
			||||||
 | 
					set(OpenGL_GL_PREFERENCE LEGACY)
 | 
				
			||||||
 | 
					find_package(OpenGL REQUIRED)
 | 
				
			||||||
 | 
					if (!OPENGL_FOUND)
 | 
				
			||||||
 | 
					  message(
 | 
				
			||||||
 | 
					      "Error: CMake was unable to find the OpenGL package\n"
 | 
				
			||||||
 | 
					      "Please install OpenGL and try again\n"
 | 
				
			||||||
 | 
					      "sudo apt install mesa-utils\n"
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# https://github.com/assimp/assimp/commit/6ac8279977c3a54118551e549d77329497116f66
 | 
				
			||||||
 | 
					find_package(assimp REQUIRED)
 | 
				
			||||||
 | 
					if (!assimp_FOUND)
 | 
				
			||||||
 | 
					  message(
 | 
				
			||||||
 | 
					      "Error: CMake was unable to find the Assimp package\n"
 | 
				
			||||||
 | 
					      "Please install Assimp and try again\n"
 | 
				
			||||||
 | 
					      "sudo apt install libassimp-dev\n"
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					################################################################################
 | 
				
			||||||
 | 
					# Custom Libraries
 | 
				
			||||||
 | 
					################################################################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Mainwidget
 | 
				
			||||||
 | 
					add_library(main-widget lib/mainwidget.cpp)
 | 
				
			||||||
 | 
					target_include_directories(main-widget PUBLIC lib/)
 | 
				
			||||||
 | 
					#target_link_libraries(main-widget PUBLIC Qt5::Widgets)
 | 
				
			||||||
 | 
					# + This lib and all linked targets will also link to OpenGL
 | 
				
			||||||
 | 
					target_include_directories(main-widget PUBLIC ${OPENGL_INCLUDE_DIR})
 | 
				
			||||||
 | 
					target_link_libraries(main-widget PUBLIC ${OPENGL_LIBRARIES})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Model
 | 
				
			||||||
 | 
					add_library(model lib/model.cpp)
 | 
				
			||||||
 | 
					target_include_directories(model PRIVATE ${ASSIMP_INCLUDE_DIR})
 | 
				
			||||||
 | 
					target_link_libraries(model PRIVATE ${ASSIMP_LIBRARIES})
 | 
				
			||||||
 | 
					target_link_libraries(model PUBLIC Qt5::Widgets)
 | 
				
			||||||
 | 
					target_link_libraries(model PRIVATE main-widget)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Input
 | 
				
			||||||
 | 
					add_library(input lib/input.cpp)
 | 
				
			||||||
 | 
					target_include_directories(input PUBLIC lib/)
 | 
				
			||||||
 | 
					target_link_libraries(input PUBLIC Qt5::Widgets)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Mesh
 | 
				
			||||||
 | 
					add_library(mesh lib/mesh.cpp)
 | 
				
			||||||
 | 
					target_include_directories(mesh PUBLIC lib/)
 | 
				
			||||||
 | 
					target_link_libraries(mesh PUBLIC Qt5::Widgets)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Transform3D
 | 
				
			||||||
 | 
					add_library(transform3d lib/transform3D.cpp)
 | 
				
			||||||
 | 
					target_include_directories(transform3d PUBLIC lib/)
 | 
				
			||||||
 | 
					target_link_libraries(transform3d PUBLIC Qt5::Widgets)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Camera3D
 | 
				
			||||||
 | 
					add_library(camera3d lib/camera3d.cpp)
 | 
				
			||||||
 | 
					target_include_directories(camera3d PUBLIC lib/)
 | 
				
			||||||
 | 
					target_link_libraries(camera3d PUBLIC Qt5::Widgets)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Texture
 | 
				
			||||||
 | 
					add_library(texture lib/texture.cpp)
 | 
				
			||||||
 | 
					target_include_directories(texture PUBLIC lib/)
 | 
				
			||||||
 | 
					target_link_libraries(texture PUBLIC Qt5::Widgets)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Object
 | 
				
			||||||
 | 
					add_library(object lib/object.cpp)
 | 
				
			||||||
 | 
					target_include_directories(object PUBLIC lib/)
 | 
				
			||||||
 | 
					target_link_libraries(object PUBLIC Qt5::Widgets)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# MeshRenderer
 | 
				
			||||||
 | 
					add_library(meshrenderer lib/meshrenderer.cpp)
 | 
				
			||||||
 | 
					target_include_directories(meshrenderer PUBLIC lib/)
 | 
				
			||||||
 | 
					target_link_libraries(meshrenderer PUBLIC Qt5::Widgets)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Skybox
 | 
				
			||||||
 | 
					add_library(skybox lib/skybox.cpp)
 | 
				
			||||||
 | 
					target_link_libraries(skybox PUBLIC Qt5::Widgets)
 | 
				
			||||||
 | 
					target_link_libraries(skybox PRIVATE mesh)
 | 
				
			||||||
 | 
					target_link_libraries(skybox PRIVATE camera3d)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					################################################################################
 | 
				
			||||||
 | 
					# Final Application
 | 
				
			||||||
 | 
					################################################################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					target_link_libraries(main-widget PUBLIC model)
 | 
				
			||||||
 | 
					target_link_libraries(main-widget PUBLIC input)
 | 
				
			||||||
 | 
					target_link_libraries(main-widget PUBLIC transform3d)
 | 
				
			||||||
 | 
					target_link_libraries(main-widget PUBLIC object)
 | 
				
			||||||
 | 
					target_link_libraries(main-widget PUBLIC meshrenderer)
 | 
				
			||||||
 | 
					target_link_libraries(main-widget PUBLIC texture)
 | 
				
			||||||
 | 
					target_link_libraries(main-widget PUBLIC skybox)
 | 
				
			||||||
 | 
					target_link_libraries(main-widget PUBLIC mesh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Link qtk executable to main main-widget library
 | 
				
			||||||
 | 
					target_link_libraries(qtk PUBLIC main-widget)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Set up QT Linguist translation
 | 
				
			||||||
 | 
					qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
 | 
				
			||||||
							
								
								
									
										60
									
								
								README.md
									
									
									
									
									
								
							
							
						
						@ -1,2 +1,58 @@
 | 
				
			|||||||
# qtk
 | 
					# Qtk
 | 
				
			||||||
Practice using OpenGL in Qt5 widget application
 | 
					
 | 
				
			||||||
 | 
					Practice project for learning about using OpenGL in Qt5 widget applications. 
 | 
				
			||||||
 | 
					Model loader using [Assimp](https://assimp.org/).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can fly around and see the examples I made, or import your own models within 
 | 
				
			||||||
 | 
					`mainwdget.cpp`, inside the `MainWidget::initObjects()` function. I've commented 
 | 
				
			||||||
 | 
					throughout the code there to explain which model or example I'm modifying. 
 | 
				
			||||||
 | 
					Rotations and translations happen in `MainWidget::update()`, to get textures 
 | 
				
			||||||
 | 
					loading on models look into 
 | 
				
			||||||
 | 
					[material files](http://www.paulbourke.net/dataformats/mtl/) and see some 
 | 
				
			||||||
 | 
					examples in the `resources/models/` directory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Can be built with cmake manually or using 
 | 
				
			||||||
 | 
					[Qt Creator](https://github.com/qt-creator/qt-creator).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To build and run `qtk` on Ubuntu -
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					# Qt Creator
 | 
				
			||||||
 | 
					sudo apt update -y && sudo apt install qttools5-dev freeglut3-dev libassimp-dev
 | 
				
			||||||
 | 
					git clone https://gitlab.com/shaunrd0/qtk
 | 
				
			||||||
 | 
					mkdir build && cd build
 | 
				
			||||||
 | 
					cmake .. && cmake --build
 | 
				
			||||||
 | 
					./qtk
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can fly around the scene if you hold the right mouse button and use WASD.
 | 
				
			||||||
 | 
					If you see a small triangle floating by a model it represents the light source
 | 
				
			||||||
 | 
					that is being used for the shader rendering the model. These appear on models
 | 
				
			||||||
 | 
					using phong, specular, and diffuse lighting techniques.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Spartan with no normals -
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Spartan with normals -
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Model Artists
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"Alien Hominid" (https://skfb.ly/onStx) by Nwilly_art is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"Scythe World Of Warcraft" (https://skfb.ly/6UooG) by Warcraft-3D-Models is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"Spartan Armour MKV - Halo Reach" () by McCarthy3D is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"Survival Guitar Backpack (Low Poly)" (https://skfb.ly/6RnCB) by Berk Gedik is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).
 | 
				
			||||||
 | 
					Model by Berk Gedik, from: https://sketchfab.com/3d-models/survival-guitar-backpack-low-poly-799f8c4511f84fab8c3f12887f7e6b36
 | 
				
			||||||
 | 
					Modified material assignment (Joey de Vries) for easier load in OpenGL model loading chapter, and renamed albedo to diffuse and metallic to specular to match non-PBR lighting setup.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"Terror-bird (NHMW-Geo 2012/0007/0001)" (https://skfb.ly/onAWy) by Natural History Museum Vienna is licensed under Creative Commons Attribution-NonCommercial (http://creativecommons.org/licenses/by-nc/4.0/).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"Golden Lion Sitting OBJ Low Poly FREE" (https://skfb.ly/onZAH) by LordSamueliSolo is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										38
									
								
								app/main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Main program for practice using Qt5 widgets and OpenGL              ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com  | URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QApplication>
 | 
				
			||||||
 | 
					#include <QLabel>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <mainwidget.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char *argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  QApplication a(argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Set OpenGL Version information
 | 
				
			||||||
 | 
					  // Note: This format must be set before show() is called.
 | 
				
			||||||
 | 
					  QSurfaceFormat format;
 | 
				
			||||||
 | 
					  format.setRenderableType(QSurfaceFormat::OpenGL);
 | 
				
			||||||
 | 
					  format.setProfile(QSurfaceFormat::CoreProfile);
 | 
				
			||||||
 | 
					  format.setVersion(4,5);
 | 
				
			||||||
 | 
					  // Set the number of samples used for glEnable(GL_MULTISAMPLING)
 | 
				
			||||||
 | 
					  format.setSamples(4);
 | 
				
			||||||
 | 
					  // Set the size of teh depth bufer for glEnable(GL_DEPTH_TEST)
 | 
				
			||||||
 | 
					  format.setDepthBufferSize(16);
 | 
				
			||||||
 | 
					#ifdef QTK_DEBUG
 | 
				
			||||||
 | 
					  format.setOption(QSurfaceFormat::DebugContext);
 | 
				
			||||||
 | 
					#endif // QTK_DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Set the widget up using a custom format
 | 
				
			||||||
 | 
					  MainWidget widget(format);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return a.exec();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										58
									
								
								lib/camera3d.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Fly camera class from tutorials followed at trentreed.net           ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com	| URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <camera3d.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const QVector3D Camera3D::LocalForward(0.0f, 0.0f, -1.0f);
 | 
				
			||||||
 | 
					const QVector3D Camera3D::LocalUp(0.0f, 1.0f, 0.0f);
 | 
				
			||||||
 | 
					const QVector3D Camera3D::LocalRight(1.0f, 0.0f, 0.0f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Accessors
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Produces worldToView matrix
 | 
				
			||||||
 | 
					const QMatrix4x4 & Camera3D::toMatrix()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  mWorld.setToIdentity();
 | 
				
			||||||
 | 
					  mWorld.rotate(mTransform.rotation().conjugate());
 | 
				
			||||||
 | 
					  mWorld.translate(-mTransform.translation());
 | 
				
			||||||
 | 
					  return mWorld;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Qt Streams
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QDataStream & operator<<(QDataStream & out, Camera3D & transform)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  out << transform.transform();
 | 
				
			||||||
 | 
					  return out;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QDataStream & operator>>(QDataStream & in, Camera3D & transform)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  in >> transform.transform();
 | 
				
			||||||
 | 
					  return in;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QDebug operator<<(QDebug dbg, const Camera3D & transform)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  dbg << "Camera3D\n{\n";
 | 
				
			||||||
 | 
					  dbg << "Position: <" << transform.translation().x() << ", "
 | 
				
			||||||
 | 
					      << transform.translation().y() << ", "
 | 
				
			||||||
 | 
					      << transform.translation().z() << ">\n";
 | 
				
			||||||
 | 
					  dbg << "Rotation: <" << transform.rotation().x() << ", "
 | 
				
			||||||
 | 
					      << transform.rotation().y() << ", "
 | 
				
			||||||
 | 
					      << transform.rotation().z() << " | "
 | 
				
			||||||
 | 
					      << transform.rotation().scalar() << ">\n}";
 | 
				
			||||||
 | 
					  return dbg;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										62
									
								
								lib/camera3d.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Fly camera class from tutorials followed at trentreed.net           ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com	| URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef QTK_CAMERA3D_H
 | 
				
			||||||
 | 
					#define QTK_CAMERA3D_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QDebug>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <transform3D.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Camera3D {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  // Constants
 | 
				
			||||||
 | 
					  static const QVector3D LocalForward;
 | 
				
			||||||
 | 
					  static const QVector3D LocalUp;
 | 
				
			||||||
 | 
					  static const QVector3D LocalRight;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Accessors
 | 
				
			||||||
 | 
					  inline Transform3D & transform() { return mTransform;}
 | 
				
			||||||
 | 
					  inline const QVector3D & translation() const
 | 
				
			||||||
 | 
					  { return mTransform.translation();}
 | 
				
			||||||
 | 
					  inline const QQuaternion & rotation() const
 | 
				
			||||||
 | 
					  { return mTransform.rotation();}
 | 
				
			||||||
 | 
					  const QMatrix4x4 & toMatrix();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Queries
 | 
				
			||||||
 | 
					  inline QVector3D forward() const
 | 
				
			||||||
 | 
					  { return mTransform.rotation().rotatedVector(LocalForward);}
 | 
				
			||||||
 | 
					  inline QVector3D right() const
 | 
				
			||||||
 | 
					  { return mTransform.rotation().rotatedVector(LocalRight);}
 | 
				
			||||||
 | 
					  inline QVector3D up() const
 | 
				
			||||||
 | 
					  { return mTransform.rotation().rotatedVector(LocalUp);}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  Transform3D mTransform;
 | 
				
			||||||
 | 
					  QMatrix4x4 mWorld;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef QT_NO_DATASTREAM
 | 
				
			||||||
 | 
					  friend QDataStream & operator<<(QDataStream & out, Camera3D & transform);
 | 
				
			||||||
 | 
					  friend QDataStream & operator>>(QDataStream & in, Camera3D & transform);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Q_DECLARE_TYPEINFO(Camera3D, Q_MOVABLE_TYPE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Qt Streams
 | 
				
			||||||
 | 
					#ifndef QT_NO_DATASTREAM
 | 
				
			||||||
 | 
					QDataStream & operator<<(QDataStream & out, const Camera3D & transform);
 | 
				
			||||||
 | 
					QDataStream & operator>>(QDataStream & in, Camera3D & transform);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef QT_NO_DEBUG_STREAM
 | 
				
			||||||
 | 
					QDebug operator<<(QDebug dbg, const Camera3D & transform);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // QTK_CAMERA3D_H
 | 
				
			||||||
							
								
								
									
										185
									
								
								lib/input.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,185 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Input class from tutorials followed at trentreed.net                ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com	| URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QCursor>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <input.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Static Helper Structs
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					struct InputInstance : std::pair<T, Input::InputState>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  typedef std::pair<T, Input::InputState> base_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  inline InputInstance(T value)
 | 
				
			||||||
 | 
					      : base_class(value, Input::InputInvalid) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  inline InputInstance(T value, Input::InputState state)
 | 
				
			||||||
 | 
					      : base_class(value, state) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  inline bool operator==(const InputInstance & rhs) const
 | 
				
			||||||
 | 
					  { return this->first == rhs.first;}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Key, button instance typedefs
 | 
				
			||||||
 | 
					typedef InputInstance<Qt::Key> KeyInstance;
 | 
				
			||||||
 | 
					typedef InputInstance<Qt::MouseButton> ButtonInstance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Key, button instance container typedefs
 | 
				
			||||||
 | 
					typedef std::vector<KeyInstance> KeyContainer;
 | 
				
			||||||
 | 
					typedef std::vector<ButtonInstance> ButtonContainer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Static containers for key, button instances
 | 
				
			||||||
 | 
					static KeyContainer sg_keyInstances;
 | 
				
			||||||
 | 
					static ButtonContainer sg_buttonInstances;
 | 
				
			||||||
 | 
					// Static containers for mouse data
 | 
				
			||||||
 | 
					static QPoint sg_mouseCurrPosition;
 | 
				
			||||||
 | 
					static QPoint sg_mousePrevPosition;
 | 
				
			||||||
 | 
					static QPoint sg_mouseDelta;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Static Inline Helper Functions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline KeyContainer::iterator FindKey(Qt::Key value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return std::find(sg_keyInstances.begin(), sg_keyInstances.end(), value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline ButtonContainer::iterator FindButton(Qt::MouseButton value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return std::find(sg_buttonInstances.begin(), sg_buttonInstances.end(), value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename TPair>
 | 
				
			||||||
 | 
					static inline void UpdateStates(TPair & instance)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  switch (instance.second)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    case Input::InputRegistered:
 | 
				
			||||||
 | 
					      instance.second = Input::InputTriggered;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case Input::InputTriggered:
 | 
				
			||||||
 | 
					      instance.second = Input::InputPressed;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case Input::InputUnregistered:
 | 
				
			||||||
 | 
					      instance.second = Input::InputReleased;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename TPair>
 | 
				
			||||||
 | 
					static inline bool CheckReleased(const TPair & instance)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return instance.second == Input::InputReleased;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename Container>
 | 
				
			||||||
 | 
					static inline void Update(Container & container)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  typedef typename Container::iterator Iter;
 | 
				
			||||||
 | 
					  typedef typename Container::value_type TPair;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Remove old data
 | 
				
			||||||
 | 
					  Iter remove =
 | 
				
			||||||
 | 
					      std::remove_if(container.begin(), container.end(), &CheckReleased<TPair>);
 | 
				
			||||||
 | 
					  container.erase(remove, container.end());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Update existing data
 | 
				
			||||||
 | 
					  std::for_each(container.begin(), container.end(), &UpdateStates<TPair>);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Input Implementation
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Input::InputState Input::keyState(Qt::Key k)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  KeyContainer::iterator it = FindKey(k);
 | 
				
			||||||
 | 
					  return (it != sg_keyInstances.end()) ? it->second : InputInvalid;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Input::InputState Input::buttonState(Qt::MouseButton k)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  ButtonContainer::iterator it = FindButton(k);
 | 
				
			||||||
 | 
					  return (it != sg_buttonInstances.end()) ? it->second : InputInvalid;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QPoint Input::mousePosition()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return QCursor::pos();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QPoint Input::mouseDelta()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return sg_mouseDelta;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Input::update()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  // Update Mouse Delta
 | 
				
			||||||
 | 
					  sg_mousePrevPosition = sg_mouseCurrPosition;
 | 
				
			||||||
 | 
					  sg_mouseCurrPosition = QCursor::pos();
 | 
				
			||||||
 | 
					  sg_mouseDelta = sg_mouseCurrPosition - sg_mousePrevPosition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Update KeyState values
 | 
				
			||||||
 | 
					  Update(sg_buttonInstances);
 | 
				
			||||||
 | 
					  Update(sg_keyInstances);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Input::registerKeyPress(int k)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  KeyContainer::iterator it = FindKey((Qt::Key)k);
 | 
				
			||||||
 | 
					  if (it == sg_keyInstances.end())
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    sg_keyInstances.push_back(KeyInstance((Qt::Key)k, InputRegistered));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Input::registerKeyRelease(int k)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  KeyContainer::iterator it = FindKey((Qt::Key)k);
 | 
				
			||||||
 | 
					  if (it != sg_keyInstances.end())
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    it->second = InputUnregistered;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Input::registerMousePress(Qt::MouseButton btn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  ButtonContainer::iterator it = FindButton(btn);
 | 
				
			||||||
 | 
					  if (it == sg_buttonInstances.end())
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    sg_buttonInstances.push_back(ButtonInstance(btn, InputRegistered));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Input::registerMouseRelease(Qt::MouseButton btn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  ButtonContainer::iterator it = FindButton(btn);
 | 
				
			||||||
 | 
					  if (it != sg_buttonInstances.end())
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    it->second = InputUnregistered;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Input::reset()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  sg_keyInstances.clear();
 | 
				
			||||||
 | 
					  sg_buttonInstances.clear();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										63
									
								
								lib/input.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Input class from tutorials followed at trentreed.net                ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com	| URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef QTOPENGL_INPUT_H
 | 
				
			||||||
 | 
					#define QTOPENGL_INPUT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QPoint>
 | 
				
			||||||
 | 
					#include <Qt>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Input {
 | 
				
			||||||
 | 
					  friend class MainWidget;
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Possible key states
 | 
				
			||||||
 | 
					  enum InputState
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    InputInvalid,
 | 
				
			||||||
 | 
					    InputRegistered,
 | 
				
			||||||
 | 
					    InputUnregistered,
 | 
				
			||||||
 | 
					    InputTriggered,
 | 
				
			||||||
 | 
					    InputPressed,
 | 
				
			||||||
 | 
					    InputReleased
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // State checking
 | 
				
			||||||
 | 
					  inline static bool keyTriggered(Qt::Key key)
 | 
				
			||||||
 | 
					  { return keyState(key) == InputTriggered;}
 | 
				
			||||||
 | 
					  inline static bool keyPressed(Qt::Key key)
 | 
				
			||||||
 | 
					  { return keyState(key) == InputPressed;}
 | 
				
			||||||
 | 
					  inline static bool keyReleased(Qt::Key key)
 | 
				
			||||||
 | 
					  { return keyState(key) == InputReleased;}
 | 
				
			||||||
 | 
					  inline static bool buttonTriggered(Qt::MouseButton button)
 | 
				
			||||||
 | 
					  { return buttonState(button) == InputTriggered;}
 | 
				
			||||||
 | 
					  inline static bool buttonPressed(Qt::MouseButton button)
 | 
				
			||||||
 | 
					  { return buttonState(button) == InputPressed;}
 | 
				
			||||||
 | 
					  inline static bool buttonReleased(Qt::MouseButton button)
 | 
				
			||||||
 | 
					  { return buttonState(button) == InputReleased;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Implementation
 | 
				
			||||||
 | 
					  static InputState keyState(Qt::Key key);
 | 
				
			||||||
 | 
					  static InputState buttonState(Qt::MouseButton button);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static QPoint mousePosition();
 | 
				
			||||||
 | 
					  static QPoint mouseDelta();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // State updating
 | 
				
			||||||
 | 
					  static void update();
 | 
				
			||||||
 | 
					  static void registerKeyPress(int key);
 | 
				
			||||||
 | 
					  static void registerKeyRelease(int key);
 | 
				
			||||||
 | 
					  static void registerMousePress(Qt::MouseButton button);
 | 
				
			||||||
 | 
					  static void registerMouseRelease(Qt::MouseButton button);
 | 
				
			||||||
 | 
					  static void reset();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // QTOPENGL_INPUT_H
 | 
				
			||||||
							
								
								
									
										1064
									
								
								lib/mainwidget.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										84
									
								
								lib/mainwidget.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,84 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Main window for Qt5 OpenGL widget application                       ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com  | URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					#ifndef QTK_MAINWIDGET_H
 | 
				
			||||||
 | 
					#define QTK_MAINWIDGET_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QMatrix4x4>
 | 
				
			||||||
 | 
					#include <QOpenGLDebugLogger>
 | 
				
			||||||
 | 
					#include <QOpenGLFunctions>
 | 
				
			||||||
 | 
					#include <QOpenGLWidget>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <camera3d.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define QTK_DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MeshRenderer;
 | 
				
			||||||
 | 
					class Model;
 | 
				
			||||||
 | 
					class Object;
 | 
				
			||||||
 | 
					class Skybox;
 | 
				
			||||||
 | 
					class Texture;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MainWidget : public QOpenGLWidget,
 | 
				
			||||||
 | 
					                   protected QOpenGLFunctions {
 | 
				
			||||||
 | 
					Q_OBJECT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  // Constructors
 | 
				
			||||||
 | 
					  MainWidget();
 | 
				
			||||||
 | 
					  explicit MainWidget(const QSurfaceFormat &format);
 | 
				
			||||||
 | 
					  ~MainWidget() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Static Members
 | 
				
			||||||
 | 
					  static inline QMatrix4x4 &Projection() { return mProjection;}
 | 
				
			||||||
 | 
					  static inline Camera3D &Camera() { return mCamera;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  void teardownGL();
 | 
				
			||||||
 | 
					  void initObjects();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  // Inherited virtual Members
 | 
				
			||||||
 | 
					  void paintGL() override;
 | 
				
			||||||
 | 
					  void initializeGL() override;
 | 
				
			||||||
 | 
					  void resizeGL(int width, int height) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected slots:
 | 
				
			||||||
 | 
					  void update();
 | 
				
			||||||
 | 
					  void messageLogged(const QOpenGLDebugMessage &msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Protected Helpers
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					  void keyPressEvent(QKeyEvent *event);
 | 
				
			||||||
 | 
					  void keyReleaseEvent(QKeyEvent *event);
 | 
				
			||||||
 | 
					  void mousePressEvent(QMouseEvent *event);
 | 
				
			||||||
 | 
					  void mouseReleaseEvent(QMouseEvent *event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  // Private helpers
 | 
				
			||||||
 | 
					  void printContextInformation();
 | 
				
			||||||
 | 
					  void updateCameraInput();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Private Members
 | 
				
			||||||
 | 
					  static Camera3D mCamera;
 | 
				
			||||||
 | 
					  static QMatrix4x4 mProjection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Skybox * mSkybox;
 | 
				
			||||||
 | 
					  Object * mObject;
 | 
				
			||||||
 | 
					  MeshRenderer * mTestPhong;
 | 
				
			||||||
 | 
					  MeshRenderer * mTestSpecular;
 | 
				
			||||||
 | 
					  MeshRenderer * mTestDiffuse;
 | 
				
			||||||
 | 
					  MeshRenderer * mTestAmbient;
 | 
				
			||||||
 | 
					  std::vector<MeshRenderer *> mMeshes;
 | 
				
			||||||
 | 
					  std::vector<Model *> mModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  QOpenGLDebugLogger * mDebugLogger;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // QTK_MAINWIDGET_H
 | 
				
			||||||
							
								
								
									
										336
									
								
								lib/mesh.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,336 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Collection of static mesh data for quick initialization             ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com  | URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <mesh.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Cube::Cube(DrawMode mode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  mDrawMode = mode;
 | 
				
			||||||
 | 
					  switch(mode) {
 | 
				
			||||||
 | 
					    // Cube data for use with glDrawArrays
 | 
				
			||||||
 | 
					    case QTK_DRAW_ARRAYS:
 | 
				
			||||||
 | 
					      mIndices = { /* No indices needed for glDrawArrays */ };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mNormals =
 | 
				
			||||||
 | 
					          {FACE_FRONT, FACE_BACK, FACE_TOP, FACE_BOTTOM, FACE_LEFT, FACE_RIGHT};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mVertices = {
 | 
				
			||||||
 | 
					          // Face 1 (Front)
 | 
				
			||||||
 | 
					          VERTEX_FTR, VERTEX_FTL, VERTEX_FBL,
 | 
				
			||||||
 | 
					          VERTEX_FBL, VERTEX_FBR, VERTEX_FTR,
 | 
				
			||||||
 | 
					          // Face 2 (Back)
 | 
				
			||||||
 | 
					          VERTEX_BBR, VERTEX_BTL, VERTEX_BTR,
 | 
				
			||||||
 | 
					          VERTEX_BTL, VERTEX_BBR, VERTEX_BBL,
 | 
				
			||||||
 | 
					          // Face 3 (Top)
 | 
				
			||||||
 | 
					          VERTEX_FTR, VERTEX_BTR, VERTEX_BTL,
 | 
				
			||||||
 | 
					          VERTEX_BTL, VERTEX_FTL, VERTEX_FTR,
 | 
				
			||||||
 | 
					          // Face 4 (Bottom)
 | 
				
			||||||
 | 
					          VERTEX_FBR, VERTEX_FBL, VERTEX_BBL,
 | 
				
			||||||
 | 
					          VERTEX_BBL, VERTEX_BBR, VERTEX_FBR,
 | 
				
			||||||
 | 
					          // Face 5 (Left)
 | 
				
			||||||
 | 
					          VERTEX_FBL, VERTEX_FTL, VERTEX_BTL,
 | 
				
			||||||
 | 
					          VERTEX_FBL, VERTEX_BTL, VERTEX_BBL,
 | 
				
			||||||
 | 
					          // Face 6 (Right)
 | 
				
			||||||
 | 
					          VERTEX_FTR, VERTEX_FBR, VERTEX_BBR,
 | 
				
			||||||
 | 
					          VERTEX_BBR, VERTEX_BTR, VERTEX_FTR
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mColors = {
 | 
				
			||||||
 | 
					          // Face 1 (Front)
 | 
				
			||||||
 | 
					          RED, GREEN, BLUE,
 | 
				
			||||||
 | 
					          BLUE, WHITE, RED,
 | 
				
			||||||
 | 
					          // Face 2 (Back)
 | 
				
			||||||
 | 
					          YELLOW, CYAN, MAGENTA,
 | 
				
			||||||
 | 
					          CYAN, YELLOW, BLACK,
 | 
				
			||||||
 | 
					          // Face 3 (Top)
 | 
				
			||||||
 | 
					          RED, MAGENTA, CYAN,
 | 
				
			||||||
 | 
					          CYAN, GREEN, RED,
 | 
				
			||||||
 | 
					          // Face 4 (Bottom)
 | 
				
			||||||
 | 
					          WHITE, BLUE, BLACK,
 | 
				
			||||||
 | 
					          BLACK, YELLOW, WHITE,
 | 
				
			||||||
 | 
					          // Face 5 (Left)
 | 
				
			||||||
 | 
					          BLUE, GREEN, CYAN,
 | 
				
			||||||
 | 
					          BLUE, CYAN, BLACK,
 | 
				
			||||||
 | 
					          // Face 6 (Right)
 | 
				
			||||||
 | 
					          RED, WHITE, YELLOW,
 | 
				
			||||||
 | 
					          YELLOW, MAGENTA, RED
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mTexCoords = {
 | 
				
			||||||
 | 
					          // Face 1 (Front)
 | 
				
			||||||
 | 
					          UV_TOP, UV_ORIGIN, UV_RIGHT,
 | 
				
			||||||
 | 
					          UV_RIGHT, UV_CORNER, UV_TOP,
 | 
				
			||||||
 | 
					          // Face 2 (Back)
 | 
				
			||||||
 | 
					          UV_TOP, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					          UV_RIGHT, UV_TOP, UV_ORIGIN,
 | 
				
			||||||
 | 
					          // Face 3 (Top)
 | 
				
			||||||
 | 
					          UV_CORNER, UV_TOP, UV_ORIGIN,
 | 
				
			||||||
 | 
					          UV_ORIGIN, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					          // Face 4 (Bottom)
 | 
				
			||||||
 | 
					          UV_TOP, UV_ORIGIN, UV_RIGHT,
 | 
				
			||||||
 | 
					          UV_RIGHT, UV_CORNER, UV_TOP,
 | 
				
			||||||
 | 
					          // Face 5 (Left)
 | 
				
			||||||
 | 
					          UV_TOP, UV_CORNER, UV_RIGHT,
 | 
				
			||||||
 | 
					          UV_TOP, UV_RIGHT, UV_ORIGIN,
 | 
				
			||||||
 | 
					          // Face 6 (Right)
 | 
				
			||||||
 | 
					          UV_TOP, UV_CORNER, UV_RIGHT,
 | 
				
			||||||
 | 
					          UV_RIGHT, UV_ORIGIN, UV_TOP
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Cube data for use with glDrawElements
 | 
				
			||||||
 | 
					    case QTK_DRAW_ELEMENTS:
 | 
				
			||||||
 | 
					      mNormals =
 | 
				
			||||||
 | 
					          {/* For normals and glDrawElements, see QTK_DRAW_ELEMENTS_NORMALS */};
 | 
				
			||||||
 | 
					      mTexCoords =
 | 
				
			||||||
 | 
					          { /* For UVs and glDrawElements, see QTK_DRAW_ELEMENTS_NORMALS */ };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mColors = {RED, GREEN, BLUE, WHITE, YELLOW, CYAN, MAGENTA, BLACK};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mVertices = {
 | 
				
			||||||
 | 
					          //       0           1           2           3
 | 
				
			||||||
 | 
					          VERTEX_FTR, VERTEX_FTL, VERTEX_FBL, VERTEX_FBR,
 | 
				
			||||||
 | 
					          //       4           5           6           7
 | 
				
			||||||
 | 
					          VERTEX_BTR, VERTEX_BTL, VERTEX_BBL, VERTEX_BBR
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					      mIndices = {
 | 
				
			||||||
 | 
					          // Face 1 (Front)
 | 
				
			||||||
 | 
					          0, 1, 2,    2, 3, 0,
 | 
				
			||||||
 | 
					          // Face 2 (Back)
 | 
				
			||||||
 | 
					          7, 5, 4,    5, 7, 6,
 | 
				
			||||||
 | 
					          // Face 3 (Top)
 | 
				
			||||||
 | 
					          0, 4, 5,    5, 1, 0,
 | 
				
			||||||
 | 
					          // Face 4 (Bottom)
 | 
				
			||||||
 | 
					          3, 2, 6,    6, 7, 3,
 | 
				
			||||||
 | 
					          // Face 5 (Left)
 | 
				
			||||||
 | 
					          2, 1, 5,    2, 5, 6,
 | 
				
			||||||
 | 
					          // Face 6 (Right)
 | 
				
			||||||
 | 
					          0, 3, 7,    7, 4, 0
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Cube shape data for using normals and UVs with glDrawElements
 | 
				
			||||||
 | 
					    case QTK_DRAW_ELEMENTS_NORMALS:
 | 
				
			||||||
 | 
					      mColors = {RED, GREEN, BLUE, WHITE, YELLOW, CYAN, MAGENTA, BLACK};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mVertices = {
 | 
				
			||||||
 | 
					          // Face 1 (Front)
 | 
				
			||||||
 | 
					          //       0           1           2           3
 | 
				
			||||||
 | 
					          VERTEX_FTL, VERTEX_FBL, VERTEX_FBR, VERTEX_FTR,
 | 
				
			||||||
 | 
					          // Face 2 (Back)
 | 
				
			||||||
 | 
					          //       4           5           6           7
 | 
				
			||||||
 | 
					          VERTEX_BTL, VERTEX_BBL, VERTEX_BBR, VERTEX_BTR,
 | 
				
			||||||
 | 
					          // Face 3 (Top)
 | 
				
			||||||
 | 
					          //       8           9          10          11
 | 
				
			||||||
 | 
					          VERTEX_FTL, VERTEX_BTL, VERTEX_BTR, VERTEX_FTR,
 | 
				
			||||||
 | 
					          // Face 4 (Bottom)
 | 
				
			||||||
 | 
					          //      12          13          14          15
 | 
				
			||||||
 | 
					          VERTEX_FBL, VERTEX_BBL, VERTEX_BBR, VERTEX_FBR,
 | 
				
			||||||
 | 
					          // Face 5 (Left)
 | 
				
			||||||
 | 
					          //      16          17          18          19
 | 
				
			||||||
 | 
					          VERTEX_FBL, VERTEX_BBL, VERTEX_BTL, VERTEX_FTL,
 | 
				
			||||||
 | 
					          // Face 6 (Right)
 | 
				
			||||||
 | 
					          //      20          21          22          23
 | 
				
			||||||
 | 
					          VERTEX_FBR, VERTEX_BBR, VERTEX_BTR, VERTEX_FTR
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mIndices = {
 | 
				
			||||||
 | 
					          // Face 1 (Front)
 | 
				
			||||||
 | 
					          0, 1, 2,    2, 3, 0,
 | 
				
			||||||
 | 
					          // Face 2 (Back)
 | 
				
			||||||
 | 
					          4, 5, 6,    6, 7, 4,
 | 
				
			||||||
 | 
					          // Face 3 (Top)
 | 
				
			||||||
 | 
					          8, 9, 10,    10, 11, 8,
 | 
				
			||||||
 | 
					          // Face 4 (Bottom)
 | 
				
			||||||
 | 
					          12, 13, 14,    14, 15, 12,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // Face 5 (Left)
 | 
				
			||||||
 | 
					          16, 17, 18,    18, 19, 16,
 | 
				
			||||||
 | 
					          // Face 6 (Right)
 | 
				
			||||||
 | 
					          20, 21, 22,    22, 23, 20
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mNormals = {
 | 
				
			||||||
 | 
					          VECTOR_FORWARD, VECTOR_FORWARD, VECTOR_FORWARD, VECTOR_FORWARD,
 | 
				
			||||||
 | 
					          VECTOR_BACK, VECTOR_BACK, VECTOR_BACK, VECTOR_BACK,
 | 
				
			||||||
 | 
					          VECTOR_UP, VECTOR_UP, VECTOR_UP, VECTOR_UP,
 | 
				
			||||||
 | 
					          VECTOR_DOWN, VECTOR_DOWN, VECTOR_DOWN, VECTOR_DOWN,
 | 
				
			||||||
 | 
					          VECTOR_LEFT, VECTOR_LEFT, VECTOR_LEFT, VECTOR_LEFT,
 | 
				
			||||||
 | 
					          VECTOR_RIGHT, VECTOR_RIGHT, VECTOR_RIGHT, VECTOR_RIGHT,
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mTexCoords = {
 | 
				
			||||||
 | 
					          // Face 1 (Front)
 | 
				
			||||||
 | 
					          UV_TOP, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					          UV_RIGHT, UV_TOP, UV_ORIGIN,
 | 
				
			||||||
 | 
					          // Face 2 (Back)
 | 
				
			||||||
 | 
					          UV_TOP, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					          UV_RIGHT, UV_TOP, UV_ORIGIN,
 | 
				
			||||||
 | 
					          // Face 3 (Top)
 | 
				
			||||||
 | 
					          UV_TOP, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					          UV_RIGHT, UV_TOP, UV_ORIGIN,
 | 
				
			||||||
 | 
					          // Face 4 (Bottom)
 | 
				
			||||||
 | 
					          UV_TOP, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					          UV_RIGHT, UV_TOP, UV_ORIGIN,
 | 
				
			||||||
 | 
					          // Face 5 (Left)
 | 
				
			||||||
 | 
					          UV_TOP, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					          UV_RIGHT, UV_TOP, UV_ORIGIN,
 | 
				
			||||||
 | 
					          // Face 6 (Right)
 | 
				
			||||||
 | 
					          UV_TOP, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					          UV_RIGHT, UV_TOP, UV_ORIGIN,
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Triangle::Triangle(DrawMode mode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  mDrawMode = mode;
 | 
				
			||||||
 | 
					  const QVector3D triangleTop = QVector3D(0.0f, 0.5f, 0.0f);
 | 
				
			||||||
 | 
					  switch(mode) {
 | 
				
			||||||
 | 
					    case QTK_DRAW_ARRAYS:
 | 
				
			||||||
 | 
					      mIndices = { /* No indices needed for glDrawArrays */ };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mColors = { RED, GREEN, BLUE, WHITE, YELLOW, CYAN, MAGENTA, BLACK };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mVertices = {
 | 
				
			||||||
 | 
					          // Bottom face (Base of the pyramid)
 | 
				
			||||||
 | 
					          VERTEX_BBL, VERTEX_BBR, VERTEX_FBR,
 | 
				
			||||||
 | 
					          VERTEX_FBR, VERTEX_FBL, VERTEX_BBL,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // Front face
 | 
				
			||||||
 | 
					          VERTEX_FBL, VERTEX_FBR, triangleTop,
 | 
				
			||||||
 | 
					          // Back face
 | 
				
			||||||
 | 
					          VERTEX_BBR, VERTEX_BBL, triangleTop,
 | 
				
			||||||
 | 
					          // Left face
 | 
				
			||||||
 | 
					          VERTEX_BBL, VERTEX_FBL, triangleTop,
 | 
				
			||||||
 | 
					          // Right face
 | 
				
			||||||
 | 
					          VERTEX_FBR, VERTEX_BBR, triangleTop,
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Find normals for each triangle of the mesh
 | 
				
			||||||
 | 
					      for (int i = 0; i < mVertices.size(); i += 3) {
 | 
				
			||||||
 | 
					        QVector3D vertexNormal =
 | 
				
			||||||
 | 
					            QVector3D::normal(mVertices[i], mVertices[i+1], mVertices[i+2]);
 | 
				
			||||||
 | 
					        // Three points share this normal
 | 
				
			||||||
 | 
					        for (int j = 0; j < 3; j++) {
 | 
				
			||||||
 | 
					          mNormals.push_back(vertexNormal);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mTexCoords = {
 | 
				
			||||||
 | 
					          // Bottom face (Base of the pyramid)
 | 
				
			||||||
 | 
					          UV_ORIGIN, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					          UV_CORNER, UV_TOP, UV_ORIGIN,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // Front face
 | 
				
			||||||
 | 
					          UV_ORIGIN, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					          // Back face
 | 
				
			||||||
 | 
					          UV_ORIGIN, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					          // Left face
 | 
				
			||||||
 | 
					          UV_ORIGIN, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					          // Right face
 | 
				
			||||||
 | 
					          UV_ORIGIN, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Triangle shape data for using glDrawElements
 | 
				
			||||||
 | 
					    case QTK_DRAW_ELEMENTS:
 | 
				
			||||||
 | 
					      mColors = { RED, GREEN, BLUE, WHITE, YELLOW, CYAN, MAGENTA, BLACK };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mVertices = {VERTEX_FBL, VERTEX_FBR, VERTEX_BBL, VERTEX_BBR, triangleTop};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mIndices = {
 | 
				
			||||||
 | 
					          // Bottom face (Base of the pyramid)
 | 
				
			||||||
 | 
					          2, 3, 1, // Use customVertexes[2], then 3, 1...
 | 
				
			||||||
 | 
					          1, 0, 2, // Use customVertexes[1], then 0, 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          0, 1, 4, // Front face
 | 
				
			||||||
 | 
					          3, 2, 4, // Back face
 | 
				
			||||||
 | 
					          2, 0, 4, // Left face
 | 
				
			||||||
 | 
					          1, 3, 4, // Right face
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mNormals =
 | 
				
			||||||
 | 
					          {/* Use QTK_DRAW_ELEMENTS_NORMALS for normals with glDrawElements */};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mTexCoords = { /* No UVs for triangle with glDrawElements */ };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Triangle shape data for using normals and UVs with glDrawElements
 | 
				
			||||||
 | 
					    case QTK_DRAW_ELEMENTS_NORMALS:
 | 
				
			||||||
 | 
					      mColors = { RED, GREEN, BLUE, WHITE, YELLOW, CYAN, MAGENTA, BLACK };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mVertices = {
 | 
				
			||||||
 | 
					          // Bottom face
 | 
				
			||||||
 | 
					          //       0           1           2
 | 
				
			||||||
 | 
					          VERTEX_FBL, VERTEX_FBR, VERTEX_BBL,
 | 
				
			||||||
 | 
					          //       3            4          5
 | 
				
			||||||
 | 
					          VERTEX_BBR, VERTEX_FBR, VERTEX_BBL,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // Front face
 | 
				
			||||||
 | 
					          //       6           7           8
 | 
				
			||||||
 | 
					          VERTEX_FBL, VERTEX_FBR, triangleTop,
 | 
				
			||||||
 | 
					          // Back face
 | 
				
			||||||
 | 
					          //       9           10        11
 | 
				
			||||||
 | 
					          VERTEX_BBR, VERTEX_BBL, triangleTop,
 | 
				
			||||||
 | 
					          // Left face
 | 
				
			||||||
 | 
					          //      12          13          14
 | 
				
			||||||
 | 
					          VERTEX_BBL, VERTEX_FBL, triangleTop,
 | 
				
			||||||
 | 
					          // Right face
 | 
				
			||||||
 | 
					          //      15           16         17
 | 
				
			||||||
 | 
					          VERTEX_FBR, VERTEX_BBR, triangleTop,
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mIndices = {
 | 
				
			||||||
 | 
					          // Bottom face (Base of the pyramid)
 | 
				
			||||||
 | 
					          0, 1, 2, // Use customVertexes[2], then 3, 1...
 | 
				
			||||||
 | 
					          3, 4, 5, // Use customVertexes[1], then 0, 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          6, 7, 8, // Front face
 | 
				
			||||||
 | 
					          9, 10, 11, // Back face
 | 
				
			||||||
 | 
					          12, 13, 14, // Left face
 | 
				
			||||||
 | 
					          15, 16, 17, // Right face
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Find normals for each triangle of the mesh
 | 
				
			||||||
 | 
					      for (int i = 0; i < mVertices.size(); i += 3) {
 | 
				
			||||||
 | 
					        QVector3D vertexNormal =
 | 
				
			||||||
 | 
					            QVector3D::normal(mVertices[mIndices[i]],
 | 
				
			||||||
 | 
					                              mVertices[mIndices[i+1]],
 | 
				
			||||||
 | 
					                              mVertices[mIndices[i+2]]);
 | 
				
			||||||
 | 
					        // Three points share this normal
 | 
				
			||||||
 | 
					        for (int j = 0; j < 3; j++) {
 | 
				
			||||||
 | 
					          mNormals.push_back(vertexNormal);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mTexCoords = {
 | 
				
			||||||
 | 
					          // Bottom face
 | 
				
			||||||
 | 
					          UV_ORIGIN, UV_RIGHT, UV_TOP,
 | 
				
			||||||
 | 
					          UV_CORNER, UV_RIGHT, UV_TOP,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // Front face
 | 
				
			||||||
 | 
					          UV_ORIGIN, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					          // Back face
 | 
				
			||||||
 | 
					          UV_ORIGIN, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					          // Left face
 | 
				
			||||||
 | 
					          UV_ORIGIN, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					          // Right face
 | 
				
			||||||
 | 
					          UV_ORIGIN, UV_RIGHT, UV_CORNER,
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										131
									
								
								lib/mesh.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,131 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Collection of static mesh data for quick initialization             ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com  | URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					#ifndef QTK_MESH_H
 | 
				
			||||||
 | 
					#define QTK_MESH_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QOpenGLWidget>
 | 
				
			||||||
 | 
					#include <QVector2D>
 | 
				
			||||||
 | 
					#include <QVector3D>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <mainwidget.h>
 | 
				
			||||||
 | 
					#include <transform3D.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Define vertices for drawing a cube using two faces (8 vertex points)
 | 
				
			||||||
 | 
					// Front Vertices
 | 
				
			||||||
 | 
					#define VERTEX_FTR QVector3D( 0.5f,  0.5f,  0.5f) // 1
 | 
				
			||||||
 | 
					#define VERTEX_FTL QVector3D(-0.5f,  0.5f,  0.5f) // 2
 | 
				
			||||||
 | 
					#define VERTEX_FBL QVector3D(-0.5f, -0.5f,  0.5f) // 3
 | 
				
			||||||
 | 
					#define VERTEX_FBR QVector3D( 0.5f, -0.5f,  0.5f) // 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Back Vertices
 | 
				
			||||||
 | 
					#define VERTEX_BTR QVector3D( 0.5f,  0.5f, -0.5f) // 5
 | 
				
			||||||
 | 
					#define VERTEX_BTL QVector3D(-0.5f,  0.5f, -0.5f) // 6
 | 
				
			||||||
 | 
					#define VERTEX_BBL QVector3D(-0.5f, -0.5f, -0.5f) // 7
 | 
				
			||||||
 | 
					#define VERTEX_BBR QVector3D( 0.5f, -0.5f, -0.5f) // 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Direction vectors
 | 
				
			||||||
 | 
					#define VECTOR_UP      QVector3D(0.0f, 1.0f, 0.0f)
 | 
				
			||||||
 | 
					#define VECTOR_DOWN    QVector3D(0.0f, -1.0f, 0.0f)
 | 
				
			||||||
 | 
					#define VECTOR_LEFT    QVector3D(-1.0f, 0.0f, 0.0f)
 | 
				
			||||||
 | 
					#define VECTOR_RIGHT   QVector3D(1.0f, 0.0f, 0.0f)
 | 
				
			||||||
 | 
					#define VECTOR_FORWARD QVector3D(0.0f, 0.0f, 1.0f)
 | 
				
			||||||
 | 
					#define VECTOR_BACK    QVector3D(0.0f, 0.0f, -1.0f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Identity and zero vectors
 | 
				
			||||||
 | 
					#define VECTOR_ONE     QVector3D(1.0f, 1.0f, 1.0f)
 | 
				
			||||||
 | 
					#define VECTOR_ZERO    QVector3D(0.0f, 0.0f, 0.0f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A series of direction vectors to represent cube face normal
 | 
				
			||||||
 | 
					#define FACE_TOP    VECTOR_UP, VECTOR_UP, VECTOR_UP, \
 | 
				
			||||||
 | 
					                    VECTOR_UP, VECTOR_UP, VECTOR_UP
 | 
				
			||||||
 | 
					#define FACE_BOTTOM VECTOR_DOWN, VECTOR_DOWN, VECTOR_DOWN, \
 | 
				
			||||||
 | 
					                    VECTOR_DOWN, VECTOR_DOWN, VECTOR_DOWN
 | 
				
			||||||
 | 
					#define FACE_LEFT   VECTOR_LEFT, VECTOR_LEFT, VECTOR_LEFT, \
 | 
				
			||||||
 | 
					                    VECTOR_LEFT, VECTOR_LEFT, VECTOR_LEFT
 | 
				
			||||||
 | 
					#define FACE_RIGHT  VECTOR_RIGHT, VECTOR_RIGHT, VECTOR_RIGHT, \
 | 
				
			||||||
 | 
					                    VECTOR_RIGHT, VECTOR_RIGHT, VECTOR_RIGHT
 | 
				
			||||||
 | 
					#define FACE_FRONT  VECTOR_FORWARD, VECTOR_FORWARD, VECTOR_FORWARD, \
 | 
				
			||||||
 | 
					                    VECTOR_FORWARD, VECTOR_FORWARD, VECTOR_FORWARD
 | 
				
			||||||
 | 
					#define FACE_BACK   VECTOR_BACK, VECTOR_BACK, VECTOR_BACK, \
 | 
				
			||||||
 | 
					                    VECTOR_BACK, VECTOR_BACK, VECTOR_BACK
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Colors using QVector3Ds as RGB values
 | 
				
			||||||
 | 
					#define WHITE VECTOR_ONE
 | 
				
			||||||
 | 
					#define BLACK VECTOR_ZERO
 | 
				
			||||||
 | 
					#define RED   QVector3D(1.0f, 0.0f, 0.0f)
 | 
				
			||||||
 | 
					#define GREEN QVector3D(0.0f, 1.0f, 0.0f)
 | 
				
			||||||
 | 
					#define BLUE  QVector3D(0.0f, 0.0f, 1.0f)
 | 
				
			||||||
 | 
					#define YELLOW  QVector3D(1.0f, 1.0f, 0.0f)
 | 
				
			||||||
 | 
					#define CYAN    QVector3D(0.0f, 1.0f, 1.0f)
 | 
				
			||||||
 | 
					#define MAGENTA QVector3D(1.0f, 0.0f, 1.0f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define UV_ORIGIN  QVector2D(0.0f, 0.0f)
 | 
				
			||||||
 | 
					#define UV_TOP     QVector2D(1.0f, 0.0f)
 | 
				
			||||||
 | 
					#define UV_RIGHT   QVector2D(0.0f, 1.0f)
 | 
				
			||||||
 | 
					#define UV_CORNER  QVector2D(1.0f, 1.0f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef std::vector<QVector3D> Vertices;
 | 
				
			||||||
 | 
					typedef std::vector<QVector3D> Colors;
 | 
				
			||||||
 | 
					typedef std::vector<GLuint> Indices;
 | 
				
			||||||
 | 
					typedef std::vector<QVector2D> TexCoords;
 | 
				
			||||||
 | 
					typedef std::vector<QVector3D> Normals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum DrawMode { QTK_DRAW_ARRAYS, QTK_DRAW_ELEMENTS, QTK_DRAW_ELEMENTS_NORMALS };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ShapeBase {
 | 
				
			||||||
 | 
					  ShapeBase(DrawMode mode=QTK_DRAW_ARRAYS, Vertices v={},Indices i={}, Colors c={},
 | 
				
			||||||
 | 
					            TexCoords t={}, Normals n={})
 | 
				
			||||||
 | 
					      : mVertices(v), mColors(c), mIndices(i), mTexCoords(t), mNormals(n)
 | 
				
			||||||
 | 
					  {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  inline const Vertices & vertices() const { return mVertices;}
 | 
				
			||||||
 | 
					  inline const Indices & indices() const { return mIndices;}
 | 
				
			||||||
 | 
					  inline const Colors & colors() const { return mColors;}
 | 
				
			||||||
 | 
					  inline const TexCoords & texCoords() const { return mTexCoords;}
 | 
				
			||||||
 | 
					  inline const Normals & normals() const { return mNormals;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					  DrawMode mDrawMode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Vertices mVertices;
 | 
				
			||||||
 | 
					  Colors mColors;
 | 
				
			||||||
 | 
					  Indices mIndices;
 | 
				
			||||||
 | 
					  TexCoords mTexCoords;
 | 
				
			||||||
 | 
					  Normals mNormals;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Shape : public ShapeBase {
 | 
				
			||||||
 | 
					  friend MeshRenderer;
 | 
				
			||||||
 | 
					  friend Object;
 | 
				
			||||||
 | 
					  Shape () {}
 | 
				
			||||||
 | 
					  Shape(const ShapeBase & rhs) : ShapeBase(rhs) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual inline void setVertices(const Vertices & value) {mVertices = value;}
 | 
				
			||||||
 | 
					  virtual inline void setIndices(const Indices & value) {mIndices = value;}
 | 
				
			||||||
 | 
					  virtual inline void setColors(const Colors & value) {mColors = value;}
 | 
				
			||||||
 | 
					  virtual inline void setTexCoords(const TexCoords & value) {mTexCoords = value;}
 | 
				
			||||||
 | 
					  virtual inline void setNormals(const Normals & value) {mNormals = value;}
 | 
				
			||||||
 | 
					  virtual inline void setShape(const Shape & value) { *this = value;}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Primitives inherit from ShapeBase, does not allow setting of shape values
 | 
				
			||||||
 | 
					class Mesh {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Cube : public ShapeBase {
 | 
				
			||||||
 | 
					  Cube(DrawMode mode=QTK_DRAW_ARRAYS);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Triangle : public ShapeBase {
 | 
				
			||||||
 | 
					  Triangle(DrawMode mode=QTK_DRAW_ARRAYS);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // QTK_MESH_H
 | 
				
			||||||
							
								
								
									
										171
									
								
								lib/meshrenderer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,171 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: MeshRenderer class for quick object creation and drawing            ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com  | URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QImageReader>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <texture.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <meshrenderer.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Static QHash that holds all MeshRenderer instances using their mName as keys
 | 
				
			||||||
 | 
					MeshRenderer::MeshManager MeshRenderer::sInstances;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MeshRenderer::MeshRenderer(const char * name, const ShapeBase & shape)
 | 
				
			||||||
 | 
					    : Object(name, shape), mVertexShader(":/multi-color.vert"),
 | 
				
			||||||
 | 
					      mFragmentShader(":/multi-color.frag"), mDrawType(GL_TRIANGLES),
 | 
				
			||||||
 | 
					      mHasTexture(false)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  mShape = Shape(shape);
 | 
				
			||||||
 | 
					  init();
 | 
				
			||||||
 | 
					  sInstances.insert(name, this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MeshRenderer::~MeshRenderer()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (mHasTexture) {
 | 
				
			||||||
 | 
					    mTexture->destroy();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  sInstances.remove(mName);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Static member function to retrieve instances of MeshRenderers
 | 
				
			||||||
 | 
					MeshRenderer * MeshRenderer::getInstance(const QString & name)
 | 
				
			||||||
 | 
					{ return sInstances[name];}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Public Member Functions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MeshRenderer::init()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (mVAO.isCreated()) mVAO.destroy();
 | 
				
			||||||
 | 
					  if (mProgram.isLinked()) mProgram.removeAllShaders();
 | 
				
			||||||
 | 
					  if (mVBO.isCreated()) mVBO.destroy();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mVAO.create();
 | 
				
			||||||
 | 
					  mVAO.bind();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mProgram.create();
 | 
				
			||||||
 | 
					  mProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,
 | 
				
			||||||
 | 
					                                   mVertexShader.c_str());
 | 
				
			||||||
 | 
					  mProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,
 | 
				
			||||||
 | 
					                                   mFragmentShader.c_str());
 | 
				
			||||||
 | 
					  mProgram.link();
 | 
				
			||||||
 | 
					  mProgram.bind();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mVBO.create();
 | 
				
			||||||
 | 
					  mVBO.setUsagePattern(QOpenGLBuffer::StaticDraw);
 | 
				
			||||||
 | 
					  mVBO.bind();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Combine position and color data into one vector, allowing us to use one VBO
 | 
				
			||||||
 | 
					  Vertices combined;
 | 
				
			||||||
 | 
					  combined.reserve(vertices().size() + colors().size());
 | 
				
			||||||
 | 
					  combined.insert(combined.end(), vertices().begin(), vertices().end());
 | 
				
			||||||
 | 
					  combined.insert(combined.end(), colors().begin(), colors().end());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mVBO.allocate(combined.data(),
 | 
				
			||||||
 | 
					                combined.size() * sizeof(combined[0]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Enable position attribute
 | 
				
			||||||
 | 
					  mProgram.enableAttributeArray(0);
 | 
				
			||||||
 | 
					  mProgram.setAttributeBuffer(0, GL_FLOAT, 0,
 | 
				
			||||||
 | 
					                              3, sizeof(QVector3D));
 | 
				
			||||||
 | 
					  // Enable color attribute, setting offset to total size of vertices()
 | 
				
			||||||
 | 
					  mProgram.enableAttributeArray(1);
 | 
				
			||||||
 | 
					  mProgram.setAttributeBuffer(1, GL_FLOAT,
 | 
				
			||||||
 | 
					                              vertices().size() * sizeof(vertices()[0]),
 | 
				
			||||||
 | 
					                              3, sizeof(QVector3D));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mVBO.release();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mProgram.release();
 | 
				
			||||||
 | 
					  mVAO.release();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MeshRenderer::draw()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  mProgram.bind();
 | 
				
			||||||
 | 
					  mVAO.bind();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(mHasTexture) {
 | 
				
			||||||
 | 
					    mTexture->bind();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // TODO: Automate uniforms some other way
 | 
				
			||||||
 | 
					  setUniformMVP();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (mShape.mDrawMode == QTK_DRAW_ARRAYS) {
 | 
				
			||||||
 | 
					    glDrawArrays(mDrawType, 0, vertices().size());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if (mShape.mDrawMode == QTK_DRAW_ELEMENTS
 | 
				
			||||||
 | 
					           || mShape.mDrawMode == QTK_DRAW_ELEMENTS_NORMALS) {
 | 
				
			||||||
 | 
					    glDrawElements(mDrawType, mShape.mIndices.size(),
 | 
				
			||||||
 | 
					                   GL_UNSIGNED_INT, mShape.mIndices.data());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(mHasTexture) {
 | 
				
			||||||
 | 
					    mTexture->release();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mVAO.release();
 | 
				
			||||||
 | 
					  mProgram.release();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MeshRenderer::setShaders(const std::string & vert, const std::string & frag)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  mVertexShader = vert;
 | 
				
			||||||
 | 
					  mFragmentShader = frag;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MeshRenderer::setUniformMVP(const char * model, const char * view,
 | 
				
			||||||
 | 
					                                 const char * projection)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  mProgram.setUniformValue(projection, MainWidget::Projection());
 | 
				
			||||||
 | 
					  mProgram.setUniformValue(view, MainWidget::Camera().toMatrix());
 | 
				
			||||||
 | 
					  mProgram.setUniformValue(model, mTransform.toMatrix());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MeshRenderer::setColor(const QVector3D & color)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (mShape.mColors.empty()) {
 | 
				
			||||||
 | 
					    for (const auto & vertex : mShape.vertices()) {
 | 
				
			||||||
 | 
					      mShape.mColors.push_back(color);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else {
 | 
				
			||||||
 | 
					    for (int i = 0; i < mShape.colors().size(); i++) {
 | 
				
			||||||
 | 
					      mShape.mColors[i] = color;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MeshRenderer::setTexture(const char * path)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  mTexture = new QOpenGLTexture(*Texture::initImage(path));
 | 
				
			||||||
 | 
					  mHasTexture = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MeshRenderer::setTexture(QOpenGLTexture * texture)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  mTexture = texture;
 | 
				
			||||||
 | 
					  mHasTexture = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Inherited Virtual Member Functions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MeshRenderer::setShape(const Shape & value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  Object::setShape(value);
 | 
				
			||||||
 | 
					  init();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										76
									
								
								lib/meshrenderer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,76 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: MeshRenderer class for quick object creation and drawing            ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com  | URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					#ifndef QTK_MESHRENDERER_H
 | 
				
			||||||
 | 
					#define QTK_MESHRENDERER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <mesh.h>
 | 
				
			||||||
 | 
					#include <object.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MeshRenderer : public Object {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  // Delegate constructors
 | 
				
			||||||
 | 
					  MeshRenderer(const char * name, Vertices vertices, Indices indices,
 | 
				
			||||||
 | 
					               DrawMode mode=QTK_DRAW_ARRAYS)
 | 
				
			||||||
 | 
					      : MeshRenderer(name, ShapeBase(mode, vertices, indices))
 | 
				
			||||||
 | 
					  {}
 | 
				
			||||||
 | 
					  MeshRenderer(const char * name)
 | 
				
			||||||
 | 
					      : MeshRenderer(name, Cube(QTK_DRAW_ELEMENTS))
 | 
				
			||||||
 | 
					  {}
 | 
				
			||||||
 | 
					  // Constructor
 | 
				
			||||||
 | 
					  MeshRenderer(const char * name, const ShapeBase &shape);
 | 
				
			||||||
 | 
					  ~MeshRenderer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Retrieve a mesh by name stored within a static QHash
 | 
				
			||||||
 | 
					  static MeshRenderer * getInstance(const QString & name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void init();
 | 
				
			||||||
 | 
					  void draw();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Draw types like GL_TRIANGLES, GL_POINTS, GL_LINES, etc
 | 
				
			||||||
 | 
					  void setDrawType(int drawType) { mDrawType = drawType;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Shader settings
 | 
				
			||||||
 | 
					  inline void setShaderVertex(const std::string & vert) { mVertexShader = vert;}
 | 
				
			||||||
 | 
					  inline void setShaderFragment(const std::string & frag) { mFragmentShader = frag;}
 | 
				
			||||||
 | 
					  void setShaders(const std::string & vert, const std::string & frag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <typename T>
 | 
				
			||||||
 | 
					  inline void setUniform(int location, T value)
 | 
				
			||||||
 | 
					  { mProgram.setUniformValue(location, value);}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <typename T>
 | 
				
			||||||
 | 
					  inline void setUniform(const char * location, T value)
 | 
				
			||||||
 | 
					  { mProgram.setUniformValue(location, value);}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Set MVP matrix using this Object's transform
 | 
				
			||||||
 | 
					  // + View and projection provided by MainWidget static members
 | 
				
			||||||
 | 
					  void setUniformMVP(const char * model="uModel", const char * view="uView",
 | 
				
			||||||
 | 
					                     const char * projection="uProjection");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Sets the texture to the image at the given path
 | 
				
			||||||
 | 
					  // + Sets mHasTexture to enable texture binding in draw()
 | 
				
			||||||
 | 
					  void setTexture(const char * path);
 | 
				
			||||||
 | 
					  void setTexture(QOpenGLTexture * texture);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // These functions modify data stored in a VBO
 | 
				
			||||||
 | 
					  // + After calling them, the VBO will need to be reallocated
 | 
				
			||||||
 | 
					  void setShape(const Shape & value) override;
 | 
				
			||||||
 | 
					  void setColor(const QVector3D & color);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Static QHash of all mesh objects within the scene
 | 
				
			||||||
 | 
					  typedef QHash<QString, MeshRenderer *> MeshManager;
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  static MeshManager sInstances;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int mDrawType;
 | 
				
			||||||
 | 
					  bool mHasTexture;
 | 
				
			||||||
 | 
					  std::string mVertexShader, mFragmentShader;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // QTK_MESHRENDERER_H
 | 
				
			||||||
							
								
								
									
										401
									
								
								lib/model.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,401 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Model classes for importing with Assimp                             ##
 | 
				
			||||||
 | 
					##        From following tutorials on learnopengl.com                         ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com  | URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QFileInfo>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <mainwidget.h>
 | 
				
			||||||
 | 
					#include <texture.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <model.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Model::ModelManager Model::mManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Static function to access ModelManager for getting Models by name
 | 
				
			||||||
 | 
					Model * Model::getInstance(const char * name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return mManager[name];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * ModelMesh Private Member Functions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModelMesh::initMesh(const char * vert, const char * frag)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  // Create VAO, VBO, EBO
 | 
				
			||||||
 | 
					  mVAO->create();
 | 
				
			||||||
 | 
					  mVBO->create();
 | 
				
			||||||
 | 
					  mEBO->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mVAO->bind();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Allocate VBO
 | 
				
			||||||
 | 
					  mVBO->setUsagePattern(QOpenGLBuffer::StaticDraw);
 | 
				
			||||||
 | 
					  mVBO->bind();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mVBO->allocate(mVertices.data(),
 | 
				
			||||||
 | 
					                 mVertices.size() * sizeof(mVertices[0]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Allocate EBO
 | 
				
			||||||
 | 
					  mEBO->setUsagePattern(QOpenGLBuffer::StaticDraw);
 | 
				
			||||||
 | 
					  mEBO->bind();
 | 
				
			||||||
 | 
					  mEBO->allocate(mIndices.data(),
 | 
				
			||||||
 | 
					                 mIndices.size() * sizeof(mIndices[0]));
 | 
				
			||||||
 | 
					  mEBO->release();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Load and link shaders
 | 
				
			||||||
 | 
					  mProgram->addShaderFromSourceFile(QOpenGLShader::Vertex, vert);
 | 
				
			||||||
 | 
					  mProgram->addShaderFromSourceFile(QOpenGLShader::Fragment, frag);
 | 
				
			||||||
 | 
					  mProgram->link();
 | 
				
			||||||
 | 
					  mProgram->bind();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Positions
 | 
				
			||||||
 | 
					  mProgram->enableAttributeArray(0);
 | 
				
			||||||
 | 
					  mProgram->setAttributeBuffer(0, GL_FLOAT,
 | 
				
			||||||
 | 
					                               offsetof(ModelVertex, mPosition), 3,
 | 
				
			||||||
 | 
					                               sizeof(ModelVertex));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Normals
 | 
				
			||||||
 | 
					  mProgram->enableAttributeArray(1);
 | 
				
			||||||
 | 
					  mProgram->setAttributeBuffer(1, GL_FLOAT,
 | 
				
			||||||
 | 
					                               offsetof(ModelVertex, mNormal), 3,
 | 
				
			||||||
 | 
					                               sizeof(ModelVertex));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Texture Coordinates
 | 
				
			||||||
 | 
					  mProgram->enableAttributeArray(2);
 | 
				
			||||||
 | 
					  mProgram->setAttributeBuffer(2, GL_FLOAT,
 | 
				
			||||||
 | 
					                               offsetof(ModelVertex, mTextureCoord), 2,
 | 
				
			||||||
 | 
					                               sizeof(ModelVertex));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Vertex tangents
 | 
				
			||||||
 | 
					  mProgram->enableAttributeArray(3);
 | 
				
			||||||
 | 
					  mProgram->setAttributeBuffer(3, GL_FLOAT,
 | 
				
			||||||
 | 
					                               offsetof(ModelVertex, mTangent), 3,
 | 
				
			||||||
 | 
					                               sizeof(ModelVertex));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Vertex bitangents
 | 
				
			||||||
 | 
					  mProgram->enableAttributeArray(4);
 | 
				
			||||||
 | 
					  mProgram->setAttributeBuffer(4, GL_FLOAT,
 | 
				
			||||||
 | 
					                               offsetof(ModelVertex, mBitangent), 3,
 | 
				
			||||||
 | 
					                               sizeof(ModelVertex));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mProgram->release();
 | 
				
			||||||
 | 
					  mVBO->release();
 | 
				
			||||||
 | 
					  mVAO->release();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * ModelMesh Public Member Functions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModelMesh::draw(QOpenGLShaderProgram & shader)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  mVAO->bind();
 | 
				
			||||||
 | 
					  // Bind shader
 | 
				
			||||||
 | 
					  shader.bind();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Set Model View Projection values
 | 
				
			||||||
 | 
					  shader.setUniformValue("uModel", mTransform.toMatrix());
 | 
				
			||||||
 | 
					  shader.setUniformValue("uView", MainWidget::Camera().toMatrix());
 | 
				
			||||||
 | 
					  shader.setUniformValue("uProjection", MainWidget::Projection());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GLuint diffuseCount = 1;
 | 
				
			||||||
 | 
					  GLuint specularCount = 1;
 | 
				
			||||||
 | 
					  GLuint normalCount = 1;
 | 
				
			||||||
 | 
					  for (GLuint i = 0; i < mTextures.size(); i++) {
 | 
				
			||||||
 | 
					    // Activate the current texture index by adding offset to GL_TEXTURE0
 | 
				
			||||||
 | 
					    glActiveTexture(GL_TEXTURE0 + i);
 | 
				
			||||||
 | 
					    mTextures[i].mTexture->bind();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get a name for the texture using a known convention -
 | 
				
			||||||
 | 
					    // Diffuse:   material.texture_diffuse1, material.texture_diffuse2, ...
 | 
				
			||||||
 | 
					    // Specular:   material.texture_specular1, material.texture_specular2, ...
 | 
				
			||||||
 | 
					    std::string number;
 | 
				
			||||||
 | 
					    std::string name = mTextures[i].mType;
 | 
				
			||||||
 | 
					    if (name == "texture_diffuse") number = std::to_string(diffuseCount++);
 | 
				
			||||||
 | 
					    if (name == "texture_specular") number = std::to_string(specularCount++);
 | 
				
			||||||
 | 
					    if (name == "texture_normal") number = std::to_string(normalCount++);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Set the uniform to track this texture ID using our naming convention
 | 
				
			||||||
 | 
					    shader.setUniformValue((name + number).c_str(), i);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Draw the mesh
 | 
				
			||||||
 | 
					  glDrawElements(GL_TRIANGLES, mIndices.size(),
 | 
				
			||||||
 | 
					                 GL_UNSIGNED_INT, mIndices.data());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Release shader, textures
 | 
				
			||||||
 | 
					  for (const auto & texture : mTextures) {
 | 
				
			||||||
 | 
					    texture.mTexture->release();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  shader.release();
 | 
				
			||||||
 | 
					  mVAO->release();
 | 
				
			||||||
 | 
					  glActiveTexture(GL_TEXTURE0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Model Public Member Functions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Model::draw()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  for (GLuint i = 0; i < mMeshes.size(); i++) {
 | 
				
			||||||
 | 
					    mMeshes[i].mTransform = mTransform;
 | 
				
			||||||
 | 
					    mMeshes[i].draw();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Model::draw(QOpenGLShaderProgram & shader)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  for (GLuint i = 0; i < mMeshes.size(); i++) {
 | 
				
			||||||
 | 
					    mMeshes[i].mTransform = mTransform;
 | 
				
			||||||
 | 
					    mMeshes[i].draw(shader);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Model::flipTexture(const std::string & fileName, bool flipX, bool flipY)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  bool modified = false;
 | 
				
			||||||
 | 
					  std::string fullPath = mDirectory + '/' + fileName;
 | 
				
			||||||
 | 
					  for (auto & texture : mTexturesLoaded) {
 | 
				
			||||||
 | 
					    if (texture.mPath == fileName) {
 | 
				
			||||||
 | 
					      texture.mTexture->destroy();
 | 
				
			||||||
 | 
					      texture.mTexture->create();
 | 
				
			||||||
 | 
					      texture.mTexture->setData(
 | 
				
			||||||
 | 
					          *Texture::initImage(fullPath.c_str(), flipX, flipY));
 | 
				
			||||||
 | 
					      modified = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (!modified) {
 | 
				
			||||||
 | 
					    qDebug() << "Attempt to flip texture that doesn't exist: "
 | 
				
			||||||
 | 
					             << fullPath.c_str() << "\n";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Model Private Member Functions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Model::loadModel(const std::string & path)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  Assimp::Importer import;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // JIC a relative path was used, get the absolute file path
 | 
				
			||||||
 | 
					  QFileInfo info(path.c_str());
 | 
				
			||||||
 | 
					  info.makeAbsolute();
 | 
				
			||||||
 | 
					  std::string temp = info.absoluteFilePath().toStdString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Import the model, converting non-triangular geometry to triangles
 | 
				
			||||||
 | 
					  // + And flipping texture UVs, etc..
 | 
				
			||||||
 | 
					  // Assimp options: http://assimp.sourceforge.net/lib_html/postprocess_8h.html
 | 
				
			||||||
 | 
					  const aiScene * scene =
 | 
				
			||||||
 | 
					      import.ReadFile(temp, aiProcess_Triangulate
 | 
				
			||||||
 | 
					                            | aiProcess_FlipUVs
 | 
				
			||||||
 | 
					                            | aiProcess_GenSmoothNormals
 | 
				
			||||||
 | 
					                            | aiProcess_CalcTangentSpace
 | 
				
			||||||
 | 
					                            | aiProcess_OptimizeMeshes
 | 
				
			||||||
 | 
					                            | aiProcess_SplitLargeMeshes
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // If there were errors, print and return
 | 
				
			||||||
 | 
					  if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
 | 
				
			||||||
 | 
					    qDebug() << "Error::ASSIMP::" << import.GetErrorString() << "\n";
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // If there were no errors, find the directory that contains this model
 | 
				
			||||||
 | 
					  mDirectory = path.substr(0, path.find_last_of('/'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Pass the pointers to the root node and the scene to recursive function
 | 
				
			||||||
 | 
					  // + Base case breaks when no nodes left to process on model
 | 
				
			||||||
 | 
					  processNode(scene->mRootNode, scene);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Sort models by their distance from the camera
 | 
				
			||||||
 | 
					  // Optimizes drawing so that overlapping objects are not overwritten
 | 
				
			||||||
 | 
					  // + Since the topmost object will be drawn first
 | 
				
			||||||
 | 
					  sortModels();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Object finished loading, insert it into ModelManager
 | 
				
			||||||
 | 
					  mManager.insert(mName, this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Model::processNode(aiNode * node, const aiScene * scene)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  // Process each mesh that is available for this node
 | 
				
			||||||
 | 
					  for (GLuint i  = 0; i < node->mNumMeshes; i++) {
 | 
				
			||||||
 | 
					    aiMesh * mesh = scene->mMeshes[node->mMeshes[i]];
 | 
				
			||||||
 | 
					    mMeshes.push_back(processMesh(mesh, scene));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Process each child node for this mesh using recursion
 | 
				
			||||||
 | 
					  for (GLuint i  = 0; i < node->mNumChildren; i++) {
 | 
				
			||||||
 | 
					    processNode(node->mChildren[i], scene);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ModelMesh Model::processMesh(aiMesh * mesh, const aiScene * scene)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  ModelMesh::Vertices vertices;
 | 
				
			||||||
 | 
					  ModelMesh::Indices indices;
 | 
				
			||||||
 | 
					  ModelMesh::Textures textures;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // For each vertex in the aiMesh
 | 
				
			||||||
 | 
					  for (GLuint i = 0; i < mesh->mNumVertices; i++) {
 | 
				
			||||||
 | 
					    // Create a local vertex object for positions, normals, and texture coords
 | 
				
			||||||
 | 
					    ModelVertex vertex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Reuse this vector to initialize positions and normals
 | 
				
			||||||
 | 
					    QVector3D vector3D;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Initialize vertex position
 | 
				
			||||||
 | 
					    vector3D.setX(mesh->mVertices[i].x);
 | 
				
			||||||
 | 
					    vector3D.setY(mesh->mVertices[i].y);
 | 
				
			||||||
 | 
					    vector3D.setZ(mesh->mVertices[i].z);
 | 
				
			||||||
 | 
					    // Set the position of our local vertex to the local vector object
 | 
				
			||||||
 | 
					    vertex.mPosition = vector3D;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (mesh->HasNormals()) {
 | 
				
			||||||
 | 
					      // Initialize vertex normal
 | 
				
			||||||
 | 
					      vector3D.setX(mesh->mNormals[i].x);
 | 
				
			||||||
 | 
					      vector3D.setY(mesh->mNormals[i].y);
 | 
				
			||||||
 | 
					      vector3D.setZ(mesh->mNormals[i].z);
 | 
				
			||||||
 | 
					      // Set the normals of our local vertex to the local vector object
 | 
				
			||||||
 | 
					      vertex.mNormal = vector3D;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Initialize texture coordinates, if any are available
 | 
				
			||||||
 | 
					    if (mesh->mTextureCoords[0]) {
 | 
				
			||||||
 | 
					      QVector2D vector2D;
 | 
				
			||||||
 | 
					      // Texture coordinates
 | 
				
			||||||
 | 
					      vector2D.setX(mesh->mTextureCoords[0][i].x);
 | 
				
			||||||
 | 
					      vector2D.setY(mesh->mTextureCoords[0][i].y);
 | 
				
			||||||
 | 
					      vertex.mTextureCoord = vector2D;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Tangents
 | 
				
			||||||
 | 
					      vector3D.setX(mesh->mTangents[i].x);
 | 
				
			||||||
 | 
					      vector3D.setY(mesh->mTangents[i].y);
 | 
				
			||||||
 | 
					      vector3D.setZ(mesh->mTangents[i].z);
 | 
				
			||||||
 | 
					      vertex.mTangent = vector3D;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Bitangents
 | 
				
			||||||
 | 
					      vector3D.setX(mesh->mBitangents[i].x);
 | 
				
			||||||
 | 
					      vector3D.setY(mesh->mBitangents[i].y);
 | 
				
			||||||
 | 
					      vector3D.setZ(mesh->mBitangents[i].z);
 | 
				
			||||||
 | 
					      vertex.mBitangent = vector3D;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					      vertex.mTextureCoord = {0.0f, 0.0f};
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Add the initialized vertex to our container of vertices
 | 
				
			||||||
 | 
					    vertices.push_back(vertex);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // For each face on the mesh, process its indices
 | 
				
			||||||
 | 
					  for (GLuint i = 0; i < mesh->mNumFaces; i++) {
 | 
				
			||||||
 | 
					    aiFace face = mesh->mFaces[i];
 | 
				
			||||||
 | 
					    for (GLuint j = 0; j < face.mNumIndices; j++) {
 | 
				
			||||||
 | 
					      // Add the index to out container of indices
 | 
				
			||||||
 | 
					      indices.push_back(face.mIndices[j]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Process material
 | 
				
			||||||
 | 
					  if (mesh->mMaterialIndex >= 0) {
 | 
				
			||||||
 | 
					    // Get the material attached to the model using Assimp
 | 
				
			||||||
 | 
					    aiMaterial * material = scene->mMaterials[mesh->mMaterialIndex];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get all diffuse textures from the material
 | 
				
			||||||
 | 
					    ModelMesh::Textures diffuseMaps =
 | 
				
			||||||
 | 
					        loadMaterialTextures(material, aiTextureType_DIFFUSE,
 | 
				
			||||||
 | 
					                             "texture_diffuse");
 | 
				
			||||||
 | 
					    // Insert all diffuse textures found into our textures container
 | 
				
			||||||
 | 
					    textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get all specular textures from the material
 | 
				
			||||||
 | 
					    ModelMesh::Textures specularMaps =
 | 
				
			||||||
 | 
					        loadMaterialTextures(material, aiTextureType_SPECULAR,
 | 
				
			||||||
 | 
					                             "texture_specular");
 | 
				
			||||||
 | 
					    // Insert all specular textures found into our textures container
 | 
				
			||||||
 | 
					    textures.insert(textures.end(), specularMaps.begin(), specularMaps.end());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get all normal textures from the material
 | 
				
			||||||
 | 
					    ModelMesh::Textures normalMaps =
 | 
				
			||||||
 | 
					        loadMaterialTextures(material, aiTextureType_HEIGHT,
 | 
				
			||||||
 | 
					                             "texture_normal");
 | 
				
			||||||
 | 
					    // Insert all normal maps found into our textures container
 | 
				
			||||||
 | 
					    textures.insert(textures.end(), normalMaps.begin(), normalMaps.end());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return ModelMesh(vertices, indices, textures,
 | 
				
			||||||
 | 
					                   mVertexShader, mFragmentShader);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ModelMesh::Textures Model::loadMaterialTextures(
 | 
				
			||||||
 | 
					    aiMaterial * mat, aiTextureType type, const std::string & typeName)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  ModelMesh::Textures textures;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for  (GLuint i = 0; i < mat->GetTextureCount(type); i++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Call GetTexture to get the name of the texture file to load
 | 
				
			||||||
 | 
					    aiString fileName;
 | 
				
			||||||
 | 
					    mat->GetTexture(type, i, &fileName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check if we have already loaded this texture
 | 
				
			||||||
 | 
					    bool skip = false;
 | 
				
			||||||
 | 
					    for (GLuint j = 0; j < mTexturesLoaded.size(); j++) {
 | 
				
			||||||
 | 
					      // If the path to the texture already exists in m_texturesLoaded, skip it
 | 
				
			||||||
 | 
					      if (std::strcmp(mTexturesLoaded[j].mPath.data(), fileName.C_Str()) == 0) {
 | 
				
			||||||
 | 
					        textures.push_back(mTexturesLoaded[j]);
 | 
				
			||||||
 | 
					        // If we have loaded the texture, do not load it again
 | 
				
			||||||
 | 
					        skip = true;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // If the texture has not yet been loaded
 | 
				
			||||||
 | 
					    if (!skip) {
 | 
				
			||||||
 | 
					      ModelTexture texture;
 | 
				
			||||||
 | 
					      texture.mTexture = Texture::initTexture2D(
 | 
				
			||||||
 | 
					          std::string(mDirectory + '/' + fileName.C_Str()).c_str(),
 | 
				
			||||||
 | 
					          false, false);
 | 
				
			||||||
 | 
					      texture.mID = texture.mTexture->textureId();
 | 
				
			||||||
 | 
					      texture.mType = typeName;
 | 
				
			||||||
 | 
					      texture.mPath = fileName.C_Str();
 | 
				
			||||||
 | 
					      // Add the texture to the textures container
 | 
				
			||||||
 | 
					      textures.push_back(texture);
 | 
				
			||||||
 | 
					      // Add the texture to the loaded textures to avoid loading it twice
 | 
				
			||||||
 | 
					      mTexturesLoaded.push_back(texture);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Return the resulting textures
 | 
				
			||||||
 | 
					  return textures;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Model::sortModels()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  auto cameraPos = MainWidget::Camera().transform();
 | 
				
			||||||
 | 
					  auto cameraDistance = [&cameraPos](const ModelMesh &a, const ModelMesh &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    // Sort by the first vertex position, since all transforms will be the same
 | 
				
			||||||
 | 
					    return (cameraPos.translation().distanceToPoint(a.mVertices[0].mPosition))
 | 
				
			||||||
 | 
					           < (cameraPos.translation().distanceToPoint(b.mVertices[0].mPosition));
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  std::sort(mMeshes.begin(), mMeshes.end(), cameraDistance);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										139
									
								
								lib/model.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,139 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Model classes for importing with Assimp                             ##
 | 
				
			||||||
 | 
					##        From following tutorials on learnopengl.com                         ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com  | URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					#ifndef QTK_MODEL_H
 | 
				
			||||||
 | 
					#define QTK_MODEL_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// QT
 | 
				
			||||||
 | 
					#include <QObject>
 | 
				
			||||||
 | 
					#include <QOpenGLBuffer>
 | 
				
			||||||
 | 
					#include <QOpenGLFunctions>
 | 
				
			||||||
 | 
					#include <QOpenGLShaderProgram>
 | 
				
			||||||
 | 
					#include <QOpenGLTexture>
 | 
				
			||||||
 | 
					#include <QOpenGLVertexArrayObject>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Assimp
 | 
				
			||||||
 | 
					#include <assimp/Importer.hpp>
 | 
				
			||||||
 | 
					#include <assimp/postprocess.h>
 | 
				
			||||||
 | 
					#include <assimp/scene.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// QTK
 | 
				
			||||||
 | 
					#include <transform3D.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ModelVertex {
 | 
				
			||||||
 | 
					  QVector3D mPosition;
 | 
				
			||||||
 | 
					  QVector3D mNormal;
 | 
				
			||||||
 | 
					  QVector3D mTangent;
 | 
				
			||||||
 | 
					  QVector3D mBitangent;
 | 
				
			||||||
 | 
					  QVector2D mTextureCoord;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ModelTexture {
 | 
				
			||||||
 | 
					  GLuint mID;
 | 
				
			||||||
 | 
					  QOpenGLTexture * mTexture;
 | 
				
			||||||
 | 
					  std::string mType;
 | 
				
			||||||
 | 
					  std::string mPath;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ModelMesh {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  friend Model;
 | 
				
			||||||
 | 
					  typedef std::vector<ModelVertex> Vertices;
 | 
				
			||||||
 | 
					  typedef std::vector<GLuint> Indices;
 | 
				
			||||||
 | 
					  typedef std::vector<ModelTexture> Textures;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Constructors, Destructors
 | 
				
			||||||
 | 
					  ModelMesh(Vertices vertices, Indices indices, Textures textures,
 | 
				
			||||||
 | 
					            const char * vertexShader=":/model-basic.vert",
 | 
				
			||||||
 | 
					            const char * fragmentShader=":/model-basic.frag")
 | 
				
			||||||
 | 
					      : mProgram(new QOpenGLShaderProgram),
 | 
				
			||||||
 | 
					        mVAO(new QOpenGLVertexArrayObject),
 | 
				
			||||||
 | 
					        mVBO(new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer)),
 | 
				
			||||||
 | 
					        mEBO(new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer)),
 | 
				
			||||||
 | 
					        mVertices(std::move(vertices)),
 | 
				
			||||||
 | 
					        mIndices(std::move(indices)),
 | 
				
			||||||
 | 
					        mTextures(std::move(textures))
 | 
				
			||||||
 | 
					  { initMesh(vertexShader, fragmentShader);}
 | 
				
			||||||
 | 
					  ~ModelMesh() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  void initMesh(const char * vert, const char * frag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // ModelMesh Private Members
 | 
				
			||||||
 | 
					  QOpenGLBuffer * mVBO, * mEBO;
 | 
				
			||||||
 | 
					  QOpenGLVertexArrayObject * mVAO;
 | 
				
			||||||
 | 
					  QOpenGLShaderProgram * mProgram;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  inline void draw() { draw(*mProgram);}
 | 
				
			||||||
 | 
					  void draw(QOpenGLShaderProgram & shader);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // ModelMesh Public Members
 | 
				
			||||||
 | 
					  Vertices mVertices;
 | 
				
			||||||
 | 
					  Indices mIndices;
 | 
				
			||||||
 | 
					  Textures mTextures;
 | 
				
			||||||
 | 
					  Transform3D mTransform;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Model : public QObject {
 | 
				
			||||||
 | 
					Q_OBJECT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  inline Model(const char * name, const char * path,
 | 
				
			||||||
 | 
					               const char * vertexShader=":/model-basic.vert",
 | 
				
			||||||
 | 
					               const char * fragmentShader=":/model-basic.frag")
 | 
				
			||||||
 | 
					      : mName(name), mVertexShader(vertexShader),
 | 
				
			||||||
 | 
					        mFragmentShader(fragmentShader)
 | 
				
			||||||
 | 
					  { loadModel(path);}
 | 
				
			||||||
 | 
					  inline ~Model() { mManager.remove(mName);}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void draw();
 | 
				
			||||||
 | 
					  void draw(QOpenGLShaderProgram & shader);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void flipTexture(const std::string & fileName,
 | 
				
			||||||
 | 
					                   bool flipX=false, bool flipY=true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <typename T>
 | 
				
			||||||
 | 
					  void setUniform(const char * location, T value)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    for (auto & mesh : mMeshes) {
 | 
				
			||||||
 | 
					      mesh.mProgram->bind();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mesh.mProgram->setUniformValue(location, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mesh.mProgram->release();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Transform3D mTransform;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static Model * getInstance(const char * name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef QHash<QString, Model *> ModelManager;
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  static ModelManager mManager;
 | 
				
			||||||
 | 
					  void loadModel(const std::string & path);
 | 
				
			||||||
 | 
					  void processNode(aiNode * node, const aiScene * scene);
 | 
				
			||||||
 | 
					  ModelMesh processMesh(aiMesh * mesh, const aiScene * scene);
 | 
				
			||||||
 | 
					  ModelMesh::Textures loadMaterialTextures(aiMaterial * mat, aiTextureType type,
 | 
				
			||||||
 | 
					                                           const std::string & typeName);
 | 
				
			||||||
 | 
					  void sortModels();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Model Private Members
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ModelMesh::Textures mTexturesLoaded;
 | 
				
			||||||
 | 
					  std::vector<ModelMesh> mMeshes;
 | 
				
			||||||
 | 
					  std::string mDirectory;
 | 
				
			||||||
 | 
					  const char * mVertexShader, * mFragmentShader, * mName;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // QTK_MODEL_H
 | 
				
			||||||
							
								
								
									
										9
									
								
								lib/object.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Object class for storing object data                                ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com  | URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <object.h>
 | 
				
			||||||
							
								
								
									
										62
									
								
								lib/object.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Object class for storing object data                                ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com  | URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					#ifndef QTK_OBJECT_H
 | 
				
			||||||
 | 
					#define QTK_OBJECT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QOpenGLBuffer>
 | 
				
			||||||
 | 
					#include <QOpenGLShaderProgram>
 | 
				
			||||||
 | 
					#include <QOpenGLTexture>
 | 
				
			||||||
 | 
					#include <QOpenGLVertexArrayObject>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <mainwidget.h>
 | 
				
			||||||
 | 
					#include <mesh.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Object : public QObject {
 | 
				
			||||||
 | 
					Q_OBJECT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  friend MeshRenderer;
 | 
				
			||||||
 | 
					  // Initialize an object with no shape data assigned
 | 
				
			||||||
 | 
					  Object(const char * name)
 | 
				
			||||||
 | 
					      : mName(name), mVBO(QOpenGLBuffer::VertexBuffer)
 | 
				
			||||||
 | 
					  { }
 | 
				
			||||||
 | 
					  // Initialize an object with shape data assigned
 | 
				
			||||||
 | 
					  Object(const char * name, const ShapeBase & shape)
 | 
				
			||||||
 | 
					      : mName(name), mVBO(QOpenGLBuffer::VertexBuffer), mShape(shape)
 | 
				
			||||||
 | 
					  { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ~Object() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  inline const Vertices & vertices() { return mShape.mVertices;}
 | 
				
			||||||
 | 
					  inline const Indices & indices() { return mShape.mIndices;}
 | 
				
			||||||
 | 
					  inline const Colors & colors() { return mShape.mColors;}
 | 
				
			||||||
 | 
					  inline const TexCoords & texCoords() { return mShape.mTexCoords;}
 | 
				
			||||||
 | 
					  inline const Normals & normals() { return mShape.mNormals;}
 | 
				
			||||||
 | 
					  inline QOpenGLTexture & texture() const { return *mTexture;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual inline void setVertices(const Vertices & value) { mShape.mVertices = value;}
 | 
				
			||||||
 | 
					  virtual inline void setIndices(const Indices & value) { mShape.mIndices = value;}
 | 
				
			||||||
 | 
					  virtual inline void setColors(const Colors & value) { mShape.mColors = value;}
 | 
				
			||||||
 | 
					  virtual inline void setTexCoords(const TexCoords & value) { mShape.mTexCoords = value;}
 | 
				
			||||||
 | 
					  virtual inline void setNormals(const Normals & value) { mShape.mNormals = value;}
 | 
				
			||||||
 | 
					  virtual inline void setShape(const Shape & value) { mShape = value;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  QOpenGLBuffer mVBO, mNBO;
 | 
				
			||||||
 | 
					  QOpenGLVertexArrayObject mVAO;
 | 
				
			||||||
 | 
					  QOpenGLShaderProgram mProgram;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Transform3D mTransform;
 | 
				
			||||||
 | 
					  Shape mShape;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const char * mName;
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  QOpenGLTexture * mTexture;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // QTK_OBJECT_H
 | 
				
			||||||
							
								
								
									
										100
									
								
								lib/skybox.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,100 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Skybox class using QtOpenGL                                         ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com  | URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <texture.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <skybox.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Skybox::Skybox(std::string right, std::string top, std::string front,
 | 
				
			||||||
 | 
					               std::string left, std::string bottom, std::string back,
 | 
				
			||||||
 | 
					               const std::string & name)
 | 
				
			||||||
 | 
					    : mCubeMap(Texture::initCubeMap(
 | 
				
			||||||
 | 
					    QImage(right.c_str()).mirrored(), QImage(top.c_str()),
 | 
				
			||||||
 | 
					    QImage(front.c_str()), QImage(left.c_str()),
 | 
				
			||||||
 | 
					    QImage(bottom.c_str()), QImage(back.c_str()))),
 | 
				
			||||||
 | 
					      mVBO(QOpenGLBuffer::VertexBuffer),
 | 
				
			||||||
 | 
					      mVertices(Cube(QTK_DRAW_ELEMENTS).vertices()),
 | 
				
			||||||
 | 
					      mIndices(Cube(QTK_DRAW_ELEMENTS).indices())
 | 
				
			||||||
 | 
					{ init();}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Skybox::Skybox(std::string name)
 | 
				
			||||||
 | 
					    : Skybox(":/right.png", ":/top.png", ":/front.png",
 | 
				
			||||||
 | 
					             ":/left.png", ":/bottom.png", ":/back.png",
 | 
				
			||||||
 | 
					             name)
 | 
				
			||||||
 | 
					{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Skybox::Skybox(QOpenGLTexture * cubeMap, const std::string & name)
 | 
				
			||||||
 | 
					    : mCubeMap(cubeMap) { init();}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Public Member Functions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Skybox::draw()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  glDepthFunc(GL_LEQUAL);
 | 
				
			||||||
 | 
					  glDepthMask(GL_FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mVAO.bind();
 | 
				
			||||||
 | 
					  mProgram.bind();
 | 
				
			||||||
 | 
					  mCubeMap->bind();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mProgram.setUniformValue("uProjectionMatrix", MainWidget::Projection());
 | 
				
			||||||
 | 
					  mProgram.setUniformValue("uViewMatrix", MainWidget::Camera().toMatrix());
 | 
				
			||||||
 | 
					  mProgram.setUniformValue("uTexture", 0);
 | 
				
			||||||
 | 
					  glDrawElements(GL_TRIANGLES, mIndices.size(),
 | 
				
			||||||
 | 
					                 GL_UNSIGNED_INT, mIndices.data());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mCubeMap->release();
 | 
				
			||||||
 | 
					  mProgram.release();
 | 
				
			||||||
 | 
					  mVAO.release();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  glDepthFunc(GL_LESS);
 | 
				
			||||||
 | 
					  glDepthMask(GL_TRUE);
 | 
				
			||||||
 | 
					  glActiveTexture(GL_TEXTURE0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Private Member Functions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Skybox::init()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  // Set up shader program
 | 
				
			||||||
 | 
					  mProgram.create();
 | 
				
			||||||
 | 
					  mProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/skybox.vert");
 | 
				
			||||||
 | 
					  mProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/skybox.frag");
 | 
				
			||||||
 | 
					  mProgram.link();
 | 
				
			||||||
 | 
					  mProgram.bind();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Setup VAO
 | 
				
			||||||
 | 
					  mVAO.create();
 | 
				
			||||||
 | 
					  mVAO.bind();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Setup VBO for vertex position data
 | 
				
			||||||
 | 
					  mVBO.create();
 | 
				
			||||||
 | 
					  mVBO.setUsagePattern(QOpenGLBuffer::StaticDraw);
 | 
				
			||||||
 | 
					  mVBO.bind();
 | 
				
			||||||
 | 
					  // Allocate vertex positions into VBO
 | 
				
			||||||
 | 
					  mVBO.allocate(mVertices.data(),
 | 
				
			||||||
 | 
					                mVertices.size() * sizeof(mVertices[0]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Enable attribute array for vertex positions
 | 
				
			||||||
 | 
					  mProgram.enableAttributeArray(0);
 | 
				
			||||||
 | 
					  mProgram.setAttributeBuffer(0, GL_FLOAT, 0,
 | 
				
			||||||
 | 
					                              3, sizeof(QVector3D));
 | 
				
			||||||
 | 
					  // Set shader texture unit to 0
 | 
				
			||||||
 | 
					  mProgram.setUniformValue("uTexture", 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mVAO.release();
 | 
				
			||||||
 | 
					  mVBO.release();
 | 
				
			||||||
 | 
					  mProgram.release();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										48
									
								
								lib/skybox.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Skybox class using QtOpenGL                                         ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com  | URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					#ifndef QTK_SKYBOX_H
 | 
				
			||||||
 | 
					#define QTK_SKYBOX_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QImage>
 | 
				
			||||||
 | 
					#include <QOpenGLBuffer>
 | 
				
			||||||
 | 
					#include <QOpenGLShaderProgram>
 | 
				
			||||||
 | 
					#include <QOpenGLTexture>
 | 
				
			||||||
 | 
					#include <QOpenGLVertexArrayObject>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <camera3d.h>
 | 
				
			||||||
 | 
					#include <mainwidget.h>
 | 
				
			||||||
 | 
					#include <mesh.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Skybox {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  // Delegate this constructor to use default skybox images
 | 
				
			||||||
 | 
					  // + This allows creating a skybox with no arguments ( auto s = new Skybox; )
 | 
				
			||||||
 | 
					  explicit Skybox(std::string name="Skybox");
 | 
				
			||||||
 | 
					  explicit Skybox(QOpenGLTexture * cubeMap, const std::string & name="Skybox");
 | 
				
			||||||
 | 
					  // Constructor, Destructor
 | 
				
			||||||
 | 
					  Skybox(std::string right, std::string top, std::string front,
 | 
				
			||||||
 | 
					         std::string left, std::string bottom, std::string back,
 | 
				
			||||||
 | 
					         const std::string & name="Skybox");
 | 
				
			||||||
 | 
					  ~Skybox() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void draw();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  void init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Vertices mVertices;
 | 
				
			||||||
 | 
					  Indices mIndices;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  QOpenGLShaderProgram mProgram;
 | 
				
			||||||
 | 
					  QOpenGLVertexArrayObject mVAO;
 | 
				
			||||||
 | 
					  QOpenGLBuffer mVBO;
 | 
				
			||||||
 | 
					  QOpenGLTexture * mCubeMap;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // QTK_SKYBOX_H
 | 
				
			||||||
							
								
								
									
										103
									
								
								lib/texture.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,103 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Texture class to help with texture and image initializations        ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com  | URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QImageReader>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <texture.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QImage * Texture::initImage(const char * image, bool flipX, bool flipY)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  auto loadedImage = new QImage(QImage(image).mirrored(flipX, flipY));
 | 
				
			||||||
 | 
					  if (loadedImage->isNull()) {
 | 
				
			||||||
 | 
					    qDebug() << "Error loading image: " << image << "\n";
 | 
				
			||||||
 | 
					    qDebug() << QImageReader::supportedImageFormats();
 | 
				
			||||||
 | 
					    return Q_NULLPTR;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return loadedImage;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QOpenGLTexture * Texture::initTexture2D(const char * texture,
 | 
				
			||||||
 | 
					                                        bool flipX, bool flipY)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  QImage * image = initImage(texture, flipX, flipY);
 | 
				
			||||||
 | 
					  auto newTexture = new QOpenGLTexture(QOpenGLTexture::Target2D);
 | 
				
			||||||
 | 
					  newTexture->setData(*image);
 | 
				
			||||||
 | 
					  newTexture->setWrapMode(QOpenGLTexture::Repeat);
 | 
				
			||||||
 | 
					  newTexture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear,
 | 
				
			||||||
 | 
					                               QOpenGLTexture::Linear);
 | 
				
			||||||
 | 
					  delete image;
 | 
				
			||||||
 | 
					  return newTexture;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QOpenGLTexture * Texture::initCubeMap(const char * tile)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return initCubeMap(QImage(tile), QImage(tile),
 | 
				
			||||||
 | 
					                     QImage(tile), QImage(tile),
 | 
				
			||||||
 | 
					                     QImage(tile), QImage(tile));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QOpenGLTexture * Texture::initCubeMap(
 | 
				
			||||||
 | 
					    const char * right, const char * top,
 | 
				
			||||||
 | 
					    const char * front, const char * left,
 | 
				
			||||||
 | 
					    const char * bottom, const char * back)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return initCubeMap(QImage(right), QImage(top),
 | 
				
			||||||
 | 
					                     QImage(front), QImage(left),
 | 
				
			||||||
 | 
					                     QImage(bottom), QImage(back));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QOpenGLTexture * Texture::initCubeMap(
 | 
				
			||||||
 | 
					    QImage right, QImage top,
 | 
				
			||||||
 | 
					    QImage front, QImage left,
 | 
				
			||||||
 | 
					    QImage bottom, QImage back)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  auto texture = new QOpenGLTexture(QOpenGLTexture::TargetCubeMap);
 | 
				
			||||||
 | 
					  std::vector<QImage> faceTextures = {
 | 
				
			||||||
 | 
					      right, top, front,
 | 
				
			||||||
 | 
					      left, bottom, back
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  // Initialize skybox cubemap texture
 | 
				
			||||||
 | 
					  texture->create();
 | 
				
			||||||
 | 
					  texture->bind();
 | 
				
			||||||
 | 
					  // For each cube map face
 | 
				
			||||||
 | 
					  std::vector<QOpenGLTexture::CubeMapFace> faces = {
 | 
				
			||||||
 | 
					      QOpenGLTexture::CubeMapPositiveX, QOpenGLTexture::CubeMapPositiveY,
 | 
				
			||||||
 | 
					      QOpenGLTexture::CubeMapPositiveZ, QOpenGLTexture::CubeMapNegativeX,
 | 
				
			||||||
 | 
					      QOpenGLTexture::CubeMapNegativeY, QOpenGLTexture::CubeMapNegativeZ
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  int i = 0;
 | 
				
			||||||
 | 
					  for (const auto & face : faces) {
 | 
				
			||||||
 | 
					    QImage faceImage(faceTextures[i]);
 | 
				
			||||||
 | 
					    if (faceImage.isNull()) {
 | 
				
			||||||
 | 
					      qDebug() << "Error loading cube map image\n";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    faceImage = faceImage.convertToFormat(QImage::Format_RGBA8888);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // On the first iteration, set format and allocate texture storage
 | 
				
			||||||
 | 
					    if (face == QOpenGLTexture::CubeMapPositiveX) {
 | 
				
			||||||
 | 
					      // This also needs to happen on the first iteration, anyways
 | 
				
			||||||
 | 
					      texture->setSize(faceImage.width(), faceImage.height(), faceImage.depth());
 | 
				
			||||||
 | 
					      texture->setFormat(QOpenGLTexture::RGBA8_UNorm);
 | 
				
			||||||
 | 
					      texture->allocateStorage();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    texture->setData(0, 0, face,
 | 
				
			||||||
 | 
					                     QOpenGLTexture::RGBA, QOpenGLTexture::UInt8,
 | 
				
			||||||
 | 
					                     faceImage.constBits());
 | 
				
			||||||
 | 
					    i++;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  texture->setWrapMode(QOpenGLTexture::ClampToEdge);
 | 
				
			||||||
 | 
					  texture->generateMipMaps();
 | 
				
			||||||
 | 
					  texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear);
 | 
				
			||||||
 | 
					  texture->setMagnificationFilter(QOpenGLTexture::Linear);
 | 
				
			||||||
 | 
					  texture->release();
 | 
				
			||||||
 | 
					  return texture;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										44
									
								
								lib/texture.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Texture class to help with texture and image initializations        ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com  | URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef QTOPENGL_TEXTURE_H
 | 
				
			||||||
 | 
					#define QTOPENGL_TEXTURE_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QOpenGLTexture>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <mainwidget.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Texture {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  ~Texture() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // QImage
 | 
				
			||||||
 | 
					  static QImage * initImage(const char * image,
 | 
				
			||||||
 | 
					                            bool flipX=false, bool flipY=false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 2D Texture
 | 
				
			||||||
 | 
					  static QOpenGLTexture * initTexture2D(const char * texture,
 | 
				
			||||||
 | 
					                                        bool flipX=false, bool flipY=false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Cube maps
 | 
				
			||||||
 | 
					  static QOpenGLTexture * initCubeMap(QImage right, QImage top,
 | 
				
			||||||
 | 
					                                      QImage front, QImage left,
 | 
				
			||||||
 | 
					                                      QImage bottom, QImage back);
 | 
				
			||||||
 | 
					  // Overloads for cube map initialization
 | 
				
			||||||
 | 
					  static QOpenGLTexture * initCubeMap(const char * tile);
 | 
				
			||||||
 | 
					  static QOpenGLTexture * initCubeMap(const char * right, const char * top,
 | 
				
			||||||
 | 
					                                      const char * front, const char * left,
 | 
				
			||||||
 | 
					                                      const char * bottom, const char * back);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  // Private ctor to prevent creating instances of this class
 | 
				
			||||||
 | 
					  Texture() {}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // QTOPENGL_TEXTURE_H
 | 
				
			||||||
							
								
								
									
										144
									
								
								lib/transform3D.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,144 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Transform3D class to represent object position in 3D space          ##
 | 
				
			||||||
 | 
					##        From following tutorials at trentreed.net                           ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com	| URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <transform3D.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const QVector3D Transform3D::LocalForward(0.0f, 0.0f, 1.0f);
 | 
				
			||||||
 | 
					const QVector3D Transform3D::LocalUp(0.0f, 1.0f, 0.0f);
 | 
				
			||||||
 | 
					const QVector3D Transform3D::LocalRight(1.0f, 0.0f, 0.0f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Transformations
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Transform3D::translate(const QVector3D & dt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  m_dirty = true;
 | 
				
			||||||
 | 
					  mTranslation += dt;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Transform3D::scale(const QVector3D & ds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  m_dirty = true;
 | 
				
			||||||
 | 
					  mScale *= ds;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Transform3D::rotate(const QQuaternion & dr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  m_dirty = true;
 | 
				
			||||||
 | 
					  mRotation = dr * mRotation;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Transform3D::grow(const QVector3D & ds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  m_dirty = true;
 | 
				
			||||||
 | 
					  mScale += ds;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Setters
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Transform3D::setTranslation(const QVector3D & t)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  m_dirty = true;
 | 
				
			||||||
 | 
					  mTranslation = t;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Transform3D::setScale(const QVector3D & s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  m_dirty = true;
 | 
				
			||||||
 | 
					  mScale = s;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Transform3D::setRotation(const QQuaternion & r)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  m_dirty = true;
 | 
				
			||||||
 | 
					  mRotation = r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Accessors
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Produces modelToWorld matrix using current set of transformations
 | 
				
			||||||
 | 
					// Transformation * rotation * scale = modelToWorld
 | 
				
			||||||
 | 
					const QMatrix4x4 & Transform3D::toMatrix()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (m_dirty)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    m_dirty = false;
 | 
				
			||||||
 | 
					    mWorld.setToIdentity();
 | 
				
			||||||
 | 
					    mWorld.translate(mTranslation);
 | 
				
			||||||
 | 
					    mWorld.rotate(mRotation);
 | 
				
			||||||
 | 
					    mWorld.scale(mScale);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return mWorld;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Queries
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QVector3D Transform3D::forward() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return mRotation.rotatedVector(LocalForward);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QVector3D Transform3D::up() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return mRotation.rotatedVector(LocalUp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QVector3D Transform3D::right() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return mRotation.rotatedVector(LocalRight);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * QT Streams
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QDebug operator<<(QDebug dbg, const Transform3D & transform)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  dbg << "Transform3D\n{\n";
 | 
				
			||||||
 | 
					  dbg << "Position: <" << transform.translation().x() << ", "
 | 
				
			||||||
 | 
					      << transform.translation().y() << ", "
 | 
				
			||||||
 | 
					      << transform.translation().z() << ">\n";
 | 
				
			||||||
 | 
					  dbg << "Scale: <" << transform.scale().x() << ", "
 | 
				
			||||||
 | 
					      << transform.scale().y() << ", "
 | 
				
			||||||
 | 
					      << transform.scale().z() << ">\n";
 | 
				
			||||||
 | 
					  dbg << "Rotation: <" << transform.rotation().x() << ", "
 | 
				
			||||||
 | 
					      << transform.rotation().y() << ", "
 | 
				
			||||||
 | 
					      << transform.rotation().z() << " | " <<
 | 
				
			||||||
 | 
					      transform.rotation().scalar() << ">\n}";
 | 
				
			||||||
 | 
					  return dbg;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QDataStream & operator<<(QDataStream & out, const Transform3D & transform)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  out << transform.mTranslation;
 | 
				
			||||||
 | 
					  out << transform.mScale;
 | 
				
			||||||
 | 
					  out << transform.mRotation;
 | 
				
			||||||
 | 
					  return out;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QDataStream & operator>>(QDataStream & in, Transform3D & transform)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  in >> transform.mTranslation;
 | 
				
			||||||
 | 
					  in >> transform.mScale;
 | 
				
			||||||
 | 
					  in >> transform.mRotation;
 | 
				
			||||||
 | 
					  transform.m_dirty = true;
 | 
				
			||||||
 | 
					  return in;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										117
									
								
								lib/transform3D.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,117 @@
 | 
				
			|||||||
 | 
					/*##############################################################################
 | 
				
			||||||
 | 
					## Author: Shaun Reed                                                         ##
 | 
				
			||||||
 | 
					## Legal: All Content (c) 2021 Shaun Reed, all rights reserved                ##
 | 
				
			||||||
 | 
					## About: Transform3D class to represent object position in 3D space          ##
 | 
				
			||||||
 | 
					##        From following tutorials at trentreed.net                           ##
 | 
				
			||||||
 | 
					##                                                                            ##
 | 
				
			||||||
 | 
					## Contact: shaunrd0@gmail.com	| URL: www.shaunreed.com | GitHub: shaunrd0   ##
 | 
				
			||||||
 | 
					##############################################################################*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef QTK_TRANSFORM3D_H
 | 
				
			||||||
 | 
					#define QTK_TRANSFORM3D_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QDebug>
 | 
				
			||||||
 | 
					#include <QMatrix4x4>
 | 
				
			||||||
 | 
					#include <QQuaternion>
 | 
				
			||||||
 | 
					#include <QVector3D>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Transform3D
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  // Constructors
 | 
				
			||||||
 | 
					  inline Transform3D() : m_dirty(true),
 | 
				
			||||||
 | 
					                         mScale(1.0f, 1.0f, 1.0f),
 | 
				
			||||||
 | 
					                         mTranslation(0.0f, 0.0f, 0.0f) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // Transformations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void translate(const QVector3D & dt);
 | 
				
			||||||
 | 
					  inline void translate(float dx, float dy, float dz)
 | 
				
			||||||
 | 
					  { translate(QVector3D(dx, dy, dz));}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Scale object with multiplication
 | 
				
			||||||
 | 
					  void scale(const QVector3D & ds);
 | 
				
			||||||
 | 
					  inline void scale(float dx, float dy, float dz)
 | 
				
			||||||
 | 
					  { scale(QVector3D(dx, dy, dz));}
 | 
				
			||||||
 | 
					  inline void scale(float factor)
 | 
				
			||||||
 | 
					  { scale(QVector3D(factor, factor, factor));}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Multiplying by a rotation
 | 
				
			||||||
 | 
					  void rotate(const QQuaternion & dr);
 | 
				
			||||||
 | 
					  inline void rotate(float angle, const QVector3D & axis)
 | 
				
			||||||
 | 
					  { rotate(QQuaternion::fromAxisAndAngle(axis, angle));}
 | 
				
			||||||
 | 
					  inline void rotate(float angle, float ax, float ay, float az)
 | 
				
			||||||
 | 
					  { rotate(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Scale object by addition
 | 
				
			||||||
 | 
					  void grow(const QVector3D & ds);
 | 
				
			||||||
 | 
					  inline void grow(float dx, float dy, float dz)
 | 
				
			||||||
 | 
					  { grow(QVector3D(dx, dy, dz));}
 | 
				
			||||||
 | 
					  inline void grow(float factor)
 | 
				
			||||||
 | 
					  { grow(QVector3D(factor, factor, factor));}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // Setters
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Set object position
 | 
				
			||||||
 | 
					  void setTranslation(const QVector3D & t);
 | 
				
			||||||
 | 
					  inline void setTranslation(float x, float y, float z)
 | 
				
			||||||
 | 
					  { setTranslation(QVector3D(x, y, z));}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Set object scale
 | 
				
			||||||
 | 
					  void setScale(const QVector3D & s);
 | 
				
			||||||
 | 
					  inline void setScale(float x, float y, float z)
 | 
				
			||||||
 | 
					  { setScale(QVector3D(x, y, z));}
 | 
				
			||||||
 | 
					  inline void setScale(float k)
 | 
				
			||||||
 | 
					  { setScale(QVector3D(k, k, k));}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Set object rotation
 | 
				
			||||||
 | 
					  void setRotation(const QQuaternion & r);
 | 
				
			||||||
 | 
					  inline void setRotation(float angle, const QVector3D & axis)
 | 
				
			||||||
 | 
					  { setRotation(QQuaternion::fromAxisAndAngle(axis, angle));}
 | 
				
			||||||
 | 
					  inline void setRotation(float angle, float ax, float ay, float az)
 | 
				
			||||||
 | 
					  { setRotation(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  // Accessors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  inline const QVector3D & translation() const { return mTranslation;}
 | 
				
			||||||
 | 
					  inline const QVector3D & scale() const { return mScale; }
 | 
				
			||||||
 | 
					  inline const QQuaternion & rotation() const { return mRotation; }
 | 
				
			||||||
 | 
					  const QMatrix4x4 & toMatrix();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  QVector3D forward() const;
 | 
				
			||||||
 | 
					  QVector3D up() const;
 | 
				
			||||||
 | 
					  QVector3D right() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static const QVector3D LocalForward, LocalUp, LocalRight;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  QVector3D mTranslation;
 | 
				
			||||||
 | 
					  QQuaternion mRotation;
 | 
				
			||||||
 | 
					  QVector3D mScale;
 | 
				
			||||||
 | 
					  QMatrix4x4 mWorld;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool m_dirty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef QT_NO_DATASTREAM
 | 
				
			||||||
 | 
					  friend QDataStream &operator<<(QDataStream & out, const Transform3D & transform);
 | 
				
			||||||
 | 
					  friend QDataStream &operator>>(QDataStream & in, Transform3D & transform);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Q_DECLARE_TYPEINFO(Transform3D, Q_MOVABLE_TYPE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Qt Streams
 | 
				
			||||||
 | 
					#ifndef QT_NO_DEBUG_STREAM
 | 
				
			||||||
 | 
					QDebug operator<<(QDebug dbg, const Transform3D & transform);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef QT_NO_DATASTREAM
 | 
				
			||||||
 | 
					QDataStream &operator<<(QDataStream & out, const Transform3D & transform);
 | 
				
			||||||
 | 
					QDataStream &operator>>(QDataStream & in, Transform3D & transform);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // QTK_TRANSFORM3D_H
 | 
				
			||||||
							
								
								
									
										4
									
								
								qtk_en_US.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<!DOCTYPE TS>
 | 
				
			||||||
 | 
					<TS version="2.1" language="en_US">
 | 
				
			||||||
 | 
					</TS>
 | 
				
			||||||
							
								
								
									
										81
									
								
								resources.qrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					<RCC>
 | 
				
			||||||
 | 
					    <qresource prefix="/">
 | 
				
			||||||
 | 
					        <!--3DModel test shader-->
 | 
				
			||||||
 | 
					        <file alias="model.frag">resources/shaders/fragment/model.frag</file>
 | 
				
			||||||
 | 
					        <file alias="model.vert">resources/shaders/vertex/model.vert</file>
 | 
				
			||||||
 | 
					        <!--Phong test shader-->
 | 
				
			||||||
 | 
					        <file alias="phong.frag">resources/shaders/fragment/phong.frag</file>
 | 
				
			||||||
 | 
					        <file alias="phong.vert">resources/shaders/vertex/phong.vert</file>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!--Simple Solid Shader-->
 | 
				
			||||||
 | 
					        <file alias="solid.frag">resources/shaders/fragment/solid.frag</file>
 | 
				
			||||||
 | 
					        <file alias="solid.vert">resources/shaders/vertex/solid.vert</file>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!--Solid Color Shader-->
 | 
				
			||||||
 | 
					        <file alias="solid-perspective.frag">resources/shaders/fragment/solid-perspective.frag</file>
 | 
				
			||||||
 | 
					        <file alias="solid-perspective.vert">resources/shaders/vertex/solid-perspective.vert</file>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!--Multi-color Shader-->
 | 
				
			||||||
 | 
					        <file alias="multi-color.frag">resources/shaders/fragment/multi-color.frag</file>
 | 
				
			||||||
 | 
					        <file alias="multi-color.vert">resources/shaders/vertex/multi-color.vert</file>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!--RGB Normals Shader-->
 | 
				
			||||||
 | 
					        <file alias="rgb-normals.frag">resources/shaders/fragment/rgb-normals.frag</file>
 | 
				
			||||||
 | 
					        <file alias="rgb-normals.vert">resources/shaders/vertex/rgb-normals.vert</file>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!--CubeMap Texture Shader-->
 | 
				
			||||||
 | 
					        <file alias="texture-cubemap.frag">resources/shaders/fragment/texture-cubemap.frag</file>
 | 
				
			||||||
 | 
					        <file alias="texture-cubemap.vert">resources/shaders/vertex/texture-cubemap.vert</file>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!--2D Texture Shader-->
 | 
				
			||||||
 | 
					        <file alias="texture2d.frag">resources/shaders/fragment/texture2d.frag</file>
 | 
				
			||||||
 | 
					        <file alias="texture2d.vert">resources/shaders/vertex/texture2d.vert</file>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!--Ambient Shader-->
 | 
				
			||||||
 | 
					        <file alias="solid-ambient.frag">resources/shaders/fragment/solid-ambient.frag</file>
 | 
				
			||||||
 | 
					        <file alias="solid-ambient.vert">resources/shaders/vertex/solid-ambient.vert</file>
 | 
				
			||||||
 | 
					        <!--Diffuse Shader-->
 | 
				
			||||||
 | 
					        <file alias="solid-diffuse.frag">resources/shaders/fragment/solid-diffuse.frag</file>
 | 
				
			||||||
 | 
					        <file alias="solid-diffuse.vert">resources/shaders/vertex/solid-diffuse.vert</file>
 | 
				
			||||||
 | 
					        <!--Specular Shader-->
 | 
				
			||||||
 | 
					        <file alias="solid-specular.frag">resources/shaders/fragment/solid-specular.frag</file>
 | 
				
			||||||
 | 
					        <file alias="solid-specular.vert">resources/shaders/vertex/solid-specular.vert</file>
 | 
				
			||||||
 | 
					        <!--Basic Phong Shader-->
 | 
				
			||||||
 | 
					        <file alias="solid-phong.frag">resources/shaders/fragment/solid-phong.frag</file>
 | 
				
			||||||
 | 
					        <file alias="solid-phong.vert">resources/shaders/vertex/solid-phong.vert</file>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!--3DModel Basic Shader-->
 | 
				
			||||||
 | 
					        <file alias="model-basic.frag">resources/shaders/fragment/model-basic.frag</file>
 | 
				
			||||||
 | 
					        <file alias="model-basic.vert">resources/shaders/vertex/model-basic.vert</file>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!--3DModel shader with specular mapping-->
 | 
				
			||||||
 | 
					        <file alias="model-specular.frag">resources/shaders/fragment/model-specular.frag</file>
 | 
				
			||||||
 | 
					        <file alias="model-specular.vert">resources/shaders/vertex/model-specular.vert</file>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!--3DModel shader with normal mapping-->
 | 
				
			||||||
 | 
					        <file alias="model-normals.frag">resources/shaders/fragment/model-normals.frag</file>
 | 
				
			||||||
 | 
					        <file alias="model-normals.vert">resources/shaders/vertex/model-normals.vert</file>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!-- Skybox Shaders-->
 | 
				
			||||||
 | 
					        <file alias="skybox.frag">resources/skybox/skybox.frag</file>
 | 
				
			||||||
 | 
					        <file alias="skybox.vert">resources/skybox/skybox.vert</file>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!--Texture Images-->
 | 
				
			||||||
 | 
					        <file alias="crate.png">resources/images/crate.png</file>
 | 
				
			||||||
 | 
					        <file alias="stone.png">resources/images/stone.png</file>
 | 
				
			||||||
 | 
					        <file alias="wood.png">resources/images/wood.png</file>
 | 
				
			||||||
 | 
					        <!-- Skybox Images-->
 | 
				
			||||||
 | 
					        <file alias="back.png">resources/skybox/back.png</file>
 | 
				
			||||||
 | 
					        <file alias="bottom.png">resources/skybox/bottom.png</file>
 | 
				
			||||||
 | 
					        <file alias="front.png">resources/skybox/front.png</file>
 | 
				
			||||||
 | 
					        <file alias="left.png">resources/skybox/left.png</file>
 | 
				
			||||||
 | 
					        <file alias="right.png">resources/skybox/right.png</file>
 | 
				
			||||||
 | 
					        <file alias="top.png">resources/skybox/top.png</file>
 | 
				
			||||||
 | 
					    </qresource>
 | 
				
			||||||
 | 
					</RCC>
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								resources/images/crate.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 91 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/images/stone.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.5 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/images/wood.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 76 KiB  | 
							
								
								
									
										55
									
								
								resources/models/alien-hominid/alien.mtl
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					# Blender MTL File: 'None'
 | 
				
			||||||
 | 
					# Material Count: 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					newmtl AlienHominid
 | 
				
			||||||
 | 
					Ns 225.000000
 | 
				
			||||||
 | 
					Ka 1.000000 1.000000 1.000000
 | 
				
			||||||
 | 
					Kd 0.800000 0.533344 0.000000
 | 
				
			||||||
 | 
					Ks 0.500000 0.500000 0.500000
 | 
				
			||||||
 | 
					Ke 0.000000 0.000000 0.000000
 | 
				
			||||||
 | 
					Ni 1.450000
 | 
				
			||||||
 | 
					d 1.000000
 | 
				
			||||||
 | 
					illum 2
 | 
				
			||||||
 | 
					map_Bump normal.png
 | 
				
			||||||
 | 
					map_Kd diffuse.png
 | 
				
			||||||
 | 
					map_Ns roughness.png
 | 
				
			||||||
 | 
					refl specular.png
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					newmtl Blaster
 | 
				
			||||||
 | 
					Ns 225.000000
 | 
				
			||||||
 | 
					Ka 1.000000 1.000000 1.000000
 | 
				
			||||||
 | 
					Kd 0.800000 0.800000 0.800000
 | 
				
			||||||
 | 
					Ks 0.500000 0.500000 0.500000
 | 
				
			||||||
 | 
					Ke 0.000000 0.000000 0.000000
 | 
				
			||||||
 | 
					Ni 1.450000
 | 
				
			||||||
 | 
					d 1.000000
 | 
				
			||||||
 | 
					illum 2
 | 
				
			||||||
 | 
					map_Bump blaster_normal.png
 | 
				
			||||||
 | 
					map_Kd blaster_diffuse.png
 | 
				
			||||||
 | 
					map_Ke blaster_emissive.png
 | 
				
			||||||
 | 
					map_Ns blaster_roughness.png
 | 
				
			||||||
 | 
					refl blaster_specular.png
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					newmtl Screenshot_2021-04-19_194508
 | 
				
			||||||
 | 
					Ns 225.000000
 | 
				
			||||||
 | 
					Ka 1.000000 1.000000 1.000000
 | 
				
			||||||
 | 
					Kd 0.800000 0.800000 0.800000
 | 
				
			||||||
 | 
					Ks 0.500000 0.500000 0.500000
 | 
				
			||||||
 | 
					Ke 0.000000 0.000000 0.000000
 | 
				
			||||||
 | 
					Ni 1.450000
 | 
				
			||||||
 | 
					d 1.000000
 | 
				
			||||||
 | 
					illum 2
 | 
				
			||||||
 | 
					map_Kd smoke.png
 | 
				
			||||||
 | 
					map_d smoke.png
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					newmtl Untitled-1
 | 
				
			||||||
 | 
					Ns 77.904748
 | 
				
			||||||
 | 
					Ka 1.000000 1.000000 1.000000
 | 
				
			||||||
 | 
					Kd 0.800000 0.800000 0.800000
 | 
				
			||||||
 | 
					Ks 0.500000 0.500000 0.500000
 | 
				
			||||||
 | 
					Ke 0.000000 0.000000 0.000000
 | 
				
			||||||
 | 
					Ni 1.450000
 | 
				
			||||||
 | 
					d 1.000000
 | 
				
			||||||
 | 
					illum 2
 | 
				
			||||||
 | 
					map_Kd Untitled-1.png
 | 
				
			||||||
 | 
					map_d Untitled-1.png
 | 
				
			||||||
							
								
								
									
										116822
									
								
								resources/models/alien-hominid/alien.obj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								resources/models/alien-hominid/blaster_diffuse.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 14 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/alien-hominid/blaster_emissive.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 455 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/alien-hominid/blaster_normal.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 9.4 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/alien-hominid/blaster_roughness.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.2 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/alien-hominid/blaster_specular.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.8 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/alien-hominid/diffuse.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.8 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/alien-hominid/normal.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 10 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/alien-hominid/roughness.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.0 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/alien-hominid/specular.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 26 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/backpack/ao.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.8 MiB  | 
							
								
								
									
										16
									
								
								resources/models/backpack/backpack.mtl
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					# Blender MTL File: 'None'
 | 
				
			||||||
 | 
					# Material Count: 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					newmtl Scene_-_Root
 | 
				
			||||||
 | 
					Ns 225.000000
 | 
				
			||||||
 | 
					Ka 1.000000 1.000000 1.000000
 | 
				
			||||||
 | 
					Kd 0.800000 0.800000 0.800000
 | 
				
			||||||
 | 
					Ks 0.500000 0.500000 0.500000
 | 
				
			||||||
 | 
					Ke 0.0 0.0 0.0
 | 
				
			||||||
 | 
					Ni 1.450000
 | 
				
			||||||
 | 
					d 1.000000
 | 
				
			||||||
 | 
					illum 2
 | 
				
			||||||
 | 
					map_Kd diffuse.jpg
 | 
				
			||||||
 | 
					map_Bump normal.png
 | 
				
			||||||
 | 
					map_Ks specular.jpg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										199481
									
								
								resources/models/backpack/backpack.obj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								resources/models/backpack/diffuse.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.8 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/backpack/normal.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 14 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/backpack/roughness.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.2 MiB  | 
							
								
								
									
										3
									
								
								resources/models/backpack/source_attribution.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					Model by Berk Gedik, from: https://sketchfab.com/3d-models/survival-guitar-backpack-low-poly-799f8c4511f84fab8c3f12887f7e6b36
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Modified material assignment (Joey de Vries) for easier load in OpenGL model loading chapter, and renamed albedo to diffuse and metallic to specular to match non-PBR lighting setup.
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								resources/models/backpack/specular.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 6.4 MiB  | 
							
								
								
									
										7
									
								
								resources/models/bird/bird.mtl
									
									
									
									
									
										Executable file
									
								
							
							
						
						@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					newmtl material_0
 | 
				
			||||||
 | 
					map_bump normal.jpg
 | 
				
			||||||
 | 
					norm normal.jpg
 | 
				
			||||||
 | 
					map_Kd diffuse.jpg
 | 
				
			||||||
 | 
					occlusion occlusion.jpg
 | 
				
			||||||
 | 
					Pm 0
 | 
				
			||||||
 | 
					Pr 0.793152
 | 
				
			||||||
							
								
								
									
										80009
									
								
								resources/models/bird/bird.obj
									
									
									
									
									
										Executable file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								resources/models/bird/diffuse.jpg
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 11 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/bird/normal.jpg
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.3 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/bird/occlusion.jpg
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.7 MiB  | 
							
								
								
									
										12
									
								
								resources/models/floor.obj
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					# Blender v2.82 (sub 7) OBJ File: ''
 | 
				
			||||||
 | 
					# www.blender.org
 | 
				
			||||||
 | 
					mtllib floor.mtl
 | 
				
			||||||
 | 
					o floor
 | 
				
			||||||
 | 
					v -1.000000 -0.000000 1.000000
 | 
				
			||||||
 | 
					v 1.000000 -0.000000 1.000000
 | 
				
			||||||
 | 
					v 1.000000 0.000000 -1.000000
 | 
				
			||||||
 | 
					v -1.000000 0.000000 -1.000000
 | 
				
			||||||
 | 
					vn 0.0000 1.0000 0.0000
 | 
				
			||||||
 | 
					usemtl Default_OBJ
 | 
				
			||||||
 | 
					s off
 | 
				
			||||||
 | 
					f 1//1 2//1 3//1 4//1
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								resources/models/lion/diffuse.jpg
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.1 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/lion/height.jpg
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 254 KiB  | 
							
								
								
									
										16
									
								
								resources/models/lion/lion.mtl
									
									
									
									
									
										Executable file
									
								
							
							
						
						@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					# Blender MTL File: 'None'
 | 
				
			||||||
 | 
					# Material Count: 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					newmtl Lion
 | 
				
			||||||
 | 
					Ns 500.000001
 | 
				
			||||||
 | 
					Ka 1.000000 1.000000 1.000000
 | 
				
			||||||
 | 
					Kd 0.800000 0.800000 0.800000
 | 
				
			||||||
 | 
					Ks 0.800000 0.800000 0.800000
 | 
				
			||||||
 | 
					Ke 0.000000 0.000000 0.000000
 | 
				
			||||||
 | 
					Ni 1.450000
 | 
				
			||||||
 | 
					d 1.000000
 | 
				
			||||||
 | 
					illum 2
 | 
				
			||||||
 | 
					map_Bump normal.jpg
 | 
				
			||||||
 | 
					map_Kd diffuse.jpg
 | 
				
			||||||
 | 
					map_Ns roughness.jpg
 | 
				
			||||||
 | 
					refl specular.jpg
 | 
				
			||||||
							
								
								
									
										86063
									
								
								resources/models/lion/lion.obj
									
									
									
									
									
										Executable file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								resources/models/lion/normal.jpg
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 484 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/lion/roughness.jpg
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 562 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/lion/specular.jpg
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 134 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/scythe/diffuse.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 133 KiB  | 
							
								
								
									
										8
									
								
								resources/models/scythe/scythe.mtl
									
									
									
									
									
										Executable file
									
								
							
							
						
						@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					# WaveFront *.mtl file (generated by CINEMA 4D)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					newmtl item/objectcomponents/weapon/staff_2h_artifactdeadwind_d_03.m2_Geoset_000
 | 
				
			||||||
 | 
					Ka 0.25 0.25 0.25
 | 
				
			||||||
 | 
					Kd 1 1 1
 | 
				
			||||||
 | 
					map_Kd diffuse.png
 | 
				
			||||||
 | 
					illum 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										5915
									
								
								resources/models/scythe/scythe.obj
									
									
									
									
									
										Executable file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Arms_Mat_AO.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.4 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Arms_Mat_BaseColor.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.0 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Arms_Mat_Metallic.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 807 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Arms_Mat_Normal.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.9 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Arms_Mat_Roughness.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.5 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Arms_Mat_Specular.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 614 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Chest_Mat_AO.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.7 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Chest_Mat_BaseColor.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.8 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Chest_Mat_Metallic.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.3 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Chest_Mat_Normal.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.5 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Chest_Mat_Roughness.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.2 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Chest_Mat_Specular.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 885 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Ears_Mat_AO.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 96 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Ears_Mat_BaseColor.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.1 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Ears_Mat_Metallic.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 426 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Ears_Mat_Normal.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 983 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Ears_Mat_Roughness.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 484 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Ears_Mat_Specular.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 279 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Helmet_Mat_AO.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 930 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Helmet_Mat_BaseColor.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.9 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Helmet_Mat_Metallic.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.3 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Helmet_Mat_Normal.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.4 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Helmet_Mat_Roughness.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.7 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Helmet_Mat_Specular.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 862 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Legs_Mat_AO.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.4 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Legs_Mat_BaseColor.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.0 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Legs_Mat_Metallic.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1008 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Legs_Mat_Normal.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.8 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Legs_Mat_Roughness.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.8 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Legs_Mat_Specular.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 638 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Shoulder_Mat_AO.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 844 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Shoulder_Mat_BaseColor.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.4 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Shoulder_Mat_Metallic.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.1 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Shoulder_Mat_Normal.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.8 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Shoulder_Mat_Roughness.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.7 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/models/spartan/Spartan_Shoulder_Mat_Specular.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 761 KiB  |