diff --git a/README.md b/README.md index f22c764..6a22e6a 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,17 @@ ------------------------------------------------------------------------------- -CIS565: Project 6: Deferred Shader +Deferred Shader ------------------------------------------------------------------------------- Fall 2013 ------------------------------------------------------------------------------- -Due Friday 11/15/2013 -------------------------------------------------------------------------------- +![fullscene](/renders/FullHallAllTextures.PNG "Finished Rendering") + +Youtube Video of Rendering: +
+ +
-------------------------------------------------------------------------------- NOTE: ------------------------------------------------------------------------------- This project requires any graphics card with support for a modern OpenGL @@ -17,7 +22,10 @@ this project. ------------------------------------------------------------------------------- INTRODUCTION: ------------------------------------------------------------------------------- -In this project, you will get introduced to the basics of deferred shading. You will write GLSL and OpenGL code to perform various tasks in a deferred lighting pipeline such as creating and writing to a G-Buffer. +This project implements a three stage deffered shader pipeline. +Stage 1 renders geometry and samples model textures. +Stage 2 performs point and ambient lighting calculations +Stage 3 does any post processing effects ------------------------------------------------------------------------------- CONTENTS: @@ -31,29 +39,11 @@ The Project6 root directory contains the following subdirectories: * src/ contains the c++ code for the project along with SOIL and tiny_obj_loader * shared32/ contains freeglut, glm, and glew. ---- -BASE CODE TOUR ---- - -Most of your edits will be confined to the various fragment shader programs and main.cpp. - -Some methods worth exploring are: - -[initShader](https://github.com/CIS565-Fall-2013/Project6-DeferredShader/blob/master/base/src/main.cpp#L223): -This method initializes each shader program from specified source files. Note that the source name is declared inside a `#ifdef WIN32` guard block. This is done to reflect the relative directory structure between the linux and windows versions of the code. - -[initFBO](https://github.com/CIS565-Fall-2013/Project6-DeferredShader/blob/master/base/src/main.cpp#L360): -This method initializes the framebuffer objects used as render targets for the first and second stage of the pipeline. When you go to add another slot to the G buffer you will need to modify to first FBO accordingly. Try finding all the places where `colorTexture` is used (ctrl+F in windows will be helpful) and look at how textures are created, freed, added to the FBO, and assigned to the appropriate shader programs before adding your own. Also keep in mind that textures can be reused as inputs in other pipeline stages, for instance you might want access to the normals both in the lighting stage and in the post process stage. - -[draw_mesh](https://github.com/CIS565-Fall-2013/Project6-DeferredShader/blob/master/base/src/main.cpp#L574), -[draw_quad](https://github.com/CIS565-Fall-2013/Project6-DeferredShader/blob/master/base/src/main.cpp#L647), -[draw_light](https://github.com/CIS565-Fall-2013/Project6-DeferredShader/blob/master/base/src/main.cpp#L657): -These methods render the scene geometry, viewing quad, and point light quad to the screen. The draw_light method in particular is interesting because it will set up the scissor window for efficient rendering of point lights. - -[display](https://github.com/CIS565-Fall-2013/Project6-DeferredShader/blob/master/base/src/main.cpp#L742): -This is where the graphical work of your program is done. The method is separated into three stages with the majority of work being done in stage 2. +------------------------------------------------------------------------------- +CODE TOUR/CONTROLS +------------------------------------------------------------------------------- -Stage 1 renders the scene geometry to the G-Buffer +Stage 1 samples model textures renders the scene geometry to the G-Buffer * pass.vert * pass.frag @@ -67,7 +57,8 @@ Stage 3 renders the post processing * post.vert * post.frag -[keyboard](https://github.com/CIS565-Fall-2013/Project6-DeferredShader/blob/master/base/src/main.cpp#L870): +Keyboard controls +[keyboard](https://github.com/cboots/Deferred-Shading/blob/master/base/src/main.cpp#L1178): This is a good reference for the key mappings in the program. WASDQZ - Movement X - Toggle scissor test @@ -77,114 +68,102 @@ R - Reload shaders 3 - View Diffuse color 4 - View eye space positions 5 - View lighting debug mode +6 - View Specular Mapping +7 - View Only Bloomed Geometry 0 - Standard view +x - Toggle Scissor Test +r - Reload Shaders +p - Print camera position to console +j - Toggle timing measurements to console (averaged since last reset) +SPACE - Reset timing averages + +Shift-L - Toggle Bloom +Shift-T - Toggle Toon Shading +Shift-D - Toggle Diffuse Mapping +Shift-S - Toggle Specular Mapping +Shift-B - Toggle Bump Mapping +Shift-M - Toggle Transparency Masking + +c - Reset diffuse color to default +t - Change diffuse color to texture coordinate visualization +h - Overlay diffuse color with visualization of available textures +b - Change diffuse color to bump map visualization if available +m - Change diffuse color to white if mask texture is available + ------------------------------------------------------------------------------- -REQUIREMENTS: +Features: ------------------------------------------------------------------------------- -In this project, you are given code for: -* Loading .obj files -* Rendering to a minimal G buffer: - * Depth - * Normal - * Color - * Eye space position -* Rendering simple ambient and directional lighting to texture -* Example post process shader to add a vignette +* Renders .obj files with support for .mtl files with + * Diffuse Textures + * Specular Textures + * Height Maps (Bump Mapping) + * Texture Masking + +* Bloom (Not seperable, very inefficient) +![NoBloom](/renders/LampNoBloom.PNG "Without Bloom") +![Bloom](/renders/LampWithBloom.PNG "With Bloom") -You are required to implement: -* Either of the following effects - * Bloom (feel free to use [GPU Gems](http://http.developer.nvidia.com/GPUGems/gpugems_ch21.html) as a rough guide) - * "Toon" Shading (with basic silhouetting) -* Point light sources -* An additional G buffer slot and some effect showing it off +* "Toon" Shading (with basic silhouetting and color quantization) +![Toon](/renders/ToonShadingNoColor.PNG "Toon Shading B/W") +![Toon](/renders/FullHallToon.PNG "Toon Shading") -**NOTE**: Implementing separable convolution will require another link in your pipeline and will count as an extra feature if you do performance analysis with a standard one-pass 2D convolution. The overhead of rendering and reading from a texture _may_ offset the extra computations for smaller 2D kernels. - -You must implement two of the following extras: -* The effect you did not choose above -* Screen space ambient occlusion -* Compare performance to a normal forward renderer with - * No optimizations - * Coarse sort geometry front-to-back for early-z - * Z-prepass for early-z -* Optimize g-buffer format, e.g., pack things together, quantize, reconstruct z from normal x and y (because it is normalized), etc. - * Must be accompanied with a performance analysis to count -* Additional lighting and pre/post processing effects! (email first please, if they are good you may add multiple). +* Point light sources with specular +![Point Specular](/renders/PointLightSpeculars.PNG "Point Light Speculars") ------------------------------------------------------------------------------- -README +SCREENSHOTS ------------------------------------------------------------------------------- -All students must replace or augment the contents of this Readme.md in a clear -manner with the following: -* A brief description of the project and the specific features you implemented. -* At least one screenshot of your project running. -* A 30 second or longer video of your project running. To create the video you - can use http://www.microsoft.com/expression/products/Encoder4_Overview.aspx -* A performance evaluation (described in detail below). +No special features enabled. Just Point lighting: +![Baseline](/renders/FullHallBaseline.PNG "Baseline") -------------------------------------------------------------------------------- -PERFORMANCE EVALUATION -------------------------------------------------------------------------------- -The performance evaluation is where you will investigate how to make your -program more efficient using the skills you've learned in class. You must have -performed at least one experiment on your code to investigate the positive or -negative effects on performance. +Diffuse Texture: +![Diffuse Map](/renders/FullHallDiffuseOnly.PNG "Diffuse Texture") -We encourage you to get creative with your tweaks. Consider places in your code -that could be considered bottlenecks and try to improve them. +Specular Texture: +![Specular Map](/renders/FullHallSpecularOnly.PNG "Specular Texture") -Each student should provide no more than a one page summary of their -optimizations along with tables and or graphs to visually explain any -performance differences. +Bump Mapping: +![Bump Map](/renders/FullHallBumpOnly.PNG "Bump Texture") +![Bump Map](/renders/LionCloseNoBump.PNG "Without Bump") +![Bump Map](/renders/LionClose.PNG "With Bump") -------------------------------------------------------------------------------- -THIRD PARTY CODE POLICY -------------------------------------------------------------------------------- -* Use of any third-party code must be approved by asking on the Google groups. - If it is approved, all students are welcome to use it. Generally, we approve - use of third-party code that is not a core part of the project. For example, - for the ray tracer, we would approve using a third-party library for loading - models, but would not approve copying and pasting a CUDA function for doing - refraction. -* Third-party code must be credited in README.md. -* Using third-party code without its approval, including using another - student's code, is an academic integrity violation, and will result in you - receiving an F for the semester. +Masking: +![Mask](/renders/FullHallMaskOnly.PNG "Mask Texture") +![No Mask](/renders/PlantsNoMask.PNG "No Mask") +![With Mask](/renders/PlantsWithMask.PNG "With Mask") + + +All Textures: +![All Textures Map](/renders/FullHallAllTextures.PNG "Specular Texture") + +Scissor Test Specular Bug: +![ScissorNo](/renders/SpecularNoScissorTest.PNG "No Scissor Test") +![Scissor](/renders/SpecularWithScissorTest.PNG "With Scissor Test") ------------------------------------------------------------------------------- -SELF-GRADING +PERFORMANCE EVALUATION ------------------------------------------------------------------------------- -* On the submission date, email your grade, on a scale of 0 to 100, to Liam, - liamboone@gmail.com, with a one paragraph explanation. Be concise and - realistic. Recall that we reserve 30 points as a sanity check to adjust your - grade. Your actual grade will be (0.7 * your grade) + (0.3 * our grade). We - hope to only use this in extreme cases when your grade does not realistically - reflect your work - it is either too high or too low. In most cases, we plan - to give you the exact grade you suggest. -* Projects are not weighted evenly, e.g., Project 0 doesn't count as much as - the path tracer. We will determine the weighting at the end of the semester - based on the size of each project. +I measured the synchronized time to complete each stage of the pipeline with various features enabled. +Two test scenes were used, a wide shot of the entire hall and a closeup of the lion sculpture (see above). +Bloom was so inefficient that I removed it from some charts for scale +Full Hall Metrics: ---- -SUBMISSION ---- -As with the previous projects, you should fork this project and work inside of -your fork. Upon completion, commit your finished project back to your fork, and -make a pull request to the master repository. You should include a README.md -file in the root directory detailing the following - -* A brief description of the project and specific features you implemented -* At least one screenshot of your project running. -* A link to a video of your project running. -* Instructions for building and running your project if they differ from the - base code. -* A performance writeup as detailed above. -* A list of all third-party code used. -* This Readme file edited as described above in the README section. +![TimingFH](/renders/FullHallTiming.PNG "Full Hall") +![TimingFHB](/renders/FullHallTimingBloom.PNG "Full Hall Including Bloom") + +Lion Closeup Metrics: + +![TimingLC](/renders/LionCloseupTiming.PNG "Lion Closeup") +![TimingLCB](/renders/LionCloseupTimingBloom.PNG "Lion Closeup Including Bloom") + +Clearly the non-seperated convolution involved in the bloom effect has a huge impact on performance. +Most of the other effects had only minimal impact on performance. +The scissor test gave a huge boost to stage 2 performance but as shown above it results in visual artifacts. +Another takeaway of this data is the second stage (lighting calculation) is the most intensive part of the process. --- ACKNOWLEDGEMENTS diff --git a/base/PROJ_WIN/P6/P6/P6.vcxproj b/base/PROJ_WIN/P6/P6/P6.vcxproj index 61a6915..3500f75 100644 --- a/base/PROJ_WIN/P6/P6/P6.vcxproj +++ b/base/PROJ_WIN/P6/P6/P6.vcxproj @@ -19,12 +19,14 @@ Application true Unicode + v110 Application false true Unicode + v110 @@ -60,14 +62,14 @@ MaxSpeed true true - ..\..\..\src\SOIL;..\..\..\src\tiny_obj_loader;..\..\..\..\shared32\freeglut\include;..\..\..\..\shared32\glew\include;..\..\..\..\shared32\glm;%(AdditionalIncludeDirectories) + ..\SOIL;..\..\..\src\tiny_obj_loader;..\..\..\..\shared32\freeglut\include;..\..\..\..\shared32\glew\include;..\..\..\..\shared32\glm;%(AdditionalIncludeDirectories) true true true $(SolutionDir)$(Configuration);..\..\..\..\shared32\glew\lib;..\..\..\..\shared32\freeglut\lib;%(AdditionalLibraryDirectories) - freeglut.lib;glew32.lib;%(AdditionalDependencies) + SOIL.lib;freeglut.lib;glew32.lib;%(AdditionalDependencies) Console diff --git a/base/PROJ_WIN/P6/P6/P6.vcxproj.collin boots.nvuser b/base/PROJ_WIN/P6/P6/P6.vcxproj.collin boots.nvuser new file mode 100644 index 0000000..120bd4a --- /dev/null +++ b/base/PROJ_WIN/P6/P6/P6.vcxproj.collin boots.nvuser @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/base/PROJ_WIN/P6/P6/P6.vcxproj.collin.nvuser b/base/PROJ_WIN/P6/P6/P6.vcxproj.collin.nvuser new file mode 100644 index 0000000..f262169 --- /dev/null +++ b/base/PROJ_WIN/P6/P6/P6.vcxproj.collin.nvuser @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/base/PROJ_WIN/P6/P6/freeglut.dll b/base/PROJ_WIN/P6/P6/freeglut.dll new file mode 100644 index 0000000..4ec8893 Binary files /dev/null and b/base/PROJ_WIN/P6/P6/freeglut.dll differ diff --git a/base/PROJ_WIN/P6/P6/glew32.dll b/base/PROJ_WIN/P6/P6/glew32.dll new file mode 100644 index 0000000..999a59b Binary files /dev/null and b/base/PROJ_WIN/P6/P6/glew32.dll differ diff --git a/base/PROJ_WIN/P6/SOIL/SOIL.vcxproj b/base/PROJ_WIN/P6/SOIL/SOIL.vcxproj index f341f68..2cff1d2 100644 --- a/base/PROJ_WIN/P6/SOIL/SOIL.vcxproj +++ b/base/PROJ_WIN/P6/SOIL/SOIL.vcxproj @@ -20,10 +20,12 @@ StaticLibrary Unicode true + v110 StaticLibrary Unicode + v110 diff --git a/base/res/crytek-sponza/sponza.mtl b/base/res/crytek-sponza/sponza.mtl index 168ec79..e0d1796 100644 --- a/base/res/crytek-sponza/sponza.mtl +++ b/base/res/crytek-sponza/sponza.mtl @@ -10,11 +10,12 @@ newmtl leaf illum 2 Ka 0.5880 0.5880 0.5880 Kd 0.5880 0.5880 0.5880 - Ks 0.0000 0.0000 0.0000 + Ks 0.5880 0.5880 0.5880 Ke 0.0000 0.0000 0.0000 map_Ka textures\sponza_thorn_diff.tga map_Kd textures\sponza_thorn_diff.tga - map_d textures\sponza_thorn_mask.tga + map_Ks textures\sponza_thorn_spec.tga + map_d textures\sponza_thorn_mask.png map_bump textures\sponza_thorn_bump.png bump textures\sponza_thorn_bump.png @@ -27,10 +28,11 @@ newmtl vase_round illum 2 Ka 0.5880 0.5880 0.5880 Kd 0.5880 0.5880 0.5880 - Ks 0.0000 0.0000 0.0000 + Ks 0.5880 0.5880 0.5880 Ke 0.0000 0.0000 0.0000 map_Ka textures\vase_round.tga map_Kd textures\vase_round.tga + map_Ks textures\vase_round_spec.tga map_bump textures\vase_round_bump.png bump textures\vase_round_bump.png @@ -43,11 +45,12 @@ newmtl Material__57 illum 2 Ka 0.5880 0.5880 0.5880 Kd 0.5880 0.5880 0.5880 - Ks 0.0000 0.0000 0.0000 + Ks 0.5880 0.5880 0.5880 Ke 0.0000 0.0000 0.0000 map_Ka textures\vase_plant.tga map_Kd textures\vase_plant.tga - map_d textures\vase_plant_mask.tga + map_Ks textures\vase_plant_spec.tga + map_d textures\vase_plant_mask.png newmtl Material__298 Ns 10.0000 @@ -88,11 +91,12 @@ newmtl bricks illum 2 Ka 0.5880 0.5880 0.5880 Kd 0.5880 0.5880 0.5880 - Ks 0.0000 0.0000 0.0000 + Ks 0.5880 0.5880 0.5880 Ke 0.0000 0.0000 0.0000 map_Ka textures\spnza_bricks_a_diff.tga map_Kd textures\spnza_bricks_a_diff.tga - map_bump textures\spnza_bricks_a_diff.tga + map_Ks textures\spnza_bricks_a_spec.tga + map_bump textures\spnza_bricks_a_bump.png bump textures\spnza_bricks_a_bump.png newmtl arch @@ -104,10 +108,11 @@ newmtl arch illum 2 Ka 0.5880 0.5880 0.5880 Kd 0.5880 0.5880 0.5880 - Ks 0.0000 0.0000 0.0000 + Ks 0.5880 0.5880 0.5880 Ke 0.0000 0.0000 0.0000 map_Ka textures\sponza_arch_diff.tga map_Kd textures\sponza_arch_diff.tga + map_Ks textures\sponza_arch_spec.tga newmtl ceiling Ns 10.0000 @@ -118,10 +123,12 @@ newmtl ceiling illum 2 Ka 0.5880 0.5880 0.5880 Kd 0.5880 0.5880 0.5880 - Ks 0.0000 0.0000 0.0000 + Ks 0.5880 0.5880 0.5880 Ke 0.0000 0.0000 0.0000 map_Ka textures\sponza_ceiling_a_diff.tga map_Kd textures\sponza_ceiling_a_diff.tga + map_Ks textures\sponza_ceiling_a_spec.tga + newmtl column_a Ns 10.0000 @@ -148,10 +155,12 @@ newmtl floor illum 2 Ka 0.5880 0.5880 0.5880 Kd 0.5880 0.5880 0.5880 - Ks 0.0000 0.0000 0.0000 + Ks 0.5880 0.5880 0.5880 Ke 0.0000 0.0000 0.0000 map_Ka textures\sponza_floor_a_diff.tga map_Kd textures\sponza_floor_a_diff.tga + map_Ks textures\sponza_floor_a_spec.tga + newmtl column_c Ns 10.0000 @@ -162,10 +171,11 @@ newmtl column_c illum 2 Ka 0.5880 0.5880 0.5880 Kd 0.5880 0.5880 0.5880 - Ks 0.0000 0.0000 0.0000 + Ks 0.5880 0.5880 0.5880 Ke 0.0000 0.0000 0.0000 map_Ka textures\sponza_column_c_diff.tga map_Kd textures\sponza_column_c_diff.tga + map_Ks textures\sponza_column_c_spec.tga map_bump textures\sponza_column_c_bump.png bump textures\sponza_column_c_bump.png @@ -178,10 +188,12 @@ newmtl details illum 2 Ka 0.5880 0.5880 0.5880 Kd 0.5880 0.5880 0.5880 - Ks 0.0000 0.0000 0.0000 + Ks 0.5880 0.5880 0.5880 Ke 0.0000 0.0000 0.0000 map_Ka textures\sponza_details_diff.tga map_Kd textures\sponza_details_diff.tga + map_Ks textures\sponza_details_spec.tga + newmtl column_b Ns 10.0000 @@ -192,10 +204,11 @@ newmtl column_b illum 2 Ka 0.5880 0.5880 0.5880 Kd 0.5880 0.5880 0.5880 - Ks 0.0000 0.0000 0.0000 + Ks 0.5880 0.5880 0.5880 Ke 0.0000 0.0000 0.0000 map_Ka textures\sponza_column_b_diff.tga map_Kd textures\sponza_column_b_diff.tga + map_Ks textures\sponza_column_b_spec.tga map_bump textures\sponza_column_b_bump.png bump textures\sponza_column_b_bump.png @@ -220,10 +233,12 @@ newmtl flagpole illum 2 Ka 0.5880 0.5880 0.5880 Kd 0.5880 0.5880 0.5880 - Ks 0.0000 0.0000 0.0000 + Ks 0.5880 0.5880 0.5880 Ke 0.0000 0.0000 0.0000 map_Ka textures\sponza_flagpole_diff.tga map_Kd textures\sponza_flagpole_diff.tga + map_Ks textures\sponza_flagpole_spec.tga + newmtl fabric_e Ns 10.0000 @@ -234,10 +249,12 @@ newmtl fabric_e illum 2 Ka 0.5880 0.5880 0.5880 Kd 0.5880 0.5880 0.5880 - Ks 0.0000 0.0000 0.0000 + Ks 0.5880 0.5880 0.5880 Ke 0.0000 0.0000 0.0000 map_Ka textures\sponza_fabric_green_diff.tga map_Kd textures\sponza_fabric_green_diff.tga + map_Ks textures\sponza_fabric_spec.tga + newmtl fabric_d Ns 10.0000 @@ -248,10 +265,12 @@ newmtl fabric_d illum 2 Ka 0.5880 0.5880 0.5880 Kd 0.5880 0.5880 0.5880 - Ks 0.0000 0.0000 0.0000 + Ks 0.5880 0.5880 0.5880 Ke 0.0000 0.0000 0.0000 map_Ka textures\sponza_fabric_blue_diff.tga map_Kd textures\sponza_fabric_blue_diff.tga + map_Ks textures\sponza_fabric_spec.tga + newmtl fabric_a Ns 10.0000 @@ -262,10 +281,12 @@ newmtl fabric_a illum 2 Ka 0.5880 0.5880 0.5880 Kd 0.5880 0.5880 0.5880 - Ks 0.0000 0.0000 0.0000 + Ks 0.5880 0.5880 0.5880 Ke 0.0000 0.0000 0.0000 map_Ka textures\sponza_fabric_diff.tga map_Kd textures\sponza_fabric_diff.tga + map_Ks textures\sponza_fabric_spec.tga + newmtl fabric_g Ns 10.0000 @@ -322,7 +343,7 @@ newmtl chain Ke 0.0000 0.0000 0.0000 map_Ka textures\chain_texture.tga map_Kd textures\chain_texture.tga - map_d textures\chain_texture_mask.tga + map_d textures\chain_texture_mask.png map_bump textures\chain_texture_bump.png bump textures\chain_texture_bump.png diff --git a/base/res/crytek-sponza/sponza.obj b/base/res/crytek-sponza/sponza.obj index 281a316..1eca27a 100644 --- a/base/res/crytek-sponza/sponza.obj +++ b/base/res/crytek-sponza/sponza.obj @@ -14361,6 +14361,8 @@ f 3352/690/3630 3357/695/3635 3355/693/3633 f 3355/693/3633 3358/696/3636 3356/694/3634 f 3352/690/3630 3356/694/3634 3353/691/3631 f 3352/690/3630 3359/697/3637 3357/695/3635 + +g sponza_01_a usemtl vase_round f 3360/698/3638 3361/699/3639 3362/700/3640 3363/701/3641 f 3364/702/3642 3365/703/3643 3366/704/3644 3367/705/3645 @@ -79165,6 +79167,8 @@ s 1 f 24431/14830/20801 24432/14831/20803 24434/14833/20800 24435/14834/20801 f 24425/14824/20800 24431/14830/20801 24435/14834/20801 24423/14822/20800 f 24426/14825/20800 24423/14822/20800 24435/14834/20801 + +g sponza_71_a usemtl bricks s off f 24429/14828/20840 24437/14828/20840 24438/14829/20840 24430/14829/20840 @@ -458968,6 +458972,8 @@ f 127666/75185/124029 127671/75190/124034 127669/75188/124032 f 127669/75188/124032 127672/75191/124035 127670/75189/124033 f 127666/75185/124029 127670/75189/124033 127667/75186/124030 f 127666/75185/124029 127673/75192/124036 127671/75190/124034 + +g sponza_366_a usemtl vase_round f 127674/75193/124037 127675/75194/124038 127676/75195/124039 127677/75196/124040 f 127678/75197/124041 127679/75198/124042 127680/75199/124043 127681/75200/124044 @@ -464941,6 +464947,8 @@ f 129323/76520/125645 129328/76525/125650 129326/76523/125648 f 129326/76523/125648 129329/76526/125651 129327/76524/125649 f 129323/76520/125645 129327/76524/125649 129324/76521/125646 f 129323/76520/125645 129330/76527/125652 129328/76525/125650 + +g sponza_367_a usemtl vase_round f 129331/76528/125653 129332/76529/125654 129333/76530/125655 129334/76531/125656 f 129335/76532/125657 129336/76533/125658 129337/76534/125659 129338/76535/125660 @@ -470913,6 +470921,8 @@ f 130980/77855/127260 130985/77860/127265 130983/77858/127263 f 130983/77858/127263 130986/77861/127266 130984/77859/127264 f 130980/77855/127260 130984/77859/127264 130981/77856/127261 f 130980/77855/127260 130987/77862/127267 130985/77860/127265 + +g sponza_368_a usemtl vase_round f 130988/77863/127268 130989/77864/127269 130990/77865/127270 130991/77866/127271 f 130992/77867/127272 130993/77868/127273 130994/77869/127274 130995/77870/127275 @@ -476633,6 +476643,8 @@ f 132553/79117/128782 132554/79118/128783 132555/79115/128784 132556/79116/12878 f 132557/79120/128786 132558/79119/128787 132554/79118/128783 132553/79117/128782 f 132555/79115/128784 132554/79118/128783 132559/79121/128788 132560/79122/128789 f 132558/79119/128787 132561/79123/128790 132559/79121/128788 132554/79118/128783 + +g sponza_369_a usemtl vase_round f 132562/79160/128791 132563/79161/128792 132564/79162/128793 132565/79163/128794 f 132566/79164/128795 132567/79165/128796 132568/79166/128797 132569/79167/128798 @@ -482353,6 +482365,8 @@ f 134127/80414/130305 134128/80415/130306 134129/80412/130307 134130/80413/13030 f 134131/80417/130309 134132/80416/130310 134128/80415/130306 134127/80414/130305 f 134129/80412/130307 134128/80415/130306 134133/80418/130311 134134/80419/130312 f 134132/80416/130310 134135/80420/130313 134133/80418/130311 134128/80415/130306 + +g sponza_370_a usemtl vase_round f 134136/80457/130314 134137/80458/130315 134138/80459/130316 134139/80460/130317 f 134140/80461/130318 134141/80462/130319 134142/80463/130320 134143/80464/130321 @@ -488073,6 +488087,8 @@ f 135701/81711/131828 135702/81712/131829 135703/81709/131830 135704/81710/13183 f 135705/81714/131832 135706/81713/131833 135702/81712/131829 135701/81711/131828 f 135703/81709/131830 135702/81712/131829 135707/81715/131834 135708/81716/131835 f 135706/81713/131833 135709/81717/131836 135707/81715/131834 135702/81712/131829 + +g sponza_371_a usemtl vase_round f 135710/81754/131837 135711/81755/131838 135712/81756/131839 135713/81757/131840 f 135714/81758/131841 135715/81759/131842 135716/81760/131843 135717/81761/131844 @@ -493794,6 +493810,8 @@ f 137275/83008/133352 137276/83009/133353 137277/83006/133354 137278/83007/13335 f 137279/83011/133356 137280/83010/133357 137276/83009/133353 137275/83008/133352 f 137277/83006/133354 137276/83009/133353 137281/83012/133358 137282/83013/133359 f 137280/83010/133357 137283/83014/133360 137281/83012/133358 137276/83009/133353 + +g sponza_372_a usemtl vase_round f 137284/83051/133361 137285/83052/133362 137286/83053/133363 137287/83054/133364 f 137288/83055/133365 137289/83056/133366 137290/83057/133367 137291/83058/133368 @@ -518292,6 +518310,7 @@ f 143960/88549/139950 144005/88594/139995 144001/88590/139991 144003/88592/13999 f 143960/88549/139950 143640/88229/139630 143650/88239/139640 f 143871/88460/139861 143879/88468/139869 143889/88478/139879 f 143614/88203/139604 143607/88196/139597 143610/88199/139600 +g sponza_377_a usemtl Material__298 f 144012/88601/140002 144013/88602/140003 144014/88603/140004 f 144015/88604/140005 144013/88602/140003 144012/88601/140002 @@ -524910,6 +524929,8 @@ f 145571/90160/141561 145616/90205/141606 145612/90201/141602 145614/90203/14160 f 145571/90160/141561 145251/89840/141241 145261/89850/141251 f 145482/90071/141472 145490/90079/141480 145500/90089/141490 f 145225/89814/141215 145218/89807/141208 145221/89810/141211 + +g sponza_378_a usemtl Material__298 f 145623/90212/141613 145624/90213/141614 145625/90214/141615 f 145626/90215/141616 145624/90213/141614 145623/90212/141613 diff --git a/base/res/crytek-sponza/textures/vase_hanging.tga b/base/res/crytek-sponza/textures/vase_hanging.tga index 8954561..9fcf740 100644 Binary files a/base/res/crytek-sponza/textures/vase_hanging.tga and b/base/res/crytek-sponza/textures/vase_hanging.tga differ diff --git a/base/res/crytek-sponza/textures/vase_hanging_backup.tga b/base/res/crytek-sponza/textures/vase_hanging_backup.tga new file mode 100644 index 0000000..8954561 Binary files /dev/null and b/base/res/crytek-sponza/textures/vase_hanging_backup.tga differ diff --git a/base/res/shaders/ambient.frag b/base/res/shaders/ambient.frag index 69b878c..7dfa912 100644 --- a/base/res/shaders/ambient.frag +++ b/base/res/shaders/ambient.frag @@ -20,7 +20,8 @@ uniform mat4 u_Persp; uniform sampler2D u_Depthtex; uniform sampler2D u_Normaltex; uniform sampler2D u_Positiontex; -uniform sampler2D u_Colortex; +uniform sampler2D u_DiffColortex; +uniform sampler2D u_SpecColortex; uniform sampler2D u_RandomNormaltex; uniform sampler2D u_RandomScalartex; @@ -67,9 +68,11 @@ vec3 samplePos(vec2 texcoords) { return texture(u_Positiontex,texcoords).xyz; } + + //Helper function to automicatlly sample and unpack positions -vec3 sampleCol(vec2 texcoords) { - return texture(u_Colortex,texcoords).xyz; +vec3 sampleSpecCol(vec2 texcoords) { + return texture(u_SpecColortex,texcoords).xyz; } //Get a random normal vector given a screen-space texture coordinate @@ -100,7 +103,8 @@ void main() { vec3 normal = sampleNrm(fs_Texcoord); vec3 position = samplePos(fs_Texcoord); - vec3 color = sampleCol(fs_Texcoord); + vec4 diffTexel = texture(u_DiffColortex,fs_Texcoord); + vec3 color = diffTexel.rgb; vec3 light = u_Light.xyz; float strength = u_Light.w; if (lin_depth > 0.99f) { @@ -108,7 +112,7 @@ void main() { } else { float ambient = u_LightIl; float diffuse = max(0.0, dot(normalize(light),normal)); - out_Color = vec4(color*(strength*diffuse + ambient),1.0f); + out_Color = vec4(color*(strength*diffuse + ambient),1.0); } return; } diff --git a/base/res/shaders/diagnostic.frag b/base/res/shaders/diagnostic.frag index ac73727..4a4166f 100644 --- a/base/res/shaders/diagnostic.frag +++ b/base/res/shaders/diagnostic.frag @@ -7,9 +7,11 @@ #define DISPLAY_DEPTH 0 #define DISPLAY_NORMAL 1 #define DISPLAY_POSITION 2 -#define DISPLAY_COLOR 3 +#define DISPLAY_DIFFUSE 3 #define DISPLAY_TOTAL 4 #define DISPLAY_LIGHTS 5 +#define DISPLAY_SPECULAR 6 +#define DISPLAY_BLOOM 7 ///////////////////////////////////// @@ -20,9 +22,11 @@ uniform mat4 u_Persp; uniform sampler2D u_Depthtex; uniform sampler2D u_Normaltex; uniform sampler2D u_Positiontex; -uniform sampler2D u_Colortex; +uniform sampler2D u_DiffColortex; +uniform sampler2D u_SpecColortex; uniform sampler2D u_RandomNormaltex; uniform sampler2D u_RandomScalartex; +uniform sampler2D u_Bloomtex; uniform float u_Far; uniform float u_Near; @@ -69,7 +73,12 @@ vec3 samplePos(vec2 texcoords) { //Helper function to automicatlly sample and unpack positions vec3 sampleCol(vec2 texcoords) { - return texture(u_Colortex,texcoords).xyz; + return texture(u_DiffColortex,texcoords).xyz; +} + +//Helper function to automicatlly sample and unpack positions +vec3 sampleSpecCol(vec2 texcoords) { + return texture(u_SpecColortex,texcoords).xyz; } //Get a random normal vector given a screen-space texture coordinate @@ -100,7 +109,9 @@ void main() { vec3 normal = sampleNrm(fs_Texcoord); vec3 position = samplePos(fs_Texcoord); - vec3 color = sampleCol(fs_Texcoord); + vec4 diffTexel = texture(u_DiffColortex,fs_Texcoord); + vec3 color = diffTexel.rgb; + vec3 specColor = sampleSpecCol(fs_Texcoord); vec3 light = u_Light.xyz; float lightRadius = u_Light.w; @@ -114,9 +125,16 @@ void main() { case(DISPLAY_POSITION): out_Color = vec4(abs(position) / u_Far,1.0f); break; - case(DISPLAY_COLOR): - out_Color = vec4(color, 1.0); + case(DISPLAY_DIFFUSE): + out_Color = vec4(color, 1.0); + break; + case(DISPLAY_SPECULAR): + out_Color = vec4(specColor, 1.0); break; + case (DISPLAY_BLOOM): + float bloom = texture(u_Bloomtex, fs_Texcoord); + out_Color = vec4(color, 1.0)*bloom; + break; case(DISPLAY_LIGHTS): case(DISPLAY_TOTAL): break; diff --git a/base/res/shaders/directional.frag b/base/res/shaders/directional.frag index a34daab..ea881d7 100644 --- a/base/res/shaders/directional.frag +++ b/base/res/shaders/directional.frag @@ -20,7 +20,8 @@ uniform mat4 u_Persp; uniform sampler2D u_Depthtex; uniform sampler2D u_Normaltex; uniform sampler2D u_Positiontex; -uniform sampler2D u_Colortex; +uniform sampler2D u_DiffColortex; +uniform sampler2D u_SpecColortex; uniform sampler2D u_RandomNormaltex; uniform sampler2D u_RandomScalartex; @@ -67,9 +68,10 @@ vec3 samplePos(vec2 texcoords) { return texture(u_Positiontex,texcoords).xyz; } + //Helper function to automicatlly sample and unpack positions -vec3 sampleCol(vec2 texcoords) { - return texture(u_Colortex,texcoords).xyz; +vec3 sampleSpecCol(vec2 texcoords) { + return texture(u_SpecColortex,texcoords).xyz; } //Get a random normal vector given a screen-space texture coordinate @@ -100,12 +102,15 @@ void main() { vec3 normal = sampleNrm(fs_Texcoord); vec3 position = samplePos(fs_Texcoord); - vec3 color = sampleCol(fs_Texcoord); + vec4 diffTexel = texture(u_DiffColortex,fs_Texcoord); + vec3 color = diffTexel.rgb; + float bloom = diffTexel.a; + vec3 light = u_Light.xyz; float lightRadius = u_Light.w; float diffuse = max(0.0, dot(normalize(light),normal)); - out_Color = vec4(color*u_LightIl*diffuse,1.0f); + out_Color = vec4(color*u_LightIl*diffuse,bloom); } return; diff --git a/base/res/shaders/pass.frag b/base/res/shaders/pass.frag index e37dcbf..cbcc2aa 100644 --- a/base/res/shaders/pass.frag +++ b/base/res/shaders/pass.frag @@ -1,18 +1,118 @@ #version 330 +#extension GL_EXT_gpu_shader4: enable + +//////////////////////////// +// ENUMERATIONS +//////////////////////////// + +#define NO_CHANGE 0 +#define HASTEX_OVERLAY 1 +#define TEXCOORDS_AS_DIFFUSE 2 +#define BUMP_AS_DIFFUSE 3 +#define MASK_OVERLAY 4 + uniform float u_Far; -uniform vec3 u_Color; +uniform vec3 u_Ka; +uniform vec3 u_Kd; +uniform vec3 u_Ks; +uniform float u_specExp; + +uniform int u_PassthroughMode; + +//1 if true, 0 if texture is missing. +uniform int u_hasDiffTex; +uniform int u_hasSpecTex; +uniform int u_hasBumpTex; +uniform int u_hasMaskTex; + +///====Textures============ +uniform sampler2D u_DiffTex; +uniform sampler2D u_SpecTex; +uniform sampler2D u_BumpTex; +uniform sampler2D u_MaskTex; +///======================== in vec3 fs_Normal; +in vec3 fs_Tangent; +in vec3 fs_Binormal; in vec4 fs_Position; +in vec2 fs_Texcoord; out vec4 out_Normal; out vec4 out_Position; -out vec4 out_Color; +out vec4 out_Diff_Color; +out vec4 out_Spec_Color; +out vec3 out_Bloom; void main(void) { out_Normal = vec4(normalize(fs_Normal),0.0f); out_Position = vec4(fs_Position.xyz,1.0f); //Tuck position into 0 1 range - out_Color = vec4(u_Color,1.0); + + vec4 diffuseColor = vec4(u_Kd,1.0); + + out_Bloom = vec3(0.0); + if(u_hasDiffTex > 0) + { + vec4 texel = texture(u_DiffTex,fs_Texcoord); + diffuseColor *= vec4(texel.rgb, 1.0); + out_Bloom = (1.0-texel.a)*texel.rgb; + } + + //Pass through diffuse color + out_Diff_Color = vec4(diffuseColor.rgb, clamp(1.0-diffuseColor.a, 0.0, 1.0)); + + + if(u_PassthroughMode == HASTEX_OVERLAY){ + out_Diff_Color += 0.9*vec4(u_hasMaskTex,u_hasSpecTex,u_hasBumpTex,0.0); + }else if(u_PassthroughMode == TEXCOORDS_AS_DIFFUSE){ + out_Diff_Color = vec4(fs_Texcoord.x, fs_Texcoord.y, 0.0, 1.0); + } + + + if(u_hasMaskTex > 0) + { + //Only discard samples if not in overlay mode + if(texture(u_MaskTex,fs_Texcoord).x < 1) + discard; + if(u_PassthroughMode == MASK_OVERLAY){ + out_Diff_Color = vec4(texture(u_MaskTex,fs_Texcoord).rgb,1.0); + } + + } + + if(u_hasBumpTex > 0) + { + //TODO: Do Bump Mapping Here + ivec2 size = textureSize2D(u_BumpTex,0); + float scaling = 0.2;//Strength factor + const vec3 offsetDir = vec3(-1,0,1); + vec2 offset = 1.0/size; + + float s11 = texture(u_BumpTex, fs_Texcoord).x;//Height at center + float s01 = texture(u_BumpTex, fs_Texcoord+offset*offsetDir.xy).x;//Left + float s21 = texture(u_BumpTex, fs_Texcoord+offset*offsetDir.zy).x;//Right + float s10 = texture(u_BumpTex, fs_Texcoord+offset*offsetDir.yx).x;//Down + float s12 = texture(u_BumpTex, fs_Texcoord+offset*offsetDir.yz).x;//Up + vec3 va = normalize(vec3(scaling,0.0,s21-s01)); + vec3 vb = normalize(vec3(0.0,scaling,s12-s10)); + vec4 bump = normalize(vec4( cross(va,vb), s11 )); + if(u_PassthroughMode == BUMP_AS_DIFFUSE){ + out_Diff_Color = bump; + } + + //Modify using + mat3 rotMat = mat3(fs_Tangent, fs_Binormal, fs_Normal); + out_Normal = vec4(rotMat*vec3(bump),0.0); + } + + + //Pass through specular color + out_Spec_Color = vec4(u_Ks, u_specExp); + if(u_hasSpecTex > 0) + { + out_Spec_Color *= vec4(texture(u_SpecTex,fs_Texcoord).rgb,1.0); + } + } diff --git a/base/res/shaders/pass.vert b/base/res/shaders/pass.vert index e36825f..700b449 100644 --- a/base/res/shaders/pass.vert +++ b/base/res/shaders/pass.vert @@ -8,14 +8,24 @@ uniform mat4x4 u_InvTrans; in vec3 Position; in vec3 Normal; +in vec4 Tangent; +in vec2 Texcoord; out vec3 fs_Normal; +out vec3 fs_Tangent; +out vec3 fs_Binormal; out vec4 fs_Position; +out vec2 fs_Texcoord; void main(void) { - fs_Normal = (u_InvTrans*vec4(Normal,0.0f)).xyz; + + fs_Normal =normalize((u_InvTrans*vec4(Normal,0.0f)).xyz); + fs_Tangent =normalize((u_InvTrans*vec4(Tangent.xyz,0.0f)).xyz); + fs_Binormal =normalize((u_InvTrans*vec4(normalize(cross(Normal, Tangent.xyz)*Tangent.w),0.0f)).xyz); + vec4 world = u_Model * vec4(Position, 1.0); vec4 camera = u_View * world; fs_Position = camera; gl_Position = u_Persp * camera; + fs_Texcoord = Texcoord; } diff --git a/base/res/shaders/point.frag b/base/res/shaders/point.frag index 98b90e0..e857281 100644 --- a/base/res/shaders/point.frag +++ b/base/res/shaders/point.frag @@ -20,7 +20,8 @@ uniform mat4 u_Persp; uniform sampler2D u_Depthtex; uniform sampler2D u_Normaltex; uniform sampler2D u_Positiontex; -uniform sampler2D u_Colortex; +uniform sampler2D u_DiffColortex; +uniform sampler2D u_SpecColortex; uniform sampler2D u_RandomNormaltex; uniform sampler2D u_RandomScalartex; @@ -66,9 +67,10 @@ vec3 samplePos(vec2 texcoords) { return texture(u_Positiontex,texcoords).xyz; } + //Helper function to automicatlly sample and unpack positions -vec3 sampleCol(vec2 texcoords) { - return texture(u_Colortex,texcoords).xyz; +vec3 sampleSpecCol(vec2 texcoords) { + return texture(u_SpecColortex,texcoords).xyz; } //Get a random normal vector given a screen-space texture coordinate @@ -99,17 +101,43 @@ void main() { vec3 normal = sampleNrm(fs_Texcoord); vec3 position = samplePos(fs_Texcoord); - vec3 color = sampleCol(fs_Texcoord); + vec4 diffTexel = texture(u_DiffColortex,fs_Texcoord); + vec3 color = diffTexel.rgb; + vec3 light = u_Light.xyz; float lightRadius = u_Light.w; out_Color = vec4(0,0,0,1.0); if( u_DisplayType == DISPLAY_LIGHTS ) { //Put some code here to visualize the fragment associated with this point light + out_Color = vec4(0.2,0.0,0.0,1.0); } else { //Put some code here to actually compute the light from the point light + vec3 lightDir = light-position; + float dist = length(lightDir); + + float NdotL = max(dot(normal, normalize(lightDir)),0.0); + + if(NdotL > 0.0) + { + float att = clamp((lightRadius-dist)/lightRadius, 0.0,1.0); + att *= att; + + float kd = 0.60; + //diffuse + out_Color += att*vec4(color,1.0)*NdotL*u_LightIl; + + //Specular + vec4 specColor = texture(u_SpecColortex,fs_Texcoord); + vec3 toReflectedLight = normalize(reflect((position-light), normal)); + float specular = max(dot(toReflectedLight, normalize(-position)), 0.0); + specular = pow(specular, 50.0); + + float ks = 1.0-kd; + out_Color += ks*specColor*specular; + } } return; } diff --git a/base/res/shaders/post.frag b/base/res/shaders/post.frag index 2bf5afc..4bc79cc 100644 --- a/base/res/shaders/post.frag +++ b/base/res/shaders/post.frag @@ -18,9 +18,17 @@ uniform sampler2D u_Posttex; uniform sampler2D u_RandomNormaltex; uniform sampler2D u_RandomScalartex; +uniform sampler2D u_Bloomtex; +uniform sampler2D u_Depthtex; +uniform sampler2D u_Normaltex; uniform int u_ScreenWidth; uniform int u_ScreenHeight; +uniform int u_UseBloom; +uniform int u_UseToon; +uniform float u_Far; +uniform float u_Near; + in vec2 fs_Texcoord; @@ -38,6 +46,10 @@ uniform float falloff = 0.1f; // UTILITY FUNCTIONS ///////////////////////////////////// +float linearizeDepth(float exp_depth, float near, float far) { + return (2 * near) / (far + near - exp_depth * (far - near)); +} + //Helper function to automicatlly sample and unpack positions vec3 sampleCol(vec2 texcoords) { return texture(u_Posttex,texcoords).xyz; @@ -60,15 +72,96 @@ float getRandomScalar(vec2 texcoords) { texcoords.t*u_ScreenHeight/sz.y)).r; } +//Returns gradient squared +vec3 sobel(sampler2D tex, vec2 texcoords) { + float xScale = 1.0/u_ScreenWidth; + float yScale = 1.0/u_ScreenHeight; + + vec2 off = vec2(xScale,yScale); + + vec3 ul = texture(tex, texcoords-vec2(-1.0, 1.0)*off).xyz; + vec3 u = texture(tex, texcoords-vec2( 0.0, 1.0)*off).xyz*2.0; + vec3 ur = texture(tex, texcoords-vec2( 1.0, 1.0)*off).xyz; + vec3 r = texture(tex, texcoords-vec2( 1.0, 0.0)*off).xyz*2.0; + vec3 dr = texture(tex, texcoords-vec2( 1.0,-1.0)*off).xyz; + vec3 d = texture(tex, texcoords-vec2( 1.0,-1.0)*off).xyz*2.0; + vec3 dl = texture(tex, texcoords-vec2( 0.0,-1.0)*off).xyz; + vec3 l = texture(tex, texcoords-vec2(-1.0, 0.0)*off).xyz*2.0; + + vec3 horizontal = (ul+l+dl)-(ur+r+dr); + vec3 vertical = (ul+u+ur)-(dl+d+dr); + + vec3 gradient_sq = horizontal*horizontal+vertical*vertical; + + return gradient_sq; +} + +vec4 quantize(vec4 color_in, int numBins) +{ + //Assume intial distribution between 0 and 1 + color_in.rgb *= numBins; + color_in.rgb += vec3(.5,.5,.5); + ivec3 intrgb = ivec3(color_in.rgb); + color_in.rgb = vec3(intrgb)/numBins; + return color_in; +} + + + +const int KERNEL_SIZE = 20; + +float boxFilter(float x, float y) +{ + //TODO: Find better weight function + int width = KERNEL_SIZE*2+1; + return 1.0/float(width*width); +} + + /////////////////////////////////// // MAIN ////////////////////////////////// const float occlusion_strength = 1.5f; void main() { - vec3 color = sampleCol(fs_Texcoord); - float gray = dot(color, vec3(0.2125, 0.7154, 0.0721)); - float vin = min(2*distance(vec2(0.5), fs_Texcoord), 1.0); - out_Color = vec4(mix(pow(color,vec3(1.0/1.8)),vec3(gray),vin), 1.0); + vec4 texel = texture(u_Posttex,fs_Texcoord); + vec3 color = texel.rgb; + + //Base color + out_Color = vec4(color, 1.0); + + + if(u_UseBloom > 0.0){ + //Bloom color + float xScale = 1.0/u_ScreenWidth; + float yScale = 1.0/u_ScreenHeight; + + vec3 bloomColor = vec3(0.0); + for(int x = -KERNEL_SIZE; x <= KERNEL_SIZE; x++) + { + for(int y = -KERNEL_SIZE; y <= KERNEL_SIZE; y++) + { + vec2 texCoord = fs_Texcoord + vec2(x*xScale,y*yScale); + bloomColor += 2.0*boxFilter(x,y)*texture(u_Bloomtex,texCoord).rgb; + } + } + + out_Color += vec4(bloomColor,0.0); + } + + if(u_UseToon > 0.0) + { + //Toon Shading + float exp_depth = texture(u_Depthtex, fs_Texcoord).r; + float lin_depth = linearizeDepth(exp_depth,u_Near,u_Far); + + //Silouette + vec3 gradient_sq = sobel(u_Normaltex, fs_Texcoord); + if(length(gradient_sq) > 7.0){ + out_Color = vec4(0.0); + } + //quantize colors + out_Color = quantize(out_Color,4); + } return; } diff --git a/base/src/main.cpp b/base/src/main.cpp index 9a0f6a0..f0970d1 100644 --- a/base/src/main.cpp +++ b/base/src/main.cpp @@ -17,6 +17,7 @@ #include #include #include +#include using namespace std; using namespace glm; @@ -24,63 +25,93 @@ using namespace glm; const float PI = 3.14159f; int width, height; +bool diffuseMappingEnabled = true; +bool specularMappingEnabled = true; +bool bumpMappingEnabled = true; +bool maskingEnabled = true; +bool useBloom = false; +bool useToon = false; +bool logTime = false; + +enum Display display_type = DISPLAY_TOTAL; +enum Passthrough passthrough_type = NO_CHANGE; +float FARP; +float NEARP; device_mesh_t uploadMesh(const mesh_t & mesh) { - device_mesh_t out; - //Allocate vertex array - //Vertex arrays encapsulate a set of generic vertex - //attributes and the buffers they are bound to - //Different vertex array per mesh. - glGenVertexArrays(1, &(out.vertex_array)); - glBindVertexArray(out.vertex_array); - - //Allocate vbos for data - glGenBuffers(1, &(out.vbo_vertices)); - glGenBuffers(1, &(out.vbo_normals)); - glGenBuffers(1, &(out.vbo_indices)); - glGenBuffers(1, &(out.vbo_texcoords)); - - //Upload vertex data - glBindBuffer(GL_ARRAY_BUFFER, out.vbo_vertices); - glBufferData(GL_ARRAY_BUFFER, mesh.vertices.size()*sizeof(vec3), - &mesh.vertices[0], GL_STATIC_DRAW); - glVertexAttribPointer(mesh_attributes::POSITION, 3, GL_FLOAT, GL_FALSE,0,0); - glEnableVertexAttribArray(mesh_attributes::POSITION); - //cout << mesh.vertices.size() << " verts:" << endl; - //for(int i = 0; i < mesh.vertices.size(); ++i) - // cout << " " << mesh.vertices[i][0] << ", " << mesh.vertices[i][1] << ", " << mesh.vertices[i][2] << endl; - - //Upload normal data - glBindBuffer(GL_ARRAY_BUFFER, out.vbo_normals); - glBufferData(GL_ARRAY_BUFFER, mesh.normals.size()*sizeof(vec3), - &mesh.normals[0], GL_STATIC_DRAW); - glVertexAttribPointer(mesh_attributes::NORMAL, 3, GL_FLOAT, GL_FALSE,0,0); - glEnableVertexAttribArray(mesh_attributes::NORMAL); - //cout << mesh.normals.size() << " norms:" << endl; - //for(int i = 0; i < mesh.normals.size(); ++i) - // cout << " " << mesh.normals[i][0] << ", " << mesh.normals[i][1] << ", " << mesh.normals[i][2] << endl; - - //Upload texture coord data - glBindBuffer(GL_ARRAY_BUFFER, out.vbo_texcoords); - glBufferData(GL_ARRAY_BUFFER, mesh.texcoords.size()*sizeof(vec2), - &mesh.texcoords[0], GL_STATIC_DRAW); - glVertexAttribPointer(mesh_attributes::TEXCOORD, 2, GL_FLOAT, GL_FALSE,0,0); - glEnableVertexAttribArray(mesh_attributes::TEXCOORD); - //cout << mesh.texcoords.size() << " texcos:" << endl; - //for(int i = 0; i < mesh.texcoords.size(); ++i) - // cout << " " << mesh.texcoords[i][0] << ", " << mesh.texcoords[i][1] << endl; - - //indices - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, out.vbo_indices); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.indices.size()*sizeof(GLushort), - &mesh.indices[0], GL_STATIC_DRAW); - out.num_indices = mesh.indices.size(); - //Unplug Vertex Array - glBindVertexArray(0); - - out.texname = mesh.texname; - out.color = mesh.color; - return out; + device_mesh_t out; + //Allocate vertex array + //Vertex arrays encapsulate a set of generic vertex + //attributes and the buffers they are bound to + //Different vertex array per mesh. + glGenVertexArrays(1, &(out.vertex_array)); + glBindVertexArray(out.vertex_array); + + //Allocate vbos for data + glGenBuffers(1, &(out.vbo_vertices)); + glGenBuffers(1, &(out.vbo_normals)); + glGenBuffers(1, &(out.vbo_tangents)); + glGenBuffers(1, &(out.vbo_indices)); + glGenBuffers(1, &(out.vbo_texcoords)); + + //Upload vertex data + glBindBuffer(GL_ARRAY_BUFFER, out.vbo_vertices); + glBufferData(GL_ARRAY_BUFFER, mesh.vertices.size()*sizeof(vec3), + &mesh.vertices[0], GL_STATIC_DRAW); + glVertexAttribPointer(mesh_attributes::POSITION, 3, GL_FLOAT, GL_FALSE,0,0); + glEnableVertexAttribArray(mesh_attributes::POSITION); + //cout << mesh.vertices.size() << " verts:" << endl; + //for(int i = 0; i < mesh.vertices.size(); ++i) + // cout << " " << mesh.vertices[i][0] << ", " << mesh.vertices[i][1] << ", " << mesh.vertices[i][2] << endl; + + //Upload normal data + glBindBuffer(GL_ARRAY_BUFFER, out.vbo_normals); + glBufferData(GL_ARRAY_BUFFER, mesh.normals.size()*sizeof(vec3), + &mesh.normals[0], GL_STATIC_DRAW); + glVertexAttribPointer(mesh_attributes::NORMAL, 3, GL_FLOAT, GL_FALSE,0,0); + glEnableVertexAttribArray(mesh_attributes::NORMAL); + //cout << mesh.normals.size() << " norms:" << endl; + //for(int i = 0; i < mesh.normals.size(); ++i) + // cout << " " << mesh.normals[i][0] << ", " << mesh.normals[i][1] << ", " << mesh.normals[i][2] << endl; + + + //Upload tangent data + glBindBuffer(GL_ARRAY_BUFFER, out.vbo_tangents); + glBufferData(GL_ARRAY_BUFFER, mesh.tangents.size()*sizeof(vec4), + &mesh.tangents[0], GL_STATIC_DRAW); + glVertexAttribPointer(mesh_attributes::TANGENT, 4, GL_FLOAT, GL_FALSE,0,0); + glEnableVertexAttribArray(mesh_attributes::TANGENT); + + //Upload texture coord data + glBindBuffer(GL_ARRAY_BUFFER, out.vbo_texcoords); + glBufferData(GL_ARRAY_BUFFER, mesh.texcoords.size()*sizeof(vec2), + &mesh.texcoords[0], GL_STATIC_DRAW); + glVertexAttribPointer(mesh_attributes::TEXCOORD, 2, GL_FLOAT, GL_FALSE,0,0); + glEnableVertexAttribArray(mesh_attributes::TEXCOORD); + //cout << mesh.texcoords.size() << " texcos:" << endl; + //for(int i = 0; i < mesh.texcoords.size(); ++i) + // cout << " " << mesh.texcoords[i][0] << ", " << mesh.texcoords[i][1] << endl; + + //indices + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, out.vbo_indices); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.indices.size()*sizeof(GLushort), + &mesh.indices[0], GL_STATIC_DRAW); + out.num_indices = mesh.indices.size(); + //Unplug Vertex Array + glBindVertexArray(0); + + out.diff_texid = mesh.diff_texid; + out.spec_texid = mesh.spec_texid; + out.bump_texid = mesh.bump_texid; + out.mask_texid = mesh.mask_texid; + + out.Ka = mesh.Ka; + out.Kd = mesh.Kd; + out.Ks = mesh.Ks; + + out.spec_exp = mesh.spec_exp; + + return out; } @@ -88,129 +119,240 @@ int num_boxes = 3; const int DUMP_SIZE = 1024; vector draw_meshes; +string m_Path;//Path to bbj file for texture loading. +map textureIdMap; + + +GLuint loadTexture(string textureName, GLint filteringMethod) +{ + //Check if texture alread loaded. + if(textureName.length() > 0){ + map::iterator it = textureIdMap.find(textureName); + GLuint texId; + if(it != textureIdMap.end()) + { + //element found, just return texture id. + texId = it->second; + }else{ + //If not loaded already, load texture + string textureFullPath = m_Path + textureName; + cout << "Loading Texture: " << textureFullPath << endl; + texId = (unsigned int)SOIL_load_OGL_texture(textureFullPath.c_str(),SOIL_LOAD_AUTO,SOIL_CREATE_NEW_ID,SOIL_FLAG_INVERT_Y); + if( 0 == texId ) + { + printf( "SOIL loading error: '%s'\n", SOIL_last_result() ); + } + + glBindTexture(GL_TEXTURE_2D, texId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filteringMethod); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filteringMethod); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glBindTexture(GL_TEXTURE_2D, 0); + textureIdMap.insert(make_pair(textureName, texId)); + } + return texId; + } + else{ + return 0;//No texture + } +} + void initMesh() { - for(vector::iterator it = shapes.begin(); - it != shapes.end(); ++it) - { - tinyobj::shape_t shape = *it; - int totalsize = shape.mesh.indices.size() / 3; - int f = 0; - while(f 0) - { - mesh.normals.push_back(vec3(shape.mesh.normals[3*idx0], - shape.mesh.normals[3*idx0+1], - shape.mesh.normals[3*idx0+2])); - mesh.normals.push_back(vec3(shape.mesh.normals[3*idx1], - shape.mesh.normals[3*idx1+1], - shape.mesh.normals[3*idx1+2])); - mesh.normals.push_back(vec3(shape.mesh.normals[3*idx2], - shape.mesh.normals[3*idx2+1], - shape.mesh.normals[3*idx2+2])); - } - else - { - vec3 norm = normalize(glm::cross(normalize(p1-p0), normalize(p2-p0))); - mesh.normals.push_back(norm); - mesh.normals.push_back(norm); - mesh.normals.push_back(norm); - } - - if(shape.mesh.texcoords.size() > 0) - { - mesh.texcoords.push_back(vec2(shape.mesh.positions[2*idx0], - shape.mesh.positions[2*idx0+1])); - mesh.texcoords.push_back(vec2(shape.mesh.positions[2*idx1], - shape.mesh.positions[2*idx1+1])); - mesh.texcoords.push_back(vec2(shape.mesh.positions[2*idx2], - shape.mesh.positions[2*idx2+1])); - } - else - { - vec2 tex(0.0); - mesh.texcoords.push_back(tex); - mesh.texcoords.push_back(tex); - mesh.texcoords.push_back(tex); - } - mesh.indices.push_back(point++); - mesh.indices.push_back(point++); - mesh.indices.push_back(point++); - } - - mesh.color = vec3(shape.material.diffuse[0], - shape.material.diffuse[1], - shape.material.diffuse[2]); - mesh.texname = shape.material.diffuse_texname; - draw_meshes.push_back(uploadMesh(mesh)); - f=f+process; - } - } + textureIdMap.clear(); + + for(vector::iterator it = shapes.begin(); + it != shapes.end(); ++it) + { + tinyobj::shape_t shape = *it; + int totalsize = shape.mesh.indices.size() / 3; + int f = 0; + while(f 0) + { + mesh.normals.push_back(vec3(shape.mesh.normals[3*idx0], + shape.mesh.normals[3*idx0+1], + shape.mesh.normals[3*idx0+2])); + mesh.normals.push_back(vec3(shape.mesh.normals[3*idx1], + shape.mesh.normals[3*idx1+1], + shape.mesh.normals[3*idx1+2])); + mesh.normals.push_back(vec3(shape.mesh.normals[3*idx2], + shape.mesh.normals[3*idx2+1], + shape.mesh.normals[3*idx2+2])); + } + else + { + vec3 norm = normalize(glm::cross(normalize(p1-p0), normalize(p2-p0))); + mesh.normals.push_back(norm); + mesh.normals.push_back(norm); + mesh.normals.push_back(norm); + } + + if(shape.mesh.texcoords.size() > 0) + { + mesh.texcoords.push_back(vec2(shape.mesh.texcoords[2*idx0], + shape.mesh.texcoords[2*idx0+1])); + mesh.texcoords.push_back(vec2(shape.mesh.texcoords[2*idx1], + shape.mesh.texcoords[2*idx1+1])); + mesh.texcoords.push_back(vec2(shape.mesh.texcoords[2*idx2], + shape.mesh.texcoords[2*idx2+1])); + } + else + { + vec2 tex(0.0); + mesh.texcoords.push_back(tex); + mesh.texcoords.push_back(tex); + mesh.texcoords.push_back(tex); + } + + //Mesh binormals and tangents + //Load last face as members + vec3 v0 = mesh.vertices[mesh.vertices.size()-3]; + vec3 v1 = mesh.vertices[mesh.vertices.size()-2]; + vec3 v2 = mesh.vertices[mesh.vertices.size()-1]; + + vec2 w0 = mesh.texcoords[mesh.texcoords.size()-3]; + vec2 w1 = mesh.texcoords[mesh.texcoords.size()-2]; + vec2 w2 = mesh.texcoords[mesh.texcoords.size()-1]; + + vec3 n0 = mesh.normals[mesh.normals.size()-3]; + vec3 n1 = mesh.normals[mesh.normals.size()-2]; + vec3 n2 = mesh.normals[mesh.normals.size()-1]; + + vec3 v1_v0 = v1-v0; + vec3 v2_v0 = v2-v0; + float ds1 = w1.s-w0.s; + float ds2 = w2.s-w0.s; + float dt1 = w1.t-w0.t; + float dt2 = w2.t-w0.t; + + float r = 1.0f/(ds1*dt2-ds2*dt1); + vec3 T = r*vec3((dt2*v1_v0.x-dt1*v2_v0.x),(dt2*v1_v0.y-dt1*v2_v0.y),(dt2*v1_v0.z-dt1*v2_v0.z)); + vec3 B = r*vec3((ds1*v2_v0.x-ds2*v1_v0.x),(ds1*v2_v0.y-ds2*v1_v0.y),(ds1*v2_v0.z-ds2*v1_v0.z)); + + + //Gram-schmidt orthogonalization + vec3 tangent = normalize(T-n0*dot(n0,T)); + float handedness = (dot(cross(n0,T), B) < 0.0f)?-1.0f:1.0f; + mesh.tangents.push_back(vec4(tangent, handedness)); + + tangent = normalize(T-n1*dot(n1,T)); + handedness = (dot(cross(n1,T), B) < 0.0f)?-1.0f:1.0f; + mesh.tangents.push_back(vec4(tangent, handedness)); + + tangent = normalize(T-n2*dot(n2,T)); + handedness = (dot(cross(n2,T), B) < 0.0f)?-1.0f:1.0f; + mesh.tangents.push_back(vec4(tangent, handedness)); + + + mesh.indices.push_back(point++); + mesh.indices.push_back(point++); + mesh.indices.push_back(point++); + } + + mesh.Ka =vec3(shape.material.ambient[0], + shape.material.ambient[1], + shape.material.ambient[2]); + mesh.Kd =vec3(shape.material.diffuse[0], + shape.material.diffuse[1], + shape.material.diffuse[2]); + mesh.Ks =vec3(shape.material.specular[0], + shape.material.specular[1], + shape.material.specular[2]); + + mesh.spec_exp = shape.material.shininess; + + mesh.diff_texid = loadTexture(shape.material.diffuse_texname, GL_LINEAR); + mesh.spec_texid = loadTexture(shape.material.specular_texname, GL_LINEAR); + map::iterator it = shape.material.unknown_parameter.find("map_bump"); + + if(it != shape.material.unknown_parameter.end()){ + string mapPath = it->second; + mesh.bump_texid = loadTexture(mapPath, GL_LINEAR); + }else{ + mesh.bump_texid = 0; + } + + it = shape.material.unknown_parameter.find("map_d"); + if(it != shape.material.unknown_parameter.end()){ + string mapPath = it->second; + mesh.mask_texid = loadTexture(mapPath, GL_LINEAR); + }else{ + mesh.mask_texid = 0; + } + + draw_meshes.push_back(uploadMesh(mesh)); + f=f+process; + } + } } device_mesh2_t device_quad; void initQuad() { - vertex2_t verts [] = { {vec3(-1,1,0),vec2(0,1)}, - {vec3(-1,-1,0),vec2(0,0)}, - {vec3(1,-1,0),vec2(1,0)}, - {vec3(1,1,0),vec2(1,1)}}; - - unsigned short indices[] = { 0,1,2,0,2,3}; - - //Allocate vertex array - //Vertex arrays encapsulate a set of generic vertex attributes and the buffers they are bound too - //Different vertex array per mesh. - glGenVertexArrays(1, &(device_quad.vertex_array)); - glBindVertexArray(device_quad.vertex_array); - - - //Allocate vbos for data - glGenBuffers(1,&(device_quad.vbo_data)); - glGenBuffers(1,&(device_quad.vbo_indices)); - - //Upload vertex data - glBindBuffer(GL_ARRAY_BUFFER, device_quad.vbo_data); - glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); - //Use of strided data, Array of Structures instead of Structures of Arrays - glVertexAttribPointer(quad_attributes::POSITION, 3, GL_FLOAT, GL_FALSE,sizeof(vertex2_t),0); - glVertexAttribPointer(quad_attributes::TEXCOORD, 2, GL_FLOAT, GL_FALSE,sizeof(vertex2_t),(void*)sizeof(vec3)); - glEnableVertexAttribArray(quad_attributes::POSITION); - glEnableVertexAttribArray(quad_attributes::TEXCOORD); - - //indices - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, device_quad.vbo_indices); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6*sizeof(GLushort), indices, GL_STATIC_DRAW); - device_quad.num_indices = 6; - //Unplug Vertex Array - glBindVertexArray(0); + vertex2_t verts [] = { {vec3(-1,1,0),vec2(0,1)}, + {vec3(-1,-1,0),vec2(0,0)}, + {vec3(1,-1,0),vec2(1,0)}, + {vec3(1,1,0),vec2(1,1)}}; + + unsigned short indices[] = { 0,1,2,0,2,3}; + + //Allocate vertex array + //Vertex arrays encapsulate a set of generic vertex attributes and the buffers they are bound too + //Different vertex array per mesh. + glGenVertexArrays(1, &(device_quad.vertex_array)); + glBindVertexArray(device_quad.vertex_array); + + + //Allocate vbos for data + glGenBuffers(1,&(device_quad.vbo_data)); + glGenBuffers(1,&(device_quad.vbo_indices)); + + //Upload vertex data + glBindBuffer(GL_ARRAY_BUFFER, device_quad.vbo_data); + glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); + //Use of strided data, Array of Structures instead of Structures of Arrays + glVertexAttribPointer(quad_attributes::POSITION, 3, GL_FLOAT, GL_FALSE,sizeof(vertex2_t),0); + glVertexAttribPointer(quad_attributes::TEXCOORD, 2, GL_FLOAT, GL_FALSE,sizeof(vertex2_t),(void*)sizeof(vec3)); + glEnableVertexAttribArray(quad_attributes::POSITION); + glEnableVertexAttribArray(quad_attributes::TEXCOORD); + + //indices + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, device_quad.vbo_indices); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6*sizeof(GLushort), indices, GL_STATIC_DRAW); + device_quad.num_indices = 6; + //Unplug Vertex Array + glBindVertexArray(0); } GLuint depthTexture = 0; GLuint normalTexture = 0; GLuint positionTexture = 0; -GLuint colorTexture = 0; +GLuint diffColorTexture = 0; +GLuint bloomTexture = 0; +GLuint specColorTexture = 0; GLuint postTexture = 0; GLuint FBO[2] = {0, 0}; @@ -244,89 +386,92 @@ void initShader() { #endif Utility::shaders_t shaders = Utility::loadShaders(pass_vert, pass_frag); - pass_prog = glCreateProgram(); + pass_prog = glCreateProgram(); - glBindAttribLocation(pass_prog, mesh_attributes::POSITION, "Position"); - glBindAttribLocation(pass_prog, mesh_attributes::NORMAL, "Normal"); - glBindAttribLocation(pass_prog, mesh_attributes::TEXCOORD, "Texcoord"); + glBindAttribLocation(pass_prog, mesh_attributes::POSITION, "Position"); + glBindAttribLocation(pass_prog, mesh_attributes::NORMAL, "Normal"); + glBindAttribLocation(pass_prog, mesh_attributes::TANGENT, "Tangent"); + glBindAttribLocation(pass_prog, mesh_attributes::TEXCOORD, "Texcoord"); - Utility::attachAndLinkProgram(pass_prog,shaders); + Utility::attachAndLinkProgram(pass_prog,shaders); shaders = Utility::loadShaders(shade_vert, diagnostic_frag); - diagnostic_prog = glCreateProgram(); + diagnostic_prog = glCreateProgram(); - glBindAttribLocation(diagnostic_prog, quad_attributes::POSITION, "Position"); - glBindAttribLocation(diagnostic_prog, quad_attributes::TEXCOORD, "Texcoord"); + glBindAttribLocation(diagnostic_prog, quad_attributes::POSITION, "Position"); + glBindAttribLocation(diagnostic_prog, quad_attributes::TEXCOORD, "Texcoord"); - Utility::attachAndLinkProgram(diagnostic_prog, shaders); + Utility::attachAndLinkProgram(diagnostic_prog, shaders); shaders = Utility::loadShaders(shade_vert, ambient_frag); - ambient_prog = glCreateProgram(); + ambient_prog = glCreateProgram(); - glBindAttribLocation(ambient_prog, quad_attributes::POSITION, "Position"); - glBindAttribLocation(ambient_prog, quad_attributes::TEXCOORD, "Texcoord"); + glBindAttribLocation(ambient_prog, quad_attributes::POSITION, "Position"); + glBindAttribLocation(ambient_prog, quad_attributes::TEXCOORD, "Texcoord"); - Utility::attachAndLinkProgram(ambient_prog, shaders); + Utility::attachAndLinkProgram(ambient_prog, shaders); shaders = Utility::loadShaders(shade_vert, point_frag); - point_prog = glCreateProgram(); + point_prog = glCreateProgram(); - glBindAttribLocation(point_prog, quad_attributes::POSITION, "Position"); - glBindAttribLocation(point_prog, quad_attributes::TEXCOORD, "Texcoord"); + glBindAttribLocation(point_prog, quad_attributes::POSITION, "Position"); + glBindAttribLocation(point_prog, quad_attributes::TEXCOORD, "Texcoord"); - Utility::attachAndLinkProgram(point_prog, shaders); + Utility::attachAndLinkProgram(point_prog, shaders); shaders = Utility::loadShaders(post_vert, post_frag); - post_prog = glCreateProgram(); + post_prog = glCreateProgram(); - glBindAttribLocation(post_prog, quad_attributes::POSITION, "Position"); - glBindAttribLocation(post_prog, quad_attributes::TEXCOORD, "Texcoord"); + glBindAttribLocation(post_prog, quad_attributes::POSITION, "Position"); + glBindAttribLocation(post_prog, quad_attributes::TEXCOORD, "Texcoord"); - Utility::attachAndLinkProgram(post_prog, shaders); + Utility::attachAndLinkProgram(post_prog, shaders); } void freeFBO() { - glDeleteTextures(1,&depthTexture); - glDeleteTextures(1,&normalTexture); - glDeleteTextures(1,&positionTexture); - glDeleteTextures(1,&colorTexture); - glDeleteTextures(1,&postTexture); - glDeleteFramebuffers(1,&FBO[0]); - glDeleteFramebuffers(1,&FBO[1]); + glDeleteTextures(1,&depthTexture); + glDeleteTextures(1,&normalTexture); + glDeleteTextures(1,&positionTexture); + glDeleteTextures(1,&diffColorTexture); + glDeleteTextures(1,&specColorTexture); + glDeleteTextures(1,&postTexture); + glDeleteTextures(1,&bloomTexture); + glDeleteFramebuffers(1,&FBO[0]); + glDeleteFramebuffers(1,&FBO[1]); } void checkFramebufferStatus(GLenum framebufferStatus) { - switch (framebufferStatus) { - case GL_FRAMEBUFFER_COMPLETE_EXT: break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: - printf("Attachment Point Unconnected\n"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: - printf("Missing Attachment\n"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: - printf("Dimensions do not match\n"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: - printf("Formats\n"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: - printf("Draw Buffer\n"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: - printf("Read Buffer\n"); - break; - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - printf("Unsupported Framebuffer Configuration\n"); - break; - default: - printf("Unkown Framebuffer Object Failure\n"); - break; - } + switch (framebufferStatus) { + case GL_FRAMEBUFFER_COMPLETE_EXT: break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: + printf("Attachment Point Unconnected\n"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: + printf("Missing Attachment\n"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: + printf("Dimensions do not match\n"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: + printf("Formats\n"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: + printf("Draw Buffer\n"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: + printf("Read Buffer\n"); + break; + case GL_FRAMEBUFFER_UNSUPPORTED_EXT: + printf("Unsupported Framebuffer Configuration\n"); + break; + default: + printf("Unkown Framebuffer Object Failure\n"); + break; + } } @@ -341,375 +486,452 @@ void initNoise() { const char * rand_png = "../res/random.png"; #endif random_normal_tex = (unsigned int)SOIL_load_OGL_texture(rand_norm_png,0,0,0); - glBindTexture(GL_TEXTURE_2D, random_normal_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_2D, random_normal_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glBindTexture(GL_TEXTURE_2D, 0); random_scalar_tex = (unsigned int)SOIL_load_OGL_texture(rand_png,0,0,0); - glBindTexture(GL_TEXTURE_2D, random_scalar_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_2D, random_scalar_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glBindTexture(GL_TEXTURE_2D, 0); } void initFBO(int w, int h) { - GLenum FBOstatus; + GLenum FBOstatus; + + glActiveTexture(GL_TEXTURE9); + + glGenTextures(1, &depthTexture); + glGenTextures(1, &normalTexture); + glGenTextures(1, &positionTexture); + glGenTextures(1, &diffColorTexture); + glGenTextures(1, &bloomTexture); + glGenTextures(1, &specColorTexture); + + //Set up depth FBO + glBindTexture(GL_TEXTURE_2D, depthTexture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); - glActiveTexture(GL_TEXTURE9); + glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, w, h, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); - glGenTextures(1, &depthTexture); - glGenTextures(1, &normalTexture); - glGenTextures(1, &positionTexture); - glGenTextures(1, &colorTexture); + //Set up normal FBO + glBindTexture(GL_TEXTURE_2D, normalTexture); - //Set up depth FBO - glBindTexture(GL_TEXTURE_2D, depthTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0); - glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, w, h, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); + //Set up position FBO + glBindTexture(GL_TEXTURE_2D, positionTexture); - //Set up normal FBO - glBindTexture(GL_TEXTURE_2D, normalTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0); + //Set up diffuse color FBO + glBindTexture(GL_TEXTURE_2D, diffColorTexture); - //Set up position FBO - glBindTexture(GL_TEXTURE_2D, positionTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0); + //Set up specular color FBO + glBindTexture(GL_TEXTURE_2D, specColorTexture); - //Set up color FBO - glBindTexture(GL_TEXTURE_2D, colorTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0); - // creatwwe a framebuffer object - glGenFramebuffers(1, &FBO[0]); - glBindFramebuffer(GL_FRAMEBUFFER, FBO[0]); + //Set up diffuse color FBO + glBindTexture(GL_TEXTURE_2D, bloomTexture); - // Instruct openGL that we won't bind a color texture with the currently bound FBO - glReadBuffer(GL_NONE); - GLint normal_loc = glGetFragDataLocation(pass_prog,"out_Normal"); - GLint position_loc = glGetFragDataLocation(pass_prog,"out_Position"); - GLint color_loc = glGetFragDataLocation(pass_prog,"out_Color"); - GLenum draws [3]; - draws[normal_loc] = GL_COLOR_ATTACHMENT0; - draws[position_loc] = GL_COLOR_ATTACHMENT1; - draws[color_loc] = GL_COLOR_ATTACHMENT2; - glDrawBuffers(3, draws); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - // attach the texture to FBO depth attachment point - int test = GL_COLOR_ATTACHMENT0; - glBindTexture(GL_TEXTURE_2D, depthTexture); - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0); - glBindTexture(GL_TEXTURE_2D, normalTexture); - glFramebufferTexture(GL_FRAMEBUFFER, draws[normal_loc], normalTexture, 0); - glBindTexture(GL_TEXTURE_2D, positionTexture); - glFramebufferTexture(GL_FRAMEBUFFER, draws[position_loc], positionTexture, 0); - glBindTexture(GL_TEXTURE_2D, colorTexture); - glFramebufferTexture(GL_FRAMEBUFFER, draws[color_loc], colorTexture, 0); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - // check FBO status - FBOstatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if(FBOstatus != GL_FRAMEBUFFER_COMPLETE) { - printf("GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO[0]\n"); - checkFramebufferStatus(FBOstatus); - } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGB, GL_FLOAT,0); - //Post Processing buffer! - glActiveTexture(GL_TEXTURE9); - glGenTextures(1, &postTexture); + // create a framebuffer object + glGenFramebuffers(1, &FBO[0]); + glBindFramebuffer(GL_FRAMEBUFFER, FBO[0]); - //Set up post FBO - glBindTexture(GL_TEXTURE_2D, postTexture); + // Instruct openGL that we won't bind a color texture with the currently bound FBO + glReadBuffer(GL_NONE); + GLint normal_loc = glGetFragDataLocation(pass_prog,"out_Normal"); + GLint position_loc = glGetFragDataLocation(pass_prog,"out_Position"); + GLint diff_color_loc = glGetFragDataLocation(pass_prog,"out_Diff_Color"); + GLint spec_color_loc = glGetFragDataLocation(pass_prog,"out_Spec_Color"); + GLint bloom_loc = glGetFragDataLocation(pass_prog,"out_Bloom"); + GLenum draws [5]; + draws[normal_loc] = GL_COLOR_ATTACHMENT0; + draws[position_loc] = GL_COLOR_ATTACHMENT1; + draws[diff_color_loc] = GL_COLOR_ATTACHMENT2; + draws[spec_color_loc] = GL_COLOR_ATTACHMENT3; + draws[bloom_loc] = GL_COLOR_ATTACHMENT4; + glDrawBuffers(5, draws); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + // attach the texture to FBO depth attachment point + glBindTexture(GL_TEXTURE_2D, depthTexture); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0); + glBindTexture(GL_TEXTURE_2D, normalTexture); + glFramebufferTexture(GL_FRAMEBUFFER, draws[normal_loc], normalTexture, 0); + glBindTexture(GL_TEXTURE_2D, positionTexture); + glFramebufferTexture(GL_FRAMEBUFFER, draws[position_loc], positionTexture, 0); + glBindTexture(GL_TEXTURE_2D, diffColorTexture); + glFramebufferTexture(GL_FRAMEBUFFER, draws[diff_color_loc], diffColorTexture, 0); + glBindTexture(GL_TEXTURE_2D, specColorTexture); + glFramebufferTexture(GL_FRAMEBUFFER, draws[spec_color_loc], specColorTexture, 0); + glBindTexture(GL_TEXTURE_2D, bloomTexture); + glFramebufferTexture(GL_FRAMEBUFFER, draws[bloom_loc], bloomTexture, 0); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + // check FBO status + FBOstatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if(FBOstatus != GL_FRAMEBUFFER_COMPLETE) { + printf("GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO[0]\n"); + checkFramebufferStatus(FBOstatus); + } - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0); - // creatwwe a framebuffer object - glGenFramebuffers(1, &FBO[1]); - glBindFramebuffer(GL_FRAMEBUFFER, FBO[1]); + //Buffer between stage 1 and stage 2 has been initialized - // Instruct openGL that we won't bind a color texture with the currently bound FBO - glReadBuffer(GL_BACK); - color_loc = glGetFragDataLocation(ambient_prog,"out_Color"); - GLenum draw[1]; - draw[color_loc] = GL_COLOR_ATTACHMENT0; - glDrawBuffers(1, draw); - // attach the texture to FBO depth attachment point - test = GL_COLOR_ATTACHMENT0; - glBindTexture(GL_TEXTURE_2D, postTexture); - glFramebufferTexture(GL_FRAMEBUFFER, draw[color_loc], postTexture, 0); + //=======Setup Post Processing buffer!======== + glActiveTexture(GL_TEXTURE9); - // check FBO status - FBOstatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if(FBOstatus != GL_FRAMEBUFFER_COMPLETE) { - printf("GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO[1]\n"); - checkFramebufferStatus(FBOstatus); - } - - // switch back to window-system-provided framebuffer - glClear(GL_DEPTH_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glBindTexture(GL_TEXTURE_2D, 0); + glGenTextures(1, &postTexture); + + //Set up post FBO + glBindTexture(GL_TEXTURE_2D, postTexture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0); + + // creatwwe a framebuffer object + glGenFramebuffers(1, &FBO[1]); + glBindFramebuffer(GL_FRAMEBUFFER, FBO[1]); + + // Instruct openGL that we won't bind a color texture with the currently bound FBO + glReadBuffer(GL_BACK); + GLint color_loc = glGetFragDataLocation(ambient_prog,"out_Color"); + GLenum draw[1]; + draw[color_loc] = GL_COLOR_ATTACHMENT0; + glDrawBuffers(1, draw); + + // attach the texture to FBO depth attachment point + glBindTexture(GL_TEXTURE_2D, postTexture); + glFramebufferTexture(GL_FRAMEBUFFER, draw[color_loc], postTexture, 0); + + // check FBO status + FBOstatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if(FBOstatus != GL_FRAMEBUFFER_COMPLETE) { + printf("GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO[1]\n"); + checkFramebufferStatus(FBOstatus); + } + + // switch back to window-system-provided framebuffer + glClear(GL_DEPTH_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindTexture(GL_TEXTURE_2D, 0); } void bindFBO(int buf) { - glDisable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D,0); //Bad mojo to unbind the framebuffer using the texture - glBindFramebuffer(GL_FRAMEBUFFER, FBO[buf]); - glClear(GL_DEPTH_BUFFER_BIT); - //glColorMask(false,false,false,false); - glEnable(GL_DEPTH_TEST); + glDisable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D,0); //Bad mojo to unbind the framebuffer using the texture + glBindFramebuffer(GL_FRAMEBUFFER, FBO[buf]); + glClear(GL_DEPTH_BUFFER_BIT); + //glColorMask(false,false,false,false); + glEnable(GL_DEPTH_TEST); } void setTextures() { - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D,0); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D,0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); - //glColorMask(true,true,true,true); - glDisable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT); + //glColorMask(true,true,true,true); + glDisable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT); } -Camera cam(vec3(2.5, 5, 2), - normalize(vec3(0,-1,0)), - normalize(vec3(0,0,1))); +Camera cam(vec3(-7.0, 0.0, 6.0), + normalize(vec3(1,0,0)), + normalize(vec3(0,0,1))); - void -Camera::adjust(float dx, // look left right - float dy, //look up down - float dz, - float tx, //strafe left right - float ty, - float tz)//go forward) //strafe up down +void + Camera::adjust(float dx, // look left right + float dy, //look up down + float dz, + float tx, //strafe left right + float ty, + float tz)//go forward) //strafe up down { - if (abs(dx) > 0) { - rx += dx; - rx = fmod(rx,360.0f); - } - - if (abs(dy) > 0) { - ry += dy; - ry = clamp(ry,-70.0f, 70.0f); - } - - if (abs(tx) > 0) { - vec3 dir = glm::gtx::rotate_vector::rotate(start_dir,rx + 90,up); - vec2 dir2(dir.x,dir.y); - vec2 mag = dir2 * tx; - pos += mag; - } - - if (abs(ty) > 0) { - z += ty; - } - - if (abs(tz) > 0) { - vec3 dir = glm::gtx::rotate_vector::rotate(start_dir,rx,up); - vec2 dir2(dir.x,dir.y); - vec2 mag = dir2 * tz; - pos += mag; - } + if (abs(dx) > 0) { + rx += dx; + rx = fmod(rx,360.0f); + } + + if (abs(dy) > 0) { + ry += dy; + ry = clamp(ry,-70.0f, 70.0f); + } + + if (abs(tx) > 0) { + vec3 dir = glm::gtx::rotate_vector::rotate(start_dir,rx + 90,up); + vec2 dir2(dir.x,dir.y); + vec2 mag = dir2 * tx; + pos += mag; + } + + if (abs(ty) > 0) { + z += ty; + } + + if (abs(tz) > 0) { + vec3 dir = glm::gtx::rotate_vector::rotate(start_dir,rx,up); + vec2 dir2(dir.x,dir.y); + vec2 mag = dir2 * tz; + pos += mag; + } } mat4x4 Camera::get_view() { - vec3 inclin = glm::gtx::rotate_vector::rotate(start_dir,ry,start_left); - vec3 spun = glm::gtx::rotate_vector::rotate(inclin,rx,up); - vec3 cent(pos, z); - return lookAt(cent, cent + spun, up); + vec3 inclin = glm::gtx::rotate_vector::rotate(start_dir,ry,start_left); + vec3 spun = glm::gtx::rotate_vector::rotate(inclin,rx,up); + vec3 cent(pos, z); + return lookAt(cent, cent + spun, up); } mat4x4 get_mesh_world() { - vec3 tilt(1.0f,0.0f,0.0f); - //mat4 translate_mat = glm::translate(glm::vec3(0.0f,.5f,0.0f)); - mat4 tilt_mat = glm::rotate(mat4(), 90.0f, tilt); - mat4 scale_mat = glm::scale(mat4(), vec3(0.01)); - return tilt_mat * scale_mat; //translate_mat; + vec3 tilt(1.0f,0.0f,0.0f); + //mat4 translate_mat = glm::translate(glm::vec3(0.0f,.5f,0.0f)); + mat4 tilt_mat = glm::rotate(mat4(), 90.0f, tilt); + mat4 scale_mat = glm::scale(mat4(), vec3(0.01)); + return tilt_mat * scale_mat; //translate_mat; } -float FARP; -float NEARP; void draw_mesh() { - FARP = 100.0f; - NEARP = 0.1f; - - glUseProgram(pass_prog); - - - mat4 model = get_mesh_world(); - mat4 view = cam.get_view(); - mat4 persp = perspective(45.0f,(float)width/(float)height,NEARP,FARP); - mat4 inverse_transposed = transpose(inverse(view*model)); - - glUniform1f(glGetUniformLocation(pass_prog, "u_Far"), FARP); - glUniformMatrix4fv(glGetUniformLocation(pass_prog,"u_Model"),1,GL_FALSE,&model[0][0]); - glUniformMatrix4fv(glGetUniformLocation(pass_prog,"u_View"),1,GL_FALSE,&view[0][0]); - glUniformMatrix4fv(glGetUniformLocation(pass_prog,"u_Persp"),1,GL_FALSE,&persp[0][0]); - glUniformMatrix4fv(glGetUniformLocation(pass_prog,"u_InvTrans") ,1,GL_FALSE,&inverse_transposed[0][0]); - - for(int i=0; i 0)?1:0); + glUniform1i(glGetUniformLocation(pass_prog, "u_hasSpecTex"), + (specularMappingEnabled && draw_meshes[i].spec_texid > 0)?1:0); + glUniform1i(glGetUniformLocation(pass_prog, "u_hasBumpTex"), + (bumpMappingEnabled && draw_meshes[i].bump_texid > 0)?1:0); + glUniform1i(glGetUniformLocation(pass_prog, "u_hasMaskTex"), + (maskingEnabled && draw_meshes[i].mask_texid > 0)?1:0); + + glBindVertexArray(draw_meshes[i].vertex_array); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, draw_meshes[i].vbo_indices); + glDrawElements(GL_TRIANGLES, draw_meshes[i].num_indices, GL_UNSIGNED_SHORT,0); + } + glBindVertexArray(0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); } -enum Display display_type = DISPLAY_TOTAL; - void setup_quad(GLuint prog) { - glUseProgram(prog); - glEnable(GL_TEXTURE_2D); - - mat4 persp = perspective(45.0f,(float)width/(float)height,NEARP,FARP); - vec4 test(-2,0,10,1); - vec4 testp = persp * test; - vec4 testh = testp / testp.w; - vec2 coords = vec2(testh.x, testh.y) / 2.0f + 0.5f; - glUniform1i(glGetUniformLocation(prog, "u_ScreenHeight"), height); - glUniform1i(glGetUniformLocation(prog, "u_ScreenWidth"), width); - glUniform1f(glGetUniformLocation(prog, "u_Far"), FARP); - glUniform1f(glGetUniformLocation(prog, "u_Near"), NEARP); - glUniform1i(glGetUniformLocation(prog, "u_DisplayType"), display_type); - glUniformMatrix4fv(glGetUniformLocation(prog, "u_Persp"),1, GL_FALSE, &persp[0][0] ); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, depthTexture); - glUniform1i(glGetUniformLocation(prog, "u_Depthtex"),0); - - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, normalTexture); - glUniform1i(glGetUniformLocation(prog, "u_Normaltex"),1); - - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, positionTexture); - glUniform1i(glGetUniformLocation(prog, "u_Positiontex"),2); - - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, colorTexture); - glUniform1i(glGetUniformLocation(prog, "u_Colortex"),3); - - glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_2D, random_normal_tex); - glUniform1i(glGetUniformLocation(prog, "u_RandomNormaltex"),4); - - glActiveTexture(GL_TEXTURE5); - glBindTexture(GL_TEXTURE_2D, random_scalar_tex); - glUniform1i(glGetUniformLocation(prog, "u_RandomScalartex"),5); + glUseProgram(prog); + glEnable(GL_TEXTURE_2D); + + mat4 persp = perspective(45.0f,(float)width/(float)height,NEARP,FARP); + vec4 test(-2,0,10,1); + vec4 testp = persp * test; + vec4 testh = testp / testp.w; + vec2 coords = vec2(testh.x, testh.y) / 2.0f + 0.5f; + glUniform1i(glGetUniformLocation(prog, "u_ScreenHeight"), height); + glUniform1i(glGetUniformLocation(prog, "u_ScreenWidth"), width); + glUniform1f(glGetUniformLocation(prog, "u_Far"), FARP); + glUniform1f(glGetUniformLocation(prog, "u_Near"), NEARP); + glUniform1i(glGetUniformLocation(prog, "u_DisplayType"), display_type); + glUniformMatrix4fv(glGetUniformLocation(prog, "u_Persp"),1, GL_FALSE, &persp[0][0] ); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, depthTexture); + glUniform1i(glGetUniformLocation(prog, "u_Depthtex"),0); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, normalTexture); + glUniform1i(glGetUniformLocation(prog, "u_Normaltex"),1); + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, positionTexture); + glUniform1i(glGetUniformLocation(prog, "u_Positiontex"),2); + + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, diffColorTexture); + glUniform1i(glGetUniformLocation(prog, "u_DiffColortex"),3); + + glActiveTexture(GL_TEXTURE4); + glBindTexture(GL_TEXTURE_2D, specColorTexture); + glUniform1i(glGetUniformLocation(prog, "u_SpecColortex"),4); + + + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_2D, random_normal_tex); + glUniform1i(glGetUniformLocation(prog, "u_RandomNormaltex"),5); + + glActiveTexture(GL_TEXTURE6); + glBindTexture(GL_TEXTURE_2D, random_scalar_tex); + glUniform1i(glGetUniformLocation(prog, "u_RandomScalartex"),6); + + glActiveTexture(GL_TEXTURE7); + glBindTexture(GL_TEXTURE_2D, bloomTexture); + glUniform1i(glGetUniformLocation(prog, "u_Bloomtex"),7); } void draw_quad() { - glBindVertexArray(device_quad.vertex_array); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, device_quad.vbo_indices); + glBindVertexArray(device_quad.vertex_array); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, device_quad.vbo_indices); - glDrawElements(GL_TRIANGLES, device_quad.num_indices, GL_UNSIGNED_SHORT,0); + glDrawElements(GL_TRIANGLES, device_quad.num_indices, GL_UNSIGNED_SHORT,0); - glBindVertexArray(0); + glBindVertexArray(0); } +bool doIScissor = false; void draw_light(vec3 pos, float strength, mat4 sc, mat4 vp, float NEARP) { - float radius = strength; - vec4 light = cam.get_view() * vec4(pos, 1.0); - if( light.z > NEARP) - { - return; - } - light.w = radius; - glUniform4fv(glGetUniformLocation(point_prog, "u_Light"), 1, &(light[0])); - glUniform1f(glGetUniformLocation(point_prog, "u_LightIl"), strength); - - vec4 left = vp * vec4(pos + radius*cam.start_left, 1.0); - vec4 up = vp * vec4(pos + radius*cam.up, 1.0); - vec4 center = vp * vec4(pos, 1.0); - - left = sc * left; - up = sc * up; - center = sc * center; - - left /= left.w; - up /= up.w; - center /= center.w; - - float hw = glm::distance(left, center); - float hh = glm::distance(up, center); - - float r = (hh > hw) ? hh : hw; - - float x = center.x-r; - float y = center.y-r; - - glScissor(x, y, 2*r, 2*r); - draw_quad(); + float radius = strength; + vec4 light = cam.get_view() * vec4(pos, 1.0); + if( light.z > NEARP && doIScissor) + { + return; + } + light.w = radius; + glUniform4fv(glGetUniformLocation(point_prog, "u_Light"), 1, &(light[0])); + glUniform1f(glGetUniformLocation(point_prog, "u_LightIl"), strength); + + vec4 left = vp * vec4(pos + radius*cam.start_left, 1.0); + vec4 up = vp * vec4(pos + radius*cam.up, 1.0); + vec4 center = vp * vec4(pos, 1.0); + + left /= left.w; + up /= up.w; + center /= center.w; + + left = sc * left; + up = sc * up; + center = sc * center; + + float hw = glm::distance(left, center); + float hh = glm::distance(up, center); + + float r = (hh > hw) ? hh : hw; + + float x = center.x-r; + float y = center.y-r; + + glScissor(x, y, 2*r, 2*r); + draw_quad(); } void updateDisplayText(char * disp) { - switch(display_type) { - case(DISPLAY_DEPTH): - sprintf(disp, "Displaying Depth"); - break; - case(DISPLAY_NORMAL): - sprintf(disp, "Displaying Normal"); - break; - case(DISPLAY_COLOR): - sprintf(disp, "Displaying Color"); - break; - case(DISPLAY_POSITION): - sprintf(disp, "Displaying Position"); - break; - case(DISPLAY_TOTAL): - sprintf(disp, "Displaying Diffuse"); - break; - case(DISPLAY_LIGHTS): - sprintf(disp, "Displaying Lights"); - break; - } + switch(display_type) { + case(DISPLAY_DEPTH): + sprintf(disp, "Displaying Depth"); + break; + case(DISPLAY_NORMAL): + sprintf(disp, "Displaying Normal"); + break; + case(DISPLAY_DIFFUSE): + sprintf(disp, "Displaying Diffuse Color"); + break; + case (DISPLAY_SPECULAR): + sprintf(disp, "Displaying Specular Color"); + break; + case (DISPLAY_BLOOM): + sprintf(disp, "Displaying Bloom Mask"); + break; + case(DISPLAY_POSITION): + sprintf(disp, "Displaying Position"); + break; + case(DISPLAY_TOTAL): + sprintf(disp, "Displaying Total"); + break; + case(DISPLAY_LIGHTS): + sprintf(disp, "Displaying Lights"); + break; + } } int frame = 0; @@ -720,118 +942,204 @@ char disp[1024]; char occl[1024]; void updateTitle() { - updateDisplayText(disp); - //calculate the frames per second - frame++; - - //get the current time - currenttime = glutGet(GLUT_ELAPSED_TIME); - - //check if a second has passed - if (currenttime - timebase > 1000) - { - sprintf(title, "CIS565 OpenGL Frame | %s FPS: %4.2f", disp, frame*1000.0/(currenttime-timebase)); - //sprintf(title, "CIS565 OpenGL Frame | %4.2f FPS", frame*1000.0/(currenttime-timebase)); - glutSetWindowTitle(title); - timebase = currenttime; - frame = 0; - } + updateDisplayText(disp); + //calculate the frames per second + frame++; + + //get the current time + currenttime = glutGet(GLUT_ELAPSED_TIME); + + //check if a second has passed + if (currenttime - timebase > 1000) + { + sprintf(title, "CIS565 OpenGL Frame | %s FPS: %4.2f", disp, frame*1000.0/(currenttime-timebase)); + //sprintf(title, "CIS565 OpenGL Frame | %4.2f FPS", frame*1000.0/(currenttime-timebase)); + glutSetWindowTitle(title); + timebase = currenttime; + frame = 0; + } } -bool doIScissor = true; + +double t_ms_s1 = 0.0, t_ms_s2 = 0.0, t_ms_s3 = 0.0; +int frameCount = 0; void display(void) { - // Stage 1 -- RENDER TO G-BUFFER - bindFBO(0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - draw_mesh(); - - // Stage 2 -- RENDER TO P-BUFFER - setTextures(); - bindFBO(1); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glDisable(GL_DEPTH_TEST); - glBlendFunc(GL_ONE, GL_ONE); - glClear(GL_COLOR_BUFFER_BIT); - if(display_type == DISPLAY_LIGHTS || display_type == DISPLAY_TOTAL) - { - setup_quad(point_prog); - if(doIScissor) glEnable(GL_SCISSOR_TEST); - mat4 vp = perspective(45.0f,(float)width/(float)height,NEARP,FARP) * - cam.get_view(); - mat4 sc = mat4(width, 0.0, 0.0, 0.0, - 0.0, height, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0) * - mat4(0.5, 0.0, 0.0, 0.0, - 0.0, 0.5, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.5, 0.5, 0.0, 1.0); - - draw_light(vec3(2.5, -2.5, 5.0), 0.50, sc, vp, NEARP); - - glDisable(GL_SCISSOR_TEST); - vec4 dir_light(0.1, 1.0, 1.0, 0.0); - dir_light = cam.get_view() * dir_light; - dir_light = normalize(dir_light); - dir_light.w = 0.3; - float strength = 0.09; - setup_quad(ambient_prog); - glUniform4fv(glGetUniformLocation(ambient_prog, "u_Light"), 1, &(dir_light[0])); - glUniform1f(glGetUniformLocation(ambient_prog, "u_LightIl"), strength); - draw_quad(); - } - else - { - setup_quad(diagnostic_prog); - draw_quad(); - } - glDisable(GL_BLEND); - - //Stage 3 -- RENDER TO SCREEN - setTextures(); - glUseProgram(post_prog); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_TEXTURE_2D); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, postTexture); - glUniform1i(glGetUniformLocation(post_prog, "u_Posttex"),0); - - glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_2D, random_normal_tex); - glUniform1i(glGetUniformLocation(post_prog, "u_RandomNormaltex"),4); - - glActiveTexture(GL_TEXTURE5); - glBindTexture(GL_TEXTURE_2D, random_scalar_tex); - glUniform1i(glGetUniformLocation(post_prog, "u_RandomScalartex"),5); - - glUniform1i(glGetUniformLocation(post_prog, "u_ScreenHeight"), height); - glUniform1i(glGetUniformLocation(post_prog, "u_ScreenWidth"), width); - draw_quad(); - - glEnable(GL_DEPTH_TEST); - updateTitle(); - - glutPostRedisplay(); - glutSwapBuffers(); + double freq; + LARGE_INTEGER beginTime; + LARGE_INTEGER endTime; + if(logTime){ + frameCount++; + LARGE_INTEGER timerFreq; + QueryPerformanceFrequency( &timerFreq ); + freq = 1.0f / timerFreq.QuadPart; + + + + //Measure stage 1 runtime + QueryPerformanceCounter( &beginTime ); + } + + // Stage 1 -- RENDER TO G-BUFFER + bindFBO(0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + draw_mesh(); + //At this point, G-Buffer has appropriate geometry rendered + + if(logTime){ + glFinish(); + QueryPerformanceCounter( &endTime ); + t_ms_s1 = ((frameCount - 1)*t_ms_s1+( endTime.QuadPart - beginTime.QuadPart )* freq*1000.0)/float(frameCount); + + //Measure stage two runtime + QueryPerformanceCounter( &beginTime ); + } + + // Stage 2 -- RENDER TO P-BUFFER + setTextures(); + bindFBO(1); + glEnable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glBlendFunc(GL_ONE, GL_ONE); + glClear(GL_COLOR_BUFFER_BIT); + if(display_type == DISPLAY_LIGHTS || display_type == DISPLAY_TOTAL) + { + setup_quad(point_prog); + if(doIScissor) glEnable(GL_SCISSOR_TEST); + mat4 vp = perspective(45.0f,(float)width/(float)height,NEARP,FARP) * + cam.get_view(); + mat4 sc = mat4(width, 0.0, 0.0, 0.0, + 0.0, height, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0) * + mat4(0.5, 0.0, 0.0, 0.0, + 0.0, 0.5, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.5, 0.5, 0.0, 1.0); + + //Floor fixtures + draw_light(vec3(-9.36, -1.5, 0.8), 2.0, sc, vp, NEARP); + draw_light(vec3(-9.36, 2.25, 0.8), 2.0, sc, vp, NEARP); + draw_light(vec3(-2.25, -1.5, 0.8), 2.0, sc, vp, NEARP); + draw_light(vec3(-2.25, 2.25, 0.8), 2.0, sc, vp, NEARP); + draw_light(vec3(1.25, -1.5, 0.8), 2.0, sc, vp, NEARP); + draw_light(vec3(1.25, 2.25, 0.8), 2.0, sc, vp, NEARP); + draw_light(vec3(8.25, -1.5, 0.8), 2.0, sc, vp, NEARP); + draw_light(vec3(8.25, 2.25, 0.8), 2.0, sc, vp, NEARP); + + //Lamps + draw_light(vec3(4.8, 2.0, 1.6), 5.0, sc, vp, NEARP); + draw_light(vec3(4.8, -1.2, 1.6), 5.0, sc, vp, NEARP); + draw_light(vec3(-6.0, 2.0, 1.6), 5.0, sc, vp, NEARP); + draw_light(vec3(-6.0, -1.2, 1.6), 5.0, sc, vp, NEARP); + + //Overhead lights + draw_light(vec3(5.0, 0.0, 10.0), 7.0, sc, vp, NEARP); + draw_light(vec3(1.25, 0.0, 10.0), 7.0, sc, vp, NEARP); + draw_light(vec3(-2.5, 0.0, 10.0), 7.0, sc, vp, NEARP); + draw_light(vec3(-6.25, 0.0, 10.0), 7.0, sc, vp, NEARP); + + //Lion lighting + draw_light(vec3(12.0, 0.0, 3.5), 7.0, sc, vp, NEARP); + draw_light(vec3(-12.0, 0.0, 3.5), 7.0, sc, vp, NEARP); + + glDisable(GL_SCISSOR_TEST); + vec4 dir_light(0.1, 1.0, 10.0, 0.0); + dir_light = cam.get_view() * dir_light; + dir_light = normalize(dir_light); + dir_light.w = 0.3; + float strength = 0.09; + setup_quad(ambient_prog); + glUniform4fv(glGetUniformLocation(ambient_prog, "u_Light"), 1, &(dir_light[0])); + glUniform1f(glGetUniformLocation(ambient_prog, "u_LightIl"), strength); + draw_quad(); + } + else + { + setup_quad(diagnostic_prog); + draw_quad(); + } + glDisable(GL_BLEND); + + if(logTime){ + glFinish(); + QueryPerformanceCounter( &endTime ); + t_ms_s2 = ((frameCount - 1)*t_ms_s2+( endTime.QuadPart - beginTime.QuadPart )* freq*1000.0)/float(frameCount); + + //Stage 3 timing + QueryPerformanceCounter( &beginTime ); + } + //Stage 3 -- RENDER TO SCREEN + setTextures(); + glUseProgram(post_prog); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_TEXTURE_2D); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, postTexture); + glUniform1i(glGetUniformLocation(post_prog, "u_Posttex"),0); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, depthTexture); + glUniform1i(glGetUniformLocation(post_prog, "u_Depthtex"),1); + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, normalTexture); + glUniform1i(glGetUniformLocation(post_prog, "u_Normaltex"),2); + + + + glActiveTexture(GL_TEXTURE4); + glBindTexture(GL_TEXTURE_2D, random_normal_tex); + glUniform1i(glGetUniformLocation(post_prog, "u_RandomNormaltex"),4); + + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_2D, random_scalar_tex); + glUniform1i(glGetUniformLocation(post_prog, "u_RandomScalartex"),5); + + glActiveTexture(GL_TEXTURE7); + glBindTexture(GL_TEXTURE_2D, bloomTexture); + glUniform1i(glGetUniformLocation(post_prog, "u_Bloomtex"),7); + + glUniform1i(glGetUniformLocation(post_prog, "u_ScreenHeight"), height); + glUniform1i(glGetUniformLocation(post_prog, "u_ScreenWidth"), width); + glUniform1i(glGetUniformLocation(post_prog, "u_UseBloom"), useBloom?1.0:0.0); + glUniform1i(glGetUniformLocation(post_prog, "u_UseToon"), useToon?1.0:0.0); + glUniform1f(glGetUniformLocation(post_prog, "u_Far"), FARP); + glUniform1f(glGetUniformLocation(post_prog, "u_Near"), NEARP); + draw_quad(); + + if(logTime){ + glFinish(); + QueryPerformanceCounter( &endTime ); + t_ms_s3 = ((frameCount - 1)*t_ms_s3+( endTime.QuadPart - beginTime.QuadPart )* freq*1000.0)/float(frameCount); + } + glEnable(GL_DEPTH_TEST); + updateTitle(); + + glutPostRedisplay(); + glutSwapBuffers(); + + if(logTime){ + printf("Time (ms) s1: %3.5f, s2: %3.5f, s3 %3.5f\n", t_ms_s1, t_ms_s2, t_ms_s3); + } } void reshape(int w, int h) { - width = w; - height = h; - glBindFramebuffer(GL_FRAMEBUFFER,0); - glViewport(0,0,(GLsizei)w,(GLsizei)h); - if (FBO[0] != 0 || depthTexture != 0 || normalTexture != 0 ) { - freeFBO(); - } - initFBO(w,h); + width = w; + height = h; + glBindFramebuffer(GL_FRAMEBUFFER,0); + glViewport(0,0,(GLsizei)w,(GLsizei)h); + if (FBO[0] != 0 || depthTexture != 0 || normalTexture != 0 ) { + freeFBO(); + } + initFBO(w,h); } @@ -840,153 +1148,269 @@ int mouse_old_x = 0; int mouse_old_y = 0; void mouse(int button, int state, int x, int y) { - if (state == GLUT_DOWN) { - mouse_buttons |= 1< 0 || abs(tz) > 0 || abs(ty) > 0) { - cam.adjust(0,0,0,tx,ty,tz); - } + float tx = 0; + float ty = 0; + float tz = 0; + switch(key) { + case(27): + exit(0.0); + break; + case('w'): + tz = 0.1; + break; + case('s'): + tz = -0.1; + break; + case('d'): + tx = -0.1; + break; + case('a'): + tx = 0.1; + break; + case('q'): + ty = 0.1; + break; + case('z'): + ty = -0.1; + break; + case('1'): + cout << "Depth Debug Mode" << endl; + display_type = DISPLAY_DEPTH; + break; + case('2'): + cout << "Normal Debug Mode" << endl; + display_type = DISPLAY_NORMAL; + break; + case('3'): + cout << "Display Diffuse Debug Mode" << endl; + display_type = DISPLAY_DIFFUSE; + break; + case('4'): + cout << "Display Eye Space Position Debug Mode" << endl; + display_type = DISPLAY_POSITION; + break; + case('5'): + cout << "Display Lights Debug Mode" << endl; + display_type = DISPLAY_LIGHTS; + break; + case('6'): + cout << "Display Specular Debug Mode" << endl; + display_type = DISPLAY_SPECULAR; + break; + case('7'): + cout << "Display Bloom Debug Mode" << endl; + display_type = DISPLAY_BLOOM; + break; + case('0'): + cout << "Full Rendering Mode" << endl; + display_type = DISPLAY_TOTAL; + break; + case('L'): + cout << "Turning Bloom "; + useBloom ^= true; + if(useBloom) + { + cout << "On" << endl; + }else{ + cout << "Off" << endl; + } + break; + case('T'): + cout << "Turning Toon Shading "; + useToon ^= true; + if(useToon) + { + cout << "On" << endl; + }else{ + cout << "Off" << endl; + } + break; + case('t'): + cout << "Passthrough Texture Coordinates as Diffuse Color" << endl; + passthrough_type = TEXCOORDS_AS_DIFFUSE; + break; + case('c'): + cout << "Passthrough Diffuse Color as Diffuse Color" << endl; + passthrough_type = NO_CHANGE; + break; + case('h'): + cout << "Has Texture Overlay" << endl; + passthrough_type = HASTEX_OVERLAY; + break; + case('b'): + cout << "Bump Texture as Diffuse Color" << endl; + passthrough_type = BUMP_AS_DIFFUSE; + break; + case('m'): + cout << "Mask Texture as Diffuse Color" << endl; + passthrough_type = MASK_OVERLAY; + break; + case('x'): + cout << "Turning Scissor Test "; + doIScissor ^= true; + if(doIScissor) + { + cout << "On" << endl; + }else{ + cout << "Off" << endl; + } + break; + case('r'): + cout << "Reloading Shaders" < 0 || abs(tz) > 0 || abs(ty) > 0) { + cam.adjust(0,0,0,tx,ty,tz); + } } void init() { - glEnable(GL_DEPTH_TEST); - glClearColor(0.0f, 0.0f, 0.0f,1.0f); + glEnable(GL_DEPTH_TEST); + glClearColor(0.0f, 0.0f, 0.0f,1.0f); } int main (int argc, char* argv[]) { - bool loadedScene = false; - for(int i=1; i::max(), '\n' ); - return 0; - } - - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); - width = 1280; - height = 720; - glutInitWindowSize(width,height); - glutCreateWindow("CIS565 OpenGL Frame"); - glewInit(); - GLenum err = glewInit(); - if (GLEW_OK != err) - { - /* Problem: glewInit failed, something is seriously wrong. */ - cout << "glewInit failed, aborting." << endl; - exit (1); - } - cout << "Status: Using GLEW " << glewGetString(GLEW_VERSION) << endl; - cout << "OpenGL version " << glGetString(GL_VERSION) << " supported" << endl; - - initNoise(); - initShader(); - initFBO(width,height); - init(); - initMesh(); - initQuad(); - - - glutDisplayFunc(display); - glutReshapeFunc(reshape); - glutKeyboardFunc(keyboard); - glutMouseFunc(mouse); - glutMotionFunc(motion); - - glutMainLoop(); - return 0; + bool loadedScene = false; + for(int i=1; i::max(), '\n' ); + return 0; + } + + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); + width = 1280; + height = 720; + glutInitWindowSize(width,height); + glutCreateWindow("CIS565 OpenGL Frame"); + glewInit(); + GLenum err = glewInit(); + if (GLEW_OK != err) + { + /* Problem: glewInit failed, something is seriously wrong. */ + cout << "glewInit failed, aborting." << endl; + exit (1); + } + cout << "Status: Using GLEW " << glewGetString(GLEW_VERSION) << endl; + cout << "OpenGL version " << glGetString(GL_VERSION) << " supported" << endl; + + initNoise(); + initShader(); + initFBO(width,height); + init(); + initMesh(); + initQuad(); + + + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyboard); + glutMouseFunc(mouse); + glutMotionFunc(motion); + + glutMainLoop(); + return 0; } diff --git a/base/src/main.h b/base/src/main.h index 0a96a3a..5969b76 100644 --- a/base/src/main.h +++ b/base/src/main.h @@ -11,21 +11,21 @@ class Camera { public: - Camera(glm::vec3 start_pos, glm::vec3 start_dir, glm::vec3 up) : - pos(start_pos.x, start_pos.y), z(start_pos.z), up(up), - start_dir(start_dir), start_left(glm::cross(start_dir,up)), rx(0), ry(0) { } + Camera(glm::vec3 start_pos, glm::vec3 start_dir, glm::vec3 up) : + pos(start_pos.x, start_pos.y), z(start_pos.z), up(up), + start_dir(start_dir), start_left(glm::cross(start_dir,up)), rx(0), ry(0) { } - void adjust(float dx, float dy, float dz, float tx, float ty, float tz); + void adjust(float dx, float dy, float dz, float tx, float ty, float tz); - glm::mat4x4 get_view(); + glm::mat4x4 get_view(); - float rx; - float ry; - float z; - glm::vec2 pos; - glm::vec3 up; - glm::vec3 start_left; - glm::vec3 start_dir; + float rx; + float ry; + float z; + glm::vec2 pos; + glm::vec3 up; + glm::vec3 start_left; + glm::vec3 start_dir; }; std::vector shapes; @@ -33,10 +33,19 @@ std::vector shapes; typedef struct { std::vector vertices; std::vector normals; + std::vector tangents; std::vector texcoords; std::vector indices; - std::string texname; - glm::vec3 color; + + glm::vec3 Ka; + glm::vec3 Kd; + glm::vec3 Ks; + float spec_exp; + + unsigned int diff_texid; + unsigned int spec_texid; + unsigned int bump_texid; + unsigned int mask_texid; } mesh_t; typedef struct { @@ -45,9 +54,19 @@ typedef struct { unsigned int num_indices; unsigned int vbo_vertices; unsigned int vbo_normals; + unsigned int vbo_tangents; unsigned int vbo_texcoords; - glm::vec3 color; - std::string texname; + + glm::vec3 Ka; + glm::vec3 Kd; + glm::vec3 Ks; + float spec_exp; + + unsigned int diff_texid; + unsigned int spec_texid; + unsigned int bump_texid; + unsigned int mask_texid; + } device_mesh_t; typedef struct { @@ -67,23 +86,36 @@ namespace mesh_attributes { enum { POSITION, NORMAL, - TEXCOORD + TANGENT, + TEXCOORD }; } namespace quad_attributes { - enum { - POSITION, - TEXCOORD - }; + enum { + POSITION, + TEXCOORD + }; } enum Display { - DISPLAY_DEPTH = 0, - DISPLAY_NORMAL = 1, - DISPLAY_POSITION = 2, - DISPLAY_COLOR = 3, - DISPLAY_TOTAL = 4, - DISPLAY_LIGHTS = 5 + DISPLAY_DEPTH = 0, + DISPLAY_NORMAL = 1, + DISPLAY_POSITION = 2, + DISPLAY_DIFFUSE = 3, + DISPLAY_TOTAL = 4, + DISPLAY_LIGHTS = 5, + DISPLAY_SPECULAR = 6, + DISPLAY_BLOOM = 7 + +}; + + +enum Passthrough { + NO_CHANGE = 0, + HASTEX_OVERLAY = 1, + TEXCOORDS_AS_DIFFUSE = 2, + BUMP_AS_DIFFUSE = 3, + MASK_OVERLAY = 4 }; char* loadFile(char *fname, GLint &fSize); diff --git a/base/src/tiny_obj_loader/tiny_obj_loader.cc b/base/src/tiny_obj_loader/tiny_obj_loader.cc index 7894e70..05e8b38 100644 --- a/base/src/tiny_obj_loader/tiny_obj_loader.cc +++ b/base/src/tiny_obj_loader/tiny_obj_loader.cc @@ -270,6 +270,7 @@ void InitMaterial(material_t& material) { material.emission[i] = 0.f; } material.shininess = 1.f; + material.unknown_parameter.clear();//flush unknown parameters. } std::string LoadMtl ( diff --git a/renders/FullHallAllTextures.PNG b/renders/FullHallAllTextures.PNG new file mode 100644 index 0000000..de3419e Binary files /dev/null and b/renders/FullHallAllTextures.PNG differ diff --git a/renders/FullHallBaseline.PNG b/renders/FullHallBaseline.PNG new file mode 100644 index 0000000..83001ba Binary files /dev/null and b/renders/FullHallBaseline.PNG differ diff --git a/renders/FullHallBloom.PNG b/renders/FullHallBloom.PNG new file mode 100644 index 0000000..ac22ea4 Binary files /dev/null and b/renders/FullHallBloom.PNG differ diff --git a/renders/FullHallBumpOnly.PNG b/renders/FullHallBumpOnly.PNG new file mode 100644 index 0000000..95fb367 Binary files /dev/null and b/renders/FullHallBumpOnly.PNG differ diff --git a/renders/FullHallDiffuseOnly.PNG b/renders/FullHallDiffuseOnly.PNG new file mode 100644 index 0000000..992d041 Binary files /dev/null and b/renders/FullHallDiffuseOnly.PNG differ diff --git a/renders/FullHallMaskOnly.PNG b/renders/FullHallMaskOnly.PNG new file mode 100644 index 0000000..5810a62 Binary files /dev/null and b/renders/FullHallMaskOnly.PNG differ diff --git a/renders/FullHallSpecularOnly.PNG b/renders/FullHallSpecularOnly.PNG new file mode 100644 index 0000000..4b4809d Binary files /dev/null and b/renders/FullHallSpecularOnly.PNG differ diff --git a/renders/FullHallTiming.PNG b/renders/FullHallTiming.PNG new file mode 100644 index 0000000..51d7fe3 Binary files /dev/null and b/renders/FullHallTiming.PNG differ diff --git a/renders/FullHallTimingBloom.PNG b/renders/FullHallTimingBloom.PNG new file mode 100644 index 0000000..aa10b37 Binary files /dev/null and b/renders/FullHallTimingBloom.PNG differ diff --git a/renders/FullHallToon.PNG b/renders/FullHallToon.PNG new file mode 100644 index 0000000..ca4f7eb Binary files /dev/null and b/renders/FullHallToon.PNG differ diff --git a/renders/HighView.PNG b/renders/HighView.PNG new file mode 100644 index 0000000..ca0a1ed Binary files /dev/null and b/renders/HighView.PNG differ diff --git a/renders/LampNoBloom.PNG b/renders/LampNoBloom.PNG new file mode 100644 index 0000000..e6114d7 Binary files /dev/null and b/renders/LampNoBloom.PNG differ diff --git a/renders/LampWithBloom.PNG b/renders/LampWithBloom.PNG new file mode 100644 index 0000000..5dc6367 Binary files /dev/null and b/renders/LampWithBloom.PNG differ diff --git a/renders/LionClose.PNG b/renders/LionClose.PNG new file mode 100644 index 0000000..03c7730 Binary files /dev/null and b/renders/LionClose.PNG differ diff --git a/renders/LionCloseNoBump.PNG b/renders/LionCloseNoBump.PNG new file mode 100644 index 0000000..4f7fb89 Binary files /dev/null and b/renders/LionCloseNoBump.PNG differ diff --git a/renders/LionCloseupTiming.PNG b/renders/LionCloseupTiming.PNG new file mode 100644 index 0000000..0cb883f Binary files /dev/null and b/renders/LionCloseupTiming.PNG differ diff --git a/renders/LionCloseupTimingBloom.PNG b/renders/LionCloseupTimingBloom.PNG new file mode 100644 index 0000000..3f57e31 Binary files /dev/null and b/renders/LionCloseupTimingBloom.PNG differ diff --git a/renders/Performance Estimates.xlsx b/renders/Performance Estimates.xlsx new file mode 100644 index 0000000..1f2feda Binary files /dev/null and b/renders/Performance Estimates.xlsx differ diff --git a/renders/PlantsNoMask.PNG b/renders/PlantsNoMask.PNG new file mode 100644 index 0000000..58198da Binary files /dev/null and b/renders/PlantsNoMask.PNG differ diff --git a/renders/PlantsWithMask.PNG b/renders/PlantsWithMask.PNG new file mode 100644 index 0000000..c5ced42 Binary files /dev/null and b/renders/PlantsWithMask.PNG differ diff --git a/renders/PointLightSpeculars.PNG b/renders/PointLightSpeculars.PNG new file mode 100644 index 0000000..801fe87 Binary files /dev/null and b/renders/PointLightSpeculars.PNG differ diff --git a/renders/SpecularNoScissorTest.PNG b/renders/SpecularNoScissorTest.PNG new file mode 100644 index 0000000..b796882 Binary files /dev/null and b/renders/SpecularNoScissorTest.PNG differ diff --git a/renders/SpecularWithScissorTest.PNG b/renders/SpecularWithScissorTest.PNG new file mode 100644 index 0000000..b71a5a2 Binary files /dev/null and b/renders/SpecularWithScissorTest.PNG differ diff --git a/renders/ToonShadingNoColor.PNG b/renders/ToonShadingNoColor.PNG new file mode 100644 index 0000000..2872ddf Binary files /dev/null and b/renders/ToonShadingNoColor.PNG differ