mirror of
https://github.com/glfw/glfw.git
synced 2025-10-04 13:46:37 +00:00
添加代码
This commit is contained in:
parent
e635a3fda4
commit
4037e38d49
@ -239,6 +239,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fbomsaa", "..\examples\fbom
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fbostencil", "..\examples\fbostencil\fbostencil.vcxproj", "{8F030B44-DFBF-4975-90ED-59815D2FC6B4}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DeferredRendering", "..\examples\DeferredRendering\DeferredRendering.vcxproj", "{88A62A12-3C14-42BF-838C-EB8FB54F6E2D}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShadowMapsDR", "..\examples\ShadowMaps\ShadowMapsDR.vcxproj", "{9D24251F-FD72-4A76-9B1C-999ED22D4DCA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
@ -751,6 +755,34 @@ Global
|
||||
{8F030B44-DFBF-4975-90ED-59815D2FC6B4}.RelWithDebInfo|Win32.Build.0 = Release|Win32
|
||||
{8F030B44-DFBF-4975-90ED-59815D2FC6B4}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{8F030B44-DFBF-4975-90ED-59815D2FC6B4}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{88A62A12-3C14-42BF-838C-EB8FB54F6E2D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{88A62A12-3C14-42BF-838C-EB8FB54F6E2D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{88A62A12-3C14-42BF-838C-EB8FB54F6E2D}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{88A62A12-3C14-42BF-838C-EB8FB54F6E2D}.MinSizeRel|Win32.ActiveCfg = Release|Win32
|
||||
{88A62A12-3C14-42BF-838C-EB8FB54F6E2D}.MinSizeRel|Win32.Build.0 = Release|Win32
|
||||
{88A62A12-3C14-42BF-838C-EB8FB54F6E2D}.MinSizeRel|x64.ActiveCfg = Release|x64
|
||||
{88A62A12-3C14-42BF-838C-EB8FB54F6E2D}.MinSizeRel|x64.Build.0 = Release|x64
|
||||
{88A62A12-3C14-42BF-838C-EB8FB54F6E2D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{88A62A12-3C14-42BF-838C-EB8FB54F6E2D}.Release|Win32.Build.0 = Release|Win32
|
||||
{88A62A12-3C14-42BF-838C-EB8FB54F6E2D}.Release|x64.ActiveCfg = Release|Win32
|
||||
{88A62A12-3C14-42BF-838C-EB8FB54F6E2D}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
|
||||
{88A62A12-3C14-42BF-838C-EB8FB54F6E2D}.RelWithDebInfo|Win32.Build.0 = Release|Win32
|
||||
{88A62A12-3C14-42BF-838C-EB8FB54F6E2D}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{88A62A12-3C14-42BF-838C-EB8FB54F6E2D}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{9D24251F-FD72-4A76-9B1C-999ED22D4DCA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{9D24251F-FD72-4A76-9B1C-999ED22D4DCA}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{9D24251F-FD72-4A76-9B1C-999ED22D4DCA}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{9D24251F-FD72-4A76-9B1C-999ED22D4DCA}.MinSizeRel|Win32.ActiveCfg = Release|Win32
|
||||
{9D24251F-FD72-4A76-9B1C-999ED22D4DCA}.MinSizeRel|Win32.Build.0 = Release|Win32
|
||||
{9D24251F-FD72-4A76-9B1C-999ED22D4DCA}.MinSizeRel|x64.ActiveCfg = Release|Win32
|
||||
{9D24251F-FD72-4A76-9B1C-999ED22D4DCA}.MinSizeRel|x64.Build.0 = Release|Win32
|
||||
{9D24251F-FD72-4A76-9B1C-999ED22D4DCA}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{9D24251F-FD72-4A76-9B1C-999ED22D4DCA}.Release|Win32.Build.0 = Release|Win32
|
||||
{9D24251F-FD72-4A76-9B1C-999ED22D4DCA}.Release|x64.ActiveCfg = Release|Win32
|
||||
{9D24251F-FD72-4A76-9B1C-999ED22D4DCA}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
|
||||
{9D24251F-FD72-4A76-9B1C-999ED22D4DCA}.RelWithDebInfo|Win32.Build.0 = Release|Win32
|
||||
{9D24251F-FD72-4A76-9B1C-999ED22D4DCA}.RelWithDebInfo|x64.ActiveCfg = Release|Win32
|
||||
{9D24251F-FD72-4A76-9B1C-999ED22D4DCA}.RelWithDebInfo|x64.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -797,5 +829,7 @@ Global
|
||||
{487BB169-F91A-4436-BF55-68568636FE35} = {46666672-CE20-3D1B-9180-1909006B3676}
|
||||
{114E9625-4259-4C6E-84D1-F854FC0C4E28} = {46666672-CE20-3D1B-9180-1909006B3676}
|
||||
{8F030B44-DFBF-4975-90ED-59815D2FC6B4} = {46666672-CE20-3D1B-9180-1909006B3676}
|
||||
{88A62A12-3C14-42BF-838C-EB8FB54F6E2D} = {46666672-CE20-3D1B-9180-1909006B3676}
|
||||
{9D24251F-FD72-4A76-9B1C-999ED22D4DCA} = {46666672-CE20-3D1B-9180-1909006B3676}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
116
examples/DeferredRendering/DeferredRendering.vcxproj
Normal file
116
examples/DeferredRendering/DeferredRendering.vcxproj
Normal file
@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="DeferredRendering\DeferredRendering.cpp" />
|
||||
<ClCompile Include="DeferredRendering\FBORenderTexture.cpp" />
|
||||
<ClCompile Include="GLApplication.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="Model\CubeModel.cpp" />
|
||||
<ClCompile Include="Model\GLSLShaderData.cpp" />
|
||||
<ClCompile Include="Model\IModel.cpp" />
|
||||
<ClCompile Include="Model\PlaneModel.cpp" />
|
||||
<ClCompile Include="Model\SphereModel.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="DeferredRendering\DeferredRendering.h" />
|
||||
<ClInclude Include="DeferredRendering\FBORenderTexture.h" />
|
||||
<ClInclude Include="GLApplication.h" />
|
||||
<ClInclude Include="Model\CubeModel.h" />
|
||||
<ClInclude Include="Model\GLSLShaderData.h" />
|
||||
<ClInclude Include="Model\IModel.h" />
|
||||
<ClInclude Include="Model\PlaneModel.h" />
|
||||
<ClInclude Include="Model\SphereModel.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="data\deferredRendering.frag" />
|
||||
<None Include="data\deferredRendering.vert" />
|
||||
<None Include="data\deferredShading.frag" />
|
||||
<None Include="data\deferredShading.vert" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{88A62A12-3C14-42BF-838C-EB8FB54F6E2D}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>OpenGL3Project</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>D:\Programmi\OpenGL\glew-1.7.0\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>D:\Programmi\OpenGL\glew-1.7.0\lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>D:\Programmi\OpenGL\glew-1.7.0\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>D:\Programmi\OpenGL\glew-1.7.0\lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\glew;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>glew32.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\glew\lib</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>glew32.lib;opengl32.lib;glu32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
77
examples/DeferredRendering/DeferredRendering.vcxproj.filters
Normal file
77
examples/DeferredRendering/DeferredRendering.vcxproj.filters
Normal file
@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Model">
|
||||
<UniqueIdentifier>{194f9210-1c9b-4617-94f4-1db0f1ab129c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="DeferredRendering">
|
||||
<UniqueIdentifier>{197942dc-0c5d-4dc1-8509-94bbec59e11b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="data">
|
||||
<UniqueIdentifier>{68752574-5107-46f3-9ad7-28e9d41efab8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GLApplication.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="Model\CubeModel.cpp">
|
||||
<Filter>Model</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Model\GLSLShaderData.cpp">
|
||||
<Filter>Model</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Model\IModel.cpp">
|
||||
<Filter>Model</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Model\PlaneModel.cpp">
|
||||
<Filter>Model</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Model\SphereModel.cpp">
|
||||
<Filter>Model</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DeferredRendering\DeferredRendering.cpp">
|
||||
<Filter>DeferredRendering</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DeferredRendering\FBORenderTexture.cpp">
|
||||
<Filter>DeferredRendering</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GLApplication.h" />
|
||||
<ClInclude Include="Model\CubeModel.h">
|
||||
<Filter>Model</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Model\GLSLShaderData.h">
|
||||
<Filter>Model</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Model\IModel.h">
|
||||
<Filter>Model</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Model\PlaneModel.h">
|
||||
<Filter>Model</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Model\SphereModel.h">
|
||||
<Filter>Model</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DeferredRendering\DeferredRendering.h">
|
||||
<Filter>DeferredRendering</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DeferredRendering\FBORenderTexture.h">
|
||||
<Filter>DeferredRendering</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="data\deferredRendering.frag">
|
||||
<Filter>data</Filter>
|
||||
</None>
|
||||
<None Include="data\deferredRendering.vert">
|
||||
<Filter>data</Filter>
|
||||
</None>
|
||||
<None Include="data\deferredShading.frag">
|
||||
<Filter>data</Filter>
|
||||
</None>
|
||||
<None Include="data\deferredShading.vert">
|
||||
<Filter>data</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -0,0 +1,90 @@
|
||||
#include "FBORenderTexture.h"
|
||||
#include "DeferredRendering.h"
|
||||
#include <exception>
|
||||
|
||||
/**
|
||||
* Create the deferred rendering object. I have hardcoded the shader's name here.
|
||||
*/
|
||||
DeferredRendering::DeferredRendering(int _dWidth, int _dHeight, FBORenderTexture* fboRenderTexture)
|
||||
: m_shader("data/deferredRendering.vert", "data/deferredRendering.frag")
|
||||
, m_fboRenderTexture(fboRenderTexture)
|
||||
, m_width(_dWidth)
|
||||
, m_height(_dHeight)
|
||||
{
|
||||
// Get the handles from the shader
|
||||
m_diffuseID = glGetUniformLocationARB(m_shader.m_programHandler,"tDiffuse");
|
||||
m_positionID = glGetUniformLocationARB(m_shader.m_programHandler,"tPosition");
|
||||
m_normalsID = glGetUniformLocationARB(m_shader.m_programHandler,"tNormals");
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the big quad with the deferred rendering shader on it
|
||||
*/
|
||||
void DeferredRendering::render()
|
||||
{
|
||||
//Projection setup
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(0,m_width,0,m_height,0.1f,2);
|
||||
|
||||
//Model setup
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
|
||||
glUseProgramObjectARB(m_shader.m_programHandler);
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, m_fboRenderTexture->getDiffuseTexture());
|
||||
glUniform1iARB ( m_diffuseID, 0 );
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, m_fboRenderTexture->getPositionTexture());
|
||||
glUniform1iARB ( m_positionID, 1 );
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, m_fboRenderTexture->getNormalsTexture());
|
||||
glUniform1iARB ( m_normalsID, 2 );
|
||||
|
||||
// Render the quad
|
||||
glLoadIdentity();
|
||||
glColor3f(1,1,1);
|
||||
glTranslatef(0,0,-1.0);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f( 0, 0 );
|
||||
glVertex3f( 0.0f, 0.0f, 0.0f);
|
||||
glTexCoord2f( 1, 0 );
|
||||
glVertex3f( (float) m_width, 0.0f, 0.0f);
|
||||
glTexCoord2f( 1, 1 );
|
||||
glVertex3f( (float) m_width, (float) m_height, 0.0f);
|
||||
glTexCoord2f( 0, 1 );
|
||||
glVertex3f( 0.0f, (float) m_height, 0.0f);
|
||||
glEnd();
|
||||
|
||||
// Reset OpenGL state
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glUseProgramObjectARB(0);
|
||||
|
||||
//Reset to the matrices
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <gl/glew.h>
|
||||
#include <gl/gl.h>
|
||||
#include <gl/glu.h>
|
||||
#include "../Model/GLSLShaderData.h"
|
||||
#include "FBORenderTexture.h"
|
||||
|
||||
/**
|
||||
* This object is used to render a big screen sized quad with the deferred rendering shader applied on it.
|
||||
*/
|
||||
class DeferredRendering
|
||||
{
|
||||
public:
|
||||
// Ctors/Dtors
|
||||
DeferredRendering(int width, int height, FBORenderTexture* fboRenderTexture);
|
||||
|
||||
// Methods
|
||||
void render();
|
||||
|
||||
private:
|
||||
// Variables
|
||||
GLSLShaderData m_shader; // Deferred rendering shader
|
||||
FBORenderTexture* m_fboRenderTexture; // A pointer to the FBO render texture that contains diffuse, normals and positions
|
||||
|
||||
unsigned int m_width; // width
|
||||
unsigned int m_height; // height
|
||||
|
||||
GLuint m_diffuseID; // Diffuse texture handle for the shader
|
||||
GLuint m_positionID; // Position texture handle for the shader
|
||||
GLuint m_normalsID; // Normals texture handle for the shader
|
||||
};
|
@ -0,0 +1,175 @@
|
||||
#include "FBORenderTexture.h"
|
||||
#include <exception>
|
||||
|
||||
/**
|
||||
* Create the FBO render texture initializing all the stuff that we need
|
||||
*/
|
||||
FBORenderTexture::FBORenderTexture(int _dWidth, int _dHeight)
|
||||
{
|
||||
// Save extensions
|
||||
m_width = _dWidth;
|
||||
m_height = _dHeight;
|
||||
|
||||
// Generate the OGL resources for what we need
|
||||
glGenFramebuffersEXT(1, &m_fbo);
|
||||
glGenRenderbuffersEXT(1, &m_diffuseRT);
|
||||
glGenRenderbuffersEXT(1, &m_positionRT);
|
||||
glGenRenderbuffersEXT(1, &m_normalsRT);
|
||||
glGenRenderbuffersEXT(1, &m_depthBuffer);
|
||||
|
||||
// Bind the FBO so that the next operations will be bound to it
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
|
||||
|
||||
// Bind the diffuse render target
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_diffuseRT);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, m_width, m_height);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_diffuseRT);
|
||||
|
||||
// Bind the position render target
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_positionRT);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA32F_ARB, m_width, m_height);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_RENDERBUFFER_EXT, m_positionRT);
|
||||
|
||||
// Bind the normal render target
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_normalsRT);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA16F_ARB, m_width, m_height);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_RENDERBUFFER_EXT, m_normalsRT);
|
||||
|
||||
// Bind the depth buffer
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, m_width, m_height);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
|
||||
|
||||
// Generate and bind the OGL texture for diffuse
|
||||
glGenTextures(1, &m_diffuseTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_diffuseTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
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_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// Attach the texture to the FBO
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_diffuseTexture, 0);
|
||||
|
||||
// Generate and bind the OGL texture for positions
|
||||
glGenTextures(1, &m_positionTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_positionTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, m_width, m_height, 0, GL_RGBA, GL_FLOAT, NULL);
|
||||
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_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// Attach the texture to the FBO
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, m_positionTexture, 0);
|
||||
|
||||
// Generate and bind the OGL texture for normals
|
||||
glGenTextures(1, &m_normalsTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_normalsTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, m_width, m_height, 0, GL_RGBA, GL_FLOAT, NULL);
|
||||
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_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// Attach the texture to the FBO
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, m_normalsTexture, 0);
|
||||
|
||||
// Check if all worked fine and unbind the FBO
|
||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
if( status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
throw new std::exception("Can't initialize an FBO render texture. FBO initialization failed.");
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
FBORenderTexture::~FBORenderTexture(){
|
||||
glDeleteTextures(1, &m_normalsTexture);
|
||||
glDeleteTextures(1, &m_positionTexture);
|
||||
glDeleteTextures(1, &m_diffuseTexture);
|
||||
glDeleteFramebuffersEXT(1, &m_fbo);
|
||||
glDeleteRenderbuffersEXT(1, &m_diffuseRT);
|
||||
glDeleteRenderbuffersEXT(1, &m_positionRT);
|
||||
glDeleteRenderbuffersEXT(1, &m_normalsRT);
|
||||
glDeleteRenderbuffersEXT(1, &m_depthBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start rendering to the texture
|
||||
* Both color and depth buffers are cleared.
|
||||
*/
|
||||
void FBORenderTexture::start(){
|
||||
// Bind our FBO and set the viewport to the proper size
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
|
||||
glPushAttrib(GL_VIEWPORT_BIT);
|
||||
glViewport(0,0,m_width, m_height);
|
||||
|
||||
// Clear the render targets
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
// Specify what to render an start acquiring
|
||||
GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT };
|
||||
glDrawBuffers(3, buffers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop rendering to this texture.
|
||||
*/
|
||||
void FBORenderTexture::stop(){
|
||||
// Stop acquiring and unbind the FBO
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the texture to screen. It is just for debug purposes.
|
||||
*/
|
||||
void FBORenderTexture::showTexture(unsigned int i, float fSizeX, float fSizeY, float x, float y) const {
|
||||
GLuint texture = m_diffuseTexture;
|
||||
if(i == 1) texture = m_positionTexture;
|
||||
else
|
||||
if(i == 2) texture = m_normalsTexture;
|
||||
|
||||
//Projection setup
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(0,m_width,0,m_height,0.1f,2);
|
||||
|
||||
//Model setup
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
// Render the quad
|
||||
glLoadIdentity();
|
||||
glTranslatef(x,-y,-1.0);
|
||||
|
||||
glColor3f(1,1,1);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f( 0, 1 );
|
||||
glVertex3f( 0.0f, (float) m_height, 0.0f);
|
||||
glTexCoord2f( 0, 0 );
|
||||
glVertex3f( 0.0f, m_height-fSizeY, 0.0f);
|
||||
glTexCoord2f( 1, 0 );
|
||||
glVertex3f( fSizeX, m_height-fSizeY, 0.0f);
|
||||
glTexCoord2f( 1, 1 );
|
||||
glVertex3f( fSizeX, (float) m_height, 0.0f);
|
||||
glEnd();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
//Reset to the matrices
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <gl/glew.h>
|
||||
#include <gl/gl.h>
|
||||
#include <gl/glu.h>
|
||||
|
||||
/**
|
||||
* A Frame Buffer Object is used by OpenGL to render into a texture. Specifically this implementation assumes that the
|
||||
* rendered model will provide diffuse, position and normal at the same time in a MRT fashion
|
||||
*/
|
||||
|
||||
class FBORenderTexture
|
||||
{
|
||||
public:
|
||||
// Ctors/Dtors
|
||||
FBORenderTexture(int width, int height);
|
||||
~FBORenderTexture();
|
||||
|
||||
// Methods
|
||||
void start();
|
||||
void stop();
|
||||
void showTexture(unsigned int i, float fSizeX = 400, float fSizeY = 400, float x = 0, float y = 0) const;
|
||||
|
||||
GLuint getDiffuseTexture() const { return m_diffuseTexture; }
|
||||
GLuint getPositionTexture() const { return m_positionTexture; }
|
||||
GLuint getNormalsTexture() const { return m_normalsTexture; }
|
||||
|
||||
private:
|
||||
|
||||
// Variables
|
||||
GLuint m_fbo; // The FBO ID
|
||||
GLuint m_diffuseRT; // The diffuse render target
|
||||
unsigned int m_diffuseTexture; // The OpenGL texture for the diffuse render target
|
||||
GLuint m_positionRT; // The position render target
|
||||
unsigned int m_positionTexture; // The OpenGL texture for the position render target
|
||||
GLuint m_normalsRT; // The normals render target
|
||||
unsigned int m_normalsTexture; // The OpenGL texture for the normals render target
|
||||
GLuint m_depthBuffer; // Depth buffer handle
|
||||
|
||||
unsigned int m_width; // FBO width
|
||||
unsigned int m_height; // FBO height
|
||||
};
|
187
examples/DeferredRendering/GLApplication.cpp
Normal file
187
examples/DeferredRendering/GLApplication.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
#include <windows.h>
|
||||
#include "GLApplication.h"
|
||||
#include "Model/SphereModel.h"
|
||||
#include "Model/CubeModel.h"
|
||||
#include "Model/PlaneModel.h"
|
||||
|
||||
/**
|
||||
* Initialize our GL application
|
||||
*/
|
||||
bool GLApplication::initialize(HWND hwnd, int width, int height)
|
||||
{
|
||||
GLuint pixelFormat;
|
||||
m_windowHeight = height;
|
||||
m_windowWidth = width;
|
||||
|
||||
m_hWnd = hwnd;
|
||||
|
||||
static PIXELFORMATDESCRIPTOR pfd=
|
||||
{
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
1,
|
||||
PFD_DRAW_TO_WINDOW |
|
||||
PFD_SUPPORT_OPENGL |
|
||||
PFD_DOUBLEBUFFER,
|
||||
PFD_TYPE_RGBA,
|
||||
16,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
16,
|
||||
0,
|
||||
0,
|
||||
PFD_MAIN_PLANE,
|
||||
0,
|
||||
0, 0, 0
|
||||
};
|
||||
|
||||
if (!(m_hdc=GetDC(m_hWnd)))
|
||||
return FALSE;
|
||||
|
||||
if (!(pixelFormat=ChoosePixelFormat(m_hdc,&pfd)))
|
||||
return FALSE;
|
||||
|
||||
if(!SetPixelFormat(m_hdc,pixelFormat,&pfd))
|
||||
return FALSE;
|
||||
|
||||
if (!(m_hrc=wglCreateContext(m_hdc)))
|
||||
return FALSE;
|
||||
|
||||
if(!wglMakeCurrent(m_hdc,m_hrc))
|
||||
return FALSE;
|
||||
|
||||
ShowWindow(m_hWnd,SW_SHOW);
|
||||
SetForegroundWindow(m_hWnd);
|
||||
SetFocus(m_hWnd);
|
||||
setSize(width, height);
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||
|
||||
GLenum err = glewInit();
|
||||
if (GLEW_OK != err)
|
||||
return false;
|
||||
|
||||
loadAssets();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set window's size
|
||||
*/
|
||||
void GLApplication::setSize(int w, int h)
|
||||
{
|
||||
m_windowWidth = w;
|
||||
m_windowHeight = h;
|
||||
|
||||
glViewport(0,0,m_windowWidth,m_windowHeight);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
gluPerspective(45.0f,(GLfloat)m_windowWidth/(GLfloat)m_windowHeight,0.1f,100.0f);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update
|
||||
*/
|
||||
void GLApplication::update()
|
||||
{
|
||||
float time = (GetTickCount() - m_lastTick) * 0.01f;
|
||||
m_lastTick = GetTickCount();
|
||||
|
||||
m_models[0]->addRotation( time, time*2, 0 );
|
||||
m_models[1]->addRotation( 0, time*2, time );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the scene
|
||||
*/
|
||||
void GLApplication::render()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClearColor(0.2f, 0.3f, 0.8f, 1.0f);
|
||||
|
||||
glLoadIdentity();
|
||||
glRotatef(20, 1, 0, 0);
|
||||
glTranslatef(0.0f,-4.6f,-10.0f);
|
||||
|
||||
// Render our geometry into the FBO
|
||||
m_multipleRenderTarget->start();
|
||||
for(int i=0; i<c_modelsCount; ++i)
|
||||
m_models[i]->render();
|
||||
m_multipleRenderTarget->stop();
|
||||
|
||||
// Render to the screen
|
||||
if(m_state == 0)
|
||||
{
|
||||
// Render to screen using the deferred rendering shader
|
||||
m_deferredRendering->render();
|
||||
}
|
||||
else if(m_state == 1)
|
||||
{
|
||||
m_multipleRenderTarget->showTexture( 0, 512, 384, 0);
|
||||
m_multipleRenderTarget->showTexture( 1, 512, 384, 512);
|
||||
m_multipleRenderTarget->showTexture( 2, 512, 384, 0, 384);
|
||||
}
|
||||
|
||||
SwapBuffers(m_hdc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release all the GL resources we have allocated
|
||||
*/
|
||||
void GLApplication::release()
|
||||
{
|
||||
releaseAssets();
|
||||
|
||||
wglMakeCurrent(m_hdc, 0);
|
||||
wglDeleteContext(m_hrc);
|
||||
|
||||
ReleaseDC(m_hWnd, m_hdc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all the required assets
|
||||
*/
|
||||
void GLApplication::loadAssets()
|
||||
{
|
||||
m_state = 0;
|
||||
|
||||
m_multipleRenderTarget = new FBORenderTexture(m_windowWidth, m_windowHeight);
|
||||
m_deferredRendering = new DeferredRendering(m_windowWidth, m_windowHeight, m_multipleRenderTarget);
|
||||
|
||||
m_models[0] = new SphereModel("data/deferredShading.vert", "data/deferredShading.frag", 1, 64);
|
||||
m_models[0]->loadTexture("data/earth.raw");
|
||||
m_models[0]->setPosition(2,2.5f,0);
|
||||
|
||||
m_models[1] = new CubeModel("data/deferredShading.vert", "data/deferredShading.frag", 1);
|
||||
m_models[1]->loadTexture("data/box.raw");
|
||||
m_models[1]->setPosition(-2,2.5f,0);
|
||||
|
||||
m_models[2] = new PlaneModel("data/deferredShading.vert", "data/deferredShading.frag", 5);
|
||||
m_models[2]->loadTexture("data/plane.raw");
|
||||
m_models[2]->setPosition(0,0,0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release all the assets
|
||||
*/
|
||||
void GLApplication::releaseAssets()
|
||||
{
|
||||
delete m_multipleRenderTarget;
|
||||
delete m_deferredRendering;
|
||||
|
||||
for(int i=0; i<c_modelsCount; ++i)
|
||||
delete m_models[i];
|
||||
}
|
46
examples/DeferredRendering/GLApplication.h
Normal file
46
examples/DeferredRendering/GLApplication.h
Normal file
@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include "DeferredRendering/DeferredRendering.h"
|
||||
#include "DeferredRendering/FBORenderTexture.h"
|
||||
|
||||
//Fwd
|
||||
class IModel;
|
||||
|
||||
/**
|
||||
* This class contains all the system stuff that we need to render with OpenGL
|
||||
*/
|
||||
class GLApplication {
|
||||
public:
|
||||
// Methods
|
||||
bool initialize(HWND hwnd, int w, int h);
|
||||
void setSize(int w, int h);
|
||||
void update();
|
||||
void render();
|
||||
void release();
|
||||
|
||||
void showDeferredRendering(){ m_state = 0; }
|
||||
void showRenderTargets(){ m_state = 1; }
|
||||
|
||||
private:
|
||||
// Methods
|
||||
void loadAssets();
|
||||
void releaseAssets();
|
||||
|
||||
// Static consts
|
||||
static const int c_modelsCount = 3;
|
||||
|
||||
// Fields
|
||||
IModel* m_models[c_modelsCount];
|
||||
DeferredRendering* m_deferredRendering;
|
||||
FBORenderTexture* m_multipleRenderTarget;
|
||||
|
||||
int m_windowWidth;
|
||||
int m_windowHeight;
|
||||
|
||||
HGLRC m_hrc; // Rendering's context
|
||||
HDC m_hdc; // Device's context
|
||||
HWND m_hWnd; // Window's handle
|
||||
|
||||
unsigned int m_lastTick;
|
||||
unsigned char m_state; // 0 - Normal render, 1 - Show render targets
|
||||
};
|
73
examples/DeferredRendering/Model/CubeModel.cpp
Normal file
73
examples/DeferredRendering/Model/CubeModel.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include "CubeModel.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* Construct the cube
|
||||
*/
|
||||
CubeModel::CubeModel(const std::string& sVSFileName, const std::string& sFSFileName, float side)
|
||||
: IModel(sVSFileName, sFSFileName)
|
||||
, m_side(side)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Render
|
||||
*/
|
||||
void CubeModel::render() const
|
||||
{
|
||||
glPushMatrix();
|
||||
|
||||
// Save the current world matrix to compensate the normals in the shader
|
||||
float worldMatrix[16];
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, worldMatrix);
|
||||
|
||||
glScalef(m_side,m_side,m_side);
|
||||
glTranslatef(m_posX, m_posY, m_posZ);
|
||||
glRotatef(m_rotX, 1, 0, 0);
|
||||
glRotatef(m_rotY, 0, 1, 0);
|
||||
glRotatef(m_rotZ, 0, 0, 1);
|
||||
|
||||
glUseProgramObjectARB(m_shader.m_programHandler);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
glUniform1iARB ( m_textureID, 0);
|
||||
glUniformMatrix4fvARB ( m_worldMatrixID, 1, false, worldMatrix);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
// Front Face
|
||||
glTexCoord2f(0.0f, 0.0f); glNormal3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 0.0f); glNormal3f(0.0f, 0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f); glNormal3f(0.0f, 0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, 1.0f); glNormal3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
|
||||
// Back Face
|
||||
glTexCoord2f(1.0f, 0.0f); glNormal3f(0.0f, 0.0f, -1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f); glNormal3f(0.0f, 0.0f, -1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 1.0f); glNormal3f(0.0f, 0.0f, -1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 0.0f); glNormal3f(0.0f, 0.0f, -1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
||||
// Top Face
|
||||
glTexCoord2f(0.0f, 1.0f); glNormal3f(0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 0.0f); glNormal3f(0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 0.0f); glNormal3f(0.0f, 1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f); glNormal3f(0.0f, 1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
|
||||
// Bottom Face
|
||||
glTexCoord2f(1.0f, 1.0f); glNormal3f(0.0f, -1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 1.0f); glNormal3f(0.0f, -1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 0.0f); glNormal3f(0.0f, -1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 0.0f); glNormal3f(0.0f, -1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
|
||||
// Right face
|
||||
glTexCoord2f(1.0f, 0.0f); glNormal3f(1.0f, 0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f); glNormal3f(1.0f, 0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 1.0f); glNormal3f(1.0f, 0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, 0.0f); glNormal3f(1.0f, 0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
|
||||
// Left Face
|
||||
glTexCoord2f(0.0f, 0.0f); glNormal3f(-1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
||||
glTexCoord2f(1.0f, 0.0f); glNormal3f(-1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f); glNormal3f(-1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, 1.0f); glNormal3f(-1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
|
||||
glEnd();
|
||||
|
||||
glUseProgramObjectARB(0);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
19
examples/DeferredRendering/Model/CubeModel.h
Normal file
19
examples/DeferredRendering/Model/CubeModel.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "IModel.h"
|
||||
|
||||
/**
|
||||
* A simple cube model that is easy to render
|
||||
*/
|
||||
class CubeModel : public IModel
|
||||
{
|
||||
public:
|
||||
// Methods
|
||||
CubeModel(const std::string& sVSFileName, const std::string& sFSFileName, float side);
|
||||
|
||||
void render() const;
|
||||
|
||||
protected:
|
||||
// Fields
|
||||
float m_side;
|
||||
};
|
||||
|
82
examples/DeferredRendering/Model/GLSLShaderData.cpp
Normal file
82
examples/DeferredRendering/Model/GLSLShaderData.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
#include <windows.h>
|
||||
#include "gl/glew.h"
|
||||
#include <gl/gl.h>
|
||||
#include <gl/glu.h>
|
||||
#include "GLSLShaderData.h"
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
GLSLShaderData::GLSLShaderData(const std::string& _sVSFileName, const std::string& _sFSFileName)
|
||||
: m_VSFileName(_sVSFileName)
|
||||
, m_FSFileName(_sFSFileName)
|
||||
{
|
||||
// Create OGL resources
|
||||
m_vertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
|
||||
m_fragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
|
||||
|
||||
//Read out the shader data from the given files
|
||||
char *sVSData, *sFSData;
|
||||
|
||||
//Read out the vertex shader data
|
||||
FILE *file;
|
||||
fopen_s(&file, m_VSFileName.c_str(),"r");
|
||||
if(!file)
|
||||
throw new std::exception( std::string("Can't load GLSL Vertex Shader from file: " + m_VSFileName).c_str() );
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
long count = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
sVSData = new char[count+1];
|
||||
memset(sVSData,0,count+1);
|
||||
fread(sVSData, 1, count, file);
|
||||
fclose(file);
|
||||
|
||||
file = NULL;
|
||||
|
||||
//Read out the fragment shader data
|
||||
fopen_s(&file, m_FSFileName.c_str(),"r");
|
||||
if(!file)
|
||||
throw new std::exception( std::string("Can't load GLSL Fragment Shader from file: "+m_FSFileName).c_str() );
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
count = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
sFSData = new char[count+1];
|
||||
memset(sFSData,0,count+1);
|
||||
fread(sFSData, 1, count, file);
|
||||
fclose(file);
|
||||
|
||||
// Now that we have the two shaders in memory we can compile them
|
||||
const char * pVS = sVSData;
|
||||
const char * pFS = sFSData;
|
||||
int bCompiled = false;
|
||||
|
||||
glShaderSourceARB(m_vertexShader, 1, &pVS, NULL);
|
||||
glCompileShaderARB(m_vertexShader);
|
||||
|
||||
glGetObjectParameterivARB( m_vertexShader, GL_OBJECT_COMPILE_STATUS_ARB, &bCompiled );
|
||||
if( bCompiled == false )
|
||||
throw new std::exception("Vertex shader compilation failed.");
|
||||
|
||||
glShaderSourceARB(m_fragmentShader, 1, &pFS, NULL);
|
||||
glCompileShaderARB(m_fragmentShader);
|
||||
|
||||
glGetObjectParameterivARB( m_fragmentShader, GL_OBJECT_COMPILE_STATUS_ARB, &bCompiled );
|
||||
if( bCompiled == false )
|
||||
throw new std::exception("Fragment shader compilation failed.");
|
||||
|
||||
// Once compiled we can bind everything together for OpenGL to use
|
||||
m_programHandler = glCreateProgramObjectARB();
|
||||
glAttachObjectARB(m_programHandler,m_vertexShader);
|
||||
glAttachObjectARB(m_programHandler,m_fragmentShader);
|
||||
|
||||
glLinkProgramARB(m_programHandler);
|
||||
|
||||
// We release the shader data read from file since we now have everything compiled in memory
|
||||
delete [] sFSData;
|
||||
delete [] sVSData;
|
||||
}
|
||||
|
22
examples/DeferredRendering/Model/GLSLShaderData.h
Normal file
22
examples/DeferredRendering/Model/GLSLShaderData.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* GLSLShaderData encapsulate all the GLSL data.<br>
|
||||
* Constructor initialize data from files.
|
||||
*/
|
||||
class GLSLShaderData
|
||||
{
|
||||
public:
|
||||
// Functions
|
||||
//------------------------------------------------------------
|
||||
GLSLShaderData(const std::string& sVSFileName, const std::string& sFSFileName);
|
||||
|
||||
// Variables
|
||||
//------------------------------------------------------------
|
||||
GLhandleARB m_vertexShader; // Vertex shader handle
|
||||
GLhandleARB m_fragmentShader; // Fragment shader handle
|
||||
GLhandleARB m_programHandler; // Shader handle
|
||||
std::string m_VSFileName; // Vertex shader filename
|
||||
std::string m_FSFileName; // Fragment shader filename
|
||||
};
|
79
examples/DeferredRendering/Model/IModel.cpp
Normal file
79
examples/DeferredRendering/Model/IModel.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
#include "IModel.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* This method assumes that the file passed as parameter is a raw block of data made of RGB components (one byte per channel)
|
||||
* It is *NOT* a good way to load/store textures, but for sake of simplicity I've decided to use it for this tutorial.
|
||||
*/
|
||||
bool IModel::loadTexture(const std::string& textureName)
|
||||
{
|
||||
byte* data = NULL;
|
||||
|
||||
FILE* f;
|
||||
fopen_s(&f, textureName.c_str(), "r");
|
||||
if(f != NULL)
|
||||
{
|
||||
fseek (f, 0, SEEK_END);
|
||||
unsigned int size = ftell (f);
|
||||
fseek (f, 0, SEEK_SET);
|
||||
|
||||
data = new byte[size];
|
||||
fread( data, sizeof(byte), size, f);
|
||||
fclose(f);
|
||||
|
||||
// Assuming that the raw image is square and RGB; don't fancy doing anything more complicated since the tutorial is not focused on textures loading
|
||||
GLuint side = (GLuint)sqrt(size/3.0f);
|
||||
|
||||
// Generate the texture
|
||||
if(m_texture != 0)
|
||||
glDeleteTextures(1, &m_texture);
|
||||
glGenTextures(1, &m_texture);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 3, side, side, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set position
|
||||
*/
|
||||
void IModel::setPosition(float x, float y, float z)
|
||||
{
|
||||
m_posX = x;
|
||||
m_posY = y;
|
||||
m_posZ = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set rotation
|
||||
*/
|
||||
void IModel::setRotation(float x, float y, float z)
|
||||
{
|
||||
m_rotX = x;
|
||||
m_rotY = y;
|
||||
m_rotZ = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a delta to the current rotation
|
||||
*/
|
||||
void IModel::addRotation(float x, float y, float z)
|
||||
{
|
||||
m_rotX += x;
|
||||
m_rotY += y;
|
||||
m_rotZ += z;
|
||||
}
|
||||
|
45
examples/DeferredRendering/Model/IModel.h
Normal file
45
examples/DeferredRendering/Model/IModel.h
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include "gl/glew.h"
|
||||
#include <gl/gl.h>
|
||||
#include <gl/glu.h>
|
||||
#include <string>
|
||||
#include "GLSLShaderData.h"
|
||||
|
||||
/**
|
||||
* Every renderable object inherits from this interface for simplicity
|
||||
*/
|
||||
class IModel
|
||||
{
|
||||
public:
|
||||
// Methods
|
||||
IModel(const std::string& sVSFileName, const std::string& sFSFileName)
|
||||
: m_shader(sVSFileName, sFSFileName)
|
||||
, m_texture(0)
|
||||
{
|
||||
m_rotX = m_rotY = m_rotZ = 0;
|
||||
m_posX = m_posY = m_posZ = 0;
|
||||
|
||||
m_worldMatrixID = glGetUniformLocationARB(m_shader.m_programHandler,"WorldMatrix");
|
||||
m_textureID = glGetUniformLocationARB(m_shader.m_programHandler,"tDiffuse");
|
||||
}
|
||||
virtual ~IModel(){}
|
||||
|
||||
bool loadTexture(const std::string& textureName);
|
||||
void setPosition(float x, float y, float z);
|
||||
void setRotation(float x, float y, float z);
|
||||
void addRotation(float x, float y, float z);
|
||||
virtual void render() const = 0;
|
||||
|
||||
protected:
|
||||
// Fields
|
||||
GLSLShaderData m_shader; // Every model must have a shader associated (both vertex and fragment)
|
||||
|
||||
GLuint m_worldMatrixID; // This ID is used to pass the world matrix into the shader
|
||||
float m_rotX, m_rotY, m_rotZ; // Rotations
|
||||
float m_posX, m_posY, m_posZ; // Positions
|
||||
|
||||
GLuint m_textureID; // Texture ID used to pass the texture into the shader
|
||||
GLuint m_texture; // OpenGL texture ID
|
||||
};
|
||||
|
57
examples/DeferredRendering/Model/PlaneModel.cpp
Normal file
57
examples/DeferredRendering/Model/PlaneModel.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
#include "PlaneModel.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* Construct the plane
|
||||
*/
|
||||
PlaneModel::PlaneModel(const std::string& sVSFileName, const std::string& sFSFileName, float side)
|
||||
: IModel(sVSFileName, sFSFileName)
|
||||
, m_side(side)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Render
|
||||
*/
|
||||
void PlaneModel::render() const
|
||||
{
|
||||
glPushMatrix();
|
||||
|
||||
// Save the current world matrix to compensate the normals in the shader
|
||||
float worldMatrix[16];
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, worldMatrix);
|
||||
|
||||
glTranslatef(m_posX, m_posY, m_posZ);
|
||||
glRotatef(m_rotX, 1, 0, 0);
|
||||
glRotatef(m_rotY, 0, 1, 0);
|
||||
glRotatef(m_rotZ, 0, 0, 1);
|
||||
glScalef(m_side,m_side,m_side);
|
||||
|
||||
glUseProgramObjectARB(m_shader.m_programHandler);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
glUniform1iARB ( m_textureID, 0);
|
||||
glUniformMatrix4fvARB ( m_worldMatrixID, 1, false, worldMatrix);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glVertex3f(-1.0f, 0.0f, -1.0f);
|
||||
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glVertex3f(-1.0f, 0.0f, 1.0f);
|
||||
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glVertex3f( 1.0f, 0.0f, 1.0f);
|
||||
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glVertex3f( 1.0f, 0.0f, -1.0f);
|
||||
glEnd();
|
||||
|
||||
glUseProgramObjectARB(0);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
19
examples/DeferredRendering/Model/PlaneModel.h
Normal file
19
examples/DeferredRendering/Model/PlaneModel.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "IModel.h"
|
||||
|
||||
/**
|
||||
* A plane model that is easy to render
|
||||
*/
|
||||
class PlaneModel : public IModel
|
||||
{
|
||||
public:
|
||||
// Methods
|
||||
PlaneModel(const std::string& sVSFileName, const std::string& sFSFileName, float side);
|
||||
|
||||
void render() const;
|
||||
|
||||
protected:
|
||||
// Fields
|
||||
float m_side;
|
||||
};
|
||||
|
45
examples/DeferredRendering/Model/SphereModel.cpp
Normal file
45
examples/DeferredRendering/Model/SphereModel.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include "SphereModel.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* Construct the sphere
|
||||
*/
|
||||
SphereModel::SphereModel(const std::string& sVSFileName, const std::string& sFSFileName, float radius, unsigned int meshPrecision)
|
||||
: IModel(sVSFileName, sFSFileName)
|
||||
{
|
||||
m_radius = radius;
|
||||
m_meshPrecision = meshPrecision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render
|
||||
*/
|
||||
void SphereModel::render() const
|
||||
{
|
||||
glPushMatrix();
|
||||
|
||||
// Save the current world matrix to compensate the normals in the shader
|
||||
float worldMatrix[16];
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, worldMatrix);
|
||||
|
||||
glTranslatef(m_posX, m_posY, m_posZ);
|
||||
glRotatef(m_rotX, 1, 0, 0);
|
||||
glRotatef(m_rotY, 0, 1, 0);
|
||||
glRotatef(m_rotZ, 0, 0, 1);
|
||||
|
||||
glUseProgramObjectARB(m_shader.m_programHandler);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
glUniform1iARB ( m_textureID, 0);
|
||||
glUniformMatrix4fvARB ( m_worldMatrixID, 1, false, worldMatrix);
|
||||
|
||||
GLUquadricObj *sphere = gluNewQuadric();
|
||||
gluQuadricTexture(sphere, true);
|
||||
gluSphere(sphere, m_radius, m_meshPrecision, m_meshPrecision);
|
||||
gluDeleteQuadric(sphere);
|
||||
|
||||
glUseProgramObjectARB(0);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
20
examples/DeferredRendering/Model/SphereModel.h
Normal file
20
examples/DeferredRendering/Model/SphereModel.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include "IModel.h"
|
||||
|
||||
/**
|
||||
* A simple sphere model that is easy to render
|
||||
*/
|
||||
class SphereModel : public IModel
|
||||
{
|
||||
public:
|
||||
// Methods
|
||||
SphereModel(const std::string& sVSFileName, const std::string& sFSFileName, float radius, unsigned int meshPrecision);
|
||||
|
||||
void render() const;
|
||||
|
||||
private:
|
||||
// Fields
|
||||
float m_radius;
|
||||
unsigned int m_meshPrecision;
|
||||
};
|
||||
|
1
examples/DeferredRendering/data/box.raw
Normal file
1
examples/DeferredRendering/data/box.raw
Normal file
File diff suppressed because one or more lines are too long
22
examples/DeferredRendering/data/deferredRendering.frag
Normal file
22
examples/DeferredRendering/data/deferredRendering.frag
Normal file
@ -0,0 +1,22 @@
|
||||
uniform sampler2D tDiffuse;
|
||||
uniform sampler2D tPosition;
|
||||
uniform sampler2D tNormals;
|
||||
uniform vec3 cameraPosition;
|
||||
|
||||
void main( void )
|
||||
{
|
||||
vec4 image = texture2D( tDiffuse, gl_TexCoord[0].xy );
|
||||
vec4 position = texture2D( tPosition, gl_TexCoord[0].xy );
|
||||
vec4 normal = texture2D( tNormals, gl_TexCoord[0].xy );
|
||||
|
||||
vec3 light = vec3(50,100,50);
|
||||
vec3 lightDir = light - position.xyz ;
|
||||
|
||||
normal = normalize(normal);
|
||||
lightDir = normalize(lightDir);
|
||||
|
||||
vec3 eyeDir = normalize(cameraPosition-position.xyz);
|
||||
vec3 vHalfVector = normalize(lightDir.xyz+eyeDir);
|
||||
|
||||
gl_FragColor = max(dot(normal,lightDir),0) * image + pow(max(dot(normal,vHalfVector),0.0), 100) * 1.5;
|
||||
}
|
7
examples/DeferredRendering/data/deferredRendering.vert
Normal file
7
examples/DeferredRendering/data/deferredRendering.vert
Normal file
@ -0,0 +1,7 @@
|
||||
void main( void )
|
||||
{
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
}
|
11
examples/DeferredRendering/data/deferredShading.frag
Normal file
11
examples/DeferredRendering/data/deferredShading.frag
Normal file
@ -0,0 +1,11 @@
|
||||
varying vec4 position;
|
||||
varying vec3 normals;
|
||||
varying mat4 TBN;
|
||||
uniform sampler2D tDiffuse;
|
||||
|
||||
void main( void )
|
||||
{
|
||||
gl_FragData[0] = vec4(texture2D(tDiffuse,gl_TexCoord[0].st).rgb, 0);
|
||||
gl_FragData[1] = vec4(position.xyz,0);
|
||||
gl_FragData[2] = vec4(normals.xyz,0);
|
||||
}
|
16
examples/DeferredRendering/data/deferredShading.vert
Normal file
16
examples/DeferredRendering/data/deferredShading.vert
Normal file
@ -0,0 +1,16 @@
|
||||
varying vec3 normals;
|
||||
varying vec4 position;
|
||||
uniform mat4 ModelMatrix;
|
||||
uniform mat4 WorldMatrix;
|
||||
|
||||
void main( void )
|
||||
{
|
||||
// Move the normals back from the camera space to the world space
|
||||
mat3 worldRotationInverse = transpose(mat3(WorldMatrix));
|
||||
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
normals = normalize(worldRotationInverse * gl_NormalMatrix * gl_Normal);
|
||||
position = gl_ModelViewMatrix * gl_Vertex;
|
||||
gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
}
|
9198
examples/DeferredRendering/data/earth.raw
Normal file
9198
examples/DeferredRendering/data/earth.raw
Normal file
File diff suppressed because one or more lines are too long
BIN
examples/DeferredRendering/data/plane.raw
Normal file
BIN
examples/DeferredRendering/data/plane.raw
Normal file
Binary file not shown.
102
examples/DeferredRendering/main.cpp
Normal file
102
examples/DeferredRendering/main.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
#include <windows.h>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include "GLApplication.h"
|
||||
|
||||
GLApplication application;
|
||||
bool running = true;
|
||||
HINSTANCE hInstance;
|
||||
|
||||
// The window callback function
|
||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message) {
|
||||
case WM_SIZE:
|
||||
{
|
||||
application.setSize(LOWORD(lParam), HIWORD(lParam));
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_KEYDOWN:
|
||||
{
|
||||
if((unsigned short) wParam == 112) application.showDeferredRendering();
|
||||
if((unsigned short) wParam == 113) application.showRenderTargets();
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
// Main entry point
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow)
|
||||
{
|
||||
MSG msg;
|
||||
WNDCLASS windowClass;
|
||||
HWND hWnd;
|
||||
DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
|
||||
const int width = 1024;
|
||||
const int height = 768;
|
||||
|
||||
hInstance = GetModuleHandle(NULL);
|
||||
|
||||
windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
||||
windowClass.lpfnWndProc = (WNDPROC) WndProc;
|
||||
windowClass.cbClsExtra = 0;
|
||||
windowClass.cbWndExtra = 0;
|
||||
windowClass.hInstance = hInstance;
|
||||
windowClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
|
||||
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
windowClass.hbrBackground = NULL;
|
||||
windowClass.lpszMenuName = NULL;
|
||||
windowClass.lpszClassName = L"DeferredRenderingClass";
|
||||
|
||||
if (!RegisterClass(&windowClass)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hWnd = CreateWindowEx(dwExStyle, L"DeferredRenderingClass", L"Deferred rendering tutorial", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, width, height, NULL, NULL, hInstance, NULL);
|
||||
|
||||
|
||||
if(!application.initialize(hWnd, width, height))
|
||||
return 0;
|
||||
|
||||
ShowWindow(hWnd, SW_SHOW);
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
|
||||
bool running = true;
|
||||
while (running)
|
||||
{
|
||||
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
if (msg.message == WM_QUIT)
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
application.update();
|
||||
application.render();
|
||||
}
|
||||
}
|
||||
|
||||
application.release();
|
||||
|
||||
return (int) msg.wParam;
|
||||
}
|
112
examples/ShadowMaps/ShadowMapsDR.vcxproj
Normal file
112
examples/ShadowMaps/ShadowMapsDR.vcxproj
Normal file
@ -0,0 +1,112 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="source\DeferredRendering\DeferredRendering.cpp" />
|
||||
<ClCompile Include="source\DeferredRendering\DepthRenderTexture.cpp" />
|
||||
<ClCompile Include="source\DeferredRendering\FBORenderTexture.cpp" />
|
||||
<ClCompile Include="source\GLApplication.cpp" />
|
||||
<ClCompile Include="source\main.cpp" />
|
||||
<ClCompile Include="source\Model\CubeModel.cpp" />
|
||||
<ClCompile Include="source\Model\GLSLShaderData.cpp" />
|
||||
<ClCompile Include="source\Model\IModel.cpp" />
|
||||
<ClCompile Include="source\Model\PlaneModel.cpp" />
|
||||
<ClCompile Include="source\Model\SphereModel.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="source\DeferredRendering\DeferredRendering.h" />
|
||||
<ClInclude Include="source\DeferredRendering\DepthRenderTexture.h" />
|
||||
<ClInclude Include="source\DeferredRendering\FBORenderTexture.h" />
|
||||
<ClInclude Include="source\GLApplication.h" />
|
||||
<ClInclude Include="source\Model\CubeModel.h" />
|
||||
<ClInclude Include="source\Model\GLSLShaderData.h" />
|
||||
<ClInclude Include="source\Model\IModel.h" />
|
||||
<ClInclude Include="source\Model\PlaneModel.h" />
|
||||
<ClInclude Include="source\Model\SphereModel.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{9D24251F-FD72-4A76-9B1C-999ED22D4DCA}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>OpenGL3Project</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>D:\Programmi\OpenGL\glew-1.7.0\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>D:\Programmi\OpenGL\glew-1.7.0\lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>D:\Programmi\OpenGL\glew-1.7.0\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>D:\Programmi\OpenGL\glew-1.7.0\lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\glew;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>glew32.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\glew\lib</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>glew32.lib;opengl32.lib;glu32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
1
examples/ShadowMaps/data/box.raw
Normal file
1
examples/ShadowMaps/data/box.raw
Normal file
File diff suppressed because one or more lines are too long
46
examples/ShadowMaps/data/deferredRendering.frag
Normal file
46
examples/ShadowMaps/data/deferredRendering.frag
Normal file
@ -0,0 +1,46 @@
|
||||
uniform sampler2D tDiffuse;
|
||||
uniform sampler2D tPosition;
|
||||
uniform sampler2D tNormals;
|
||||
uniform sampler2D tShadowMap;
|
||||
uniform vec3 cameraPosition;
|
||||
uniform mat4 worldToLightViewMatrix;
|
||||
uniform mat4 lightViewToProjectionMatrix;
|
||||
uniform mat4 worldToCameraViewMatrix;
|
||||
|
||||
float readShadowMap(vec3 eyeDir)
|
||||
{
|
||||
mat4 cameraViewToWorldMatrix = inverse(worldToCameraViewMatrix);
|
||||
mat4 cameraViewToProjectedLightSpace = lightViewToProjectionMatrix * worldToLightViewMatrix * cameraViewToWorldMatrix;
|
||||
vec4 projectedEyeDir = cameraViewToProjectedLightSpace * vec4(eyeDir,1);
|
||||
projectedEyeDir = projectedEyeDir/projectedEyeDir.w;
|
||||
|
||||
vec2 textureCoordinates = projectedEyeDir.xy * vec2(0.5,0.5) + vec2(0.5,0.5);
|
||||
|
||||
const float bias = 0.0001;
|
||||
float depthValue = texture2D( tShadowMap, textureCoordinates ) - bias;
|
||||
return projectedEyeDir.z * 0.5 + 0.5 < depthValue;
|
||||
}
|
||||
|
||||
void main( void )
|
||||
{
|
||||
// Read the data from the textures
|
||||
vec4 image = texture2D( tDiffuse, gl_TexCoord[0].xy );
|
||||
vec4 position = texture2D( tPosition, gl_TexCoord[0].xy );
|
||||
vec4 normal = texture2D( tNormals, gl_TexCoord[0].xy );
|
||||
|
||||
mat4 lightViewToWolrdMatrix = inverse(worldToLightViewMatrix);
|
||||
vec3 light = lightViewToWolrdMatrix[3].xyz;
|
||||
vec3 lightDir = light - position.xyz;
|
||||
|
||||
normal = normalize(normal);
|
||||
lightDir = normalize(lightDir);
|
||||
|
||||
vec3 eyeDir = position.xyz - cameraPosition;
|
||||
vec3 reflectedEyeVector = normalize(reflect(eyeDir, normal));
|
||||
|
||||
float shadow = readShadowMap(eyeDir);
|
||||
float diffuseLight = max(dot(normal,lightDir),0) * shadow;
|
||||
float ambientLight = 0.1;
|
||||
|
||||
gl_FragColor = (diffuseLight + ambientLight ) * image + pow(max(dot(lightDir,reflectedEyeVector),0.0), 100) * 1.5 * shadow;
|
||||
}
|
7
examples/ShadowMaps/data/deferredRendering.vert
Normal file
7
examples/ShadowMaps/data/deferredRendering.vert
Normal file
@ -0,0 +1,7 @@
|
||||
void main( void )
|
||||
{
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
}
|
11
examples/ShadowMaps/data/deferredShading.frag
Normal file
11
examples/ShadowMaps/data/deferredShading.frag
Normal file
@ -0,0 +1,11 @@
|
||||
varying vec4 position;
|
||||
varying vec3 normals;
|
||||
varying mat4 TBN;
|
||||
uniform sampler2D tDiffuse;
|
||||
|
||||
void main( void )
|
||||
{
|
||||
gl_FragData[0] = vec4(texture2D(tDiffuse,gl_TexCoord[0].st).rgb, 0);
|
||||
gl_FragData[1] = vec4(position.xyz,0);
|
||||
gl_FragData[2] = vec4(normals.xyz,0);
|
||||
}
|
16
examples/ShadowMaps/data/deferredShading.vert
Normal file
16
examples/ShadowMaps/data/deferredShading.vert
Normal file
@ -0,0 +1,16 @@
|
||||
varying vec3 normals;
|
||||
varying vec4 position;
|
||||
uniform mat4 ModelMatrix;
|
||||
uniform mat4 WorldMatrix;
|
||||
|
||||
void main( void )
|
||||
{
|
||||
// Move the normals back from the camera space to the world space
|
||||
mat3 worldRotationInverse = transpose(mat3(WorldMatrix));
|
||||
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
normals = normalize(worldRotationInverse * gl_NormalMatrix * gl_Normal);
|
||||
position = gl_ModelViewMatrix * gl_Vertex;
|
||||
gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
}
|
9198
examples/ShadowMaps/data/earth.raw
Normal file
9198
examples/ShadowMaps/data/earth.raw
Normal file
File diff suppressed because one or more lines are too long
BIN
examples/ShadowMaps/data/plane.raw
Normal file
BIN
examples/ShadowMaps/data/plane.raw
Normal file
Binary file not shown.
@ -0,0 +1,167 @@
|
||||
#include "FBORenderTexture.h"
|
||||
#include "DeferredRendering.h"
|
||||
#include <exception>
|
||||
|
||||
/**
|
||||
* Create the deferred rendering object. I have hardcoded the shader's name here.
|
||||
*/
|
||||
DeferredRendering::DeferredRendering(int _dWidth, int _dHeight)
|
||||
: m_shader("data/deferredRendering.vert", "data/deferredRendering.frag")
|
||||
, m_fboRenderTexture(_dWidth, _dHeight)
|
||||
, m_shadowMap(1024, 1024)
|
||||
, m_width(_dWidth)
|
||||
, m_height(_dHeight)
|
||||
{
|
||||
// Get the handles from the shader
|
||||
m_diffuseID = glGetUniformLocationARB(m_shader.m_programHandler,"tDiffuse");
|
||||
m_positionID = glGetUniformLocationARB(m_shader.m_programHandler,"tPosition");
|
||||
m_normalsID = glGetUniformLocationARB(m_shader.m_programHandler,"tNormals");
|
||||
m_shadowMapID = glGetUniformLocationARB(m_shader.m_programHandler,"tShadowMap");
|
||||
|
||||
m_worldToLightViewMatrix_shaderID = glGetUniformLocationARB(m_shader.m_programHandler,"worldToLightViewMatrix");
|
||||
m_lightViewToProjectionMatrix_shaderID = glGetUniformLocationARB(m_shader.m_programHandler,"lightViewToProjectionMatrix");
|
||||
m_worldToCameraViewMatrix_shaderID = glGetUniformLocationARB(m_shader.m_programHandler,"worldToCameraViewMatrix");
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire the light matrices
|
||||
*/
|
||||
void DeferredRendering::setLightMatrices(float worldToLightViewMatrix[16], float lightViewToProjectionMatrix[16], float worldToCameraViewMatrix[16])
|
||||
{
|
||||
memcpy(m_worldToLightViewMatrix, worldToLightViewMatrix, sizeof(float) * 16);
|
||||
memcpy(m_lightViewToProjectionMatrix, lightViewToProjectionMatrix, sizeof(float) * 16);
|
||||
memcpy(m_worldToCameraViewMatrix, worldToCameraViewMatrix, sizeof(float) * 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start rendering to the FBO
|
||||
*/
|
||||
void DeferredRendering::startRenderToFBO()
|
||||
{
|
||||
m_fboRenderTexture.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop rendering to the FBO
|
||||
*/
|
||||
void DeferredRendering::stopRenderToFBO()
|
||||
{
|
||||
m_fboRenderTexture.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the debug texture
|
||||
*/
|
||||
void DeferredRendering::showTexture(unsigned int i, float fWindowsWidth, float fWindowsHeight, float fSizeX, float fSizeY, float x, float y) const
|
||||
{
|
||||
m_fboRenderTexture.showTexture(i, fWindowsWidth, fWindowsHeight, fSizeX, fSizeY, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the depth into the shadow map
|
||||
*/
|
||||
void DeferredRendering::startRenderToShadowMap()
|
||||
{
|
||||
m_shadowMap.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop to render the depth into the shadow map
|
||||
*/
|
||||
void DeferredRendering::stopRenderToShadowMap()
|
||||
{
|
||||
m_shadowMap.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the debug texture for the shadow map
|
||||
*/
|
||||
void DeferredRendering::showShadowMap( float fWindowsWidth, float fWindowsHeight, float fSizeX, float fSizeY, float x, float y) const
|
||||
{
|
||||
m_shadowMap.showTexture(fWindowsWidth, fWindowsHeight, fSizeX, fSizeY, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the big quad with the deferred rendering shader on it
|
||||
*/
|
||||
void DeferredRendering::render()
|
||||
{
|
||||
//Projection setup
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(0,m_width,0,m_height,0.1f,2);
|
||||
|
||||
//Model setup
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
|
||||
glUseProgramObjectARB(m_shader.m_programHandler);
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, m_fboRenderTexture.getDiffuseTexture());
|
||||
glUniform1iARB ( m_diffuseID, 0 );
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, m_fboRenderTexture.getPositionTexture());
|
||||
glUniform1iARB ( m_positionID, 1 );
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, m_fboRenderTexture.getNormalsTexture());
|
||||
glUniform1iARB ( m_normalsID, 2 );
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE3_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, m_shadowMap.getTexture());
|
||||
glUniform1iARB ( m_shadowMapID, 3 );
|
||||
|
||||
glUniformMatrix4fv ( m_worldToCameraViewMatrix_shaderID, 1, GL_FALSE, m_worldToCameraViewMatrix );
|
||||
glUniformMatrix4fv ( m_lightViewToProjectionMatrix_shaderID, 1, GL_FALSE, m_lightViewToProjectionMatrix );
|
||||
glUniformMatrix4fv ( m_worldToLightViewMatrix_shaderID, 1, GL_FALSE, m_worldToLightViewMatrix );
|
||||
|
||||
// Render the quad
|
||||
glLoadIdentity();
|
||||
glColor3f(1,1,1);
|
||||
glTranslatef(0,0,-1.0);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f( 0, 0 );
|
||||
glVertex3f( 0.0f, 0.0f, 0.0f);
|
||||
glTexCoord2f( 1, 0 );
|
||||
glVertex3f( (float) m_width, 0.0f, 0.0f);
|
||||
glTexCoord2f( 1, 1 );
|
||||
glVertex3f( (float) m_width, (float) m_height, 0.0f);
|
||||
glTexCoord2f( 0, 1 );
|
||||
glVertex3f( 0.0f, (float) m_height, 0.0f);
|
||||
glEnd();
|
||||
|
||||
// Reset OpenGL state
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE3_ARB);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glUseProgramObjectARB(0);
|
||||
|
||||
//Reset to the matrices
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <gl/glew.h>
|
||||
#include <gl/gl.h>
|
||||
#include <gl/glu.h>
|
||||
#include "../Model/GLSLShaderData.h"
|
||||
#include "FBORenderTexture.h"
|
||||
#include "DepthRenderTexture.h"
|
||||
|
||||
/**
|
||||
* This object is used to render a big screen sized quad with the deferred rendering shader applied on it.
|
||||
*/
|
||||
class DeferredRendering
|
||||
{
|
||||
public:
|
||||
// Ctors/Dtors
|
||||
DeferredRendering(int width, int height);
|
||||
|
||||
// Methods
|
||||
void setLightMatrices(float worldToLightViewMatrix[16], float lightViewToProjectionMatrix[16], float worldToCameraViewMatrix[16]);
|
||||
void startRenderToFBO();
|
||||
void stopRenderToFBO();
|
||||
void startRenderToShadowMap();
|
||||
void stopRenderToShadowMap();
|
||||
void showTexture(unsigned int i, float fWindowsWidth, float fWindowsHeight, float fSizeX = 400, float fSizeY = 400, float x = 0, float y = 0) const;
|
||||
void showShadowMap(float fWindowsWidth, float fWindowsHeight, float fSizeX = 400, float fSizeY = 400, float x = 0, float y = 0) const;
|
||||
void render();
|
||||
|
||||
private:
|
||||
// Variables
|
||||
GLSLShaderData m_shader; // Deferred rendering shader
|
||||
FBORenderTexture m_fboRenderTexture; // A pointer to the FBO render texture that contains diffuse, normals and positions
|
||||
DepthRenderTexture m_shadowMap; // A pointer to the FBO that renders the depth into the shadow map
|
||||
|
||||
unsigned int m_width; // width
|
||||
unsigned int m_height; // height
|
||||
|
||||
float m_worldToLightViewMatrix[16]; // Matrix that takes a vector from World Space into Light View Space
|
||||
float m_lightViewToProjectionMatrix[16]; // Matrix that takes a vector from View Space into Projection Space (Clip Space)
|
||||
float m_worldToCameraViewMatrix[16]; // Matrix that takes a vector from World Space into Camera View Space
|
||||
|
||||
GLuint m_diffuseID; // Diffuse texture handle for the shader
|
||||
GLuint m_positionID; // Position texture handle for the shader
|
||||
GLuint m_normalsID; // Normals texture handle for the shader
|
||||
GLuint m_shadowMapID; // Shadow Map texture handle for the shader
|
||||
|
||||
GLuint m_worldToLightViewMatrix_shaderID; // Shader ID for the specified matrix
|
||||
GLuint m_lightViewToProjectionMatrix_shaderID; // Shader ID for the specified matrix
|
||||
GLuint m_worldToCameraViewMatrix_shaderID; // Shader ID for the specified matrix
|
||||
};
|
@ -0,0 +1,120 @@
|
||||
#include "DepthRenderTexture.h"
|
||||
#include <exception>
|
||||
|
||||
/**
|
||||
* Create the FBO render texture initializing all the stuff that we need
|
||||
*/
|
||||
DepthRenderTexture::DepthRenderTexture(int _dWidth, int _dHeight)
|
||||
{
|
||||
// Save extensions
|
||||
m_width = _dWidth;
|
||||
m_height = _dHeight;
|
||||
|
||||
// Generate the OGL resources for what we need
|
||||
glGenFramebuffersEXT(1, &m_fbo);
|
||||
glGenRenderbuffersEXT(1, &m_depthBufferRT);
|
||||
|
||||
// Bind the FBO so that the next operations will be bound to it
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
|
||||
|
||||
// Bind the depth buffer
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBufferRT);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, m_width, m_height);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBufferRT);
|
||||
|
||||
// Generate and bind the OGL texture for diffuse
|
||||
glGenTextures(1, &m_depthTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_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_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, m_width, m_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
|
||||
// Attach the texture to the FBO
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0);
|
||||
|
||||
// Check if all worked fine and unbind the FBO
|
||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
if( status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
throw new std::exception("Can't initialize an FBO render texture. FBO initialization failed.");
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
DepthRenderTexture::~DepthRenderTexture(){
|
||||
glDeleteFramebuffersEXT(1, &m_fbo);
|
||||
glDeleteRenderbuffersEXT(1, &m_depthBufferRT);
|
||||
glDeleteTextures(1, &m_depthTexture);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start rendering to the texture
|
||||
* Both color and depth buffers are cleared.
|
||||
*/
|
||||
void DepthRenderTexture::start(){
|
||||
// Bind our FBO and set the viewport to the proper size
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
|
||||
glPushAttrib(GL_VIEWPORT_BIT);
|
||||
glViewport(0,0,m_width, m_height);
|
||||
|
||||
// Clear the render target
|
||||
glClear( GL_DEPTH_BUFFER_BIT );
|
||||
|
||||
// Specify that we need no colours
|
||||
glDrawBuffer(GL_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop rendering to this texture.
|
||||
*/
|
||||
void DepthRenderTexture::stop(){
|
||||
// Stop acquiring and unbind the FBO
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the texture to screen. It is just for debug purposes.
|
||||
*/
|
||||
void DepthRenderTexture::showTexture(float fWindowsWidth, float fWindowsHeight, float fSizeX, float fSizeY, float x, float y) const {
|
||||
//Projection setup
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(0,fWindowsWidth,0,fWindowsHeight,0.1f,2);
|
||||
|
||||
//Model setup
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, m_depthTexture);
|
||||
|
||||
// Render the quad
|
||||
glLoadIdentity();
|
||||
glTranslatef(x, fWindowsHeight - y - fSizeY,-1.0);
|
||||
|
||||
glColor3f(1,1,1);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f( 0, 1 );
|
||||
glVertex3f( 0.0f, (float) fSizeY, 0.0f);
|
||||
glTexCoord2f( 0, 0 );
|
||||
glVertex3f( 0.0f, 0.0f, 0.0f);
|
||||
glTexCoord2f( 1, 0 );
|
||||
glVertex3f( fSizeX, 0.0f, 0.0f);
|
||||
glTexCoord2f( 1, 1 );
|
||||
glVertex3f( fSizeX, (float) fSizeY, 0.0f);
|
||||
glEnd();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
//Reset to the matrices
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <gl/glew.h>
|
||||
#include <gl/gl.h>
|
||||
#include <gl/glu.h>
|
||||
|
||||
/**
|
||||
* With this class we wrap the ability of OpenGL to render into a Depth Texture. We need this to create the shadow map.
|
||||
*/
|
||||
class DepthRenderTexture
|
||||
{
|
||||
public:
|
||||
// Ctors/Dtors
|
||||
DepthRenderTexture(int width, int height);
|
||||
~DepthRenderTexture();
|
||||
|
||||
// Methods
|
||||
void start();
|
||||
void stop();
|
||||
void showTexture(float fWindowsWidth, float fWindowsHeight, float fSizeX = 400, float fSizeY = 400, float x = 0, float y = 0) const;
|
||||
|
||||
GLuint getTexture() const { return m_depthTexture; }
|
||||
|
||||
private:
|
||||
|
||||
// Variables
|
||||
GLuint m_fbo; // The FBO ID
|
||||
GLuint m_depthBufferRT; // Depth buffer handle
|
||||
GLuint m_depthTexture; // Texture
|
||||
|
||||
unsigned int m_width; // FBO width
|
||||
unsigned int m_height; // FBO height
|
||||
};
|
@ -0,0 +1,175 @@
|
||||
#include "FBORenderTexture.h"
|
||||
#include <exception>
|
||||
|
||||
/**
|
||||
* Create the FBO render texture initializing all the stuff that we need
|
||||
*/
|
||||
FBORenderTexture::FBORenderTexture(int _dWidth, int _dHeight)
|
||||
{
|
||||
// Save extensions
|
||||
m_width = _dWidth;
|
||||
m_height = _dHeight;
|
||||
|
||||
// Generate the OGL resources for what we need
|
||||
glGenFramebuffersEXT(1, &m_fbo);
|
||||
glGenRenderbuffersEXT(1, &m_diffuseRT);
|
||||
glGenRenderbuffersEXT(1, &m_positionRT);
|
||||
glGenRenderbuffersEXT(1, &m_normalsRT);
|
||||
glGenRenderbuffersEXT(1, &m_depthBuffer);
|
||||
|
||||
// Bind the FBO so that the next operations will be bound to it
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
|
||||
|
||||
// Bind the diffuse render target
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_diffuseRT);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, m_width, m_height);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_diffuseRT);
|
||||
|
||||
// Bind the position render target
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_positionRT);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA32F_ARB, m_width, m_height);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_RENDERBUFFER_EXT, m_positionRT);
|
||||
|
||||
// Bind the normal render target
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_normalsRT);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA16F_ARB, m_width, m_height);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_RENDERBUFFER_EXT, m_normalsRT);
|
||||
|
||||
// Bind the depth buffer
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, m_width, m_height);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
|
||||
|
||||
// Generate and bind the OGL texture for diffuse
|
||||
glGenTextures(1, &m_diffuseTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_diffuseTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
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_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// Attach the texture to the FBO
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_diffuseTexture, 0);
|
||||
|
||||
// Generate and bind the OGL texture for positions
|
||||
glGenTextures(1, &m_positionTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_positionTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, m_width, m_height, 0, GL_RGBA, GL_FLOAT, NULL);
|
||||
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_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// Attach the texture to the FBO
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, m_positionTexture, 0);
|
||||
|
||||
// Generate and bind the OGL texture for normals
|
||||
glGenTextures(1, &m_normalsTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_normalsTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, m_width, m_height, 0, GL_RGBA, GL_FLOAT, NULL);
|
||||
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_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// Attach the texture to the FBO
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, m_normalsTexture, 0);
|
||||
|
||||
// Check if all worked fine and unbind the FBO
|
||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
if( status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
throw new std::exception("Can't initialize an FBO render texture. FBO initialization failed.");
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
FBORenderTexture::~FBORenderTexture(){
|
||||
glDeleteTextures(1, &m_normalsTexture);
|
||||
glDeleteTextures(1, &m_positionTexture);
|
||||
glDeleteTextures(1, &m_diffuseTexture);
|
||||
glDeleteFramebuffersEXT(1, &m_fbo);
|
||||
glDeleteRenderbuffersEXT(1, &m_diffuseRT);
|
||||
glDeleteRenderbuffersEXT(1, &m_positionRT);
|
||||
glDeleteRenderbuffersEXT(1, &m_normalsRT);
|
||||
glDeleteRenderbuffersEXT(1, &m_depthBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start rendering to the texture
|
||||
* Both color and depth buffers are cleared.
|
||||
*/
|
||||
void FBORenderTexture::start(){
|
||||
// Bind our FBO and set the viewport to the proper size
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
|
||||
glPushAttrib(GL_VIEWPORT_BIT);
|
||||
glViewport(0,0,m_width, m_height);
|
||||
|
||||
// Clear the render targets
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
// Specify what to render an start acquiring
|
||||
GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT };
|
||||
glDrawBuffers(3, buffers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop rendering to this texture.
|
||||
*/
|
||||
void FBORenderTexture::stop(){
|
||||
// Stop acquiring and unbind the FBO
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the texture to screen. It is just for debug purposes.
|
||||
*/
|
||||
void FBORenderTexture::showTexture(unsigned int i, float fWindowsWidth, float fWindowsHeight, float fSizeX, float fSizeY, float x, float y) const {
|
||||
GLuint texture = m_diffuseTexture;
|
||||
if(i == 1) texture = m_positionTexture;
|
||||
else
|
||||
if(i == 2) texture = m_normalsTexture;
|
||||
|
||||
//Projection setup
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(0,fWindowsWidth,0,fWindowsHeight,0.1f,2);
|
||||
|
||||
//Model setup
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
// Render the quad
|
||||
glLoadIdentity();
|
||||
glTranslatef(x,fWindowsHeight - y - fSizeY,-1.0);
|
||||
|
||||
glColor3f(1,1,1);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f( 0, 1 );
|
||||
glVertex3f( 0.0f, (float) fSizeY, 0.0f);
|
||||
glTexCoord2f( 0, 0 );
|
||||
glVertex3f( 0.0f, 0.0f, 0.0f);
|
||||
glTexCoord2f( 1, 0 );
|
||||
glVertex3f( fSizeX, 0.0f, 0.0f);
|
||||
glTexCoord2f( 1, 1 );
|
||||
glVertex3f( fSizeX, (float) fSizeY, 0.0f);
|
||||
glEnd();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
//Reset to the matrices
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <gl/glew.h>
|
||||
#include <gl/gl.h>
|
||||
#include <gl/glu.h>
|
||||
|
||||
/**
|
||||
* A Frame Buffer Object is used by OpenGL to render into a texture. Specifically this implementation assumes that the
|
||||
* rendered model will provide diffuse, position and normal at the same time in a MRT fashion
|
||||
*/
|
||||
class FBORenderTexture
|
||||
{
|
||||
public:
|
||||
// Ctors/Dtors
|
||||
FBORenderTexture(int width, int height);
|
||||
~FBORenderTexture();
|
||||
|
||||
// Methods
|
||||
void start();
|
||||
void stop();
|
||||
void showTexture(unsigned int i, float fWindowsWidth, float fWindowsHeight, float fSizeX = 400, float fSizeY = 400, float x = 0, float y = 0) const;
|
||||
|
||||
GLuint getDiffuseTexture() const { return m_diffuseTexture; }
|
||||
GLuint getPositionTexture() const { return m_positionTexture; }
|
||||
GLuint getNormalsTexture() const { return m_normalsTexture; }
|
||||
|
||||
private:
|
||||
|
||||
// Variables
|
||||
GLuint m_fbo; // The FBO ID
|
||||
GLuint m_diffuseRT; // The diffuse render target
|
||||
unsigned int m_diffuseTexture; // The OpenGL texture for the diffuse render target
|
||||
GLuint m_positionRT; // The position render target
|
||||
unsigned int m_positionTexture; // The OpenGL texture for the position render target
|
||||
GLuint m_normalsRT; // The normals render target
|
||||
unsigned int m_normalsTexture; // The OpenGL texture for the normals render target
|
||||
GLuint m_depthBuffer; // Depth buffer handle
|
||||
|
||||
unsigned int m_width; // FBO width
|
||||
unsigned int m_height; // FBO height
|
||||
};
|
243
examples/ShadowMaps/source/GLApplication.cpp
Normal file
243
examples/ShadowMaps/source/GLApplication.cpp
Normal file
@ -0,0 +1,243 @@
|
||||
#include <windows.h>
|
||||
#include "GLApplication.h"
|
||||
#include "Model/SphereModel.h"
|
||||
#include "Model/CubeModel.h"
|
||||
#include "Model/PlaneModel.h"
|
||||
|
||||
/**
|
||||
* Initialize our GL application
|
||||
*/
|
||||
bool GLApplication::initialize(HWND hwnd, int width, int height)
|
||||
{
|
||||
GLuint pixelFormat;
|
||||
m_windowHeight = height;
|
||||
m_windowWidth = width;
|
||||
|
||||
m_hWnd = hwnd;
|
||||
m_lightRotation = 0.0f;
|
||||
|
||||
static PIXELFORMATDESCRIPTOR pfd=
|
||||
{
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
1,
|
||||
PFD_DRAW_TO_WINDOW |
|
||||
PFD_SUPPORT_OPENGL |
|
||||
PFD_DOUBLEBUFFER,
|
||||
PFD_TYPE_RGBA,
|
||||
16,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
16,
|
||||
0,
|
||||
0,
|
||||
PFD_MAIN_PLANE,
|
||||
0,
|
||||
0, 0, 0
|
||||
};
|
||||
|
||||
if (!(m_hdc=GetDC(m_hWnd)))
|
||||
return FALSE;
|
||||
|
||||
if (!(pixelFormat=ChoosePixelFormat(m_hdc,&pfd)))
|
||||
return FALSE;
|
||||
|
||||
if(!SetPixelFormat(m_hdc,pixelFormat,&pfd))
|
||||
return FALSE;
|
||||
|
||||
if (!(m_hrc=wglCreateContext(m_hdc)))
|
||||
return FALSE;
|
||||
|
||||
if(!wglMakeCurrent(m_hdc,m_hrc))
|
||||
return FALSE;
|
||||
|
||||
ShowWindow(m_hWnd,SW_SHOW);
|
||||
SetForegroundWindow(m_hWnd);
|
||||
SetFocus(m_hWnd);
|
||||
setSize(width, height);
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
GLenum err = glewInit();
|
||||
if (GLEW_OK != err)
|
||||
return false;
|
||||
|
||||
loadAssets();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set window's size
|
||||
*/
|
||||
void GLApplication::setSize(int w, int h)
|
||||
{
|
||||
m_windowWidth = w;
|
||||
m_windowHeight = h;
|
||||
|
||||
glViewport(0,0,m_windowWidth,m_windowHeight);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
gluPerspective(40.0f,(GLfloat)m_windowWidth/(GLfloat)m_windowHeight,1.0f,30.0f);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update
|
||||
*/
|
||||
void GLApplication::update()
|
||||
{
|
||||
float time = (GetTickCount() - m_lastTick) * 0.01f;
|
||||
m_lastTick = GetTickCount();
|
||||
|
||||
m_models[3]->addRotation( time, time*2, 0 );
|
||||
m_models[4]->addRotation( 0.2f + time, 0.1f + time*2, 0 );
|
||||
|
||||
m_lightRotation += time;
|
||||
if(m_lightRotation > 360)
|
||||
m_lightRotation -= 360;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the scene
|
||||
*/
|
||||
void GLApplication::render()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClearColor(0.2f, 0.3f, 0.8f, 1.0f);
|
||||
|
||||
// We move the near plane just a bit to make the depth texture a bit more visible.
|
||||
// It also increases the precision.
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
gluPerspective(20.0f, 1, 40.0f, 70.0f);
|
||||
|
||||
// Set the light position
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glRotatef(55, 1, 0, 0);
|
||||
glRotatef(-45, 0, 1, 0);
|
||||
glTranslatef(-25.0f, -50.0f, -25.0f);
|
||||
glRotatef(m_lightRotation, 0, 1, 0);
|
||||
glFrontFace(GL_CW);
|
||||
|
||||
// Render the shadow map
|
||||
m_deferredRendering->startRenderToShadowMap();
|
||||
for(int i=0; i<c_modelsCount; ++i)
|
||||
m_models[i]->render();
|
||||
m_deferredRendering->stopRenderToShadowMap();
|
||||
|
||||
// We then save out the matrices and send them to the deferred rendering, so when it comes to do the deferred pass
|
||||
// it can project the pixel it's rendering to the light and see if it's in shadows
|
||||
float worldToLightViewMatrix[16];
|
||||
float lightViewToProjectionMatrix[16];
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, worldToLightViewMatrix);
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, lightViewToProjectionMatrix);
|
||||
|
||||
// Re-set the projection to the default one we have pushed on the stack
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
||||
// Set the camera position
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glRotatef(20, 1, 0, 0);
|
||||
glTranslatef(0.0f,-6.5f,-11.0f);
|
||||
glFrontFace(GL_CCW);
|
||||
|
||||
float worldToCameraViewMatrix[16];
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, worldToCameraViewMatrix);
|
||||
|
||||
// Render our geometry into the FBO
|
||||
m_deferredRendering->startRenderToFBO();
|
||||
for(int i=0; i<c_modelsCount; ++i)
|
||||
m_models[i]->render();
|
||||
m_deferredRendering->stopRenderToFBO();
|
||||
|
||||
// Render to the screen
|
||||
if(m_state == 0)
|
||||
{
|
||||
// Render to screen using the deferred rendering shader
|
||||
m_deferredRendering->setLightMatrices(worldToLightViewMatrix, lightViewToProjectionMatrix, worldToCameraViewMatrix);
|
||||
m_deferredRendering->render();
|
||||
}
|
||||
else if(m_state == 1)
|
||||
{
|
||||
m_deferredRendering->showTexture( 0, (float)m_windowWidth, (float)m_windowHeight, 512, 384, 0);
|
||||
m_deferredRendering->showTexture( 1, (float)m_windowWidth, (float)m_windowHeight, 512, 384, 512);
|
||||
m_deferredRendering->showTexture( 2, (float)m_windowWidth, (float)m_windowHeight, 512, 384, 0, 384);
|
||||
m_deferredRendering->showShadowMap( (float)m_windowWidth, (float)m_windowHeight, 384, 384, 512, 384);
|
||||
}
|
||||
|
||||
SwapBuffers(m_hdc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release all the GL resources we have allocated
|
||||
*/
|
||||
void GLApplication::release()
|
||||
{
|
||||
releaseAssets();
|
||||
|
||||
wglMakeCurrent(m_hdc, 0);
|
||||
wglDeleteContext(m_hrc);
|
||||
|
||||
ReleaseDC(m_hWnd, m_hdc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all the required assets
|
||||
*/
|
||||
void GLApplication::loadAssets()
|
||||
{
|
||||
m_state = 0;
|
||||
|
||||
m_deferredRendering = new DeferredRendering(m_windowWidth, m_windowHeight);
|
||||
|
||||
m_models[0] = new PlaneModel("data/deferredShading.vert", "data/deferredShading.frag", 5);
|
||||
m_models[0]->loadTexture("data/plane.raw");
|
||||
m_models[0]->setPosition(0,0,0);
|
||||
|
||||
m_models[1] = new CubeModel("data/deferredShading.vert", "data/deferredShading.frag", 1);
|
||||
m_models[1]->loadTexture("data/box.raw");
|
||||
m_models[1]->setPosition(-1.0f,3.0f,-1);
|
||||
|
||||
m_models[2] = new CubeModel("data/deferredShading.vert", "data/deferredShading.frag", 1);
|
||||
m_models[2]->loadTexture("data/box.raw");
|
||||
m_models[2]->setPosition(-1.0f,1.0f,-1);
|
||||
m_models[2]->setRotation(0, 20.0f, 0.0f);
|
||||
|
||||
m_models[3] = new SphereModel("data/deferredShading.vert", "data/deferredShading.frag", 1, 64);
|
||||
m_models[3]->loadTexture("data/earth.raw");
|
||||
m_models[3]->setPosition(1.5f, 2.0f, 0.5f);
|
||||
|
||||
m_models[4] = new SphereModel("data/deferredShading.vert", "data/deferredShading.frag", 1, 64);
|
||||
m_models[4]->loadTexture("data/earth.raw");
|
||||
m_models[4]->setPosition(1.5f, 5.0f, 0.5f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release all the assets
|
||||
*/
|
||||
void GLApplication::releaseAssets()
|
||||
{
|
||||
delete m_deferredRendering;
|
||||
|
||||
for(int i=0; i<c_modelsCount; ++i)
|
||||
delete m_models[i];
|
||||
}
|
47
examples/ShadowMaps/source/GLApplication.h
Normal file
47
examples/ShadowMaps/source/GLApplication.h
Normal file
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include "DeferredRendering/DeferredRendering.h"
|
||||
#include "DeferredRendering/FBORenderTexture.h"
|
||||
|
||||
//Fwd
|
||||
class IModel;
|
||||
|
||||
/**
|
||||
* This class contains all the system stuff that we need to render with OpenGL
|
||||
*/
|
||||
class GLApplication {
|
||||
public:
|
||||
// Methods
|
||||
bool initialize(HWND hwnd, int w, int h);
|
||||
void setSize(int w, int h);
|
||||
void update();
|
||||
void render();
|
||||
void release();
|
||||
|
||||
void showDeferredRendering(){ m_state = 0; }
|
||||
void showRenderTargets(){ m_state = 1; }
|
||||
|
||||
private:
|
||||
// Methods
|
||||
void loadAssets();
|
||||
void releaseAssets();
|
||||
|
||||
// Static consts
|
||||
static const int c_modelsCount = 5;
|
||||
|
||||
// Fields
|
||||
IModel* m_models[c_modelsCount];
|
||||
DeferredRendering* m_deferredRendering;
|
||||
|
||||
int m_windowWidth;
|
||||
int m_windowHeight;
|
||||
|
||||
HGLRC m_hrc; // Rendering's context
|
||||
HDC m_hdc; // Device's context
|
||||
HWND m_hWnd; // Window's handle
|
||||
|
||||
unsigned int m_lastTick;
|
||||
unsigned char m_state; // 0 - Normal render, 1 - Show render targets
|
||||
|
||||
float m_lightRotation;
|
||||
};
|
73
examples/ShadowMaps/source/Model/CubeModel.cpp
Normal file
73
examples/ShadowMaps/source/Model/CubeModel.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include "CubeModel.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* Construct the cube
|
||||
*/
|
||||
CubeModel::CubeModel(const std::string& sVSFileName, const std::string& sFSFileName, float side)
|
||||
: IModel(sVSFileName, sFSFileName)
|
||||
, m_side(side)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Render
|
||||
*/
|
||||
void CubeModel::render() const
|
||||
{
|
||||
glPushMatrix();
|
||||
|
||||
// Save the current world matrix to compensate the normals in the shader
|
||||
float worldMatrix[16];
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, worldMatrix);
|
||||
|
||||
glScalef(m_side,m_side,m_side);
|
||||
glTranslatef(m_posX, m_posY, m_posZ);
|
||||
glRotatef(m_rotX, 1, 0, 0);
|
||||
glRotatef(m_rotY, 0, 1, 0);
|
||||
glRotatef(m_rotZ, 0, 0, 1);
|
||||
|
||||
glUseProgramObjectARB(m_shader.m_programHandler);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
glUniform1iARB ( m_textureID, 0);
|
||||
glUniformMatrix4fvARB ( m_worldMatrixID, 1, false, worldMatrix);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
// Front Face
|
||||
glTexCoord2f(0.0f, 0.0f); glNormal3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 0.0f); glNormal3f(0.0f, 0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f); glNormal3f(0.0f, 0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, 1.0f); glNormal3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
|
||||
// Back Face
|
||||
glTexCoord2f(1.0f, 0.0f); glNormal3f(0.0f, 0.0f, -1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f); glNormal3f(0.0f, 0.0f, -1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 1.0f); glNormal3f(0.0f, 0.0f, -1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 0.0f); glNormal3f(0.0f, 0.0f, -1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
||||
// Top Face
|
||||
glTexCoord2f(0.0f, 1.0f); glNormal3f(0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 0.0f); glNormal3f(0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 0.0f); glNormal3f(0.0f, 1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f); glNormal3f(0.0f, 1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
|
||||
// Bottom Face
|
||||
glTexCoord2f(1.0f, 1.0f); glNormal3f(0.0f, -1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 1.0f); glNormal3f(0.0f, -1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 0.0f); glNormal3f(0.0f, -1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 0.0f); glNormal3f(0.0f, -1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
|
||||
// Right face
|
||||
glTexCoord2f(1.0f, 0.0f); glNormal3f(1.0f, 0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f); glNormal3f(1.0f, 0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 1.0f); glNormal3f(1.0f, 0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, 0.0f); glNormal3f(1.0f, 0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
|
||||
// Left Face
|
||||
glTexCoord2f(0.0f, 0.0f); glNormal3f(-1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
||||
glTexCoord2f(1.0f, 0.0f); glNormal3f(-1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f); glNormal3f(-1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, 1.0f); glNormal3f(-1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
|
||||
glEnd();
|
||||
|
||||
glUseProgramObjectARB(0);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
19
examples/ShadowMaps/source/Model/CubeModel.h
Normal file
19
examples/ShadowMaps/source/Model/CubeModel.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "IModel.h"
|
||||
|
||||
/**
|
||||
* A simple cube model that is easy to render
|
||||
*/
|
||||
class CubeModel : public IModel
|
||||
{
|
||||
public:
|
||||
// Methods
|
||||
CubeModel(const std::string& sVSFileName, const std::string& sFSFileName, float side);
|
||||
|
||||
void render() const;
|
||||
|
||||
protected:
|
||||
// Fields
|
||||
float m_side;
|
||||
};
|
||||
|
82
examples/ShadowMaps/source/Model/GLSLShaderData.cpp
Normal file
82
examples/ShadowMaps/source/Model/GLSLShaderData.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
#include <windows.h>
|
||||
#include "gl/glew.h"
|
||||
#include <gl/gl.h>
|
||||
#include <gl/glu.h>
|
||||
#include "GLSLShaderData.h"
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
GLSLShaderData::GLSLShaderData(const std::string& _sVSFileName, const std::string& _sFSFileName)
|
||||
: m_VSFileName(_sVSFileName)
|
||||
, m_FSFileName(_sFSFileName)
|
||||
{
|
||||
// Create OGL resources
|
||||
m_vertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
|
||||
m_fragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
|
||||
|
||||
//Read out the shader data from the given files
|
||||
char *sVSData, *sFSData;
|
||||
|
||||
//Read out the vertex shader data
|
||||
FILE *file;
|
||||
fopen_s(&file, m_VSFileName.c_str(),"r");
|
||||
if(!file)
|
||||
throw new std::exception( std::string("Can't load GLSL Vertex Shader from file: " + m_VSFileName).c_str() );
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
long count = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
sVSData = new char[count+1];
|
||||
memset(sVSData,0,count+1);
|
||||
fread(sVSData, 1, count, file);
|
||||
fclose(file);
|
||||
|
||||
file = NULL;
|
||||
|
||||
//Read out the fragment shader data
|
||||
fopen_s(&file, m_FSFileName.c_str(),"r");
|
||||
if(!file)
|
||||
throw new std::exception( std::string("Can't load GLSL Fragment Shader from file: "+m_FSFileName).c_str() );
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
count = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
sFSData = new char[count+1];
|
||||
memset(sFSData,0,count+1);
|
||||
fread(sFSData, 1, count, file);
|
||||
fclose(file);
|
||||
|
||||
// Now that we have the two shaders in memory we can compile them
|
||||
const char * pVS = sVSData;
|
||||
const char * pFS = sFSData;
|
||||
int bCompiled = false;
|
||||
|
||||
glShaderSourceARB(m_vertexShader, 1, &pVS, NULL);
|
||||
glCompileShaderARB(m_vertexShader);
|
||||
|
||||
glGetObjectParameterivARB( m_vertexShader, GL_OBJECT_COMPILE_STATUS_ARB, &bCompiled );
|
||||
if( bCompiled == false )
|
||||
throw new std::exception("Vertex shader compilation failed.");
|
||||
|
||||
glShaderSourceARB(m_fragmentShader, 1, &pFS, NULL);
|
||||
glCompileShaderARB(m_fragmentShader);
|
||||
|
||||
glGetObjectParameterivARB( m_fragmentShader, GL_OBJECT_COMPILE_STATUS_ARB, &bCompiled );
|
||||
if( bCompiled == false )
|
||||
throw new std::exception("Fragment shader compilation failed.");
|
||||
|
||||
// Once compiled we can bind everything together for OpenGL to use
|
||||
m_programHandler = glCreateProgramObjectARB();
|
||||
glAttachObjectARB(m_programHandler,m_vertexShader);
|
||||
glAttachObjectARB(m_programHandler,m_fragmentShader);
|
||||
|
||||
glLinkProgramARB(m_programHandler);
|
||||
|
||||
// We release the shader data read from file since we now have everything compiled in memory
|
||||
delete [] sFSData;
|
||||
delete [] sVSData;
|
||||
}
|
||||
|
22
examples/ShadowMaps/source/Model/GLSLShaderData.h
Normal file
22
examples/ShadowMaps/source/Model/GLSLShaderData.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* GLSLShaderData encapsulate all the GLSL data.<br>
|
||||
* Constructor initialize data from files.
|
||||
*/
|
||||
class GLSLShaderData
|
||||
{
|
||||
public:
|
||||
// Functions
|
||||
//------------------------------------------------------------
|
||||
GLSLShaderData(const std::string& sVSFileName, const std::string& sFSFileName);
|
||||
|
||||
// Variables
|
||||
//------------------------------------------------------------
|
||||
GLhandleARB m_vertexShader; // Vertex shader handle
|
||||
GLhandleARB m_fragmentShader; // Fragment shader handle
|
||||
GLhandleARB m_programHandler; // Shader handle
|
||||
std::string m_VSFileName; // Vertex shader filename
|
||||
std::string m_FSFileName; // Fragment shader filename
|
||||
};
|
79
examples/ShadowMaps/source/Model/IModel.cpp
Normal file
79
examples/ShadowMaps/source/Model/IModel.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
#include "IModel.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* This method assumes that the file passed as parameter is a raw block of data made of RGB components (one byte per channel)
|
||||
* It is *NOT* a good way to load/store textures, but for sake of simplicity I've decided to use it for this tutorial.
|
||||
*/
|
||||
bool IModel::loadTexture(const std::string& textureName)
|
||||
{
|
||||
byte* data = NULL;
|
||||
|
||||
FILE* f;
|
||||
fopen_s(&f, textureName.c_str(), "r");
|
||||
if(f != NULL)
|
||||
{
|
||||
fseek (f, 0, SEEK_END);
|
||||
unsigned int size = ftell (f);
|
||||
fseek (f, 0, SEEK_SET);
|
||||
|
||||
data = new byte[size];
|
||||
fread( data, sizeof(byte), size, f);
|
||||
fclose(f);
|
||||
|
||||
// Assuming that the raw image is square and RGB; don't fancy doing anything more complicated since the tutorial is not focused on textures loading
|
||||
GLuint side = (GLuint)sqrt(size/3.0f);
|
||||
|
||||
// Generate the texture
|
||||
if(m_texture != 0)
|
||||
glDeleteTextures(1, &m_texture);
|
||||
glGenTextures(1, &m_texture);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 3, side, side, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set position
|
||||
*/
|
||||
void IModel::setPosition(float x, float y, float z)
|
||||
{
|
||||
m_posX = x;
|
||||
m_posY = y;
|
||||
m_posZ = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set rotation
|
||||
*/
|
||||
void IModel::setRotation(float x, float y, float z)
|
||||
{
|
||||
m_rotX = x;
|
||||
m_rotY = y;
|
||||
m_rotZ = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a delta to the current rotation
|
||||
*/
|
||||
void IModel::addRotation(float x, float y, float z)
|
||||
{
|
||||
m_rotX += x;
|
||||
m_rotY += y;
|
||||
m_rotZ += z;
|
||||
}
|
||||
|
45
examples/ShadowMaps/source/Model/IModel.h
Normal file
45
examples/ShadowMaps/source/Model/IModel.h
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include "gl/glew.h"
|
||||
#include <gl/gl.h>
|
||||
#include <gl/glu.h>
|
||||
#include <string>
|
||||
#include "GLSLShaderData.h"
|
||||
|
||||
/**
|
||||
* Every renderable object inherits from this interface for simplicity
|
||||
*/
|
||||
class IModel
|
||||
{
|
||||
public:
|
||||
// Methods
|
||||
IModel(const std::string& sVSFileName, const std::string& sFSFileName)
|
||||
: m_shader(sVSFileName, sFSFileName)
|
||||
, m_texture(0)
|
||||
{
|
||||
m_rotX = m_rotY = m_rotZ = 0;
|
||||
m_posX = m_posY = m_posZ = 0;
|
||||
|
||||
m_worldMatrixID = glGetUniformLocationARB(m_shader.m_programHandler,"WorldMatrix");
|
||||
m_textureID = glGetUniformLocationARB(m_shader.m_programHandler,"tDiffuse");
|
||||
}
|
||||
virtual ~IModel(){}
|
||||
|
||||
bool loadTexture(const std::string& textureName);
|
||||
void setPosition(float x, float y, float z);
|
||||
void setRotation(float x, float y, float z);
|
||||
void addRotation(float x, float y, float z);
|
||||
virtual void render() const = 0;
|
||||
|
||||
protected:
|
||||
// Fields
|
||||
GLSLShaderData m_shader; // Every model must have a shader associated (both vertex and fragment)
|
||||
|
||||
GLuint m_worldMatrixID; // This ID is used to pass the world matrix into the shader
|
||||
float m_rotX, m_rotY, m_rotZ; // Rotations
|
||||
float m_posX, m_posY, m_posZ; // Positions
|
||||
|
||||
GLuint m_textureID; // Texture ID used to pass the texture into the shader
|
||||
GLuint m_texture; // OpenGL texture ID
|
||||
};
|
||||
|
57
examples/ShadowMaps/source/Model/PlaneModel.cpp
Normal file
57
examples/ShadowMaps/source/Model/PlaneModel.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
#include "PlaneModel.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* Construct the plane
|
||||
*/
|
||||
PlaneModel::PlaneModel(const std::string& sVSFileName, const std::string& sFSFileName, float side)
|
||||
: IModel(sVSFileName, sFSFileName)
|
||||
, m_side(side)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Render
|
||||
*/
|
||||
void PlaneModel::render() const
|
||||
{
|
||||
glPushMatrix();
|
||||
|
||||
// Save the current world matrix to compensate the normals in the shader
|
||||
float worldMatrix[16];
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, worldMatrix);
|
||||
|
||||
glTranslatef(m_posX, m_posY, m_posZ);
|
||||
glRotatef(m_rotX, 1, 0, 0);
|
||||
glRotatef(m_rotY, 0, 1, 0);
|
||||
glRotatef(m_rotZ, 0, 0, 1);
|
||||
glScalef(m_side,m_side,m_side);
|
||||
|
||||
glUseProgramObjectARB(m_shader.m_programHandler);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
glUniform1iARB ( m_textureID, 0);
|
||||
glUniformMatrix4fvARB ( m_worldMatrixID, 1, false, worldMatrix);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glVertex3f(-1.0f, 0.0f, -1.0f);
|
||||
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glVertex3f(-1.0f, 0.0f, 1.0f);
|
||||
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glVertex3f( 1.0f, 0.0f, 1.0f);
|
||||
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glVertex3f( 1.0f, 0.0f, -1.0f);
|
||||
glEnd();
|
||||
|
||||
glUseProgramObjectARB(0);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
19
examples/ShadowMaps/source/Model/PlaneModel.h
Normal file
19
examples/ShadowMaps/source/Model/PlaneModel.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "IModel.h"
|
||||
|
||||
/**
|
||||
* A plane model that is easy to render
|
||||
*/
|
||||
class PlaneModel : public IModel
|
||||
{
|
||||
public:
|
||||
// Methods
|
||||
PlaneModel(const std::string& sVSFileName, const std::string& sFSFileName, float side);
|
||||
|
||||
void render() const;
|
||||
|
||||
protected:
|
||||
// Fields
|
||||
float m_side;
|
||||
};
|
||||
|
45
examples/ShadowMaps/source/Model/SphereModel.cpp
Normal file
45
examples/ShadowMaps/source/Model/SphereModel.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include "SphereModel.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* Construct the sphere
|
||||
*/
|
||||
SphereModel::SphereModel(const std::string& sVSFileName, const std::string& sFSFileName, float radius, unsigned int meshPrecision)
|
||||
: IModel(sVSFileName, sFSFileName)
|
||||
{
|
||||
m_radius = radius;
|
||||
m_meshPrecision = meshPrecision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render
|
||||
*/
|
||||
void SphereModel::render() const
|
||||
{
|
||||
glPushMatrix();
|
||||
|
||||
// Save the current world matrix to compensate the normals in the shader
|
||||
float worldMatrix[16];
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, worldMatrix);
|
||||
|
||||
glTranslatef(m_posX, m_posY, m_posZ);
|
||||
glRotatef(m_rotX, 1, 0, 0);
|
||||
glRotatef(m_rotY, 0, 1, 0);
|
||||
glRotatef(m_rotZ, 0, 0, 1);
|
||||
|
||||
glUseProgramObjectARB(m_shader.m_programHandler);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
glUniform1iARB ( m_textureID, 0);
|
||||
glUniformMatrix4fvARB ( m_worldMatrixID, 1, false, worldMatrix);
|
||||
|
||||
GLUquadricObj *sphere = gluNewQuadric();
|
||||
gluQuadricTexture(sphere, true);
|
||||
gluSphere(sphere, m_radius, m_meshPrecision, m_meshPrecision);
|
||||
gluDeleteQuadric(sphere);
|
||||
|
||||
glUseProgramObjectARB(0);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
20
examples/ShadowMaps/source/Model/SphereModel.h
Normal file
20
examples/ShadowMaps/source/Model/SphereModel.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include "IModel.h"
|
||||
|
||||
/**
|
||||
* A simple sphere model that is easy to render
|
||||
*/
|
||||
class SphereModel : public IModel
|
||||
{
|
||||
public:
|
||||
// Methods
|
||||
SphereModel(const std::string& sVSFileName, const std::string& sFSFileName, float radius, unsigned int meshPrecision);
|
||||
|
||||
void render() const;
|
||||
|
||||
private:
|
||||
// Fields
|
||||
float m_radius;
|
||||
unsigned int m_meshPrecision;
|
||||
};
|
||||
|
102
examples/ShadowMaps/source/main.cpp
Normal file
102
examples/ShadowMaps/source/main.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
#include <windows.h>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include "GLApplication.h"
|
||||
|
||||
GLApplication application;
|
||||
bool running = true;
|
||||
HINSTANCE hInstance;
|
||||
|
||||
// The window callback function
|
||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message) {
|
||||
case WM_SIZE:
|
||||
{
|
||||
application.setSize(LOWORD(lParam), HIWORD(lParam));
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_KEYDOWN:
|
||||
{
|
||||
if((unsigned short) wParam == 112) application.showDeferredRendering();
|
||||
if((unsigned short) wParam == 113) application.showRenderTargets();
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
// Main entry point
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow)
|
||||
{
|
||||
MSG msg;
|
||||
WNDCLASS windowClass;
|
||||
HWND hWnd;
|
||||
DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
|
||||
const int width = 1024;
|
||||
const int height = 768;
|
||||
|
||||
hInstance = GetModuleHandle(NULL);
|
||||
|
||||
windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
||||
windowClass.lpfnWndProc = (WNDPROC) WndProc;
|
||||
windowClass.cbClsExtra = 0;
|
||||
windowClass.cbWndExtra = 0;
|
||||
windowClass.hInstance = hInstance;
|
||||
windowClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
|
||||
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
windowClass.hbrBackground = NULL;
|
||||
windowClass.lpszMenuName = NULL;
|
||||
windowClass.lpszClassName = L"DeferredRenderingClass";
|
||||
|
||||
if (!RegisterClass(&windowClass)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hWnd = CreateWindowEx(dwExStyle, L"DeferredRenderingClass", L"Deferred Rendering Shadow Mapping tutorial", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, width, height, NULL, NULL, hInstance, NULL);
|
||||
|
||||
|
||||
if(!application.initialize(hWnd, width, height))
|
||||
return 0;
|
||||
|
||||
ShowWindow(hWnd, SW_SHOW);
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
|
||||
bool running = true;
|
||||
while (running)
|
||||
{
|
||||
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
if (msg.message == WM_QUIT)
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
application.update();
|
||||
application.render();
|
||||
}
|
||||
}
|
||||
|
||||
application.release();
|
||||
|
||||
return (int) msg.wParam;
|
||||
}
|
Loading…
Reference in New Issue
Block a user