From 68042634b81e103ced9c91a7aba9e2d08b59e26e Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Sat, 14 Jul 2012 14:54:01 +0100 Subject: [PATCH] Added chapter 10 --- .../OpenGLInsightsTessellation.sln | 20 + .../OpenGLInsightsTessellation/Makefile | 19 + .../OpenGLInsightsTessellation.vcxproj | 109 ++ ...OpenGLInsightsTessellation.vcxproj.filters | 95 + .../OpenGLInsightsTessellation.vcxproj.user | 3 + .../fonts/couriernew10.tga | Bin 0 -> 262162 bytes .../fonts/couriernew10.xml | 100 + .../shaders/dirlightdiffambpix.frag | 39 + .../shaders/dirlightdiffambpix.vert | 24 + .../shaders/terrainTessDemoSingleScaled.frag | 54 + .../shaders/terrainTessDemoSingleScaled.tesc | 195 ++ .../shaders/terrainTessDemoSingleScaled.tese | 57 + .../shaders/terrainTessDemoSingleScaled.vert | 14 + .../terrainTessDemo.cpp | 525 +++++ .../vsGLInfoLib.cpp | 1695 +++++++++++++++++ .../OpenGLInsightsTessellation/vsGLInfoLib.h | 161 ++ .../OpenGLInsightsTessellation/vsLogLib.cpp | 99 + .../OpenGLInsightsTessellation/vsLogLib.h | 96 + .../OpenGLInsightsTessellation/vsMathLib.cpp | 830 ++++++++ .../OpenGLInsightsTessellation/vsMathLib.h | 403 ++++ .../vsResourceLib.cpp | 285 +++ .../vsResourceLib.h | 171 ++ .../vsShaderLib.cpp | 876 +++++++++ .../OpenGLInsightsTessellation/vsShaderLib.h | 241 +++ .../vsTerrainLODSingleScaledLib.cpp | 386 ++++ .../vsTerrainLODSingleScaledLib.h | 57 + .../vsTerrainLib.cpp | 437 +++++ .../OpenGLInsightsTessellation/vsTerrainLib.h | 80 + .../OpenGLInsightsTessellation/vslibs.h | 36 + .../README.first.txt | 51 + 30 files changed, 7158 insertions(+) create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation.sln create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/Makefile create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/OpenGLInsightsTessellation.vcxproj create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/OpenGLInsightsTessellation.vcxproj.filters create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/OpenGLInsightsTessellation.vcxproj.user create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/fonts/couriernew10.tga create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/fonts/couriernew10.xml create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/dirlightdiffambpix.frag create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/dirlightdiffambpix.vert create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/terrainTessDemoSingleScaled.frag create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/terrainTessDemoSingleScaled.tesc create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/terrainTessDemoSingleScaled.tese create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/terrainTessDemoSingleScaled.vert create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/terrainTessDemo.cpp create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsGLInfoLib.cpp create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsGLInfoLib.h create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsLogLib.cpp create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsLogLib.h create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsMathLib.cpp create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsMathLib.h create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsResourceLib.cpp create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsResourceLib.h create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsShaderLib.cpp create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsShaderLib.h create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsTerrainLODSingleScaledLib.cpp create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsTerrainLODSingleScaledLib.h create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsTerrainLib.cpp create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsTerrainLib.h create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vslibs.h create mode 100644 Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/README.first.txt diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation.sln b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation.sln new file mode 100644 index 0000000..efefa00 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenGLInsightsTessellation", "OpenGLInsightsTessellation\OpenGLInsightsTessellation.vcxproj", "{C293EC5B-5EF8-4BBC-A474-D8B0A71D37A5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C293EC5B-5EF8-4BBC-A474-D8B0A71D37A5}.Debug|Win32.ActiveCfg = Debug|Win32 + {C293EC5B-5EF8-4BBC-A474-D8B0A71D37A5}.Debug|Win32.Build.0 = Debug|Win32 + {C293EC5B-5EF8-4BBC-A474-D8B0A71D37A5}.Release|Win32.ActiveCfg = Release|Win32 + {C293EC5B-5EF8-4BBC-A474-D8B0A71D37A5}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/Makefile b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/Makefile new file mode 100644 index 0000000..b6d7c7d --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/Makefile @@ -0,0 +1,19 @@ +CC=g++ +CCFLAGS=-I. -I/usr/include -g -D_LINUX -rdynamic +LIBS=-lglut -lGL -lGLEW -lIL -ltinyxml -L/usr/lib +FILES= vsFontLib.cpp \ + vsGLInfoLib.cpp \ + vsLogLib.cpp \ + vsShaderLib.cpp \ + vsMathLib.cpp \ + vsTerrainLib.cpp \ + vsResourceLib.cpp \ + vsTerrainLODSingleScaledLib.cpp \ + terrainTessDemo.cpp + +main: $(FILES) + $(CC) -o $@ $^ $(CCFLAGS) $(LIBS) + +clean: + rm -f *.o *~ main + diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/OpenGLInsightsTessellation.vcxproj b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/OpenGLInsightsTessellation.vcxproj new file mode 100644 index 0000000..007fd9f --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/OpenGLInsightsTessellation.vcxproj @@ -0,0 +1,109 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {C293EC5B-5EF8-4BBC-A474-D8B0A71D37A5} + Win32Proj + OpenGLInsightsTessellation + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + true + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + libcmt.lib + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + libcmt.lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/OpenGLInsightsTessellation.vcxproj.filters b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/OpenGLInsightsTessellation.vcxproj.filters new file mode 100644 index 0000000..286a33c --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/OpenGLInsightsTessellation.vcxproj.filters @@ -0,0 +1,95 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {a583fe43-df6e-45d7-a7f7-ccaf5741e26f} + + + {35e1490a-dcf1-4c9e-ba07-b53c46dbdb09} + + + + + Source Files + + + Source Files\VSL + + + Source Files\VSL + + + Source Files\VSL + + + Source Files\VSL + + + Source Files\VSL + + + Source Files\VSL + + + Source Files\VSL + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + Shaders + + + \ No newline at end of file diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/OpenGLInsightsTessellation.vcxproj.user b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/OpenGLInsightsTessellation.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/OpenGLInsightsTessellation.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/fonts/couriernew10.tga b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/fonts/couriernew10.tga new file mode 100644 index 0000000000000000000000000000000000000000..71e2177ae483169b7473fec9d73cb9838005344c GIT binary patch literal 262162 zcmeI5&8{3bl7*}1NoLnCGk%SEfqso{^lqM^x4j;~?X9)7HUFu|HS;KmYvm|Fkw=UcdeJ+yA|K_3F=&OVQ@jr%%6r{P^(| z4SxLb$N!FY&YOScz_uJ{vOHaa!7so3^1qdyfB4~t|7v>wUOu^I4XA8o<8)gNIR3|t z|E=}Uv%u5S(@*GLyyAJl`adqm!~>_}aRB|JS)Sut{;OB@Y%dIZ_kZej&yUWm|M9RF zmQIh0P1ES<68vZM|4sZ(;MZS&{lWS_F2^q6m)oqvmwV_Rt;c&m&;Q1A9XuUp$N3x% zoTGnqEG@_TKi~Jo&->@}Z(H-#9N3Nn=juP+*Olk{ed~Wa46Pr>{!$K{qyJ0$a69wU z92k=W*8iBeSTDw94GviU=GhuNb01^!%=#Y_7wg5itib{6-#lA`XYON6o>~86;$poR zmo+$G{hMcN@XURT$usMJOkAuN3II|b`?61+c`!L7Nfo(aU`#)!Nw71uo zY>SEG@A$990qLLp{8RgQt24q=_G^vb{a7pJz~vl}{&i-Lb)bqT`p>`X!RLne@8AEk zvUl0#m^gNh-C7)w{x9i|HKBcOc>o8wYD+VJtESuF*f=6;{sxe3$6I4VY`0 zYrYkl73d>e7~UZU|Zj`%old?E+V)qia3yt!l!?3)AD|Gx3F{*2!> z9I*b)pKJKzw)^If^}lcYtUu#-4F{}$^XD4=xb43AWBuz}{>@wflx zw|q_gpQ6{y!)>htbKraqG?AVhxAWuXm^o&Tzya&uJbnZodk&ZJ*!sULZswcg_6Quv z`e*Nc?{~oT8zHUDbKLh&K3+dUTs#Ns`v@F3NB_hlp8@2$_nSdSh@a=^bz;vPxJLgx z5BU3h^MB9$Kl<3w|J2{?(0Ggy_xsl7%d7WUA+~YeYlJy4CI_03PZ67`&;Quv=YKx; z=QSewbAC+Rjf-)C1J~-`zX5C>c`ey52d>pW-~IVBz<%+!c8`r+*8dbAc+PM3U%mWy zzhm=fiZ8AkpBqigC*w3ePR7U>-Gc+xzj<{JUfJh9cxC&ZCXg9FyTd36t7+2=lZb*}!|@5`A# z(pRru{h7Sa0PX{8YtlGn4xFoh+Q&11IuGPMz~)xwmaoU>#3lM?&u?q@^78)Q@iDdz zjZu#SO~j{OT~(gX`*7d)8eo1^Tyfd>yf{byy|cco3H}X$@v*iZjZx-6)c=PMAHL-~ zJ#_x@7L^10s($@acB56yuwI1u%(XL+>G8jvyS>AY8-+xvP9%#DL_5C^1x zG~DuEUi=?kc@5}2|L5m|>N^6;)TdMP&m0(o15NNJuxQ%;hG&1Y%vylf-@bkO*NhW7 zj#|dP`ujiM3F3#hzaJa}>x`wZjf?azE=d2nu2S@`2Zf%ty*J3*s<`8_v3Qa7Z+ynW z$9Nczdvd_~H^1)5FZ&*wU)KNF_*g&2=bjv}{>`s@^2@%*=9l$9Ha^ym@wq1ltbg4@@$j>zjL9_| zI9LCi^=)mwyn3JUeg8Kvui>TJuEU=ue+e;u5x2gmsy963$8oVn z=sSX37ww!kpUr{oInYFWG7j70U<{1G796nt&ATml=RU{ao%KHk4%UNl*n$Jrzj?O> z@7(7YytDqtz`=Sj4qI@*`Zw>k;GO#%gLl^d7&urD#$gK%SpVkT7QAzxWAHBOzqgmq zSdD>|aWD?I=799i9{%|Mdfu`hp9L^)Z^quID`e_w-!p-}nCUv9~^r5&DM* zOTPa*=lQ?4R+w|FbBIOn=?_|Zgsx+Nam`{({2kz4j>U*mAeSnLmrTkGE(*dGUs*>N$m{*Q~jb#Lsg ze{;a=z;QWX{T~;5>)zN~|K@<#f#Y((`adrA*1fT}{>=fe1IOjSJ@n81pXT@Z)2C0r zvS--*IxfGA{n*&wOaH6^#(r$%KB)#xzc;d2s@B;n!zQ@lP>hFL0oIu*zzr5nwp>ps4*#`$Q z&b~elZcV%=<9!^wjkU3k9I*b)hsX!#kHrV;|5$ii-^M#~!1^~IA|IST79XttW8rOm z8}G;g>)(8cd~p6)e6aqHg}3!>ydwv!fAb;o!TDqH!TLWI-qyGAjvTQ5&4mPg84}Kd^ZJi#ASH^oEcuW7%te)*F{G@+$AAk3+(myu-f57*_feLGv9Rs_lf9}`u zxjl10`j;Kg2jnaL(-!;u+kn}puaChq<2)wLQUB6&4=d?kde7HYJJyr@Iij+2*_iw= zE{}~%)IWOGcl^EY|EQ08&c6o)U(kGfj+k3l%(2JjnDHGK->Cm7ob;JLe?P$UfAjIx z-}lfyW$_i)gQ4f^O!ub{vQ)p>(#g};ehpTo-E;sZ61>+*8gMTYP}lQB^YshV@pnU(jMp~iwK;G*4rKkuy}Rt~jj`5V-`3_2uWTF76395) z;M->dZii*W%6Z3i2?v@sPqJf=KWF>6j(OE9<;)NI)-`KJrETgdkLQKdM(I>r**G58f%ShMEEHd-j_+C=kp4OEJN29%$CLFR>vDeX{;zX|tUI}_udM@f z;JzG?{uSr=xxM$@+*19c?Y6GG#!v6_fuH~Hi?48X>Nr;%kp9u9?*CJt*YUAb|N0G3 ztplWa4A#GSnK|L>^*AB@M@{SZy?QuA+nx>UNqna7eGc&V|LbAh!^-8y#X$OBa{rGu zJS+4*AE0~c<8KA&`-S*yLB8k1oIEZkjs1GqH<_Ls@AcyCSUc7ualraFA4lS&$FeRT zt^al7ZGJo6BXPj`Hy=mhqsOu?AFcm&<86LB-Xn3q`Zpg(;-km1E+4J`b>nS*JKiI4 z!1^~IN8+Q$vMwLD)Ia-#;vPX`zb^KUx8t4lj~?0Qw+1(?fAen*p1F@c&(6_5dTsVE zFZS~iSDoM0HD%iCtG&JPOkv#rYyJ0eF=ri{H8{}3e4-z8`EO~zB+_mkLw-K!o$Fx@ zh|dxDkJ`tt^>2=6e))P`PDuaxOdr}spBay=|K3?ao(rCyo_^xqPn-CBAfML%x>zgj zP91k~K>F8pd{&S5Z`Gq&9uTNQ(_E`Ar}8!REHTwS`}4JVYYyC&1Jb`f$Hz0fRjkqL z+qZB3hNkDVEB#mZetgq@&PO!{m)({Fj^}aXDgC3v>VBWO5$(`*{!A}>tta{%QQ2Al z$K{=P;&fXMNdM?GYLtAn9z^|v9d@yu@XVhLDu34hw%7|Rr^m%X`j?j5^_N%HKYCRq z`quM3W$_uGd@RF{+C`t%|8aTeHD?U$n=Vfg3u|%=Tp}jU841N#WnXc9@nh@@i4JYjLBLY zu>Q@pwYcVf#^ajxKOQF5i7{D=15y8+0et~P0CEk0sRYObjmyb78v!F{;`ec`Q%6U@u2OhjY}w^jhh^!mg)(^vv_W)(m}~$j|n%z1M*8xKUy5vd6+n`oHA6xTxRA z3$(0f{rH`M)&belzV-jr3wzZ&eJrjS&++hV;yVc!?*FUSXtp>=2sFXe#sZ|+>m9k<&*cdY;Y zV`v>3!%I0}{hK?Na>woV&mHT3{}@__#_&=OSpVkErQC75{c~qa{pUT$>^m^0_RlF} zxE~C+)W3M*{YLxYi!gKg7?_=-|9ro0ZJ+1%^Rkzi_Y_~yf80YnW$U`f;GJFMbww91=2Wfi7Np8s{0Q0=SV z6sq(d*8{b6x<6hSvwdJD{i9dT>!V5DI=f%txJ3VaFNhzt&stZ1u^;@l@jUxCfcC*1 zVe53icxC7VBY?&GlydEeXj%ae?yuO9fd;eG#@AuKS^N+zNrCCQ*QBldEIl*vd&Sj(btw5z9gP;Pue{(*fK8n?7MO5bWi_B@jbUE`j&B6 zv#(o@dxzgUs!vFDa(F|`P|w}J^O(h z=C9@81_tlmz57QscFmXAWKOA0bEGf)G9R7IjW$bTPaA9_ z9`e)1cv5~zijNpa@|9o8;{5Wp`T_&qx@Nxl>@j{~AHp||gEDwPDqpmVzA4YXWSdjQ z0T*+*uBpRD*Yp#|sB+5UID7HJ9^1-?d?}ssp>bi;raqjpLj(IK`PcE;oH%C8^0~3>tHK$7)i~4-Y4#K6+Oxx^ifhD<_^}4`u+-dh|FKW{Y4iS{t0IA7}^Oh!bj)Q~K%k73W7^*XkdC@F9;ObARQRXTN^TqbtLl33qdd;98mD~s ze5hXOln>&`)G8jUJ?T_maenl*rvB&n5XYwZFve=WQ*oj#+yZ-1q2d8{x70s-i$rl;IHBt<$BWwe#w^cRB@mzj+N`m4nI?M>X&qi*P0)`dVHSi zOMIdq-tvP_%{h)I_f^e~}EB`7Ne{y_PjwkA{m)C0S*lR3m8|~uw@Fjm$ z%;+zV2j8v#ljacnQ@=UYxK&P{Rl9Ta&phPsmT7OzS<(k%id`B#?PG3@xk2BX-9vwnd*aeDStkaJ#(Flr^dv%=K7Lfr(Zuy?=c>FR>+t) z8l3hxACGzeoHT~pV`%+vkAZby47TEc^>6NN#Xa}CJ@>5t?J=+pjKNkMu>Q@xt+?lY zx96VqzdZ)lfic*M1J=K}w-xu?@AllY{f^=$K3Oi`^)1|pZM?9Wgk_nX{$Mr<`~LH)s`_}->cIY zW2$)f<{fQwUSpZtyG*+|+q^%T@x(Z4oWw-^$!9F1FEF4izbfppkNDH3*KhO}ZKnFn zSj4_G58CH6<@r|U!Q$DxTkAjfUtL%8i*}i-Q(7RVG49b1dFsyLW{(^4J2e*BkXC*eOXhZk zkNouTjrd_Z7lYn-)Xz03^O=hOCBCaTML$#XRcy4D^wuyqMqPYGZK^-ULVvm@&1Lkp zJ50SJ^Ok%_;XQ?r2@bw&x>ik$jA){L(g-lh4}d^&uZhv5S3DUX{@& z@9G{RU!=lQ_OVXBsUwdsp2>xP#?h`%vW+o?PrY-d*kAkZjTyhfP<>44WNGZDVi{wT z@6U{Zu_|7Sh4E=@N-2jIif{G#hp{$ZzLH($k$frb^%ch(F;hEI`igU54slHK5zAtG z)z6KQKIUwq-?_Zv7{}ggQ*lV#k)EgcA^k8{@>M_dAxufDcun;YePSmbsk|zSeNM%J zI*pAs@~L#mxLW&@?AJ_*c^m&9KKn2RVW{!+bU^)*Im!<)!d}-^icJ+uaHG68mR@=6 z1Dhq!iLs418q4xLsxfDq%yH?v;xm1zeu=i37j_j_8HYHUQ|jWpXuqUCwW(q*?r8k< znfp+ynm6MNk%1g6cix2o#Jt;P^uiluj#g5fQgV^4J%7{P#3Ry)ad~YCM!NZrLaf zx+bk+NV{lr>-^l@di@ETx$!NT6F#CJ+QjQP2I)gjMKCZD_>L1*jrpjjk#!38m#h7XCq?A)1=NIeAqgiZt z_3UC_aV^Nc#M5d##Gbf*?x}uGls|Cq*~Rh7rW&{Aj!iWl`dVV6G3_Ot!wMYG6sckm zHAtCoRD64w$G&76wUc8O + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/dirlightdiffambpix.frag b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/dirlightdiffambpix.frag new file mode 100644 index 0000000..ecb53ef --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/dirlightdiffambpix.frag @@ -0,0 +1,39 @@ +#version 330 + +layout (std140) uniform Material { + vec4 diffuse; + vec4 ambient; + vec4 specular; + vec4 emissive; + float shininess; + int texCount; +}; + +uniform sampler2D texUnit; + +in vec3 Normal; +in vec2 TexCoord; +out vec4 outputF; + +void main() +{ + vec4 color, emission,amb; + float intensity; + vec3 lightDir, n; + + lightDir = normalize(vec3(1.0,1.0,1.0)); + n = normalize(Normal); + intensity = max(dot(lightDir,n),0.0); + + if (texCount == 0) { + color = diffuse; + amb = ambient; + emission = emissive; + } + else { + color = texture(texUnit, TexCoord) * diffuse; + amb = color * ambient; + emission = texture(texUnit, TexCoord) * emissive; + } + outputF = (color * intensity) + amb + emission; +} diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/dirlightdiffambpix.vert b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/dirlightdiffambpix.vert new file mode 100644 index 0000000..46ae62a --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/dirlightdiffambpix.vert @@ -0,0 +1,24 @@ +#version 330 + +layout (std140) uniform Matrices { + + mat4 projMatrix; + mat4 modelviewMatrix; + mat4 projModelViewMatrix; + mat3 normalMatrix; +}; + +in vec3 position; +in vec3 normal; +in vec2 texCoord; + +out vec2 TexCoord; +out vec3 Normal; + +void main() +{ +// Normal = normalize(vec3(modelviewMatrix * vec4(normal, 0.0))); + Normal = normalize(normalMatrix * normal); + TexCoord = vec2(texCoord); + gl_Position = projModelViewMatrix * vec4(position, 1.0); +} \ No newline at end of file diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/terrainTessDemoSingleScaled.frag b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/terrainTessDemoSingleScaled.frag new file mode 100644 index 0000000..8fe7382 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/terrainTessDemoSingleScaled.frag @@ -0,0 +1,54 @@ +#version 410 + +layout (std140) uniform Matrices { + + mat4 projMatrix; + mat4 modelviewMatrix; + mat4 projModelViewMatrix; + mat3 normalMatrix; +}; + +uniform sampler2D texUnit,heightMap; +uniform float heightStep; +uniform float gridSpacing; +uniform int scaleFactor; + + +in vec2 uvTE; + +out vec4 outputF; + + +float height(float u, float v) { + + return (texture(heightMap, vec2(u,v)).r * heightStep); +} + +void main() { + + vec4 color; + float intensity; + vec3 lightDir,n; + + float delta = 1.0 / (textureSize(heightMap,0).x * scaleFactor) ; + + vec3 deltaX = vec3( + 2.0 * gridSpacing, + height(uvTE.s + delta, uvTE.t) - height(uvTE.s - delta, uvTE.t) , + 0.0) ; + + vec3 deltaZ = vec3( + 0.0, + height(uvTE.s, uvTE.t + delta) - height(uvTE.s, uvTE.t - delta) , + 2.0 * gridSpacing) ; + +// vec3 normalF = normalize(vec3(modelviewMatrix * vec4( cross(deltaZ, deltaX),0.0))); + vec3 normalF = normalize(normalMatrix * cross(deltaZ, deltaX)); + lightDir = vec3(0.577,0.577,0.577); + intensity = max(dot(lightDir,normalF),0.0); + + color = texture(texUnit, uvTE) * vec4(0.8, 0.8, 0.8, 1.0); + color = color * intensity + color * vec4(0.2, 0.2, 0.2, 1.0); + + outputF = color; +} \ No newline at end of file diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/terrainTessDemoSingleScaled.tesc b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/terrainTessDemoSingleScaled.tesc new file mode 100644 index 0000000..a823e91 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/terrainTessDemoSingleScaled.tesc @@ -0,0 +1,195 @@ +#version 410 + + +layout(vertices = 1) out; + +layout (std140) uniform Matrices { + + mat4 projMatrix; + mat4 modelviewMatrix; + mat4 projModelViewMatrix; + mat3 normalMatrix; +}; + +uniform float heightStep; +uniform float gridSpacing; +//uniform mat4 mvGroundCamMat; +uniform mat4 pvm; +uniform ivec2 viewportDim; +uniform sampler2D roughFactor; +uniform sampler2D heightMap; +uniform int useRoughness; +uniform int pixelsPerEdge; +uniform int culling; +uniform int scaleFactor; +uniform float patchSize; + +in vec2 posV[]; + +out vec2 posTC[]; + +#define ID gl_InvocationID + +float height(float u, float v) { + + return (texture(heightMap, vec2(u,v)).r * heightStep); +} + + + +// Checks if a segment is at least partially inside the frustum +// Need to add a little tolerance in here +bool segmentInFrustum(vec4 p1, vec4 p2) { + + if ((p1.x < -p1.w && p2.x < -p2.w) || (p1.x > p1.w && p2.x > p2.w) || +// (p1.y < -p1.w && p2.y < -p2.w) || (p1.y > p1.w && p2.y > p2.w) || + (p1.z < -p1.w && p2.z < -p2.w) || (p1.z > p1.w && p2.z > p2.w)) + return false; + else + return true; + +} + + + +// Measures the screen size of segment p1-p2 +float screenSphereSize(vec4 p1, vec4 p2) { + + vec4 viewCenter = (p1+p2) * 0.5; + vec4 viewUp = viewCenter; + viewUp.y += distance(p1,p2); + vec4 p1Proj = viewCenter; + vec4 p2Proj = viewUp; +/* vec4 p1Proj = projMatrix * viewCenter; + vec4 p2Proj = projMatrix * viewUp; +*/ + vec4 p1NDC, p2NDC; + p1NDC = p1Proj/p1Proj.w; + p2NDC = p2Proj/p2Proj.w; + + return( clamp(length((p2NDC.xy - p1NDC.xy) * viewportDim * 0.5) / (pixelsPerEdge), 1.0, patchSize)); +} + + + + +float getRoughness(vec2 disp) { + + return (pow(( 1.8 - texture(roughFactor, posV[0]+ disp /textureSize(roughFactor,0)).x ),4)); +// return (texture(roughFactor, posV[0]+ disp /textureSize(roughFactor,0)).x ); +} + + + +void main() { + + int scaleF; + if (scaleFactor == 0) + scaleF = 1; + else + scaleF = scaleFactor; + + vec2 iLevel; + vec4 oLevel; + + vec4 posTransV[4]; + vec2 pAux; + vec2 posTCAux[4]; + + ivec2 tSize = textureSize(heightMap,0) * scaleF;// * 2; + float div = patchSize / tSize.x; + + posTC[gl_InvocationID] = posV[gl_InvocationID]; + + + posTCAux[0] = posV[0]; + posTCAux[1] = posV[0] + vec2(0.0, div); + posTCAux[2] = posV[0] + vec2(div,0.0); + posTCAux[3] = posV[0] + vec2(div,div); + +/* for (int i = 0; i < 4; ++i ) { + pAux = posTCAux[i] * tSize * gridSpacing; + posTransV[i] = pvm *vec4(pAux[0], height(posTCAux[i].x,posTCAux[i].y), pAux[1], 1.0); + } +*/ + pAux = posTCAux[0] * tSize * gridSpacing; + posTransV[0] = pvm * vec4(pAux[0], height(posTCAux[0].x,posTCAux[0].y), pAux[1], 1.0); + + pAux = posTCAux[1] * tSize * gridSpacing; + posTransV[1] = pvm * vec4(pAux[0], height(posTCAux[1].x,posTCAux[1].y), pAux[1], 1.0); + + pAux = posTCAux[2] * tSize * gridSpacing; + posTransV[2] = pvm * vec4(pAux[0], height(posTCAux[2].x,posTCAux[2].y), pAux[1], 1.0); + + pAux = posTCAux[3] * tSize * gridSpacing; + posTransV[3] = pvm * vec4(pAux[0], height(posTCAux[3].x,posTCAux[3].y), pAux[1], 1.0); + +/* pAux = posTCAux[0] * tSize * gridSpacing; + posTransV[0] = mvGroundCamMat * vec4(pAux[0], height(posTCAux[0].x,posTCAux[0].y), pAux[1], 1.0); + + pAux = posTCAux[1] * tSize * gridSpacing; + posTransV[1] = mvGroundCamMat * vec4(pAux[0], height(posTCAux[1].x,posTCAux[1].y), pAux[1], 1.0); + + pAux = posTCAux[2] * tSize * gridSpacing; + posTransV[2] = mvGroundCamMat * vec4(pAux[0], height(posTCAux[2].x,posTCAux[2].y), pAux[1], 1.0); + + pAux = posTCAux[3] * tSize * gridSpacing; + posTransV[3] = mvGroundCamMat * vec4(pAux[0], height(posTCAux[3].x,posTCAux[3].y), pAux[1], 1.0); +*/ + + if (culling == 0 ||( + segmentInFrustum(posTransV[ID], posTransV[ID+1]) || + segmentInFrustum(posTransV[ID], posTransV[ID+2]) || + segmentInFrustum(posTransV[ID+2], posTransV[ID+3]) || + segmentInFrustum(posTransV[ID+3], posTransV[ID+1]))) { + + if (useRoughness == 1) { + float roughness[4]; + float roughnessForCentralPatch = getRoughness(vec2(0.5)); + roughness[0] = max(roughnessForCentralPatch, getRoughness(vec2(-0.5,0.5))); + roughness[1] = max(roughnessForCentralPatch, getRoughness(vec2(0.5,-0.5))); + roughness[2] = max(roughnessForCentralPatch, getRoughness(vec2(1.5,0.5))); + roughness[3] = max(roughnessForCentralPatch, getRoughness(vec2(0.5,1.5))); + oLevel = + vec4(clamp(screenSphereSize(posTransV[ID], posTransV[ID+1]) * roughness[0],1,patchSize), + clamp(screenSphereSize(posTransV[ID+0], posTransV[ID+2]) * roughness[1],1,patchSize), + clamp(screenSphereSize(posTransV[ID+2], posTransV[ID+3]) * roughness[2],1,patchSize), + clamp(screenSphereSize(posTransV[ID+3], posTransV[ID+1]) * roughness[3],1,patchSize)) ; +// oLevel = clamp(oLevel, vec4(1),vec4(patchSize)); + iLevel = vec2(max(oLevel[1] , oLevel[3]) , max(oLevel[0] , oLevel[2]) ); + } + else if (useRoughness == 0) { + + // Screen size based LOD + + oLevel = vec4(screenSphereSize(posTransV[ID], posTransV[ID+1]), + screenSphereSize(posTransV[ID+0], posTransV[ID+2]), + screenSphereSize(posTransV[ID+2], posTransV[ID+3]), + screenSphereSize(posTransV[ID+3], posTransV[ID+1])); + iLevel = vec2(max(oLevel[1] , oLevel[3]) , max(oLevel[0] , oLevel[2]) ); + + } + else { + oLevel = vec4(patchSize); + iLevel = vec2(patchSize); + + } + } + else if (culling == 1) { + oLevel = vec4(0); + iLevel = vec2(0); + + } + else { + oLevel = vec4(patchSize); + iLevel = vec2(patchSize); + + } + + gl_TessLevelOuter[0] = oLevel[0]; + gl_TessLevelOuter[1] = oLevel[1]; + gl_TessLevelOuter[2] = oLevel[2]; + gl_TessLevelOuter[3] = oLevel[3]; + gl_TessLevelInner[0] = iLevel[0]; + gl_TessLevelInner[1] = iLevel[1]; +} \ No newline at end of file diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/terrainTessDemoSingleScaled.tese b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/terrainTessDemoSingleScaled.tese new file mode 100644 index 0000000..50b5981 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/terrainTessDemoSingleScaled.tese @@ -0,0 +1,57 @@ +#version 410 + +layout(quads, fractional_even_spacing, cw) in; + +layout (std140) uniform Matrices { + + mat4 projMatrix; + mat4 modelviewMatrix; + mat4 projModelViewMatrix; + mat3 normalMatrix; +}; + +uniform sampler2D heightMap; +uniform float heightStep; +uniform float gridSpacing; +uniform int scaleFactor; +uniform mat4 pvm; +uniform float patchSize; + + +in vec2 posTC[]; + +out vec2 uvTE; + + + +#define sizeFactor 1.0/patchSize +#define uv gl_TessCoord + + +float height(float u, float v) { + + return (texture(heightMap, vec2(u,v)).r * heightStep); +} + + +void main() { + + ivec2 tSize = textureSize(heightMap,0) * scaleFactor; + float div = tSize.x * sizeFactor; + + // Compute texture coordinates +// uvTE.s = (posTC[0].x + uv.s/div) ; +// uvTE.t = (posTC[0].y + uv.t/div) ; + uvTE = posTC[0].xy + uv.st/div; + + // compute vertex position [0 .. tSize * gridSpacing] + vec4 res; + res.x = uvTE.s * tSize.x * gridSpacing; + res.z = uvTE.t * tSize.y * gridSpacing; + res.y = height(uvTE.s, uvTE.t) ; + res.w = 1.0; + + //gl_Position = pvm * res; + gl_Position = projModelViewMatrix * res; +} + diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/terrainTessDemoSingleScaled.vert b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/terrainTessDemoSingleScaled.vert new file mode 100644 index 0000000..9d71cf6 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/shaders/terrainTessDemoSingleScaled.vert @@ -0,0 +1,14 @@ +#version 410 + +in vec2 pos; +out vec2 posV; + +void main() { + + posV = pos; + +} + + + + diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/terrainTessDemo.cpp b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/terrainTessDemo.cpp new file mode 100644 index 0000000..183cf78 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/terrainTessDemo.cpp @@ -0,0 +1,525 @@ + + +/* + +This code is provided as a companion to the text in the chapter +"GPU Tessellation: We still have a LOD of terrain to cover" +from the book "OpenGL Insights" + +The code comes with no warranties, it is provided only as a demo + +*/ + +// Have Fun :-) + +// include GLEW to access OpenGL 3.3 functions +#include + +// GLUT is the toolkit to interface with the OS +#include + +#include +#include +#include +#include +#include + +// VS Libs +#include "vslibs.h" + +// ------------------------- +// **** CONFIGURATION **** + +#define DEBUG TRUE + +#define PATCHSIZE 64 + +// set to 256 or 65536 depending in whether the image is 8 or 16 bit respectively. +#define MAX_VALUE_PER_PIXEL 65536 + +std::string terrainName = "heightMaps/pugget_sound/ps_height_1k.png"; +std::string terrainTexture = "heightMaps/pugget_sound/ps_texture_2k.png"; +float heightStep = 0.1f; +int scaleFactor = 2; +float gridSpacing = 160.0f; + + +int pixelsPerTriangle = 1; +// 0 - simple LOD; 1 - roughness LOD; 2 - full tessellation +int roughnessMode = 1; +char *rougnessModeS[] = {"simple LOD", "roughness LOD", "full tessellation"}; +// flag to enable/disable tessellation shader based view frustum culling +int culling = 1; + + + +// **** END CONFIGURATION **** +// ----------------------------- + + + +unsigned int primitiveCounter = 0; + +// Test Data + +float angle = 0.0f; +float testTime = 0.0f; +float testPrimitiveCount = 0.0f; + +VSMathLib *vsml; + +VSShaderLib shaderTerrainTess, shaderDefault; + + + +VSTerrainLib *terrainModel; +VSTerrainLODSingleScaledLib terrainTess; + +// Query to track the number of primitives +// issued by the tesselation shaders +GLuint counterQ; + +// POLYGON MODE +GLuint polygonMode = GL_FILL; + + +// CAMERA +#define SURFACE 0 +#define EXPLORER 1 +#define TESTCAM 2 +int camMode = EXPLORER; + +// Explorer Camera Position +float camX, camY, camZ; +// Camera Spherical Coordinates +float alpha = 0.0f, beta = -0.5f; +float r = 1.0f; + +// Surface Camera Settings +float posX, posY, posZ; +float alpha2 = 25.0f, beta2 = 0.0f; + +// Mouse Tracking Variables +int startX, startY, tracking = 0; + +// Frame counting and FPS computation +long myTime, timebase = 0, frame = 0; +//char s[64]; + +// window size ratio +float ratio; + + + + +// ------------------------------------------------------------ +// +// Reshape Callback Function +// + +void changeSize(int w, int h) { + + // Prevent a divide by zero, when window is too short + // (you cant make a window of zero width). + if(h == 0) + h = 1; + + // Set the viewport to be the entire window + glViewport(0, 0, w, h); + + ratio = (1.0f * w) / h; + vsml->loadIdentity(VSMathLib::PROJECTION); + vsml->perspective(53.13f, ratio, 10.0f, 400000.0f); + + int vpAux[2]; + vpAux[0] = w; + vpAux[1] = h; + shaderTerrainTess.setUniform("viewportDim", vpAux); +} + + +// ------------------------------------------------------------ +// +// Render stuff +// + +void renderScene(void) { + + + static char s[128]; + float aux; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + vsml->loadIdentity(VSMathLib::MODEL); + vsml->loadIdentity(VSMathLib::VIEW); + // set camera + + float gridSpacing = terrainModel->getGridSpacing(); + int gridSize = terrainModel->getGridSize(); + aux = terrainModel->getHeight(posX, posZ) + 150.0f; + + vsml ->lookAt(posX, posY, posZ, posX+camX, posY+camY, posZ+camZ, 0.0f, 1.0f, 0.0f); + shaderTerrainTess.setUniform("pvm", vsml->get(VSMathLib::PROJ_VIEW_MODEL)); + + // use our shader + VSShaderLib *shader; + shader = &shaderTerrainTess; + glUseProgram(shader->getProgramIndex()); + + +// shader->prepareSamplerUniforms(); +#if DEBUG == TRUE + glBeginQuery(GL_PRIMITIVES_GENERATED, counterQ); + glPolygonMode(GL_FRONT_AND_BACK, polygonMode); +#endif + terrainModel->render(); +#if DEBUG == TRUE + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glEndQuery(GL_PRIMITIVES_GENERATED); +#endif + + + // FPS computation and display + frame++; + myTime=glutGet(GLUT_ELAPSED_TIME); + if (myTime - timebase > 1000) { + sprintf(s,"FPS:%4.2f Counter: %d PPT: %d Mode: %s", + frame*1000.0/(myTime-timebase) , primitiveCounter, pixelsPerTriangle, rougnessModeS[roughnessMode]); + timebase = myTime; + frame = 0; + glutSetWindowTitle(s); + } + + glutSwapBuffers(); + +#if DEBUG == TRUE + glGetQueryObjectuiv(counterQ, GL_QUERY_RESULT, &primitiveCounter); +#endif +} + + +// ------------------------------------------------------------ +// +// Events from the Keyboard +// + +void processKeys(unsigned char key, int xx, int yy) +{ + std::string s; + + switch(key) { + + case 27: + + glutLeaveMainLoop(); + break; + + case 'u': + culling = 1; + shaderTerrainTess.setUniform("culling",&culling); + break; + case 'i': + culling = 0; + shaderTerrainTess.setUniform("culling", &culling); + break; + + case 'l' : + polygonMode = GL_LINE; + break; + case 'f' : + polygonMode = GL_FILL; + break; + case 'r': + roughnessMode = 1; + shaderTerrainTess.setUniform("useRoughness", &roughnessMode); + break; + case 't': + roughnessMode = 0; + shaderTerrainTess.setUniform("useRoughness", &roughnessMode); + break; + case 'y': + roughnessMode = 2; + shaderTerrainTess.setUniform("useRoughness", &roughnessMode); + break; + case '+': + if (pixelsPerTriangle < 64) + pixelsPerTriangle++; + shaderTerrainTess.setUniform("pixelsPerEdge", &pixelsPerTriangle); + break; + case '-': + if (pixelsPerTriangle > 1) + pixelsPerTriangle--; + shaderTerrainTess.setUniform("pixelsPerEdge", &pixelsPerTriangle); + break; + + + } + +// uncomment this if not using an idle func +// glutPostRedisplay(); +} + +void processSpecialKeys(int key, int xx, int yy) +{ + switch(key) { + + case GLUT_KEY_UP: + posX += camX * terrainModel->getGridSpacing() * 2.5f; + posY += camY * terrainModel->getGridSpacing() * 2.5f; + posZ += camZ *terrainModel->getGridSpacing() * 2.5f; + break; + + case GLUT_KEY_DOWN: + posX -= camX * terrainModel->getGridSpacing() * 2.5f; + posY -= camY * terrainModel->getGridSpacing() * 2.5f; + posZ -= camZ * terrainModel->getGridSpacing() * 2.5f; + break; + + } +} + + +// ------------------------------------------------------------ +// +// Mouse Events +// + +void processMouseButtons(int button, int state, int xx, int yy) +{ + // start tracking the mouse + if (state == GLUT_DOWN) { + startX = xx; + startY = yy; + if (button == GLUT_LEFT_BUTTON) + tracking = 1; + } + + //stop tracking the mouse + else if (state == GLUT_UP) { + if (tracking == 1) { + alpha -= (xx - startX); + beta -= (yy - startY); + } + tracking = 0; + } +} + + +// Track mouse motion while buttons are pressed +void processMouseMotion(int xx, int yy) +{ + + int deltaX, deltaY; + float alphaAux, betaAux; + + deltaX = - xx + startX; + deltaY = - yy + startY; + + // left mouse button: move camera + if (tracking == 1) { + + + alphaAux = alpha + deltaX; + betaAux = beta + deltaY; + + if (betaAux > 85.0f) + betaAux = 85.0f; + else if (betaAux < -85.0f) + betaAux = -85.0f; + + + camX = r * sin(alphaAux * 3.14f / 180.0f) * cos(betaAux * 3.14f / 180.0f); + camZ = r * cos(alphaAux * 3.14f / 180.0f) * cos(betaAux * 3.14f / 180.0f); + camY = r * sin(betaAux * 3.14f / 180.0f); + } +} + + + + +// -------------------------------------------------------- +// +// Shader Stuff +// + + +GLuint setupShaders() { + + shaderDefault.init(); + shaderDefault.loadShader(VSShaderLib::VERTEX_SHADER, "shaders/dirlightdiffambpix.vert"); + shaderDefault.loadShader(VSShaderLib::FRAGMENT_SHADER, "shaders/dirlightdiffambpix.frag"); + + shaderDefault.setProgramOutput(0,"outputF"); + shaderDefault.setVertexAttribName(VSShaderLib::VERTEX_COORD_ATTRIB, "position"); + shaderDefault.setVertexAttribName(VSShaderLib::TEXTURE_COORD_ATTRIB, "texCoord"); + shaderDefault.setVertexAttribName(VSShaderLib::NORMAL_ATTRIB, "normal"); + + shaderDefault.prepareProgram(); + + + shaderTerrainTess.init(); + + shaderTerrainTess.loadShader(VSShaderLib::VERTEX_SHADER, "shaders/terrainTessDemoSingleScaled.vert"); + shaderTerrainTess.loadShader(VSShaderLib::FRAGMENT_SHADER, "shaders/terrainTessDemoSingleScaled.frag"); + shaderTerrainTess.loadShader(VSShaderLib::TESS_CONTROL_SHADER, "shaders/terrainTessDemoSingleScaled.tesc"); + shaderTerrainTess.loadShader(VSShaderLib::TESS_EVAL_SHADER, "shaders/terrainTessDemoSingleScaled.tese"); + + shaderTerrainTess.setProgramOutput(0,"outputF"); + shaderTerrainTess.setVertexAttribName(VSShaderLib::VERTEX_COORD_ATTRIB, "pos"); + + shaderTerrainTess.prepareProgram(); + printf("Shader Terrain Tess InfoLog\n%s\n\n", shaderTerrainTess.getAllInfoLogs().c_str()); + + int t = 0; + shaderDefault.setUniform("texUnit", &t); + + t = 2; + shaderTerrainTess.setUniform("texUnit", &t); + + shaderTerrainTess.setUniform("roughFactor", &roughnessMode); + + t = 0; + shaderTerrainTess.setUniform("heightMap", &t); + + shaderTerrainTess.setUniform("patchSize", PATCHSIZE*1.0f); + + return(1); +} + +// ------------------------------------------------------------ +// +// Model loading and OpenGL setup +// + +int initGL() +{ + + // init VSL + vsml = VSMathLib::getInstance(); + vsml->setUniformBlockName("Matrices"); + vsml->setUniformName(VSMathLib::PROJECTION, "projMatrix"); + vsml->setUniformName(VSMathLib::VIEW_MODEL, "modelviewMatrix"); + vsml->setUniformName(VSMathLib::PROJ_VIEW_MODEL, "projModelViewMatrix"); + vsml->setUniformName(VSMathLib::NORMAL, "normalMatrix"); + + + // init terrain + terrainTess.setGridSpacing(gridSpacing); + terrainTess.setScaleFactor(scaleFactor); + shaderTerrainTess.setUniform("scaleFactor", &scaleFactor); + + printf("Loading terrain for tesselation\n"); + float f; + int i = 8; + shaderTerrainTess.setUniform("pixelsPerEdge",&pixelsPerTriangle); + + f = terrainTess.getGridSpacing(); + shaderTerrainTess.setUniform("gridSpacing", &f); + f = 0.1f * scaleFactor * MAX_VALUE_PER_PIXEL; + shaderTerrainTess.setUniform("heightStep", &f); + terrainTess.setHeightStep(f); + shaderTerrainTess.setUniform("patchSize", PATCHSIZE*1.0f); + + terrainTess.load(terrainName); + terrainTess.addTexture(2,terrainTexture); + terrainModel = &terrainTess; + printf("Done Loading\n"); + + terrainModel->setMaterialBlockName("Material"); + + glGenQueries(1,&counterQ); + + // Camera settings are based on spherical coordinates (alpha, beta, r); + camX = r * sin(alpha * 3.14f / 180.0f) * cos(beta * 3.14f / 180.0f); + camZ = r * cos(alpha * 3.14f / 180.0f) * cos(beta * 3.14f / 180.0f); + camY = r * sin(beta * 3.14f / 180.0f); + + posX = 0.0f; + posY = 1000.0f; + posZ = 0.0f; + + // Some GL render settings + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glEnable(GL_MULTISAMPLE); + + glClampColorARB(GL_CLAMP_READ_COLOR_ARB, GL_FALSE); + glClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, GL_FALSE); + glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_FALSE); + + printf("Done Init\n"); + + return true; +} + + + + +// ------------------------------------------------------------ +// +// Main function + + +int main(int argc, char **argv) { + + + +// GLUT initialization + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGBA|GLUT_MULTISAMPLE); + + glutInitContextVersion (4, 1); + glutInitContextProfile (GLUT_CORE_PROFILE ); + glutInitContextFlags(GLUT_DEBUG); + + glutInitWindowPosition(100,100); + glutInitWindowSize(1024,1024); + glutCreateWindow("Lighthouse3D - Tesselation Demo"); + +// Callback Registration + glutDisplayFunc(renderScene); + glutReshapeFunc(changeSize); + glutIdleFunc(renderScene); + +// Mouse and Keyboard Callbacks + glutKeyboardFunc(processKeys); + glutMouseFunc(processMouseButtons); + glutMotionFunc(processMouseMotion); + glutSpecialFunc(processSpecialKeys); + +// return from main loop + glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS); + +// Init GLEW + // Load ALL extensions + glewExperimental = GL_TRUE; + glewInit(); + if (glewIsSupported("GL_VERSION_4_1")) + printf("Ready for OpenGL 4.1\n"); + else { + printf("OpenGL 4.1 not supported\n"); + exit(1); + } + + VSGLInfoLib::getGeneralInfo(); + + GLint maxTess; + glGetIntegerv(GL_MAX_TESS_GEN_LEVEL, &maxTess); + printf("Maximum Tessellation level : %d\n", maxTess); + + setupShaders(); + + if (!initGL()) + printf("Could not Load the Model\n"); + + + printf("Entering main loop\n"); + // GLUT main loop + glutMainLoop(); + + return 1; + +} + diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsGLInfoLib.cpp b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsGLInfoLib.cpp new file mode 100644 index 0000000..25cca33 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsGLInfoLib.cpp @@ -0,0 +1,1695 @@ +/** ---------------------------------------------------------- + * \class VSGLInfoLib + * + * Lighthouse3D + * + * VSGLInfoLib - Very Simple GL Information Library + * + * + * \version 0.1.0 + * - Initial Release + * + * This class provides information about GL stuff + * + * Full documentation at + * http://www.lighthouse3d.com/very-simple-libs + * + ---------------------------------------------------------------*/ + +#include "vsGLInfoLib.h" + +// static local variables +std::map VSGLInfoLib::spInternalF; +std::map VSGLInfoLib::spDataF; +std::map VSGLInfoLib::spTextureDataType; +std::map VSGLInfoLib::spGLSLType; +std::map VSGLInfoLib::spGLSLTypeSize; +std::map VSGLInfoLib::spTextureFilter; +std::map VSGLInfoLib::spTextureWrap; +std::map VSGLInfoLib::spTextureCompFunc; +std::map VSGLInfoLib::spTextureCompMode; +std::map VSGLInfoLib::spTextureUnit; +std::map VSGLInfoLib::spTextureBound; +std::map VSGLInfoLib::spHint; +std::map VSGLInfoLib::spTextureTarget; +std::map VSGLInfoLib::spBufferAccess; +std::map VSGLInfoLib::spBufferUsage; +std::map VSGLInfoLib::spBufferBinding; +std::map VSGLInfoLib::spBufferBound; +std::map VSGLInfoLib::spBoundBuffer; +std::map VSGLInfoLib::spShaderType; +std::map VSGLInfoLib::spTransFeedBufferMode; +std::map VSGLInfoLib::spGLSLPrimitives; +std::map VSGLInfoLib::spTessGenSpacing; +std::map VSGLInfoLib::spVertexOrder; +std::map VSGLInfoLib::spShaderPrecision; + +std::vector VSGLInfoLib::spResult; +std::ostream *VSGLInfoLib::spOutS = (std::iostream *)&std::cout; +bool VSGLInfoLib::__spInit = VSGLInfoLib::init(); +char VSGLInfoLib::spAux[256]; + + +// sets the output stream +void +VSGLInfoLib::setOutputStream(std::ostream *outStream) { + + if (!outStream) + // if null use cout + spOutS = (std::iostream *)&std::cout; + else + spOutS = outStream; + +} + + +// check if an extension is supported +bool +VSGLInfoLib::isExtensionSupported(std::string extName) { + + int max, i = 0; + char *s; + + glGetIntegerv(GL_NUM_EXTENSIONS, &max); + do { + s = (char *)glGetStringi(GL_EXTENSIONS, ++i); + } + while (i < max && strcmp(s,extName.c_str()) != 0); + + if (i == max) + return false; + else + return true; +} + + +// general information +void +VSGLInfoLib::getGeneralInfo() { + + int info; + addNewLine(); + addMessage("General Information"); + addMessage("Vendor: %s", glGetString (GL_VENDOR)); + addMessage("Renderer: %s", glGetString (GL_RENDERER)); + addMessage("Version: %s", glGetString (GL_VERSION)); + addMessage("GLSL: %s", glGetString (GL_SHADING_LANGUAGE_VERSION)); + glGetIntegerv (GL_NUM_EXTENSIONS, &info); + addMessage("Num. Extensions: %d", info); +} + + +/* ------------------------------------------------------ + + Buffers + +-------------------------------------------------------- */ + +// display info for currently bound buffers +void +VSGLInfoLib::getCurrentBufferInfo() { + + int info; + + addNewLine(); + addMessage("Current Buffer Bindings"); + + // iterate for all buffer types + std::map::iterator iter = spBufferBound.begin(); + for ( ; iter != spBufferBound.end(); ++iter) { + // get current binding for a type of buffer + glGetIntegerv(iter->first, &info); + // if a buffer is bound get its info + if (info) { + + addMessage("Buffer Info for name: %d", info); + addMessage(" Buffer Type: %s", spBufferBinding[iter->first].c_str()); + + glGetBufferParameteriv(iter->second, GL_BUFFER_ACCESS, &info); + addMessage(" Access: %s", spBufferAccess[info].c_str()); + + glGetBufferParameteriv(iter->second, GL_BUFFER_MAPPED, &info); + addMessage(" Mapped: %d", info); + + glGetBufferParameteriv(iter->second, GL_BUFFER_SIZE, &info); + addMessage(" Size: %d", info); + + glGetBufferParameteriv(iter->second, GL_BUFFER_USAGE, &info); + addMessage(" Usage: %s", spBufferUsage[info].c_str()); + } + } +} + + +// gets all the names currently bound to buffers +std::vector & +VSGLInfoLib::getBufferNames() { + + spResult.clear(); + for (unsigned int i = 0; i < 65535; ++i) { + + if (glIsBuffer(i)) { + spResult.push_back(i); + + + } + } + return spResult; +} + + +// display buffer info +void +VSGLInfoLib::getBufferInfo(GLenum target, int bufferName) { + + int info, prevBuffer; + + addNewLine(); + addMessage("Info for buffer name: %d target: %s", bufferName, spBufferBinding[spBoundBuffer[target]].c_str()); + + // get previously bound buffer + glGetIntegerv(spBoundBuffer[target], &prevBuffer); + // bind requested buffer to get info + glBindBuffer(target,bufferName); + + glGetBufferParameteriv(target, GL_BUFFER_ACCESS, &info); + addMessage(" Access: %s", spBufferAccess[info].c_str()); + + glGetBufferParameteriv(target, GL_BUFFER_MAPPED, &info); + addMessage(" Mapped: %d", info); + + glGetBufferParameteriv(target, GL_BUFFER_SIZE, &info); + addMessage(" Size: %d", info); + + glGetBufferParameteriv(target, GL_BUFFER_USAGE, &info); + addMessage(" Usage: %s", spBufferUsage[info].c_str()); + + // re-bind previous buffer + glBindBuffer(target, prevBuffer); +} + + +/* ------------------------------------------------------ + + Textures + +-------------------------------------------------------- */ + + +// gets all the names currently bound to textures +std::vector & +VSGLInfoLib::getTextureNames() { + + spResult.clear(); + for (unsigned int i = 0; i < 65535; ++i) { + + if (glIsTexture(i)) + spResult.push_back(i); + } + return spResult; +} + + +// gets the current texture bindings for all texture units +void +VSGLInfoLib::getCurrentTextureInfo() { + + int info, activeUnit, anyBindings; + std::vector textures; + + // get current active unit, for later restoration + glGetIntegerv(GL_ACTIVE_TEXTURE, &activeUnit); + addNewLine(); + addMessage("Current Texture Bindings"); + addMessage("Currently Active Texture Unit: %s", spTextureUnit[activeUnit].c_str()); + + addMessage("Texture Bindings:"); + // for each unit + for (int i = 0; i < 8; ++i) { + + glActiveTexture(GL_TEXTURE0 + i); + textures.clear(); + anyBindings = 0; + std::map::iterator iterTT; + iterTT = spTextureBound.begin(); + for ( ; iterTT != spTextureBound.end(); ++iterTT) { + + glGetIntegerv((iterTT)->second, &info); + textures.push_back(info); + anyBindings |= info; + } + + if (anyBindings) { + addMessage("Unit %d", i); + iterTT = spTextureBound.begin(); + for (int j = 0 ; iterTT != spTextureBound.end(); ++j, ++iterTT) { + + if (textures[j]) + addMessage(" %s: %d", spTextureTarget[(iterTT)->first].c_str(), textures[j]); + } + + } + } + + // restore previous active texture unit + glActiveTexture(activeUnit); +} + + +// returns the name of the currently bound texture for a target +int +VSGLInfoLib::getCurrentTexture(GLenum textureTarget) { + + int t; + glGetIntegerv(spTextureBound[textureTarget], &t); + return(t); + +} + + +// returns the currently active texture unit +int +VSGLInfoLib::getCurrentTextureActiveUnitInfo() { + + int activeUnit; + glGetIntegerv(GL_ACTIVE_TEXTURE, &activeUnit); + return(activeUnit); + +} + + +// sends to the stream all the texture info +void +VSGLInfoLib::getTextureInfo(GLenum textureTarget, GLenum textureID) { + + + addNewLine(); + if (!glIsTexture(textureID)) { + addMessage("name: %d is not a texture", textureID); + return; + } + + + if (!glIsTexture(textureID)) { + addMessage("ID %d does not represent a valid texture name", textureID); + return; + } + + addMessage("Texture Info - target: %s tex ID %d", spTextureTarget[textureTarget].c_str(), textureID); + + int prevTex = getCurrentTexture(textureTarget); + glBindTexture(textureTarget, textureID); + + int info; + + // Dimensions + glGetTexLevelParameteriv(textureTarget, 0, + GL_TEXTURE_WIDTH, &info); + addMessage("Dimensions"); + addMessage(" Width: %d", info); + + if (textureTarget != GL_TEXTURE_1D) { + + glGetTexLevelParameteriv(textureTarget, 0, + GL_TEXTURE_HEIGHT, &info); + addMessage(" Height: %d", info); + + if (textureTarget != GL_TEXTURE_2D) { + glGetTexLevelParameteriv(textureTarget, 0, + GL_TEXTURE_DEPTH, &info); + addMessage(" Depth: %d", info); + } + } + + // Internal Format + glGetTexLevelParameteriv(textureTarget, 0, + GL_TEXTURE_INTERNAL_FORMAT, &info); + addMessage("Internal Format: %s", spInternalF[info].c_str()); + + // Compression info + glGetTexLevelParameteriv(textureTarget, 0, + GL_TEXTURE_COMPRESSED, &info); + // sizes + if (info) { + glGetIntegerv(GL_TEXTURE_COMPRESSION_HINT, &info); + addMessage("Compression Hint: %s", spHint[info].c_str()); + glGetTexLevelParameteriv(textureTarget, 0, + GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &info); + addMessage("Compressed Size: %d", info); + } + else { + addMessage("Bits per channel -"); + glGetTexLevelParameteriv(textureTarget, 0, + GL_TEXTURE_RED_SIZE, &info); + if (info) + addMessage(" Red: %d", info); + glGetTexLevelParameteriv(textureTarget, 0, + GL_TEXTURE_GREEN_SIZE, &info); + if (info) + addMessage(" Green: %d", info); + glGetTexLevelParameteriv(textureTarget, 0, + GL_TEXTURE_BLUE_SIZE, &info); + if (info) + addMessage(" Blue: %d", info); + glGetTexLevelParameteriv(textureTarget, 0, + GL_TEXTURE_ALPHA_SIZE, &info); + if (info) + addMessage(" Alpha: %d", info); + + glGetTexLevelParameteriv(textureTarget, 0, + GL_TEXTURE_DEPTH_SIZE, &info); + if (info) + addMessage(" Depth: %d", info); + + glGetTexLevelParameteriv(textureTarget, 0, + GL_TEXTURE_STENCIL_SIZE, &info); + if (info) + addMessage(" Stencil: %d", info); + + + glGetTexLevelParameteriv(textureTarget, 0, + GL_TEXTURE_RED_TYPE, &info); + addMessage("Data Type: %s", spTextureDataType[info].c_str()); + + } + + // Get texture sampling state + glGetTexParameteriv(textureTarget, GL_TEXTURE_MIN_FILTER, &info); + addMessage("Min Filter: %s", spTextureFilter[info].c_str()); + glGetTexParameteriv(textureTarget, GL_TEXTURE_MAG_FILTER, &info); + addMessage("Mag Filter: %s", spTextureFilter[info].c_str()); + + // wrapping info + glGetTexParameteriv(textureTarget, GL_TEXTURE_WRAP_S, &info); + addMessage("Wrap S: %s", spTextureWrap[info].c_str()); + if (textureTarget != GL_TEXTURE_1D) { + glGetTexParameteriv(textureTarget, GL_TEXTURE_WRAP_T, &info); + addMessage("Wrap T: %s", spTextureWrap[info].c_str()); + if (textureTarget != GL_TEXTURE_2D) { + glGetTexParameteriv(textureTarget, GL_TEXTURE_WRAP_R, &info); + addMessage("Wrap R: %s", spTextureWrap[info].c_str()); + } + } + + // mipmap info + glGetTexParameteriv(textureTarget, GL_TEXTURE_BASE_LEVEL, &info); + addMessage("Base Level: %d", info); + glGetTexParameteriv(textureTarget, GL_TEXTURE_MAX_LEVEL, &info); + addMessage("Max Level: %d", info); + + // compare info + glGetTexParameteriv(textureTarget, GL_TEXTURE_COMPARE_MODE, &info); + addMessage("Compare Mode : %s", spTextureCompMode[info].c_str()); + if (info != GL_NONE) { + glGetTexParameteriv(textureTarget, GL_TEXTURE_COMPARE_FUNC, &info); + addMessage("Compare Mode : %s", spTextureCompFunc[info].c_str()); + + } + glBindTexture(textureTarget, prevTex); +} + + +/* ------------------------------------------------------ + + GLSL + +-------------------------------------------------------- */ + + +// gets all the names currently boundo to programs +std::vector & +VSGLInfoLib::getProgramNames() { + + spResult.clear(); + for (unsigned int i = 0; i < 65535; ++i) { + + if (glIsProgram(i)) + spResult.push_back(i); + } + return spResult; +} + + +// gets all the names currently bound to Shaders +std::vector & +VSGLInfoLib::getShaderNames() { + + spResult.clear(); + for (unsigned int i = 0; i < 65535; ++i) { + + if (glIsShader(i)) + spResult.push_back(i); + } + return spResult; +} + + +// gets all the names currently bound to VAOs +std::vector & +VSGLInfoLib::getVAONames() { + + spResult.clear(); + for (unsigned int i = 0; i < 65535; ++i) { + + if (glIsVertexArray(i)) + spResult.push_back(i); + } + return spResult; +} + + +// display VAO information, including its attributes +void +VSGLInfoLib::getVAOInfo(unsigned int buffer) { + + int count, info, prevBuffer; + + addNewLine(); + + // is it a VAO? + if (!glIsVertexArray(buffer)) { + addMessage("name: %d is not a VAO", buffer); + return; + } + + addMessage("VAO Info for name: %d", buffer); + + // bind requested VAO + // should be able to get previously bounded VAO... + glBindVertexArray(buffer); + + // get element array buffer name + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &info); + if (info) + addMessage("Element Array: %d", info); + + // get info for each attrib mapped buffer + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &count); + for (int i = 0; i < count; ++i) { + + glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &info); + if (info) { + addMessage("Attrib index: %d", i); + + glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &info); + addMessage(" Buffer bound: %d", info); + + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prevBuffer); + glBindBuffer(GL_ARRAY_BUFFER, info); + glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &info); + glBindBuffer(GL_ARRAY_BUFFER, prevBuffer); + addMessage(" Size: %d", info); + + glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &info); + addMessage(" Components: %d", info); + + glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &info); + addMessage(" Data Type: %s", spDataF[info].c_str()); + + glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &info); + addMessage(" Stride: %d", info); + + glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &info); + addMessage(" Normalized: %d", info); + + glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, &info); + addMessage(" Divisor: %d", info); + + glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_INTEGER, &info); + addMessage(" Integer: %d", info); + } + } +} + + +// display info for all active uniforms in a program +void +VSGLInfoLib::getUniformsInfo(unsigned int program) { + + addNewLine(); + + // is it a program ? + if (!glIsProgram(program)) { + addMessage("name: %d is not a program", program); + return; + } + + int activeUnif, actualLen, index, uniType, + uniSize, uniMatStride, uniArrayStride, uniOffset; + char name[256]; + + // Get uniforms info (not in named blocks) + addMessage("Uniforms Info for program: %d", program); + glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &activeUnif); + + for (unsigned int i = 0; i < (unsigned int)activeUnif; ++i) { + glGetActiveUniformsiv(program, 1, &i, GL_UNIFORM_BLOCK_INDEX, &index); + if (index == -1) { + glGetActiveUniformName(program, i, 256, &actualLen, name); + glGetActiveUniformsiv(program, 1, &i, GL_UNIFORM_TYPE, &uniType); + addMessage("%s", name); + addMessage(" %s", spGLSLType[uniType].c_str()); + addMessage(" location: %d", i); + + glGetActiveUniformsiv(program, 1, &i, GL_UNIFORM_SIZE, &uniSize); + glGetActiveUniformsiv(program, 1, &i, GL_UNIFORM_ARRAY_STRIDE, &uniArrayStride); + + int auxSize; + if (uniArrayStride > 0) + auxSize = uniArrayStride * uniSize; + else + auxSize = spGLSLTypeSize[uniType]; + + addMessage(" size: %d", auxSize); + if (uniArrayStride > 0) + addMessage(" stride: %d", uniArrayStride); + } + } + // Get named blocks info + int count, dataSize, info; + glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &count); + + for (int i = 0; i < count; ++i) { + // Get blocks name + glGetActiveUniformBlockName(program, i, 256, NULL, name); + glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_DATA_SIZE, &dataSize); + addMessage("%s\n Size %d", name, dataSize); + + glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_BINDING, &index); + addMessage(" Block binding point: %d", index); + glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, index, &info); + addMessage(" Buffer bound to binding point: %d {", info); + + + glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &activeUnif); + + unsigned int *indices; + indices = (unsigned int *)malloc(sizeof(unsigned int) * activeUnif); + glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, (int *)indices); + + for (int k = 0; k < activeUnif; ++k) { + + glGetActiveUniformName(program, indices[k], 256, &actualLen, name); + glGetActiveUniformsiv(program, 1, &indices[k], GL_UNIFORM_TYPE, &uniType); + addMessage("\t%s\n\t %s", name, spGLSLType[uniType].c_str()); + + glGetActiveUniformsiv(program, 1, &indices[k], GL_UNIFORM_OFFSET, &uniOffset); + addMessage("\t offset: %d", uniOffset); + + glGetActiveUniformsiv(program, 1, &indices[k], GL_UNIFORM_SIZE, &uniSize); + + glGetActiveUniformsiv(program, 1, &indices[k], GL_UNIFORM_ARRAY_STRIDE, &uniArrayStride); + + glGetActiveUniformsiv(program, 1, &indices[k], GL_UNIFORM_MATRIX_STRIDE, &uniMatStride); + + int auxSize; + if (uniArrayStride > 0) + auxSize = uniArrayStride * uniSize; + + else if (uniMatStride > 0) { + + switch(uniType) { + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT2x3: + case GL_FLOAT_MAT2x4: + case GL_DOUBLE_MAT2: + case GL_DOUBLE_MAT2x3: + case GL_DOUBLE_MAT2x4: + auxSize = 2 * uniMatStride; + break; + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT3x2: + case GL_FLOAT_MAT3x4: + case GL_DOUBLE_MAT3: + case GL_DOUBLE_MAT3x2: + case GL_DOUBLE_MAT3x4: + auxSize = 3 * uniMatStride; + break; + case GL_FLOAT_MAT4: + case GL_FLOAT_MAT4x2: + case GL_FLOAT_MAT4x3: + case GL_DOUBLE_MAT4: + case GL_DOUBLE_MAT4x2: + case GL_DOUBLE_MAT4x3: + auxSize = 4 * uniMatStride; + break; + } + } + else + auxSize = spGLSLTypeSize[uniType]; + + auxSize = getUniformByteSize(uniSize, uniType, uniArrayStride, uniMatStride); + addMessage("\t size: %d", auxSize); + if (uniArrayStride > 0) + addMessage("\t array stride: %d", uniArrayStride); + if (uniMatStride > 0) + addMessage("\t mat stride: %d", uniMatStride); + } + addMessage(" }"); + } +} + + +// display the values for uniforms in the default block +void +VSGLInfoLib::getUniformInfo(unsigned int program, std::string uniName) { + + addNewLine(); + + // is it a program ? + if (!glIsProgram(program)) { + addMessage("name: %d is not a program", program); + return; + } + + GLenum type; + GLsizei l; + GLint s; + char c[50]; + int loc = glGetUniformLocation((int)program, uniName.c_str()); + glGetActiveUniform(program, loc, 0, &l, &s, &type, c); + + if (loc != -1) { + addMessage("Values for uniform %s in program %d", uniName.c_str(), program); + int rows = getRows(type), columns = getColumns(type); + if (getType(type) == FLOAT) { + float f[16]; + glGetUniformfv(program, loc, f); + displayUniformf(f,rows,columns); + } + else if (getType(type) == INT) { + int f[16]; + glGetUniformiv(program, loc, f); + displayUniformi(f,rows,columns); + } + else if (getType(type) == UNSIGNED_INT) { + unsigned int f[16]; + glGetUniformuiv(program, loc, f); + displayUniformui(f,rows,columns); + } + else if (getType(type) == DOUBLE) { + double f[16]; + glGetUniformdv(program, loc, f); + displayUniformd(f,rows,columns); + } + } + else + addMessage("%s is not an active uniform in program %u", uniName.c_str(), program); +} + + +// display the values for a uniform in a named block +void +VSGLInfoLib::getUniformInBlockInfo(unsigned int program, + std::string blockName, + std::string uniName) { + + addNewLine(); + + // is it a program ? + if (!glIsProgram(program)) { + addMessage("name: %d is not a program", program); + return; + } + + int index = glGetUniformBlockIndex(program, blockName.c_str()); + if (index == GL_INVALID_INDEX) { + addMessage("%s is not a valid uniform name in block %s", uniName.c_str(), blockName.c_str()); + return; + } + int bindIndex,bufferIndex; + glGetActiveUniformBlockiv(program, index, GL_UNIFORM_BLOCK_BINDING, &bindIndex); + addMessage("Block binding point: %d", bindIndex); + glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, bindIndex, &bufferIndex); + addMessage("Buffer bound to binding point: %d ", bufferIndex); + unsigned int uniIndex; + const char *c = uniName.c_str(); + glGetUniformIndices(program, 1, &c, &uniIndex); + addMessage("Index of Uniform: %u", uniIndex); + + int uniType, uniOffset, uniSize, uniArrayStride, uniMatStride; + glGetActiveUniformsiv(program, 1, &uniIndex, GL_UNIFORM_TYPE, &uniType); + + glGetActiveUniformsiv(program, 1, &uniIndex, GL_UNIFORM_OFFSET, &uniOffset); + + glGetActiveUniformsiv(program, 1, &uniIndex, GL_UNIFORM_SIZE, &uniSize); + + glGetActiveUniformsiv(program, 1, &uniIndex, GL_UNIFORM_ARRAY_STRIDE, &uniArrayStride); + + glGetActiveUniformsiv(program, 1, &uniIndex, GL_UNIFORM_MATRIX_STRIDE, &uniMatStride); + + int auxSize = getUniformByteSize(uniSize, uniType, uniArrayStride, uniMatStride); + // get previously bound buffer + int prevBuffer; + glGetIntegerv(spBoundBuffer[GL_UNIFORM_BUFFER], &prevBuffer); + + glBindBuffer(GL_UNIFORM_BUFFER, bufferIndex); + + int rows = getRows(uniType); + int columns = auxSize / (rows * sizeof(float)); + + if (getType(uniType) == FLOAT) { + float f[16]; + glGetBufferSubData(GL_UNIFORM_BUFFER, uniOffset, auxSize, f); + displayUniformf(f,rows,columns); + } + else if (getType(uniType) == INT) { + int f[16]; + glGetBufferSubData(GL_UNIFORM_BUFFER, uniOffset, auxSize, f); + displayUniformi(f,rows,columns); + } + else if (getType(uniType) == UNSIGNED_INT) { + unsigned int f[16]; + glGetBufferSubData(GL_UNIFORM_BUFFER, uniOffset, auxSize, f); + displayUniformui(f,rows,columns); + } + else if (getType(uniType) == DOUBLE) { + double f[16]; + glGetBufferSubData(GL_UNIFORM_BUFFER, uniOffset, auxSize, f); + displayUniformd(f,rows,columns); + } + glBindBuffer(GL_UNIFORM_BUFFER, prevBuffer); +} + + +// display information for a program's attributes +void +VSGLInfoLib::getAttributesInfo(unsigned int program) { + + int activeAttr, size, loc; + GLsizei length; + GLenum type; + char name[256]; + + addNewLine(); + + // check if it is a program + if (!glIsProgram(program)) { + addMessage("name: %d is not a program", program); + return; + } + + addMessage("Attribute Info for program %d", program); + // how many attribs? + glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &activeAttr); + // get location and type for each attrib + for (unsigned int i = 0; i < (unsigned int)activeAttr; ++i) { + + glGetActiveAttrib(program, i, 256, &length, &size, &type, name); + loc = glGetAttribLocation(program, name); + addMessage("%s loc: %d type: %s", name, loc, spGLSLType[type].c_str()); + } +} + + +// display program's information +void +VSGLInfoLib::getProgramInfo(unsigned int program) { + + addNewLine(); + + // check if name is really a program + if (!glIsProgram(program)) { + addMessage("Name %u is not a program", program); + return; + } + + addMessage("Program Information for name %u", program); + unsigned int shaders[5]; + int count, info, linked; + bool geom= false, tess = false; + + // Get the shader's name + addMessage(" Shaders {"); + glGetProgramiv(program, GL_ATTACHED_SHADERS,&count); + glGetAttachedShaders(program, count, NULL, shaders); + for (int i = 0; i < count; ++i) { + + glGetShaderiv(shaders[i], GL_SHADER_TYPE, &info); + addMessage("\t%s: %d", spShaderType[info].c_str(), shaders[i]); + if (info == GL_GEOMETRY_SHADER) + geom = true; + if (info == GL_TESS_EVALUATION_SHADER || info == GL_TESS_CONTROL_SHADER) + tess = true; + } + addMessage(" }"); + + // Get program info + glGetProgramiv(program, GL_PROGRAM_SEPARABLE, &info); + addMessage(" Program Separable: %d", info); + + glGetProgramiv(program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, &info); + addMessage(" Program Binary Retrievable Hint: %d", info); + + glGetProgramiv(program, GL_LINK_STATUS, &linked); + addMessage(" Link Status: %d", linked); + + glGetProgramiv(program, GL_VALIDATE_STATUS, &info); + addMessage(" Validate_Status: %d", info); + + glGetProgramiv(program, GL_DELETE_STATUS, &info); + addMessage(" Delete_Status: %d", info); + + glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &info); + addMessage(" Active_Attributes: %d", info); + + glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &info); + addMessage(" Active_Uniforms: %d", info); + + glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &info); + addMessage(" Active_Uniform_Blocks: %d", info); + +#ifdef VSGL_VERSION_4_2 + glGetProgramiv(program, GL_ACTIVE_ATOMIC_COUNTER_BUFFERS, &info); + addMessage(" Active_Atomic Counters: %d", info); +#endif + // check if trans feed is active + glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, &info); + addMessage(" Transform Feedback Buffer Mode: %s", spTransFeedBufferMode[info].c_str()); + + glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYINGS, &info); + addMessage(" Transform Feedback Varyings: %d", info); + + // Geometry shader info, if present + if (geom && linked) { + glGetProgramiv(program, GL_GEOMETRY_VERTICES_OUT, &info); + addMessage(" Geometry Vertices Out: %d", info); + + glGetProgramiv(program, GL_GEOMETRY_INPUT_TYPE, &info); + addMessage(" Geometry Input Type: %s", spGLSLPrimitives[info].c_str()); + + glGetProgramiv(program, GL_GEOMETRY_OUTPUT_TYPE, &info); + addMessage(" Geometry Output Type: %s", spGLSLPrimitives[info].c_str()); + + glGetProgramiv(program, GL_GEOMETRY_SHADER_INVOCATIONS, &info); + addMessage(" Geometry Shader Invocations: %d", info); + } + // tessellation shaders info, if present + if (tess && linked) { + glGetProgramiv(program, GL_TESS_CONTROL_OUTPUT_VERTICES, &info); + addMessage(" Tess Control Output Vertices: %d", info); + + glGetProgramiv(program, GL_TESS_GEN_MODE, &info); + addMessage(" Tess Gen Mode: %s", spGLSLPrimitives[info].c_str()); + + glGetProgramiv(program, GL_TESS_GEN_SPACING, &info); + addMessage(" Tess Spacing: %s", spTessGenSpacing[info].c_str()); + + glGetProgramiv(program, GL_TESS_GEN_VERTEX_ORDER, &info); + addMessage(" Tess Vertex Order: %s", spVertexOrder[info].c_str()); + + glGetProgramiv(program, GL_TESS_GEN_POINT_MODE, &info); + addMessage(" Tess Gen Point Mode: %d", info); + } + addMessage(""); +} + + +/* ---------------------------------------------- + + private auxiliary functions + +----------------------------------------------- */ + +// add a newline to the stream +void +VSGLInfoLib::addNewLine() { + + *spOutS << "\n"; +} + + +// Printf style! plus a newline at the end +void +VSGLInfoLib::addMessage(std::string format, ...) { + + va_list args; + va_start(args,format); + vsprintf(spAux, format.c_str(), args); + va_end(args); + + *spOutS << spAux << "\n"; +} + + +// init the library +// fills up the maps with enum to string +// to display human-readable messages +bool +VSGLInfoLib::init() { + + spShaderPrecision[GL_LOW_FLOAT] = "GL_LOW_FLOAT"; + spShaderPrecision[GL_MEDIUM_FLOAT] = "GL_MEDIUM_FLOAT"; + spShaderPrecision[GL_HIGH_FLOAT] = "GL_HIGH_FLOAT"; + spShaderPrecision[GL_LOW_INT] = "GL_LOW_INT"; + spShaderPrecision[GL_MEDIUM_INT] = "GL_MEDIUM_INT"; + spShaderPrecision[GL_HIGH_INT] = "GL_HIGH_INT"; + + spTessGenSpacing[GL_EQUAL] = "GL_EQUAL"; + spTessGenSpacing[GL_FRACTIONAL_EVEN] = "GL_FRACTIONAL_EVEN"; + spTessGenSpacing[GL_FRACTIONAL_ODD] = "GL_FRACTIONAL_ODD"; + + spVertexOrder[GL_CCW] = "GL_CCW"; + spVertexOrder[GL_CW] = "GL_CW"; + + spGLSLPrimitives[GL_QUADS] = "GL_QUADS"; + spGLSLPrimitives[GL_ISOLINES] = "GL_ISOLINES"; + spGLSLPrimitives[GL_POINTS] = "GL_POINTS"; + spGLSLPrimitives[GL_LINES] = "GL_LINES"; + spGLSLPrimitives[GL_LINES_ADJACENCY] = "GL_LINES_ADJACENCY"; + spGLSLPrimitives[GL_TRIANGLES] = "GL_TRIANGLES"; + spGLSLPrimitives[GL_LINE_STRIP] = "GL_LINE_STRIP"; + spGLSLPrimitives[GL_TRIANGLE_STRIP] = "GL_TRIANGLE_STRIP"; + spGLSLPrimitives[GL_TRIANGLES_ADJACENCY] = "GL_TRIANGLES_ADJACENCY"; + + spTransFeedBufferMode[GL_SEPARATE_ATTRIBS] = "GL_SEPARATE_ATTRIBS"; + spTransFeedBufferMode[GL_INTERLEAVED_ATTRIBS] = "GL_INTERLEAVED_ATTRIBS"; + + spShaderType[GL_VERTEX_SHADER] = "GL_VERTEX_SHADER"; + spShaderType[GL_GEOMETRY_SHADER] = "GL_GEOMETRY_SHADER"; + spShaderType[GL_TESS_CONTROL_SHADER] = "GL_TESS_CONTROL_SHADER"; + spShaderType[GL_TESS_EVALUATION_SHADER] = "GL_TESS_EVALUATION_SHADER"; + spShaderType[GL_FRAGMENT_SHADER] = "GL_FRAGMENT_SHADER"; + + spHint[GL_FASTEST] = "GL_FASTEST"; + spHint[GL_NICEST] = "GL_NICEST"; + spHint[GL_DONT_CARE] = "GL_DONT_CARE"; + + spBufferBinding[GL_ARRAY_BUFFER_BINDING] = "GL_ARRAY_BUFFER"; + spBufferBinding[GL_ELEMENT_ARRAY_BUFFER_BINDING] = "GL_ELEMENT_ARRAY_BUFFER"; + spBufferBinding[GL_PIXEL_PACK_BUFFER_BINDING] = "GL_PIXEL_PACK_BUFFER"; + spBufferBinding[GL_PIXEL_UNPACK_BUFFER_BINDING] = "GL_PIXEL_UNPACK_BUFFER"; + spBufferBinding[GL_TRANSFORM_FEEDBACK_BUFFER_BINDING] = "GL_TRANSFORM_FEEDBACK_BUFFER"; + spBufferBinding[GL_UNIFORM_BUFFER_BINDING] = "GL_UNIFORM_BUFFER"; + +#ifdef VSGL_VERSION_4_2 + spBufferBinding[GL_TEXTURE_BUFFER_BINDING] = "GL_TEXTURE_BUFFER"; + spBufferBinding[GL_COPY_READ_BUFFER_BINDING] = "GL_COPY_READ_BUFFER"; + spBufferBinding[GL_COPY_WRITE_BUFFER_BINDING] = "GL_COPY_WRITE_BUFFER"; + spBufferBinding[GL_DRAW_INDIRECT_BUFFER_BINDING] = "GL_DRAW_INDIRECT_BUFFER"; + spBufferBinding[GL_ATOMIC_COUNTER_BUFFER_BINDING] = "GL_ATOMIC_COUNTER_BUFFER"; +#endif + + spBufferBound[GL_ARRAY_BUFFER_BINDING] = GL_ARRAY_BUFFER; + spBufferBound[GL_ELEMENT_ARRAY_BUFFER_BINDING] = GL_ELEMENT_ARRAY_BUFFER; + spBufferBound[GL_PIXEL_PACK_BUFFER_BINDING] = GL_PIXEL_PACK_BUFFER; + spBufferBound[GL_PIXEL_UNPACK_BUFFER_BINDING] = GL_PIXEL_UNPACK_BUFFER; + spBufferBound[GL_TRANSFORM_FEEDBACK_BUFFER_BINDING] = GL_TRANSFORM_FEEDBACK_BUFFER; + spBufferBound[GL_UNIFORM_BUFFER_BINDING] = GL_UNIFORM_BUFFER; + +#ifdef VSGL_VERSION_4_2 + spBufferBound[GL_TEXTURE_BUFFER_BINDING] = GL_TEXTURE_BUFFER; + spBufferBound[GL_COPY_READ_BUFFER_BINDING] = GL_COPY_READ_BUFFER; + spBufferBound[GL_COPY_WRITE_BUFFER_BINDING] = GL_COPY_WRITE_BUFFER; + spBufferBound[GL_DRAW_INDIRECT_BUFFER_BINDING] = GL_DRAW_INDIRECT_BUFFER; + spBufferBound[GL_ATOMIC_COUNTER_BUFFER_BINDING] = GL_ATOMIC_COUNTER_BUFFER; +#endif + + spBoundBuffer[GL_ARRAY_BUFFER] = GL_ARRAY_BUFFER_BINDING; + spBoundBuffer[GL_ELEMENT_ARRAY_BUFFER] = GL_ELEMENT_ARRAY_BUFFER_BINDING; + spBoundBuffer[GL_PIXEL_PACK_BUFFER] = GL_PIXEL_PACK_BUFFER_BINDING; + spBoundBuffer[GL_PIXEL_UNPACK_BUFFER] = GL_PIXEL_UNPACK_BUFFER_BINDING; + spBoundBuffer[GL_TRANSFORM_FEEDBACK_BUFFER] = GL_TRANSFORM_FEEDBACK_BUFFER_BINDING; + spBoundBuffer[GL_UNIFORM_BUFFER] = GL_UNIFORM_BUFFER_BINDING; + +#ifdef VSGL_VERSION_4_2 + spBoundBuffer[GL_TEXTURE_BUFFER] = GL_TEXTURE_BUFFER_BINDING; + spBoundBuffer[GL_COPY_READ_BUFFER] = GL_COPY_READ_BUFFER_BINDING; + spBoundBuffer[GL_COPY_WRITE_BUFFER] = GL_COPY_WRITE_BUFFER_BINDING; + spBoundBuffer[GL_DRAW_INDIRECT_BUFFER] = GL_DRAW_INDIRECT_BUFFER; + spBoundBuffer[GL_ATOMIC_COUNTER_BUFFER] = GL_ATOMIC_COUNTER_BUFFER; +#endif + + spBufferUsage[GL_STREAM_DRAW] = "GL_STREAM_DRAW"; + spBufferUsage[GL_STREAM_READ] = "GL_STREAM_READ"; + spBufferUsage[GL_STREAM_COPY] = "GL_STREAM_COPY"; + spBufferUsage[GL_STATIC_DRAW] = "GL_STATIC_DRAW"; + spBufferUsage[GL_STATIC_READ] = "GL_STATIC_READ"; + spBufferUsage[GL_STATIC_COPY] = "GL_STATIC_COPY"; + spBufferUsage[GL_DYNAMIC_DRAW] = "GL_DYNAMIC_DRAW"; + spBufferUsage[GL_DYNAMIC_READ] = "GL_DYNAMIC_READ"; + spBufferUsage[GL_DYNAMIC_COPY] = "GL_DYNAMIC_COPY"; + + spBufferAccess[GL_READ_ONLY] = "GL_READ_ONLY"; + spBufferAccess[GL_WRITE_ONLY] = "GL_WRITE_ONLY"; + spBufferAccess[GL_READ_WRITE] = "GL_READ_WRITE"; + + spTextureTarget[GL_TEXTURE_1D] = "GL_TEXTURE_1D"; + spTextureTarget[GL_TEXTURE_1D_ARRAY] = "GL_TEXTURE_1D_ARRAY"; + spTextureTarget[GL_TEXTURE_2D] = "GL_TEXTURE_2D"; + spTextureTarget[GL_TEXTURE_2D_ARRAY] = "GL_TEXTURE_2D_ARRAY"; + spTextureTarget[GL_TEXTURE_2D_MULTISAMPLE] = "GL_TEXTURE_2D_MULTISAMPLE"; + spTextureTarget[GL_TEXTURE_2D_MULTISAMPLE_ARRAY] = "GL_TEXTURE_2D_MULTISAMPLE_ARRAY"; + spTextureTarget[GL_TEXTURE_3D] = "GL_TEXTURE_3D"; + spTextureTarget[GL_TEXTURE_BUFFER] = "GL_TEXTURE_BUFFER"; + spTextureTarget[GL_TEXTURE_CUBE_MAP] = "GL_TEXTURE_CUBE_MAP"; + spTextureTarget[GL_TEXTURE_RECTANGLE] = "GL_TEXTURE_RECTANGLE"; + + spTextureBound[GL_TEXTURE_1D] = GL_TEXTURE_BINDING_1D; + spTextureBound[GL_TEXTURE_1D_ARRAY] = GL_TEXTURE_BINDING_1D_ARRAY; + spTextureBound[GL_TEXTURE_2D] = GL_TEXTURE_BINDING_2D; + spTextureBound[GL_TEXTURE_2D_ARRAY] = GL_TEXTURE_BINDING_2D_ARRAY; + spTextureBound[GL_TEXTURE_2D_MULTISAMPLE] = GL_TEXTURE_BINDING_2D_MULTISAMPLE; + spTextureBound[GL_TEXTURE_2D_MULTISAMPLE_ARRAY] = GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY; + spTextureBound[GL_TEXTURE_3D] = GL_TEXTURE_BINDING_3D; + spTextureBound[GL_TEXTURE_BUFFER] = GL_TEXTURE_BINDING_BUFFER; + spTextureBound[GL_TEXTURE_CUBE_MAP] = GL_TEXTURE_BINDING_CUBE_MAP; + spTextureBound[GL_TEXTURE_RECTANGLE] = GL_TEXTURE_BINDING_RECTANGLE; + + spTextureUnit[GL_TEXTURE0] = "GL_TEXTURE0"; + spTextureUnit[GL_TEXTURE1] = "GL_TEXTURE1"; + spTextureUnit[GL_TEXTURE2] = "GL_TEXTURE2"; + spTextureUnit[GL_TEXTURE3] = "GL_TEXTURE3"; + spTextureUnit[GL_TEXTURE4] = "GL_TEXTURE4"; + spTextureUnit[GL_TEXTURE5] = "GL_TEXTURE5"; + spTextureUnit[GL_TEXTURE6] = "GL_TEXTURE6"; + spTextureUnit[GL_TEXTURE7] = "GL_TEXTURE7"; + + spTextureCompMode[GL_NONE] = "GL_NONE"; + spTextureCompFunc[GL_COMPARE_REF_TO_TEXTURE] = "GL_COMPARE_REF_TO_TEXTURE"; + + spTextureCompFunc[GL_LEQUAL] = "GL_LEQUAL"; + spTextureCompFunc[GL_GEQUAL] = "GL_GEQUAL"; + spTextureCompFunc[GL_LESS] = "GL_LESS"; + spTextureCompFunc[GL_GREATER] = "GL_GREATER"; + spTextureCompFunc[GL_EQUAL] = "GL_EQUAL"; + spTextureCompFunc[GL_NOTEQUAL] = "GL_NOTEQUAL"; + spTextureCompFunc[GL_ALWAYS] = "GL_ALWAYS"; + spTextureCompFunc[GL_NEVER] = "GL_NEVER"; + + spTextureWrap[GL_CLAMP_TO_EDGE] = "GL_CLAMP_TO_EDGE"; + spTextureWrap[GL_CLAMP_TO_BORDER] = "GL_CLAMP_TO_BORDER"; + spTextureWrap[GL_MIRRORED_REPEAT] = "GL_MIRRORED_REPEAT"; + spTextureWrap[GL_REPEAT] = "GL_REPEAT"; + + spTextureFilter[GL_NEAREST] = "GL_NEAREST"; + spTextureFilter[GL_LINEAR] = "GL_LINEAR"; + spTextureFilter[GL_NEAREST_MIPMAP_NEAREST] = "GL_NEAREST_MIPMAP_NEAREST"; + spTextureFilter[GL_LINEAR_MIPMAP_NEAREST] = "GL_LINEAR_MIPMAP_NEAREST"; + spTextureFilter[GL_NEAREST_MIPMAP_LINEAR] = "GL_NEAREST_MIPMAP_LINEAR"; + spTextureFilter[GL_LINEAR_MIPMAP_LINEAR] = "GL_LINEAR_MIPMAP_LINEAR"; + + spGLSLTypeSize[GL_FLOAT] = sizeof(float); + spGLSLTypeSize[GL_FLOAT_VEC2] = sizeof(float)*2; + spGLSLTypeSize[GL_FLOAT_VEC3] = sizeof(float)*3; + spGLSLTypeSize[GL_FLOAT_VEC4] = sizeof(float)*4; + + spGLSLTypeSize[GL_DOUBLE] = sizeof(double); + spGLSLTypeSize[GL_DOUBLE_VEC2] = sizeof(double)*2; + spGLSLTypeSize[GL_DOUBLE_VEC3] = sizeof(double)*3; + spGLSLTypeSize[GL_DOUBLE_VEC4] = sizeof(double)*4; + + spGLSLTypeSize[GL_SAMPLER_1D] = sizeof(int); + spGLSLTypeSize[GL_SAMPLER_2D] = sizeof(int); + spGLSLTypeSize[GL_SAMPLER_3D] = sizeof(int); + spGLSLTypeSize[GL_SAMPLER_CUBE] = sizeof(int); + spGLSLTypeSize[GL_SAMPLER_1D_SHADOW] = sizeof(int); + spGLSLTypeSize[GL_SAMPLER_2D_SHADOW] = sizeof(int); + spGLSLTypeSize[GL_SAMPLER_1D_ARRAY] = sizeof(int); + spGLSLTypeSize[GL_SAMPLER_2D_ARRAY] = sizeof(int); + spGLSLTypeSize[GL_SAMPLER_1D_ARRAY_SHADOW] = sizeof(int); + spGLSLTypeSize[GL_SAMPLER_2D_ARRAY_SHADOW] = sizeof(int); + spGLSLTypeSize[GL_SAMPLER_2D_MULTISAMPLE] = sizeof(int); + spGLSLTypeSize[GL_SAMPLER_2D_MULTISAMPLE_ARRAY] = sizeof(int); + spGLSLTypeSize[GL_SAMPLER_CUBE_SHADOW] = sizeof(int); + spGLSLTypeSize[GL_SAMPLER_BUFFER] = sizeof(int); + spGLSLTypeSize[GL_SAMPLER_2D_RECT] = sizeof(int); + spGLSLTypeSize[GL_SAMPLER_2D_RECT_SHADOW] = sizeof(int); + spGLSLTypeSize[GL_INT_SAMPLER_1D] = sizeof(int); + spGLSLTypeSize[GL_INT_SAMPLER_2D] = sizeof(int); + spGLSLTypeSize[GL_INT_SAMPLER_3D] = sizeof(int); + spGLSLTypeSize[GL_INT_SAMPLER_CUBE] = sizeof(int); + spGLSLTypeSize[GL_INT_SAMPLER_1D_ARRAY] = sizeof(int); + spGLSLTypeSize[GL_INT_SAMPLER_2D_ARRAY] = sizeof(int); + spGLSLTypeSize[GL_INT_SAMPLER_2D_MULTISAMPLE] = sizeof(int); + spGLSLTypeSize[GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY] = sizeof(int); + spGLSLTypeSize[GL_INT_SAMPLER_BUFFER] = sizeof(int); + spGLSLTypeSize[GL_INT_SAMPLER_2D_RECT] = sizeof(int); + spGLSLTypeSize[GL_UNSIGNED_INT_SAMPLER_1D] = sizeof(int); + spGLSLTypeSize[GL_UNSIGNED_INT_SAMPLER_2D] = sizeof(int); + spGLSLTypeSize[GL_UNSIGNED_INT_SAMPLER_3D] = sizeof(int); + spGLSLTypeSize[GL_UNSIGNED_INT_SAMPLER_CUBE] = sizeof(int); + spGLSLTypeSize[GL_UNSIGNED_INT_SAMPLER_1D_ARRAY] = sizeof(int); + spGLSLTypeSize[GL_UNSIGNED_INT_SAMPLER_2D_ARRAY] = sizeof(int); + spGLSLTypeSize[GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE] = sizeof(int); + spGLSLTypeSize[GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY] = sizeof(int); + spGLSLTypeSize[GL_UNSIGNED_INT_SAMPLER_BUFFER] = sizeof(int); + spGLSLTypeSize[GL_UNSIGNED_INT_SAMPLER_2D_RECT] = sizeof(int); + spGLSLTypeSize[GL_BOOL] = sizeof(int); + spGLSLTypeSize[GL_INT] = sizeof(int); + spGLSLTypeSize[GL_BOOL_VEC2] = sizeof(int)*2; + spGLSLTypeSize[GL_INT_VEC2] = sizeof(int)*2; + spGLSLTypeSize[GL_BOOL_VEC3] = sizeof(int)*3; + spGLSLTypeSize[GL_INT_VEC3] = sizeof(int)*3; + spGLSLTypeSize[GL_BOOL_VEC4] = sizeof(int)*4; + spGLSLTypeSize[GL_INT_VEC4] = sizeof(int)*4; + + spGLSLTypeSize[GL_UNSIGNED_INT] = sizeof(int); + spGLSLTypeSize[GL_UNSIGNED_INT_VEC2] = sizeof(int)*2; + spGLSLTypeSize[GL_UNSIGNED_INT_VEC3] = sizeof(int)*2; + spGLSLTypeSize[GL_UNSIGNED_INT_VEC4] = sizeof(int)*2; + + spGLSLTypeSize[GL_FLOAT_MAT2] = sizeof(float)*4; + spGLSLTypeSize[GL_FLOAT_MAT3] = sizeof(float)*9; + spGLSLTypeSize[GL_FLOAT_MAT4] = sizeof(float)*16; + spGLSLTypeSize[GL_FLOAT_MAT2x3] = sizeof(float)*6; + spGLSLTypeSize[GL_FLOAT_MAT2x4] = sizeof(float)*8; + spGLSLTypeSize[GL_FLOAT_MAT3x2] = sizeof(float)*6; + spGLSLTypeSize[GL_FLOAT_MAT3x4] = sizeof(float)*12; + spGLSLTypeSize[GL_FLOAT_MAT4x2] = sizeof(float)*8; + spGLSLTypeSize[GL_FLOAT_MAT4x3] = sizeof(float)*12; + spGLSLTypeSize[GL_DOUBLE_MAT2] = sizeof(double)*4; + spGLSLTypeSize[GL_DOUBLE_MAT3] = sizeof(double)*9; + spGLSLTypeSize[GL_DOUBLE_MAT4] = sizeof(double)*16; + spGLSLTypeSize[GL_DOUBLE_MAT2x3] = sizeof(double)*6; + spGLSLTypeSize[GL_DOUBLE_MAT2x4] = sizeof(double)*8; + spGLSLTypeSize[GL_DOUBLE_MAT3x2] = sizeof(double)*6; + spGLSLTypeSize[GL_DOUBLE_MAT3x4] = sizeof(double)*12; + spGLSLTypeSize[GL_DOUBLE_MAT4x2] = sizeof(double)*8; + spGLSLTypeSize[GL_DOUBLE_MAT4x3] = sizeof(double)*12; + + + + spGLSLType[GL_FLOAT] = "GL_FLOAT"; + spGLSLType[GL_FLOAT_VEC2] = "GL_FLOAT_VEC2"; + spGLSLType[GL_FLOAT_VEC3] = "GL_FLOAT_VEC3"; + spGLSLType[GL_FLOAT_VEC4] = "GL_FLOAT_VEC4"; + spGLSLType[GL_DOUBLE] = "GL_DOUBLE"; + spGLSLType[GL_DOUBLE_VEC2] = "GL_DOUBLE_VEC2"; + spGLSLType[GL_DOUBLE_VEC3] = "GL_DOUBLE_VEC3"; + spGLSLType[GL_DOUBLE_VEC4] = "GL_DOUBLE_VEC4"; + spGLSLType[GL_SAMPLER_1D] = "GL_SAMPLER_1D"; + spGLSLType[GL_SAMPLER_2D] = "GL_SAMPLER_2D"; + spGLSLType[GL_SAMPLER_3D] = "GL_SAMPLER_3D"; + spGLSLType[GL_SAMPLER_CUBE] = "GL_SAMPLER_CUBE"; + spGLSLType[GL_SAMPLER_1D_SHADOW] = "GL_SAMPLER_1D_SHADOW"; + spGLSLType[GL_SAMPLER_2D_SHADOW] = "GL_SAMPLER_2D_SHADOW"; + spGLSLType[GL_SAMPLER_1D_ARRAY] = "GL_SAMPLER_1D_ARRAY"; + spGLSLType[GL_SAMPLER_2D_ARRAY] = "GL_SAMPLER_2D_ARRAY"; + spGLSLType[GL_SAMPLER_1D_ARRAY_SHADOW] = "GL_SAMPLER_1D_ARRAY_SHADOW"; + spGLSLType[GL_SAMPLER_2D_ARRAY_SHADOW] = "GL_SAMPLER_2D_ARRAY_SHADOW"; + spGLSLType[GL_SAMPLER_2D_MULTISAMPLE] = "GL_SAMPLER_2D_MULTISAMPLE"; + spGLSLType[GL_SAMPLER_2D_MULTISAMPLE_ARRAY] = "GL_SAMPLER_2D_MULTISAMPLE_ARRAY"; + spGLSLType[GL_SAMPLER_CUBE_SHADOW] = "GL_SAMPLER_CUBE_SHADOW"; + spGLSLType[GL_SAMPLER_BUFFER] = "GL_SAMPLER_BUFFER"; + spGLSLType[GL_SAMPLER_2D_RECT] = "GL_SAMPLER_2D_RECT"; + spGLSLType[GL_SAMPLER_2D_RECT_SHADOW] = "GL_SAMPLER_2D_RECT_SHADOW"; + spGLSLType[GL_INT_SAMPLER_1D] = "GL_INT_SAMPLER_1D"; + spGLSLType[GL_INT_SAMPLER_2D] = "GL_INT_SAMPLER_2D"; + spGLSLType[GL_INT_SAMPLER_3D] = "GL_INT_SAMPLER_3D"; + spGLSLType[GL_INT_SAMPLER_CUBE] = "GL_INT_SAMPLER_CUBE"; + spGLSLType[GL_INT_SAMPLER_1D_ARRAY] = "GL_INT_SAMPLER_1D_ARRAY"; + spGLSLType[GL_INT_SAMPLER_2D_ARRAY] = "GL_INT_SAMPLER_2D_ARRAY"; + spGLSLType[GL_INT_SAMPLER_2D_MULTISAMPLE] = "GL_INT_SAMPLER_2D_MULTISAMPLE"; + spGLSLType[GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY] = "GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY"; + spGLSLType[GL_INT_SAMPLER_BUFFER] = "GL_INT_SAMPLER_BUFFER"; + spGLSLType[GL_INT_SAMPLER_2D_RECT] = "GL_INT_SAMPLER_2D_RECT"; + spGLSLType[GL_UNSIGNED_INT_SAMPLER_1D] = "GL_UNSIGNED_INT_SAMPLER_1D"; + spGLSLType[GL_UNSIGNED_INT_SAMPLER_2D] = "GL_UNSIGNED_INT_SAMPLER_2D"; + spGLSLType[GL_UNSIGNED_INT_SAMPLER_3D] = "GL_UNSIGNED_INT_SAMPLER_3D"; + spGLSLType[GL_UNSIGNED_INT_SAMPLER_CUBE] = "GL_UNSIGNED_INT_SAMPLER_CUBE"; + spGLSLType[GL_UNSIGNED_INT_SAMPLER_1D_ARRAY] = "GL_UNSIGNED_INT_SAMPLER_1D_ARRAY"; + spGLSLType[GL_UNSIGNED_INT_SAMPLER_2D_ARRAY] = "GL_UNSIGNED_INT_SAMPLER_2D_ARRAY"; + spGLSLType[GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE] = "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE"; + spGLSLType[GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY] = "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY"; + spGLSLType[GL_UNSIGNED_INT_SAMPLER_BUFFER] = "GL_UNSIGNED_INT_SAMPLER_BUFFER"; + spGLSLType[GL_UNSIGNED_INT_SAMPLER_2D_RECT] = "GL_UNSIGNED_INT_SAMPLER_2D_RECT"; + spGLSLType[GL_BOOL] = "GL_BOOL"; + spGLSLType[GL_INT] = "GL_INT"; + spGLSLType[GL_BOOL_VEC2] = "GL_BOOL_VEC2"; + spGLSLType[GL_INT_VEC2] = "GL_INT_VEC2"; + spGLSLType[GL_BOOL_VEC3] = "GL_BOOL_VEC3"; + spGLSLType[GL_INT_VEC3] = "GL_INT_VEC3"; + spGLSLType[GL_BOOL_VEC4] = "GL_BOOL_VEC4"; + spGLSLType[GL_INT_VEC4] = "GL_INT_VEC4"; + spGLSLType[GL_UNSIGNED_INT] = "GL_UNSIGNED_INT"; + spGLSLType[GL_UNSIGNED_INT_VEC2] = "GL_UNSIGNED_INT_VEC2"; + spGLSLType[GL_UNSIGNED_INT_VEC3] = "GL_UNSIGNED_INT_VEC3"; + spGLSLType[GL_UNSIGNED_INT_VEC4] = "GL_UNSIGNED_INT_VEC4"; + spGLSLType[GL_FLOAT_MAT2] = "GL_FLOAT_MAT2"; + spGLSLType[GL_FLOAT_MAT3] = "GL_FLOAT_MAT3"; + spGLSLType[GL_FLOAT_MAT4] = "GL_FLOAT_MAT4"; + spGLSLType[GL_FLOAT_MAT2x3] = "GL_FLOAT_MAT2x3"; + spGLSLType[GL_FLOAT_MAT2x4] = "GL_FLOAT_MAT2x4"; + spGLSLType[GL_FLOAT_MAT3x2] = "GL_FLOAT_MAT3x2"; + spGLSLType[GL_FLOAT_MAT3x4] = "GL_FLOAT_MAT3x4"; + spGLSLType[GL_FLOAT_MAT4x2] = "GL_FLOAT_MAT4x2"; + spGLSLType[GL_FLOAT_MAT4x3] = "GL_FLOAT_MAT4x3"; + spGLSLType[GL_DOUBLE_MAT2] = "GL_DOUBLE_MAT2"; + spGLSLType[GL_DOUBLE_MAT3] = "GL_DOUBLE_MAT3"; + spGLSLType[GL_DOUBLE_MAT4] = "GL_DOUBLE_MAT4"; + spGLSLType[GL_DOUBLE_MAT2x3] = "GL_DOUBLE_MAT2x3"; + spGLSLType[GL_DOUBLE_MAT2x4] = "GL_DOUBLE_MAT2x4"; + spGLSLType[GL_DOUBLE_MAT3x2] = "GL_DOUBLE_MAT3x2"; + spGLSLType[GL_DOUBLE_MAT3x4] = "GL_DOUBLE_MAT3x4"; + spGLSLType[GL_DOUBLE_MAT4x2] = "GL_DOUBLE_MAT4x2"; + spGLSLType[GL_DOUBLE_MAT4x3] = "GL_DOUBLE_MAT4x3"; + + + + spTextureDataType[GL_NONE] = "GL_NONE"; + spTextureDataType[GL_SIGNED_NORMALIZED] = "GL_SIGNED_NORMALIZED"; + spTextureDataType[GL_UNSIGNED_NORMALIZED] = "GL_UNSIGNED_NORMALIZED"; + spTextureDataType[GL_FLOAT] = "GL_FLOAT"; + spTextureDataType[GL_INT] = "GL_INT"; + spTextureDataType[GL_UNSIGNED_INT] = "GL_UNSIGNED_INT"; + + spDataF[GL_UNSIGNED_BYTE] = "GL_UNSIGNED_BYTE"; + spDataF[GL_BYTE] = "GL_BYTE"; + spDataF[GL_UNSIGNED_SHORT] = "GL_UNSIGNED_SHORT"; + spDataF[GL_SHORT] = "GL_SHORT"; + spDataF[GL_UNSIGNED_INT] = "GL_UNSIGNED_INT"; + spDataF[GL_INT] = "GL_INT"; + spDataF[GL_HALF_FLOAT] = "GL_HALF_FLOAT"; + spDataF[GL_FLOAT] = "GL_FLOAT"; + + spDataF[GL_UNSIGNED_BYTE_3_3_2] = "GL_UNSIGNED_BYTE_3_3_2"; + spDataF[GL_UNSIGNED_BYTE_2_3_3_REV] = "GL_UNSIGNED_BYTE_2_3_3_REV"; + spDataF[GL_UNSIGNED_SHORT_5_6_5] = "GL_UNSIGNED_SHORT_5_6_5"; + spDataF[GL_UNSIGNED_SHORT_5_6_5_REV] = "GL_UNSIGNED_SHORT_5_6_5_REV"; + spDataF[GL_UNSIGNED_SHORT_4_4_4_4] = "GL_UNSIGNED_SHORT_4_4_4_4"; + spDataF[GL_UNSIGNED_SHORT_4_4_4_4_REV] = "GL_UNSIGNED_SHORT_4_4_4_4_REV"; + spDataF[GL_UNSIGNED_SHORT_5_5_5_1] = "GL_UNSIGNED_SHORT_5_5_5_1"; + spDataF[GL_UNSIGNED_SHORT_1_5_5_5_REV] = "GL_UNSIGNED_SHORT_1_5_5_5_REV"; + spDataF[GL_UNSIGNED_INT_8_8_8_8] = "GL_UNSIGNED_INT_8_8_8_8"; + spDataF[GL_UNSIGNED_INT_8_8_8_8_REV] = "GL_UNSIGNED_INT_8_8_8_8_REV"; + spDataF[GL_UNSIGNED_INT_10_10_10_2] = "GL_UNSIGNED_INT_10_10_10_2"; + spDataF[GL_UNSIGNED_INT_2_10_10_10_REV] = "GL_UNSIGNED_INT_2_10_10_10_REV"; + + spInternalF[GL_STENCIL_INDEX] = "GL_STENCIL_INDEX"; + spInternalF[GL_DEPTH_COMPONENT] = "GL_DEPTH_COMPONENT"; + spInternalF[GL_DEPTH_STENCIL] = "GL_DEPTH_STENCIL"; + spInternalF[GL_DEPTH_COMPONENT16] = "GL_DEPTH_COMPONENT16"; + spInternalF[GL_DEPTH_COMPONENT24] = "GL_DEPTH_COMPONENT24"; + spInternalF[GL_DEPTH_COMPONENT32] = "GL_DEPTH_COMPONENT32"; + spInternalF[GL_DEPTH_COMPONENT32F] = "GL_DEPTH_COMPONENT32F"; + spInternalF[GL_DEPTH24_STENCIL8] = "GL_DEPTH24_STENCIL8"; + spInternalF[GL_DEPTH32F_STENCIL8] = "GL_DEPTH32F_STENCIL8"; + spInternalF[GL_RED_INTEGER] = "GL_RED_INTEGER"; + spInternalF[GL_GREEN_INTEGER] = "GL_GREEN_INTEGER"; + spInternalF[GL_BLUE_INTEGER] = "GL_BLUE_INTEGER"; + + spInternalF[GL_RG_INTEGER] = "GL_RG_INTEGER"; + spInternalF[GL_RGB_INTEGER] = "GL_RGB_INTEGER"; + spInternalF[GL_RGBA_INTEGER] = "GL_RGBA_INTEGER"; + spInternalF[GL_BGR_INTEGER] = "GL_BGR_INTEGER"; + spInternalF[GL_BGRA_INTEGER] = "GL_BGRA_INTEGER"; + + spInternalF[GL_RED] = "GL_RED"; + spInternalF[GL_RG] = "GL_RG"; + spInternalF[GL_RGB] = "GL_RGB"; + spInternalF[GL_RGBA] = "GL_RGBA"; + spInternalF[GL_R3_G3_B2] = "GL_R3_G3_B2"; + spInternalF[GL_RGB2_EXT] = "GL_RGB2_EXT"; + spInternalF[GL_COMPRESSED_RED] = "GL_COMPRESSED_RED"; + spInternalF[GL_COMPRESSED_RG] = "GL_COMPRESSED_RG"; + spInternalF[GL_COMPRESSED_RGB] = "GL_COMPRESSED_RGB"; + spInternalF[GL_COMPRESSED_RGBA] = "GL_COMPRESSED_RGBA"; + spInternalF[GL_COMPRESSED_SRGB] = "GL_COMPRESSED_SRGB"; + spInternalF[GL_COMPRESSED_SRGB_ALPHA] = "GL_COMPRESSED_SRGB_ALPHA"; + spInternalF[GL_COMPRESSED_RED_RGTC1] = "GL_COMPRESSED_RED_RGTC1"; + spInternalF[GL_COMPRESSED_SIGNED_RED_RGTC1] = "GL_COMPRESSED_SIGNED_RED_RGTC1"; + spInternalF[GL_COMPRESSED_RG_RGTC2] = "GL_COMPRESSED_RG_RGTC2"; spInternalF[GL_RG] = "GL_RG"; + spInternalF[GL_COMPRESSED_SIGNED_RG_RGTC2] = "GL_COMPRESSED_SIGNED_RG_RGTC2"; + +#ifdef VSGL_VERSION_4_2 + spInternalF[GL_COMPRESSED_RGBA_BPTC_UNORM] = "GL_COMPRESSED_RGBA_BPTC_UNORM"; + spInternalF[GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM] = "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM"; + spInternalF[GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT] = "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT"; + spInternalF[GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT] = "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT"; +#endif + + spInternalF[GL_R8] = "GL_R8"; + spInternalF[GL_R16] = "GL_R16"; + spInternalF[GL_RG8] = "GL_RG8"; + spInternalF[GL_RG16] = "GL_RG16"; + spInternalF[GL_R16F] = "GL_R16F"; + spInternalF[GL_R32F] = "GL_R32F"; + spInternalF[GL_RG16F] = "GL_RG16F"; + spInternalF[GL_RG32F] = "GL_RG32F"; + spInternalF[GL_R8I] = "GL_R8I"; + spInternalF[GL_R8UI] = "GL_R8UI"; + spInternalF[GL_R16I] = "GL_R16I"; + spInternalF[GL_R16UI] = "GL_R16UI"; + spInternalF[GL_R32I] = "GL_R32I"; + spInternalF[GL_R32UI] = "GL_R32UI"; + spInternalF[GL_RG8I] = "GL_RG8I"; + spInternalF[GL_RG8UI] = "GL_RG8UI"; + spInternalF[GL_RG16I] = "GL_RG16I"; + spInternalF[GL_RG16UI] = "GL_RG16UI"; + spInternalF[GL_RG32I] = "GL_RG32I"; + spInternalF[GL_RG32UI] = "GL_RG32UI"; + spInternalF[GL_RGB_S3TC] = "GL_RGB_S3TC"; + spInternalF[GL_RGB4_S3TC] = "GL_RGB4_S3TC"; + spInternalF[GL_RGBA_S3TC] = "GL_RGBA_S3TC"; + spInternalF[GL_RGBA4_S3TC] = "GL_RGBA4_S3TC"; + spInternalF[GL_RGBA_DXT5_S3TC] = "GL_RGBA_DXT5_S3TC"; + spInternalF[GL_RGBA4_DXT5_S3TC] = "GL_RGBA4_DXT5_S3TC"; + spInternalF[GL_COMPRESSED_RGB_S3TC_DXT1_EXT] = "GL_COMPRESSED_RGB_S3TC_DXT1_EXT"; + spInternalF[GL_COMPRESSED_RGBA_S3TC_DXT1_EXT] = "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT"; + spInternalF[GL_COMPRESSED_RGBA_S3TC_DXT3_EXT] = "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT"; + spInternalF[GL_COMPRESSED_RGBA_S3TC_DXT5_EXT] = "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT"; + spInternalF[GL_R1UI_V3F_SUN] = "GL_R1UI_V3F_SUN"; + spInternalF[GL_R1UI_C4UB_V3F_SUN] = "GL_R1UI_C4UB_V3F_SUN"; + spInternalF[GL_R1UI_C3F_V3F_SUN] = "GL_R1UI_C3F_V3F_SUN"; + spInternalF[GL_R1UI_N3F_V3F_SUN] = "GL_R1UI_N3F_V3F_SUN"; + spInternalF[GL_R1UI_C4F_N3F_V3F_SUN] = "GL_R1UI_C4F_N3F_V3F_SUN"; + spInternalF[GL_R1UI_T2F_V3F_SUN] = "GL_R1UI_T2F_V3F_SUN"; + spInternalF[GL_R1UI_T2F_N3F_V3F_SUN] = "GL_R1UI_T2F_N3F_V3F_SUN"; + spInternalF[GL_R1UI_T2F_C4F_N3F_V3F_SUN] = "GL_R1UI_T2F_C4F_N3F_V3F_SUN"; + spInternalF[GL_RGB_SIGNED_SGIX] = "GL_RGB_SIGNED_SGIX"; + spInternalF[GL_RGBA_SIGNED_SGIX] = "GL_RGBA_SIGNED_SGIX"; + spInternalF[GL_RGB16_SIGNED_SGIX] = "GL_RGB16_SIGNED_SGIX"; + spInternalF[GL_RGBA16_SIGNED_SGIX] = "GL_RGBA16_SIGNED_SGIX"; + spInternalF[GL_RGB_EXTENDED_RANGE_SGIX] = "GL_RGB_EXTENDED_RANGE_SGIX"; + spInternalF[GL_RGBA_EXTENDED_RANGE_SGIX] = "GL_RGBA_EXTENDED_RANGE_SGIX"; + spInternalF[GL_RGB16_EXTENDED_RANGE_SGIX] = "GL_RGB16_EXTENDED_RANGE_SGIX"; + spInternalF[GL_RGBA16_EXTENDED_RANGE_SGIX] = "GL_RGBA16_EXTENDED_RANGE_SGIX"; + spInternalF[GL_COMPRESSED_RGB_FXT1_3DFX] = "GL_COMPRESSED_RGB_FXT1_3DFX"; + spInternalF[GL_COMPRESSED_RGBA_FXT1_3DFX] = "GL_COMPRESSED_RGBA_FXT1_3DFX"; + spInternalF[GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV] = "GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV"; + spInternalF[GL_RGBA_FLOAT_MODE_ARB] = "GL_RGBA_FLOAT_MODE_ARB"; + spInternalF[GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI] = "GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI"; + spInternalF[GL_RGB_422_APPLE] = "GL_RGB_422_APPLE"; + spInternalF[GL_RGBA_SIGNED_COMPONENTS_EXT] = "GL_RGBA_SIGNED_COMPONENTS_EXT"; + spInternalF[GL_COMPRESSED_SRGB_S3TC_DXT1_EXT] = "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT"; + spInternalF[GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT] = "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT"; + spInternalF[GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT] = "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT"; + spInternalF[GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT] = "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT"; + spInternalF[GL_COMPRESSED_LUMINANCE_LATC1_EXT] = "GL_COMPRESSED_LUMINANCE_LATC1_EXT"; + spInternalF[GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT] = "GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT"; + spInternalF[GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT] = "GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT"; + spInternalF[GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT] = "GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT"; + spInternalF[GL_RGBA_INTEGER_MODE_EXT] = "GL_RGBA_INTEGER_MODE_EXT"; + spInternalF[GL_COMPRESSED_RGBA_BPTC_UNORM_ARB] = "GL_COMPRESSED_RGBA_BPTC_UNORM_ARB"; + spInternalF[GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB] = "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB"; + spInternalF[GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB] = "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB"; + spInternalF[GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB] = "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB"; + spInternalF[GL_RG_SNORM] = "GL_RG_SNORM"; + spInternalF[GL_RGB_SNORM] = "GL_RGB_SNORM"; + spInternalF[GL_RGBA_SNORM] = "GL_RGBA_SNORM"; + spInternalF[GL_R8_SNORM] = "GL_R8_SNORM"; + spInternalF[GL_RG8_SNORM] = "GL_RG8_SNORM"; + spInternalF[GL_RGB8_SNORM] = "GL_RGB8_SNORM"; + spInternalF[GL_RGBA8_SNORM] = "GL_RGBA8_SNORM"; + spInternalF[GL_R16_SNORM] = "GL_R16_SNORM"; + spInternalF[GL_RG16_SNORM] = "GL_RG16_SNORM"; + spInternalF[GL_RGB16_SNORM] = "GL_RGB16_SNORM"; + spInternalF[GL_RGBA16_SNORM] = "GL_RGBA16_SNORM"; + spInternalF[GL_RGB10_A2UI] = "GL_RGB10_A2UI"; + + return true; +} + + +// aux function to display float based uniforms +void +VSGLInfoLib::displayUniformf(float *f, int rows, int columns) { + + for (int i = 0; i < rows; ++i) { + if (columns == 1) + addMessage("%f", f[i*columns]); + else if (columns == 2) + addMessage("%f %f", f[i*columns], f[i*columns+1]); + else if (columns == 3) + addMessage("%f %f %f", f[i*columns], f[i*columns+1], f[i*columns+2]); + else if (columns == 4) + addMessage("%f %f %f %f", f[i*columns], f[i*columns+1], f[i*columns+2], f[i*columns+3]); + } +} + + +// aux function to display int based uniforms +void +VSGLInfoLib::displayUniformi(int *f, int rows, int columns) { + + for (int i = 0; i < rows; ++i) { + if (columns == 1) + addMessage("%d", f[i*columns]); + else if (columns == 2) + addMessage("%d %d", f[i*columns], f[i*columns+1]); + else if (columns == 3) + addMessage("%d %d %d", f[i*columns], f[i*columns+1], f[i*columns+2]); + else if (columns == 4) + addMessage("%d %d %d %d", f[i*columns], f[i*columns+1], f[i*columns+2], f[i*columns+3]); + } +} + + +// aux function to display unsigned int based uniforms +void +VSGLInfoLib::displayUniformui(unsigned int *f, int rows, int columns) { + + for (int i = 0; i < rows; ++i) { + if (columns == 1) + addMessage("%u", f[i*columns]); + else if (columns == 2) + addMessage("%u %u", f[i*columns], f[i*columns+1]); + else if (columns == 3) + addMessage("%u %u %u", f[i*columns], f[i*columns+1], f[i*columns+2]); + else if (columns == 4) + addMessage("%u %u %u %u", f[i*columns], f[i*columns+1], f[i*columns+2], f[i*columns+3]); + } +} + + +// aux function to display double based uniforms +void +VSGLInfoLib::displayUniformd(double *f, int rows, int columns) { + + for (int i = 0; i < rows; ++i) { + if (columns == 1) + addMessage("%f", f[i*columns]); + else if (columns == 2) + addMessage("%f %f", f[i*columns], f[i*columns+1]); + else if (columns == 3) + addMessage("%f %f %f", f[i*columns], f[i*columns+1], f[i*columns+2]); + else if (columns == 4) + addMessage("%f %f %f %f", f[i*columns], f[i*columns+1], f[i*columns+2], f[i*columns+3]); + } + +} + + +// gets the atomic data type +VSGLInfoLib::Types +VSGLInfoLib::getType(GLenum type) { + + switch (type) { + case GL_DOUBLE: + case GL_DOUBLE_MAT2: + case GL_DOUBLE_MAT2x3: + case GL_DOUBLE_MAT2x4: + case GL_DOUBLE_MAT3: + case GL_DOUBLE_MAT3x2: + case GL_DOUBLE_MAT3x4: + case GL_DOUBLE_MAT4: + case GL_DOUBLE_MAT4x2: + case GL_DOUBLE_MAT4x3: + case GL_DOUBLE_VEC2: + case GL_DOUBLE_VEC3: + case GL_DOUBLE_VEC4: + return VSGLInfoLib::DOUBLE; + case GL_FLOAT: + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT2x3: + case GL_FLOAT_MAT2x4: + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT3x2: + case GL_FLOAT_MAT3x4: + case GL_FLOAT_MAT4: + case GL_FLOAT_MAT4x2: + case GL_FLOAT_MAT4x3: + case GL_FLOAT_VEC2: + case GL_FLOAT_VEC3: + case GL_FLOAT_VEC4: + return VSGLInfoLib::FLOAT; + case GL_BOOL: + case GL_BOOL_VEC2: + case GL_BOOL_VEC3: + case GL_BOOL_VEC4: + case GL_INT: + case GL_INT_SAMPLER_1D: + case GL_INT_SAMPLER_1D_ARRAY: + case GL_INT_SAMPLER_2D: + case GL_INT_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_MULTISAMPLE: + case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_INT_SAMPLER_2D_RECT: + case GL_INT_SAMPLER_3D: + case GL_INT_SAMPLER_BUFFER: + case GL_INT_SAMPLER_CUBE: + case GL_INT_VEC2: + case GL_INT_VEC3: + case GL_INT_VEC4: + case GL_SAMPLER_1D: + case GL_SAMPLER_1D_ARRAY: + case GL_SAMPLER_1D_ARRAY_SHADOW: + case GL_SAMPLER_1D_SHADOW: + case GL_SAMPLER_2D: + case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_ARRAY_SHADOW: + case GL_SAMPLER_2D_MULTISAMPLE: + case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_SAMPLER_2D_RECT: + case GL_SAMPLER_2D_RECT_SHADOW: + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_3D: + case GL_SAMPLER_BUFFER: + case GL_SAMPLER_CUBE: + case GL_SAMPLER_CUBE_SHADOW: + return VSGLInfoLib::INT; + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_SAMPLER_1D: + case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D: + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_RECT: + case GL_UNSIGNED_INT_SAMPLER_3D: + case GL_UNSIGNED_INT_SAMPLER_BUFFER: + case GL_UNSIGNED_INT_SAMPLER_CUBE: + case GL_UNSIGNED_INT_VEC2: + case GL_UNSIGNED_INT_VEC3: + case GL_UNSIGNED_INT_VEC4: + return VSGLInfoLib::UNSIGNED_INT; + + default: + return VSGLInfoLib::DONT_KNOW; + + } +} + + +// gets the number of rows for a GLSL type +int +VSGLInfoLib::getRows(GLenum type) { + + switch(type) { + case GL_DOUBLE_MAT2: + case GL_DOUBLE_MAT2x3: + case GL_DOUBLE_MAT2x4: + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT2x3: + case GL_FLOAT_MAT2x4: + return 2; + + case GL_DOUBLE_MAT3: + case GL_DOUBLE_MAT3x2: + case GL_DOUBLE_MAT3x4: + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT3x2: + case GL_FLOAT_MAT3x4: + return 3; + + case GL_DOUBLE_MAT4: + case GL_DOUBLE_MAT4x2: + case GL_DOUBLE_MAT4x3: + case GL_FLOAT_MAT4: + case GL_FLOAT_MAT4x2: + case GL_FLOAT_MAT4x3: + return 4; + + default: return 1; + } +} + + +// gets the number of columns for a GLSL type +int +VSGLInfoLib::getColumns(GLenum type) { + + switch(type) { + case GL_DOUBLE_MAT2: + case GL_FLOAT_MAT2: + case GL_DOUBLE_MAT3x2: + case GL_FLOAT_MAT3x2: + case GL_DOUBLE_MAT4x2: + case GL_FLOAT_MAT4x2: + case GL_UNSIGNED_INT_VEC2: + case GL_INT_VEC2: + case GL_BOOL_VEC2: + case GL_FLOAT_VEC2: + case GL_DOUBLE_VEC2: + return 2; + + case GL_DOUBLE_MAT2x3: + case GL_FLOAT_MAT2x3: + case GL_DOUBLE_MAT3: + case GL_FLOAT_MAT3: + case GL_DOUBLE_MAT4x3: + case GL_FLOAT_MAT4x3: + case GL_UNSIGNED_INT_VEC3: + case GL_INT_VEC3: + case GL_BOOL_VEC3: + case GL_FLOAT_VEC3: + case GL_DOUBLE_VEC3: + return 3; + + case GL_DOUBLE_MAT2x4: + case GL_FLOAT_MAT2x4: + case GL_DOUBLE_MAT3x4: + case GL_FLOAT_MAT3x4: + case GL_DOUBLE_MAT4: + case GL_FLOAT_MAT4: + case GL_UNSIGNED_INT_VEC4: + case GL_INT_VEC4: + case GL_BOOL_VEC4: + case GL_FLOAT_VEC4: + case GL_DOUBLE_VEC4: + return 4; + + default: return 1; + } +} + + +// aux function to get the size in bytes of a uniform +// it takes the strides into account +int +VSGLInfoLib::getUniformByteSize(int uniSize, + int uniType, + int uniArrayStride, + int uniMatStride) { + + int auxSize; + if (uniArrayStride > 0) + auxSize = uniArrayStride * uniSize; + + else if (uniMatStride > 0) { + + switch(uniType) { + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT2x3: + case GL_FLOAT_MAT2x4: + case GL_DOUBLE_MAT2: + case GL_DOUBLE_MAT2x3: + case GL_DOUBLE_MAT2x4: + auxSize = 2 * uniMatStride; + break; + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT3x2: + case GL_FLOAT_MAT3x4: + case GL_DOUBLE_MAT3: + case GL_DOUBLE_MAT3x2: + case GL_DOUBLE_MAT3x4: + auxSize = 3 * uniMatStride; + break; + case GL_FLOAT_MAT4: + case GL_FLOAT_MAT4x2: + case GL_FLOAT_MAT4x3: + case GL_DOUBLE_MAT4: + case GL_DOUBLE_MAT4x2: + case GL_DOUBLE_MAT4x3: + auxSize = 4 * uniMatStride; + break; + } + } + else + auxSize = spGLSLTypeSize[uniType]; + + return auxSize; +} + + diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsGLInfoLib.h b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsGLInfoLib.h new file mode 100644 index 0000000..f5586d3 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsGLInfoLib.h @@ -0,0 +1,161 @@ +/** ---------------------------------------------------------- + * \class VSGLInfoLib + * + * Lighthouse3D + * + * VSGLInfoLib - Very Simple GL Information Library + * + * + * \version 0.1.0 + * - Initial Release + * + * This class provides information about GL stuff + * + * Full documentation at + * http://www.lighthouse3d.com/very-simple-libs + * + ---------------------------------------------------------------*/ + +#ifndef __VSGLIL__ +#define __VSGLIL__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#ifdef _WIN32 +#pragma comment(lib,"glew32.lib") +#endif + + +class VSGLInfoLib { + +#define VSGL_VERSION_4_1 +#undef VSGL_VERSION_4_2 + +public: + /// sets the output stream for the messages + // if null, cout is used + static void setOutputStream(std::ostream *outStream); + + /// get vendor, version and other general info + static void getGeneralInfo(); + + /// checks if an extension is supported + static bool isExtensionSupported(std::string extName); + + + // Buffers + /// returns a vector with all named buffers + static std::vector &getBufferNames(); + /// display current binded buffer info + static void getCurrentBufferInfo(); + /// display the buffer information + static void getBufferInfo(GLenum target, int bufferName); + + + // Textures + /// returns a vector with all named textures + static std::vector &getTextureNames(); + /// get the current texture bound to target + static int getCurrentTexture(GLenum textureTarget); + /// get active texture unit + static int getCurrentTextureActiveUnitInfo(); + /// display current texture bindings + static void getCurrentTextureInfo(); + /// display detailed texture info + static void getTextureInfo(GLenum textureTarget, GLenum textureID); + + + // GLSL + /// returns a vector with all named programs + static std::vector &getProgramNames(); + /// returns a vector with all named shaders + static std::vector &getShaderNames(); + /// returns a vector with all named VAOs + static std::vector &getVAONames(); + /// display detailed VAO info + static void getVAOInfo(unsigned int buffer); + /// display detailed info for uniforms in a program + static void getUniformsInfo(unsigned int program); + /// display a uniform's value(s) + static void getUniformInfo(unsigned int program, + std::string uniName); + /// display the values for a uniform in a named block + static void getUniformInBlockInfo(unsigned int program, + std::string blockName, + std::string uniName); + /// display detailed info for attributes in a program + static void getAttributesInfo(unsigned int program); + /// display detailed info for a program + static void getProgramInfo(unsigned int program); + + +private: + + // automatic init + static bool init(); + + enum Types { + DONT_KNOW, INT, UNSIGNED_INT, FLOAT, DOUBLE}; + + static void addMessage(std::string format, ...); + static void addNewLine(); + + static bool __spInit; + static std::ostream *spOutS; + + static char spAux[256]; + + static std::vector spResult; + + static std::map spInternalF; + static std::map spDataF; + static std::map spTextureDataType; + static std::map spGLSLType; + static std::map spTextureFilter; + static std::map spGLSLTypeSize; + static std::map spTextureWrap; + static std::map spTextureCompFunc; + static std::map spTextureCompMode; + static std::map spTextureUnit; + static std::map spHint; + static std::map spTextureTarget; + static std::map spBufferAccess; + static std::map spBufferUsage; + static std::map spBufferBinding; + static std::map spTextureBound; + static std::map spBufferBound; + static std::map spBoundBuffer; + static std::map spShaderType; + static std::map spTransFeedBufferMode; + static std::map spGLSLPrimitives; + static std::map spShaderPrecision; + + static std::map spTessGenSpacing; + static std::map spVertexOrder; + + + VSGLInfoLib(); + ~VSGLInfoLib(); + + + static Types getType(GLenum type); + static int getRows(GLenum type); + static int getColumns(GLenum type); + static void displayUniformf(float *f, int rows, int columns); + static void displayUniformi(int *f, int rows, int columns); + static void displayUniformui(unsigned int *f, int rows, int columns); + static void displayUniformd(double *f, int rows, int columns); + static int getUniformByteSize(int size, int uniType, int arrayStride, int matStride); +}; + + +#endif \ No newline at end of file diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsLogLib.cpp b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsLogLib.cpp new file mode 100644 index 0000000..fb9cfe5 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsLogLib.cpp @@ -0,0 +1,99 @@ +/** ---------------------------------------------------------- + * \class VSLogLib + * + * Lighthouse3D + * + * VSLogLib - Very Simple Log Library + * + * \version 0.1.0 + * Initial Release + * + * This class provides a basic logging mechanism + * + * Full documentation at + * http://www.lighthouse3d.com/very-simple-libs + * + ---------------------------------------------------------------*/ + +#include "vsLogLib.h" + + +VSLogLib::VSLogLib(): pStreamEnabled(false) { + +} + +// cleans up +VSLogLib::~VSLogLib() { + + pLogVector.clear(); +} + + +// clears the log +void +VSLogLib::clear() { + + pLogVector.clear(); +} + +// adds a message, printf style +void +VSLogLib::addMessage(std::string s, ...) { + + va_list args; + va_start(args,s); + vsnprintf( pAux, 256, s.c_str(), args ); + //vsprintf(pAux,s.c_str(), args); + va_end(args); + if (pStreamEnabled) + *pOuts << pAux << "\n"; + else + pLogVector.push_back(pAux); +} + +// dumps the log contents to a file +void +VSLogLib::dumpToFile(std::string filename) { + + std::ofstream file; + file.open(filename.c_str()); + + for (unsigned int i = 0; i < pLogVector.size(); ++i) { + file << pLogVector[i] << "\n"; + } + file.close(); +} + +// dumps the log contents to a string +std::string +VSLogLib::dumpToString() { + + pRes = ""; + + for (unsigned int i = 0; i < pLogVector.size(); ++i) { + + pRes += pLogVector[i] + "\n"; + } + + return pRes; +} + + +void +VSLogLib::disableStream() { + + pStreamEnabled = false; +} + + +void +VSLogLib::enableStream(std::ostream *outStream) { + + // set the output stream + if (!outStream) + pOuts = (std::iostream *)&std::cout; + else + pOuts = outStream; + + pStreamEnabled = true; +} \ No newline at end of file diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsLogLib.h b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsLogLib.h new file mode 100644 index 0000000..c962d17 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsLogLib.h @@ -0,0 +1,96 @@ +/** ---------------------------------------------------------- + * \class VSLogLib + * + * Lighthouse3D + * + * VSLogLib - Very Simple Log Library + * + * \version 0.2.0 + * - added streams + * - usage of a define makes it possible to remove all + * logging from the application easily + * + * \version 0.1.0 + * - Initial Release + * + * This class provides a basic logging mechanism + * + * Full documentation at + * http://www.lighthouse3d.com/very-simple-libs + * + ---------------------------------------------------------------*/ + +#ifndef __VSLogLib__ +#define __VSLogLib__ + +#ifndef VSL_MODE +#define VSL_DEBUG 1 +#define VSL_RELEASE 0 +// set this value to VS_RELEASE to disable logging +#define VSL_MODE VSL_DEBUG +#endif + +#include +#include +#include +#include +#include +#include + + +class VSLogLib { + +public: + + VSLogLib(); + ~VSLogLib(); + + /// set an output stream + void enableStream(std::ostream *outStream); + /// disable output stream, keep messages in the log + void disableStream(); + + /** Add a message, printf style + * \param format the same as the first parameter of printf + * \param ... the remaining params of printf + */ + void addMessage(std::string format, ...); + + /// Writes the log to a file + void dumpToFile(std::string filename); + + /// returns a string with the logs contents + std::string dumpToString(); + + /// clear the log + void clear(); + +private: + + /// The log itself + std::vector pLogVector; + /// just a string to return values + std::string pRes; + /// aux string to avoid malloc/dealloc + char pAux[256]; + /// the output stream + std::ostream *pOuts; + /// stream enabled status + bool pStreamEnabled; + +}; + +// This macro allow a simple usage of any log +// and when undefined it will remove all calls +// from the application +#if VSL_MODE == VSL_DEBUG +#define VSLOG(log, message, ...) \ +{\ + (log.addMessage(message, ## __VA_ARGS__));\ +}; +#else +#define VSLOG(log, message, ...) +#endif + + +#endif \ No newline at end of file diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsMathLib.cpp b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsMathLib.cpp new file mode 100644 index 0000000..284b924 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsMathLib.cpp @@ -0,0 +1,830 @@ +/* -------------------------------------------------- + +Lighthouse3D + +VSMathLib - Very Simple Matrix Library + +http://www.lighthouse3d.com/very-simple-libs + +----------------------------------------------------*/ + +#include "vsMathLib.h" +#include "vsShaderLib.h" +#include +#include +#include +#include + +// This var keeps track of the single instance of VSMathLib +VSMathLib* VSMathLib::gInstance = 0; + +#ifdef _WIN32 +#define M_PI 3.14159265358979323846f +#endif + +static inline float +DegToRad(float degrees) +{ + return (float)(degrees * (M_PI / 180.0f)); +}; + + +// Singleton implementation +// use this function to get the instance of VSMathLib +VSMathLib* +VSMathLib::getInstance (void) { + + if (0 != gInstance) + return gInstance; + else + gInstance = new VSMathLib(); + + return gInstance; +} + + +// VSMathLib constructor +VSMathLib::VSMathLib(): + mInit(false), + mBlocks(false) +{ + // set all uniform names to "" + for (int i = 0; i < COUNT_MATRICES; ++i) { + mUniformName[i] = ""; + mUniformArrayIndex[i] = 0; + } + for (int i = 0; i < COUNT_COMPUTED_MATRICES; ++i) { + mComputedMatUniformName[i] = ""; + mComputedMatUniformArrayIndex[i] = 0; + } +} + + +// VSMathLib destructor +VSMathLib::~VSMathLib() +{ +} + + +void +VSMathLib::setUniformBlockName(std::string blockName) { + + mInit = true; + // We ARE using blocks + mBlocks = true; + mBlockName = blockName; +} + + +void +VSMathLib::setUniformName(MatrixTypes matType, std::string uniformName) { + + mInit = true; + mUniformName[matType] = uniformName; + mUniformArrayIndex[matType] = 0; +} + + +void +VSMathLib::setUniformName(ComputedMatrixTypes matType, std::string uniformName) { + + mInit = true; + mComputedMatUniformName[matType] = uniformName; + mComputedMatUniformArrayIndex[matType] = 0; +} + + +void +VSMathLib::setUniformArrayIndexName(MatrixTypes matType, + std::string uniformName, int index) { + + mInit = true; + mUniformName[matType] = uniformName; + mUniformArrayIndex[matType] = index; +} + + +void +VSMathLib::setUniformArrayIndexName(ComputedMatrixTypes matType, + std::string uniformName, int index) { + + mInit = true; + mComputedMatUniformName[matType] = uniformName; + mComputedMatUniformArrayIndex[matType] = index; +} + + +// glPushMatrix implementation +void +VSMathLib::pushMatrix(MatrixTypes aType) { + + float *aux = (float *)malloc(sizeof(float) * 16); + memcpy(aux, mMatrix[aType], sizeof(float) * 16); + mMatrixStack[aType].push_back(aux); +} + + +// glPopMatrix implementation +void +VSMathLib::popMatrix(MatrixTypes aType) { + + float *m = mMatrixStack[aType][mMatrixStack[aType].size()-1]; + memcpy(mMatrix[aType], m, sizeof(float) * 16); + mMatrixStack[aType].pop_back(); + free(m); +} + + +// glLoadIdentity implementation +void +VSMathLib::loadIdentity(MatrixTypes aType) +{ + setIdentityMatrix(mMatrix[aType]); +} + + +// glMultMatrix implementation +void +VSMathLib::multMatrix(MatrixTypes aType, float *aMatrix) +{ + + float *a, *b, res[16]; + a = mMatrix[aType]; + b = aMatrix; + + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + res[j*4 + i] = 0.0f; + for (int k = 0; k < 4; ++k) { + res[j*4 + i] += a[k*4 + i] * b[j*4 + k]; + } + } + } + memcpy(mMatrix[aType], res, 16 * sizeof(float)); +} + + + + +// glLoadMatrix implementation +void +VSMathLib::loadMatrix(MatrixTypes aType, float *aMatrix) +{ + memcpy(mMatrix[aType], aMatrix, 16 * sizeof(float)); +} + + +// glTranslate implementation with matrix selection +void +VSMathLib::translate(MatrixTypes aType, float x, float y, float z) +{ + float mat[16]; + + setIdentityMatrix(mat); + mat[12] = x; + mat[13] = y; + mat[14] = z; + + multMatrix(aType,mat); +} + + +// glTranslate on the MODEL matrix +void +VSMathLib::translate(float x, float y, float z) +{ + translate(MODEL, x,y,z); +} + + +// glScale implementation with matrix selection +void +VSMathLib::scale(MatrixTypes aType, float x, float y, float z) +{ + float mat[16]; + + setIdentityMatrix(mat,4); + mat[0] = x; + mat[5] = y; + mat[10] = z; + + multMatrix(aType,mat); +} + + +// glScale on the MODELVIEW matrix +void +VSMathLib::scale(float x, float y, float z) +{ + scale(MODEL, x, y, z); +} + + +// glRotate implementation with matrix selection +void +VSMathLib::rotate(MatrixTypes aType, float angle, float x, float y, float z) +{ + float mat[16]; + + float radAngle = DegToRad(angle); + float co = cos(radAngle); + float si = sin(radAngle); + float x2 = x*x; + float y2 = y*y; + float z2 = z*z; + + mat[0] = x2 + (y2 + z2) * co; + mat[4] = x * y * (1 - co) - z * si; + mat[8] = x * z * (1 - co) + y * si; + mat[12]= 0.0f; + + mat[1] = x * y * (1 - co) + z * si; + mat[5] = y2 + (x2 + z2) * co; + mat[9] = y * z * (1 - co) - x * si; + mat[13]= 0.0f; + + mat[2] = x * z * (1 - co) - y * si; + mat[6] = y * z * (1 - co) + x * si; + mat[10]= z2 + (x2 + y2) * co; + mat[14]= 0.0f; + + mat[3] = 0.0f; + mat[7] = 0.0f; + mat[11]= 0.0f; + mat[15]= 1.0f; + + multMatrix(aType,mat); +} + + +// glRotate implementation in the MODELVIEW matrix +void +VSMathLib::rotate(float angle, float x, float y, float z) +{ + rotate(MODEL,angle,x,y,z); +} + + +// gluLookAt implementation +void +VSMathLib::lookAt(float xPos, float yPos, float zPos, + float xLook, float yLook, float zLook, + float xUp, float yUp, float zUp) +{ + float dir[3], right[3], up[3]; + + up[0] = xUp; up[1] = yUp; up[2] = zUp; + + dir[0] = (xLook - xPos); + dir[1] = (yLook - yPos); + dir[2] = (zLook - zPos); + normalize(dir); + + crossProduct(dir,up,right); + normalize(right); + + crossProduct(right,dir,up); + normalize(up); + + float m1[16],m2[16]; + + m1[0] = right[0]; + m1[4] = right[1]; + m1[8] = right[2]; + m1[12] = 0.0f; + + m1[1] = up[0]; + m1[5] = up[1]; + m1[9] = up[2]; + m1[13] = 0.0f; + + m1[2] = -dir[0]; + m1[6] = -dir[1]; + m1[10] = -dir[2]; + m1[14] = 0.0f; + + m1[3] = 0.0f; + m1[7] = 0.0f; + m1[11] = 0.0f; + m1[15] = 1.0f; + + setIdentityMatrix(m2,4); + m2[12] = -xPos; + m2[13] = -yPos; + m2[14] = -zPos; + + multMatrix(VIEW, m1); + multMatrix(VIEW, m2); +} + + +// gluPerspective implementation +void +VSMathLib::perspective(float fov, float ratio, float nearp, float farp) +{ + float projMatrix[16]; + + float f = 1.0f / tan (fov * (M_PI / 360.0f)); + + setIdentityMatrix(projMatrix,4); + + projMatrix[0] = f / ratio; + projMatrix[1 * 4 + 1] = f; + projMatrix[2 * 4 + 2] = (farp + nearp) / (nearp - farp); + projMatrix[3 * 4 + 2] = (2.0f * farp * nearp) / (nearp - farp); + projMatrix[2 * 4 + 3] = -1.0f; + projMatrix[3 * 4 + 3] = 0.0f; + + multMatrix(PROJECTION, projMatrix); +} + + +// glOrtho implementation +void +VSMathLib::ortho(float left, float right, + float bottom, float top, + float nearp, float farp) +{ + float m[16]; + + setIdentityMatrix(m,4); + + m[0 * 4 + 0] = 2 / (right - left); + m[1 * 4 + 1] = 2 / (top - bottom); + m[2 * 4 + 2] = -2 / (farp - nearp); + m[3 * 4 + 0] = -(right + left) / (right - left); + m[3 * 4 + 1] = -(top + bottom) / (top - bottom); + m[3 * 4 + 2] = -(farp + nearp) / (farp - nearp); + + multMatrix(PROJECTION, m); +} + + +// glFrustum implementation +void +VSMathLib::frustum(float left, float right, + float bottom, float top, + float nearp, float farp) +{ + float m[16]; + + setIdentityMatrix(m,4); + + m[0 * 4 + 0] = 2 * nearp / (right-left); + m[1 * 4 + 1] = 2 * nearp / (top - bottom); + m[2 * 4 + 0] = (right + left) / (right - left); + m[2 * 4 + 1] = (top + bottom) / (top - bottom); + m[2 * 4 + 2] = - (farp + nearp) / (farp - nearp); + m[2 * 4 + 3] = -1.0f; + m[3 * 4 + 2] = - 2 * farp * nearp / (farp-nearp); + m[3 * 4 + 3] = 0.0f; + + multMatrix(PROJECTION, m); +} + + +// returns a pointer to the requested matrix +float * +VSMathLib::get(MatrixTypes aType) +{ + return mMatrix[aType]; +} + + +// returns a pointer to the requested matrix +float * +VSMathLib::get(ComputedMatrixTypes aType) +{ + switch (aType) { + + case NORMAL: + computeNormalMatrix3x3(); + return mNormal3x3; + break; + default: + computeDerivedMatrix(aType); + return mCompMatrix[aType]; + break; + } + // this should never happen! + return NULL; +} + +/* ----------------------------------------------------- + SEND MATRICES TO OPENGL +------------------------------------------------------*/ + + + + +// universal +void +VSMathLib::matrixToGL(MatrixTypes aType) +{ + if (mInit) { + + if (mBlocks) { + if (mUniformName[aType] != "") { + if (mUniformArrayIndex[aType]) { + VSShaderLib::setBlockUniformArrayElement(mBlockName, + mUniformName[aType], + mUniformArrayIndex[aType], + mMatrix[aType]); + } + else { + VSShaderLib::setBlockUniform(mBlockName, + mUniformName[aType], + mMatrix[aType]); + } + } + } + else { + int p,loc; + if (mUniformName[aType] != "") { + glGetIntegerv(GL_CURRENT_PROGRAM,&p); + loc = glGetUniformLocation(p, mUniformName[aType].c_str()); + glProgramUniformMatrix4fv(p, loc, 1, false, mMatrix[aType]); + } + } + + } +} + +void +VSMathLib::matrixToGL(ComputedMatrixTypes aType) +{ + if (mInit) { + + if (mBlocks) { + if (aType == NORMAL && mComputedMatUniformName[NORMAL] != "") { + computeNormalMatrix(); + if (mComputedMatUniformArrayIndex[NORMAL]) + VSShaderLib::setBlockUniformArrayElement(mBlockName, + mComputedMatUniformName[NORMAL], + mComputedMatUniformArrayIndex[NORMAL], + mNormal); + else + VSShaderLib::setBlockUniform(mBlockName, + mComputedMatUniformName[NORMAL], + mNormal); + } + else if (mComputedMatUniformName[aType] != "") { + computeDerivedMatrix(aType); + if (mComputedMatUniformArrayIndex[aType]) + VSShaderLib::setBlockUniformArrayElement(mBlockName, + mComputedMatUniformName[aType], + mComputedMatUniformArrayIndex[aType], + mCompMatrix[aType]); + else + VSShaderLib::setBlockUniform(mBlockName, + mComputedMatUniformName[aType], + mCompMatrix[aType]); + } + } + } + else { + int p,loc; + if (mUniformName[aType] != "") { + glGetIntegerv(GL_CURRENT_PROGRAM,&p); + loc = glGetUniformLocation(p, mUniformName[aType].c_str()); + if (aType == NORMAL && mComputedMatUniformName[NORMAL] != "") { + computeNormalMatrix3x3(); + loc = glGetUniformLocation(p, + mComputedMatUniformName[NORMAL].c_str()); + glProgramUniformMatrix3fv(p, loc, 1, false, mNormal3x3); + } + else if (mComputedMatUniformName[aType] != "") { + computeDerivedMatrix(aType); + loc = glGetUniformLocation(p, + mComputedMatUniformName[aType].c_str()); + glProgramUniformMatrix4fv(p, loc, 1, false, mCompMatrix[aType]); + + } + } + + } +} + +// Sends all matrices whose respectived uniforms have been named +void +VSMathLib::matricesToGL() { + + if (mInit) { + + if (mBlocks) { + for (int i = 0 ; i < COUNT_MATRICES; ++i ) { + if (mUniformName[i] != "") + if (mUniformArrayIndex[i]) + VSShaderLib::setBlockUniformArrayElement(mBlockName, + mUniformName[i], + mUniformArrayIndex[i], + mMatrix[i]); + else + VSShaderLib::setBlockUniform(mBlockName, mUniformName[i], mMatrix[i]); + } + if (mComputedMatUniformName[NORMAL] != "") { + computeNormalMatrix(); + if (mComputedMatUniformArrayIndex[NORMAL]) + VSShaderLib::setBlockUniformArrayElement(mBlockName, + mComputedMatUniformName[NORMAL], + mComputedMatUniformArrayIndex[NORMAL], + mNormal); + else + VSShaderLib::setBlockUniform(mBlockName, + mComputedMatUniformName[NORMAL], + mNormal); + } + + for (int i = 0; i < COUNT_COMPUTED_MATRICES-1; ++i) { + + if (mComputedMatUniformName[i] != "") { + computeDerivedMatrix((VSMathLib::ComputedMatrixTypes)i); + if (mComputedMatUniformArrayIndex[i]) + VSShaderLib::setBlockUniformArrayElement(mBlockName, + mComputedMatUniformName[i], + mComputedMatUniformArrayIndex[i], + mCompMatrix[i]); + else + VSShaderLib::setBlockUniform(mBlockName, + mComputedMatUniformName[i], + mCompMatrix[i]); + } + } + } + else { + int p,loc; + glGetIntegerv(GL_CURRENT_PROGRAM,&p); + for (int i = 0; i < COUNT_MATRICES; ++i) { + if (mUniformName[i] != "") { + loc = glGetUniformLocation(p, mUniformName[i].c_str()); + glProgramUniformMatrix4fv(p, loc, 1, false, mMatrix[i]); + } + } + if (mComputedMatUniformName[NORMAL] != "") { + computeNormalMatrix3x3(); + loc = glGetUniformLocation(p, + mComputedMatUniformName[NORMAL].c_str()); + + glProgramUniformMatrix3fv(p, loc, 1, false, mNormal3x3); + } + for (int i = 0; i < COUNT_COMPUTED_MATRICES-1; ++i) { + if (mComputedMatUniformName[i] != "") { + computeDerivedMatrix((VSMathLib::ComputedMatrixTypes)i); + loc = glGetUniformLocation(p, + mComputedMatUniformName[i].c_str()); + glProgramUniformMatrix4fv(p, loc, 1, false, mCompMatrix[i]); + } + } + } + + } +} + +// ----------------------------------------------------- +// AUX functions +// ----------------------------------------------------- + +// sets the square matrix mat to the identity matrix, +// size refers to the number of rows (or columns) +void +VSMathLib::setIdentityMatrix( float *mat, int size) { + + // fill matrix with 0s + for (int i = 0; i < size * size; ++i) + mat[i] = 0.0f; + + // fill diagonal with 1s + for (int i = 0; i < size; ++i) + mat[i + i * size] = 1.0f; +} + + +// Compute res = M * point +void +VSMathLib::multMatrixPoint(MatrixTypes aType, float *point, float *res) { + + for (int i = 0; i < 4; ++i) { + + res[i] = 0.0f; + + for (int j = 0; j < 4; j++) { + + res[i] += point[j] * mMatrix[aType][j*4 + i]; + } + } +} + +// Compute res = M * point +void +VSMathLib::multMatrixPoint(ComputedMatrixTypes aType, float *point, float *res) { + + + if (aType == NORMAL) { + computeNormalMatrix(); + for (int i = 0; i < 3; ++i) { + + res[i] = 0.0f; + + for (int j = 0; j < 3; j++) { + + res[i] += point[j] * mNormal[j*4 + i]; + } + } + } + + else { + computeDerivedMatrix(aType); + for (int i = 0; i < 4; ++i) { + + res[i] = 0.0f; + + for (int j = 0; j < 4; j++) { + + res[i] += point[j] * mCompMatrix[aType][j*4 + i]; + } + } + } +} + +// res = a cross b; +void +VSMathLib::crossProduct( float *a, float *b, float *res) { + + res[0] = a[1] * b[2] - b[1] * a[2]; + res[1] = a[2] * b[0] - b[2] * a[0]; + res[2] = a[0] * b[1] - b[0] * a[1]; +} + + +// returns a . b +float +VSMathLib::dotProduct(float *a, float *b) { + + float res = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + + return res; +} + + +// Normalize a vec3 +void +VSMathLib::normalize(float *a) { + + float mag = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]); + + a[0] /= mag; + a[1] /= mag; + a[2] /= mag; +} + + +// res = a - b +void +VSMathLib::subtract(float *a, float *b, float *res) { + + res[0] = b[0] - a[0]; + res[1] = b[1] - a[1]; + res[2] = b[2] - a[2]; +} + + +// res = a + b +void +VSMathLib::add(float *a, float *b, float *res) { + + res[0] = b[0] + a[0]; + res[1] = b[1] + a[1]; + res[2] = b[2] + a[2]; +} + + +// returns |a| +float +VSMathLib::length(float *a) { + + return(sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2])); + +} + + +static inline int +M3(int i, int j) +{ + return (i*3+j); +}; + + +// computes the derived normal matrix +void +VSMathLib::computeNormalMatrix() { + + computeDerivedMatrix(VIEW_MODEL); + + mMat3x3[0] = mCompMatrix[VIEW_MODEL][0]; + mMat3x3[1] = mCompMatrix[VIEW_MODEL][1]; + mMat3x3[2] = mCompMatrix[VIEW_MODEL][2]; + + mMat3x3[3] = mCompMatrix[VIEW_MODEL][4]; + mMat3x3[4] = mCompMatrix[VIEW_MODEL][5]; + mMat3x3[5] = mCompMatrix[VIEW_MODEL][6]; + + mMat3x3[6] = mCompMatrix[VIEW_MODEL][8]; + mMat3x3[7] = mCompMatrix[VIEW_MODEL][9]; + mMat3x3[8] = mCompMatrix[VIEW_MODEL][10]; + + float det, invDet; + + det = mMat3x3[0] * (mMat3x3[4] * mMat3x3[8] - mMat3x3[5] * mMat3x3[7]) + + mMat3x3[1] * (mMat3x3[5] * mMat3x3[6] - mMat3x3[8] * mMat3x3[3]) + + mMat3x3[2] * (mMat3x3[3] * mMat3x3[7] - mMat3x3[4] * mMat3x3[6]); + + invDet = 1.0f/det; + + mNormal[0] = (mMat3x3[4] * mMat3x3[8] - mMat3x3[5] * mMat3x3[7]) * invDet; + mNormal[1] = (mMat3x3[5] * mMat3x3[6] - mMat3x3[8] * mMat3x3[3]) * invDet; + mNormal[2] = (mMat3x3[3] * mMat3x3[7] - mMat3x3[4] * mMat3x3[6]) * invDet; + mNormal[3] = 0.0f; + mNormal[4] = (mMat3x3[2] * mMat3x3[7] - mMat3x3[1] * mMat3x3[8]) * invDet; + mNormal[5] = (mMat3x3[0] * mMat3x3[8] - mMat3x3[2] * mMat3x3[6]) * invDet; + mNormal[6] = (mMat3x3[1] * mMat3x3[6] - mMat3x3[7] * mMat3x3[0]) * invDet; + mNormal[7] = 0.0f; + mNormal[8] = (mMat3x3[1] * mMat3x3[5] - mMat3x3[4] * mMat3x3[2]) * invDet; + mNormal[9] = (mMat3x3[2] * mMat3x3[3] - mMat3x3[0] * mMat3x3[5]) * invDet; + mNormal[10] =(mMat3x3[0] * mMat3x3[4] - mMat3x3[3] * mMat3x3[1]) * invDet; + mNormal[11] = 0.0; + +} + + +// computes the derived normal matrix +void +VSMathLib::computeNormalMatrix3x3() { + + computeDerivedMatrix(VIEW_MODEL); + + mMat3x3[0] = mCompMatrix[VIEW_MODEL][0]; + mMat3x3[1] = mCompMatrix[VIEW_MODEL][1]; + mMat3x3[2] = mCompMatrix[VIEW_MODEL][2]; + + mMat3x3[3] = mCompMatrix[VIEW_MODEL][4]; + mMat3x3[4] = mCompMatrix[VIEW_MODEL][5]; + mMat3x3[5] = mCompMatrix[VIEW_MODEL][6]; + + mMat3x3[6] = mCompMatrix[VIEW_MODEL][8]; + mMat3x3[7] = mCompMatrix[VIEW_MODEL][9]; + mMat3x3[8] = mCompMatrix[VIEW_MODEL][10]; + + float det, invDet; + + det = mMat3x3[0] * (mMat3x3[4] * mMat3x3[8] - mMat3x3[5] * mMat3x3[7]) + + mMat3x3[1] * (mMat3x3[5] * mMat3x3[6] - mMat3x3[8] * mMat3x3[3]) + + mMat3x3[2] * (mMat3x3[3] * mMat3x3[7] - mMat3x3[4] * mMat3x3[6]); + + invDet = 1.0f/det; + + mNormal3x3[0] = (mMat3x3[4] * mMat3x3[8] - mMat3x3[5] * mMat3x3[7]) * invDet; + mNormal3x3[1] = (mMat3x3[5] * mMat3x3[6] - mMat3x3[8] * mMat3x3[3]) * invDet; + mNormal3x3[2] = (mMat3x3[3] * mMat3x3[7] - mMat3x3[4] * mMat3x3[6]) * invDet; + mNormal3x3[3] = (mMat3x3[2] * mMat3x3[7] - mMat3x3[1] * mMat3x3[8]) * invDet; + mNormal3x3[4] = (mMat3x3[0] * mMat3x3[8] - mMat3x3[2] * mMat3x3[6]) * invDet; + mNormal3x3[5] = (mMat3x3[1] * mMat3x3[6] - mMat3x3[7] * mMat3x3[0]) * invDet; + mNormal3x3[6] = (mMat3x3[1] * mMat3x3[5] - mMat3x3[4] * mMat3x3[2]) * invDet; + mNormal3x3[7] = (mMat3x3[2] * mMat3x3[3] - mMat3x3[0] * mMat3x3[5]) * invDet; + mNormal3x3[8] = (mMat3x3[0] * mMat3x3[4] - mMat3x3[3] * mMat3x3[1]) * invDet; + +} + + +// Computes derived matrices +void +VSMathLib::computeDerivedMatrix(ComputedMatrixTypes aType) { + + memcpy(mCompMatrix[VIEW_MODEL], mMatrix[VIEW], 16 * sizeof(float)); + multMatrix(mCompMatrix[VIEW_MODEL], mMatrix[MODEL]); + + if (aType == PROJ_VIEW_MODEL) { + memcpy(mCompMatrix[PROJ_VIEW_MODEL], mMatrix[PROJECTION], 16 * sizeof(float)); + multMatrix(mCompMatrix[PROJ_VIEW_MODEL], mCompMatrix[VIEW_MODEL]); + } +} + + +// aux function resMat = resMat * aMatrix +void +VSMathLib::multMatrix(float *resMat, float *aMatrix) +{ + + float *a, *b, res[16]; + a = resMat; + b = aMatrix; + + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + res[j*4 + i] = 0.0f; + for (int k = 0; k < 4; ++k) { + res[j*4 + i] += a[k*4 + i] * b[j*4 + k]; + } + } + } + memcpy(a, res, 16 * sizeof(float)); +} \ No newline at end of file diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsMathLib.h b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsMathLib.h new file mode 100644 index 0000000..406c791 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsMathLib.h @@ -0,0 +1,403 @@ +/** ---------------------------------------------------------- + * \class VSMathLib + * + * Lighthouse3D + * + * VSMathLib - Very Simple Matrix Library + * + * Full documentation at + * http://www.lighthouse3d.com/very-simple-libs + * + * This class aims at easing geometric transforms, camera + * placement and projection definition for programmers + * working with OpenGL core versions. + * + * \version 0.2.1 + * Split MODELVIEW into MODEL and VIEW + * VIEW_MODEL is now a computed matrix + * Removed ALWAYS_SEND_TO_GL + * + * version 0.2.0 + * Added derived matrices + * Projection View Model + * Normal + * Added vector operations + * Library is now called vsMathLib + * + * version 0.1.1 + * Added multiplication of a matrix by a point + * Added AUX as a matrix type + * + * version 0.1.0 + * Initial Release + * + * This lib requires: + * External Dependencies + * GLEW (http://glew.sourceforge.net/) + * VSL Dependencies + * VSShaderLib (http://www.lighthouse3d.com/very-simple-libs) + * + ---------------------------------------------------------------*/ +#ifndef __VSMathLib__ +#define __VSMathLib__ + +#include +#include +#include + + +class VSMathLib { + + public: + /// number of settable matrices + #define COUNT_MATRICES 4 + /// number of derived matrices + #define COUNT_COMPUTED_MATRICES 3 + + + /// Enumeration of the matrix types + enum MatrixTypes{ + MODEL, + VIEW, + PROJECTION, + AUX0, + AUX1, + AUX2, + AUX3 + } ; + /// Enumeration of derived matrices + enum ComputedMatrixTypes { + VIEW_MODEL, + PROJ_VIEW_MODEL, + NORMAL + }; + + /// Singleton pattern + static VSMathLib* gInstance; + + /// Call this to get the single instance of VSMathLib + static VSMathLib* getInstance (void); + + ~VSMathLib(); + + + /** Call this function to init the library if using uniform blocks + * Uniform blocks are considered to be shaded amongst shaders + * + * \param blockName the name of the block + */ + void setUniformBlockName(std::string blockName); + + /** Call this function to init the library + * it associates the matrices with named uniforms + * + * \param matType the type of the matrix + * \param uniformName the name of the uniform variable + */ + void setUniformName(MatrixTypes matType, std::string uniformName); + + /** Call this function to init the library + * it associates the matrices with named uniforms in + * the case where they are stored in an array + * + * \param matType the type of the matrix + * \param uniformName the name of the uniform variable + * \param index the index of the array where the mat is located + */ + void setUniformArrayIndexName(MatrixTypes matType, + std::string uniformName, int index); + + /** Call this function to init the library + * it associates the matrices with named uniforms + * + * \param matType the type of the matrix + * \param uniformName the name of the uniform variable + */ + void setUniformName(ComputedMatrixTypes matType, + std::string uniformName); + + /** Call this function to init the library + * it associates the matrices with named uniforms in + * the case where they are stored in an array + * + * \param matType the type of the matrix + * \param uniformName the name of the uniform variable + * \param index the index of the array where the mat is located + */ + void setUniformArrayIndexName(ComputedMatrixTypes matType, + std::string uniformName, int index); + + /** Similar to glTranslate*. + * + * \param aType any value from MatrixTypes + * \param x,y,z vector to perform the translation + */ + void translate(MatrixTypes aType, float x, float y, float z); + + /** Similar to glTranslate*. Applied to MODELVIEW only. + * + * \param x,y,z vector to perform the translation + */ + void translate(float x, float y, float z); + + /** Similar to glScale*. + * + * \param aType any value from MatrixTypes + * \param x,y,z scale factors + */ + void scale(MatrixTypes aType, float x, float y, float z); + + /** Similar to glScale*. Applied to MODELVIEW only. + * + * \param x,y,z scale factors + */ + void scale(float x, float y, float z); + + /** Similar to glTotate*. + * + * \param aType any value from MatrixTypes + * \param angle rotation angle in degrees + * \param x,y,z rotation axis in degrees + */ + void rotate(MatrixTypes aType, float angle, float x, float y, float z); + + /** Similar to glRotate*. Applied to MODELVIEW only. + * + * \param angle rotation angle in degrees + * \param x,y,z rotation axis in degrees + */ + void rotate(float angle, float x, float y, float z); + + /** Similar to glLoadIdentity. + * + * \param aType any value from MatrixTypes + */ + void loadIdentity(MatrixTypes aType); + + /** Similar to glMultMatrix. + * + * \param aType any value from MatrixTypes + * \param aMatrix matrix in column major order data, float[16] + */ + void multMatrix(MatrixTypes aType, float *aMatrix); + + /** Similar to gLoadMatrix. + * + * \param aType any value from MatrixTypes + * \param aMatrix matrix in column major order data, float[16] + */ + + void loadMatrix(MatrixTypes aType, float *aMatrix); + + /** Similar to glPushMatrix + * + * \param aType any value from MatrixTypes + */ + void pushMatrix(MatrixTypes aType); + + /** Similar to glPopMatrix + * + * \param aType any value from MatrixTypes + */ + void popMatrix(MatrixTypes aType); + + /** Similar to gluLookAt + * + * \param xPos, yPos, zPos camera position + * \param xLook, yLook, zLook point to aim the camera at + * \param xUp, yUp, zUp camera's up vector + */ + void lookAt(float xPos, float yPos, float zPos, + float xLook, float yLook, float zLook, + float xUp, float yUp, float zUp); + + + /** Similar to gluPerspective + * + * \param fov vertical field of view + * \param ratio aspect ratio of the viewport or window + * \param nearp,farp distance to the near and far planes + */ + void perspective(float fov, float ratio, float nearp, float farp); + + /** Similar to glOrtho and gluOrtho2D (just leave the + * last two params blank). + * + * \param left,right coordinates for the left and right vertical + * clipping planes + * \param bottom,top coordinates for the bottom and top horizontal + * clipping planes + * \param nearp,farp distance to the near and far planes + */ + void ortho(float left, float right, float bottom, float top, + float nearp=-1.0f, float farp=1.0f); + + /** Similar to glFrustum + * + * \param left,right coordinates for the left and right vertical + * clipping planes + * \param bottom,top coordinates for the bottom and top horizontal + * clipping planes + * \param nearp,farp distance to the near and far planes + */ + void frustum(float left, float right, float bottom, float top, + float nearp, float farp); + + /** Similar to glGet + * + * \param aType any value from MatrixTypes + * \returns pointer to the matrix (float[16]) + */ + float *get(MatrixTypes aType); + + /** Similar to glGet for computed matrices + * + * \param aType any value from ComputedMatrixTypes + * \returns pointer to the matrix (float[16]) + */ + float *get(ComputedMatrixTypes aType); + + /** Updates the uniform buffer data + * + * \param aType any value from MatrixTypes + */ + //void matrixToBuffer(MatrixTypes aType); + + ///** Updates the uniform variables + // * + // * \param aType any value from MatrixTypes + //*/ + //void matrixToUniform(MatrixTypes aType); + + /** Updates either the buffer or the uniform variables + * based on if the block name has been set + * + * \param aType any value from MatrixTypes + */ + void matrixToGL(MatrixTypes aType); + + /** Updates either the buffer or the uniform variables + * based on if the block name has been set + * + * \param aType any value from ComputedMatrixTypes + */ + void matrixToGL(ComputedMatrixTypes aType); + + + /** Updates either the buffer or the uniform variables + * based on if the block name has been set. It updates + * all matrices whose uniform names have been provided + */ + void matricesToGL(); + + + /** Computes the multiplication of a matrix and a point + * + * \param aType any value from MatrixTypes + * \param point a float[4] representing a point + * \param res a float[4] res = M * point + */ + void multMatrixPoint(MatrixTypes aType, float *point, float *res); + + /** Computes the multiplication of a computed matrix and a point + * + * \param aType any value from ComputedMatrixTypes + * \param point a float[4] representing a point + * \param res a float[4] res = M * point + */ + void multMatrixPoint(ComputedMatrixTypes aType, float *point, float *res); + + /** vector cross product res = a x b + * Note: memory for the result must be allocatted by the caller + * + * \param a,b the two input float[3] + * \param res the ouput result, a float[3] + */ + static void crossProduct( float *a, float *b, float *res); + + /** vector dot product + * + * \param a,b the two input float[3] + * \returns the dot product a.b + */ + static float dotProduct(float *a, float * b); + + /// normalize a vec3 + static void normalize(float *a); + + /// vector subtraction res = a - b + static void subtract( float *a, float *b, float *res); + + /// vector addition res = a + b + static void add( float *a, float *b, float *res); + + /// vector length + static float length(float *a); + + protected: + + VSMathLib(); + + /// aux variable to hold the result of vector ops + float mPointRes[4]; + + /// Has an init* function been called? + bool mInit; + + /// Using uniform blocks? + bool mBlocks; + + /// Matrix stacks for all matrix types + std::vector mMatrixStack[COUNT_MATRICES]; + + /// The storage for matrices + float mMatrix[COUNT_MATRICES][16]; + float mCompMatrix[COUNT_COMPUTED_MATRICES][16]; + + /// Stores the uniform block name + std::string mBlockName; + + /// Names of the associated uniform variables + std::string mUniformName[COUNT_MATRICES]; + int mUniformArrayIndex[COUNT_MATRICES]; + + /// Names of the associated uniform variables + std::string mComputedMatUniformName[COUNT_COMPUTED_MATRICES]; + int mComputedMatUniformArrayIndex[COUNT_COMPUTED_MATRICES]; + + /// The projection matrix + // float mProjModelView[16]; + /// The ViewModel matrix + // float mViewModel[16]; + + /// The normal matrix + float mNormal[12]; + float mNormal3x3[9]; + + /// aux 3x3 matrix + float mMat3x3[9]; + + // AUX FUNCTIONS + + /** Set a float* to an identity matrix + * + * \param a float array with the matrix contents + * \param size the order of the matrix + */ + void setIdentityMatrix( float *mat, int size=4); + + /// Computes the normal matrix based on the modelview matrix + void computeNormalMatrix(); + /// Computes the normal matrix for use with glUniform + void computeNormalMatrix3x3(); + + /// Computes Derived Matrices (4x4) + void computeDerivedMatrix(ComputedMatrixTypes aType); + + //resMatrix = resMatrix * aMatrix + void multMatrix(float *resMatrix, float *aMatrix); + + +}; + +#endif \ No newline at end of file diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsResourceLib.cpp b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsResourceLib.cpp new file mode 100644 index 0000000..547758e --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsResourceLib.cpp @@ -0,0 +1,285 @@ +/** ---------------------------------------------------------- + * \class VSResourceLib + * + * Lighthouse3D + * + * VSResourceLib - Very Simple Resource Library + * + * \version 0.1.1 + * Added virtual function load cubemaps + * Added virtual function to set a preloaded texture + * Added a virtual clone method + * + * \version 0.1.0 + * Initial Release + * + * This abstract class defines an interface + * for loading and rendering resources (models) + * +* This lib requires the following classes from VSL: + * (http://www.lighthouse3d.com/very-simple-libs) + * + * VSMathLib + * VSLogLib + * VSShaderLib + * + * and the following third party libs: + * + * GLEW (http://glew.sourceforge.net/), + * DevIL (http://openil.sourceforge.net/) + * + * Full documentation at + * http://www.lighthouse3d.com/very-simple-libs + * + ---------------------------------------------------------------*/ + +#include "vsResourceLib.h" + +GLenum VSResourceLib::faceTarget[6] = { + GL_TEXTURE_CUBE_MAP_POSITIVE_X, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z + }; + + +VSResourceLib::VSResourceLib(): mScaleToUnitCube(1.0) +{ + // get a pointer to VSMathLib singleton + mVSML = VSMathLib::getInstance(); + + /* initialization of DevIL */ + ilInit(); +} + + +VSResourceLib::~VSResourceLib() { + +} + + + + +// get the scale factor used to fit the model in a unit cube +float +VSResourceLib::getScaleForUnitCube() { + + return mScaleToUnitCube; +} + + +// Set the shader's material block name +void +VSResourceLib::setMaterialBlockName(std::string name) { + + mMaterialBlockName = name; +} + + +// useful to set uniforms inside a named block +void +VSResourceLib::setMaterial(Material &aMat) { + + // use named block + if (mMaterialBlockName != "" && mMatSemanticMap.size() == 0) { + VSShaderLib::setBlock(mMaterialBlockName, &aMat); + } + // use uniforms in named block + else if (mMaterialBlockName != "" && mMatSemanticMap.size() != 0) { + + std::map::iterator iter; + for (iter = mMatSemanticMap.begin(); iter != mMatSemanticMap.end(); ++iter) { + void *value; + switch ((*iter).second) { + case DIFFUSE: value = (void *)aMat.diffuse; + break; + case AMBIENT: value = (void *)aMat.ambient; + break; + case SPECULAR: value = (void *)aMat.specular; + break; + case EMISSIVE: value = (void *)aMat.emissive; + break; + case SHININESS: value = (void *)&aMat.shininess; + break; + case TEX_COUNT: value = (void *)&aMat.texCount; + break; + } + VSShaderLib::setBlockUniform(mMaterialBlockName, + (*iter).first, value); + } + } +} + + +void +VSResourceLib::setUniformSemantics(MaterialSemantics field, std::string name) { + + mMatSemanticMap[name] = field; +} + + +// Get loading errors +std::string +VSResourceLib::getErrors() { + + return(mLogError.dumpToString()); +} + + +// get model information +std::string +VSResourceLib::getInfo() { + + return(mLogInfo.dumpToString()); +} + + +// helper function for derived classes +// loads an image and defines an 8-bit RGBA texture +unsigned int +VSResourceLib::loadRGBATexture(std::string filename, + bool mipmap, bool compress, + GLenum aFilter, GLenum aRepMode) { + + ILboolean success; + unsigned int imageID; + GLuint textureID = 0; + + // Load Texture Map + ilGenImages(1, &imageID); + + ilBindImage(imageID); /* Binding of DevIL image name */ + ilEnable(IL_ORIGIN_SET); + ilOriginFunc(IL_ORIGIN_LOWER_LEFT); + success = ilLoadImage((ILstring)filename.c_str()); + + if (!success) { + VSLOG(mLogError, "Couldn't load texture: %s", + filename.c_str()); + // The operation was not sucessfull + // hence free image and texture + ilDeleteImages(1, &imageID); + return 0; + } + + /* Convert image to RGBA */ + ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); + // Set filters + GLenum minFilter = aFilter; + if (aFilter == GL_LINEAR && mipmap) { + minFilter = GL_LINEAR_MIPMAP_LINEAR; + } + else if (aFilter == GL_NEAREST && mipmap){ + minFilter = GL_NEAREST_MIPMAP_LINEAR; + } + GLenum type; + if (compress) + type = GL_RGBA; + else + type = GL_COMPRESSED_RGBA; + + + /* Create and load textures to OpenGL */ + glGenTextures(1, &textureID); /* Texture name generation */ + glBindTexture(GL_TEXTURE_2D, textureID); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aRepMode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aRepMode); + glTexImage2D(GL_TEXTURE_2D, 0, type, + ilGetInteger(IL_IMAGE_WIDTH), + ilGetInteger(IL_IMAGE_HEIGHT), + 0, GL_RGBA, GL_UNSIGNED_BYTE, + ilGetData()); + + // Mipmapping? + if (mipmap) + glGenerateMipmap(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D,0); + + /* Because we have already copied image data into texture data + we can release memory used by image. */ + ilDeleteImages(1, &imageID); + + // add information to the log + VSLOG(mLogInfo, "Texture Loaded: %s", filename.c_str()); + + return textureID; +} + + +// helper function for derived classes +// loads an image and defines an 8-bit RGBA texture +unsigned int +VSResourceLib::loadCubeMapTexture( std::string posX, std::string negX, + std::string posY, std::string negY, + std::string posZ, std::string negZ) { + + ILboolean success; + unsigned int imageID; + GLuint textureID = 0; + + std::string files[6]; + + files[0] = posX; + files[1] = negX; + files[2] = posY; + files[3] = negY; + files[4] = posZ; + files[5] = negZ; + + glGenTextures(1, &textureID); /* Texture name generation */ + glBindTexture(GL_TEXTURE_CUBE_MAP, textureID); + + // Load Textures for Cube Map + + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT); + + ilGenImages(1, &imageID); + ilBindImage(imageID); /* Binding of DevIL image name */ + + for (int i = 0; i < 6; ++i) { + ilEnable(IL_ORIGIN_SET); + ilOriginFunc(IL_ORIGIN_LOWER_LEFT); + success = ilLoadImage((ILstring)files[i].c_str()); + + if (!success) { + VSLOG(mLogError, "Couldn't load texture: %s", + files[i].c_str()); + // The operation was not sucessfull + // hence free image and texture + ilDeleteImages(1, &imageID); + return 0; + } + + /* Convert image to RGBA */ + ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); + + /* Create and load textures to OpenGL */ + glTexImage2D(faceTarget[i], 0, GL_RGBA, + ilGetInteger(IL_IMAGE_WIDTH), + ilGetInteger(IL_IMAGE_HEIGHT), + 0, GL_RGBA, GL_UNSIGNED_BYTE, + ilGetData()); + + VSLOG(mLogInfo, "Texture Loaded: %s", files[i].c_str()); + } + + VSLOG(mLogInfo, "Cube Map Loaded Successfully"); + + glBindTexture(GL_TEXTURE_CUBE_MAP,0); + + /* Because we have already copied image data into texture data + we can release memory used by image. */ + ilDeleteImages(1, &imageID); + + // add information to the log + + return textureID; +} diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsResourceLib.h b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsResourceLib.h new file mode 100644 index 0000000..1f42e3b --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsResourceLib.h @@ -0,0 +1,171 @@ +/** ---------------------------------------------------------- + * \class VSResourceLib + * + * Lighthouse3D + * + * VSResourceLib - Very Simple Resource Library + * + * \version 0.1.1 + * Added virtual function load cubemaps + * Added virtual function to set a preloaded texture + * Added a virtual clone method + * + * version 0.1.0 + * Initial Release + * + * This abstract class defines an interface + * for loading and rendering resources (models) + * + * This lib requires the following classes from VSL: + * (http://www.lighthouse3d.com/very-simple-libs) + * + * VSMathLib + * VSLogLib + * VSShaderLib + * + * and the following third party libs: + * + * GLEW (http://glew.sourceforge.net/), + * DevIL (http://openil.sourceforge.net/) + * + * Full documentation at + * http://www.lighthouse3d.com/very-simple-libs + * + ---------------------------------------------------------------*/ + +#ifndef __VSRL__ +#define __VSRL__ + +#include +#include +#include +#include + +#include + +// include DevIL for image loading +#include +#ifdef _WIN32 +#pragma comment(lib,"glew32.lib") +#pragma comment(lib,"devil.lib") +#endif + +// Include other VSL +// vsMathLib is required for rendering and matrix manipulation +#include "vsMathLib.h" +// vsLogLib is required for logging errors and model info +#include "vsLogLib.h" +// VSShaderLib is required to enable and set the +// semantic of the vertex arrays +#include "vsShaderLib.h" + + +class VSResourceLib { + +protected: + + /// helper structure for derived classes + struct Material{ + + float diffuse[4]; + float ambient[4]; + float specular[4]; + float emissive[4]; + float shininess; + int texCount; + }; + +public: + + /// material semantics + enum MaterialSemantics { + + DIFFUSE, + AMBIENT, + SPECULAR, + EMISSIVE, + SHININESS, + TEX_COUNT + }; + + VSResourceLib(); + ~VSResourceLib(); + + /** clones the resource - must be implemented + * by the subclasses to take effect + * \param res the instance to be cloned into this + */ + virtual void clone(VSResourceLib *res) {res = NULL;}; + + /// load the resource + virtual bool load(std::string filename) = 0; + + /// render the resource + virtual void render() = 0; + + /// virtual function to be implemented in derived classes + /// assigns a texture (from an image) to a unit + virtual void addTexture(unsigned int unit, std::string filename) {}; + virtual void addCubeMapTexture(unsigned int unit, + std::string posX, std::string negX, + std::string posY, std::string negY, + std::string posZ, std::string negZ) {}; + virtual void setTexture(unsigned int unit, unsigned int textureID, + GLenum textureType = GL_TEXTURE_2D) {}; + + /// Sets the shader's material block name + void setMaterialBlockName(std::string); + + /// set the semantics of the uniforms inside the named block + void setUniformSemantics(MaterialSemantics field, std::string); + + /// set the material uniforms + void setMaterial(Material &aMat); + + /// returns errors found when loading the resource + /// it is up to the derived classes to add meaningfull + /// information + virtual std::string getErrors(); + /// returns information about the loaded resource + /// it is up to the derived classes to add meaningfull + /// information + virtual std::string getInfo(); + + /// const to ease future upgrades + static const int MAX_TEXTURES = 8; + + /// returns the scale factor to display the model in a unit cube + /// note: may not apply to all subclasses + float getScaleForUnitCube(); + + +protected: + /// helper function for derived classes + unsigned int loadRGBATexture(std::string filename, bool mipmap = true, + bool compress = false, + GLenum aFilter = GL_LINEAR, GLenum aRepMode = GL_REPEAT); + unsigned int loadCubeMapTexture( std::string posX, std::string negX, + std::string posY, std::string negY, + std::string posZ, std::string negZ); + + std::map mMatSemanticMap; + + /// shader's material block name + std::string mMaterialBlockName; + + /// keep a pointer to VSMathLib singleton + VSMathLib *mVSML; + /// Logs for errors and model Information + VSLogLib mLogError, mLogInfo; + + /// center of the model + float mCenter[3]; + /// scale factor for the model to fill a unit cube (-1, 1) + float mScaleToUnitCube; + + static GLenum faceTarget[6]; + + +}; + +#endif diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsShaderLib.cpp b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsShaderLib.cpp new file mode 100644 index 0000000..3464bc0 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsShaderLib.cpp @@ -0,0 +1,876 @@ +/** ---------------------------------------------------------- + * \class VSShaderLib + * + * Lighthouse3D + * + * VSShaderLib - Very Simple Shader Library + * + * Full documentation at + * http://www.lighthouse3d.com/very-simple-libs + * + * This class aims at making life simpler + * when using shaders and uniforms + * + * \version 0.2.1 + * Added more attrib defs, namely + * tangents, bi tangents, and 4 custom + * + * version 0.2.0 + * Added methods to set uniforms + * Added methods to set blocks + * Renamed to VSShaderLib + * + * version 0.1.0 + * Initial Release + * + * This lib requires: + * + * GLEW (http://glew.sourceforge.net/) + * + ---------------------------------------------------------------*/ + +#include +#include + +#include "vsShaderLib.h" + +// pre conditions are established with asserts +// if having errors using the lib switch to Debug mode +#include + +GLenum +VSShaderLib::spGLShaderTypes[VSShaderLib::COUNT_SHADER_TYPE] = { + GL_VERTEX_SHADER, + GL_GEOMETRY_SHADER, + GL_TESS_CONTROL_SHADER, + GL_TESS_EVALUATION_SHADER, + GL_FRAGMENT_SHADER}; + + +std::string +VSShaderLib::spStringShaderTypes[VSShaderLib::COUNT_SHADER_TYPE] = { + "Vertex Shader", + "Geometry Shader", + "Tesselation Control Shader", + "Tesselation Evaluation Shader", + "Fragment Shader"}; + + +std::map VSShaderLib::spBlocks; + + +int VSShaderLib::spBlockCount = 1; + + +VSShaderLib::VSShaderLib(): pProgram(0), pInited(false) { + + for (int i = 0; i < VSShaderLib::COUNT_SHADER_TYPE; ++i) { + pShader[i] = 0; + } +} + + +VSShaderLib::~VSShaderLib() { + + if (pProgram) + glDeleteProgram(pProgram); + + for (int i = 0; i < VSShaderLib::COUNT_SHADER_TYPE; ++i) { + if (pShader[i]) + glDeleteShader(pShader[i]); + } + pUniforms.clear(); +} + + +void +VSShaderLib::init() { + + pInited = true; + pProgram = glCreateProgram(); +} + + +void +VSShaderLib::loadShader(VSShaderLib::ShaderType st, std::string fileName) { + + // init should always be called first + assert(pInited == true); + + char *s = NULL; + + s = textFileRead(fileName); + + if (s != NULL) { + const char * ss = s; + + pShader[st] = glCreateShader(spGLShaderTypes[st]); + glShaderSource(pShader[st], 1, &ss,NULL); + glAttachShader(pProgram, pShader[st]); + glCompileShader(pShader[st]); + + free(s); + } +} + + +void +VSShaderLib::prepareProgram() { + + glLinkProgram(pProgram); + addUniforms(); + addBlocks(); +} + + +void +VSShaderLib::setProgramOutput(int index, std::string name) { + + glBindFragDataLocation(pProgram, index, name.c_str()); +} + + +GLint +VSShaderLib::getProgramOutput(std::string name) { + + return glGetFragDataLocation(pProgram, name.c_str()); +} + + +void +VSShaderLib::setVertexAttribName(VSShaderLib::AttribType at, std::string name) { + + glBindAttribLocation(pProgram,at,name.c_str()); +} + + +GLuint +VSShaderLib::getProgramIndex() { + + return pProgram; +} + + +GLuint +VSShaderLib::getShaderIndex(VSShaderLib::ShaderType aType) { + + return pShader[aType]; +} + + +void +VSShaderLib::setBlock(std::string name, void *value) { + + assert(spBlocks.count(name) != 0); + + glBindBuffer(GL_UNIFORM_BUFFER, spBlocks[name].buffer); + glBufferSubData(GL_UNIFORM_BUFFER, 0, spBlocks[name].size, value); + glBindBuffer(GL_UNIFORM_BUFFER,0); + +} + + +void +VSShaderLib::setBlockUniform(std::string blockName, + std::string uniformName, + void *value) { + + assert(spBlocks.count(blockName) && + spBlocks[blockName].uniformOffsets.count(uniformName)); + + UniformBlock b; + b = spBlocks[blockName]; + + myBlockUniform bUni; + bUni = b.uniformOffsets[uniformName]; + + glBindBuffer(GL_UNIFORM_BUFFER, b.buffer); + glBufferSubData(GL_UNIFORM_BUFFER, bUni.offset, bUni.size, value); + glBindBuffer(GL_UNIFORM_BUFFER,0); +} + + +void +VSShaderLib::setBlockUniformArrayElement(std::string blockName, + std::string uniformName, + int arrayIndex, + void * value) { + + assert(spBlocks.count(blockName) && + spBlocks[blockName].uniformOffsets.count(uniformName)); + + UniformBlock b; + b = spBlocks[blockName]; + + myBlockUniform bUni; + bUni = b.uniformOffsets[uniformName]; + + glBindBuffer(GL_UNIFORM_BUFFER, b.buffer); + glBufferSubData(GL_UNIFORM_BUFFER, + bUni.offset + bUni.arrayStride * arrayIndex, + bUni.arrayStride, value); + glBindBuffer(GL_UNIFORM_BUFFER,0); +} + + +void +VSShaderLib::setUniform(std::string name, int value) { + +// assert(pUniforms.count(name) != 0); + + int val = value; + myUniforms u = pUniforms[name]; + glProgramUniform1i(pProgram, u.location, val); + +} + + +void +VSShaderLib::setUniform(std::string name, float value) { + + assert(pUniforms.count(name) != 0); + + float val = value; + myUniforms u = pUniforms[name]; + glProgramUniform1f(pProgram, u.location, val); +} + + +void +VSShaderLib::setUniform(std::string name, void *value) { + +// assert(pUniforms.count(name) != 0); + + myUniforms u = pUniforms[name]; + switch (u.type) { + + // Floats + case GL_FLOAT: + glProgramUniform1fv(pProgram, u.location, u.size, (const GLfloat *)value); + break; + case GL_FLOAT_VEC2: + glProgramUniform2fv(pProgram, u.location, u.size, (const GLfloat *)value); + break; + case GL_FLOAT_VEC3: + glProgramUniform3fv(pProgram, u.location, u.size, (const GLfloat *)value); + break; + case GL_FLOAT_VEC4: + glProgramUniform4fv(pProgram, u.location, u.size, (const GLfloat *)value); + break; + + // Doubles + case GL_DOUBLE: + glProgramUniform1dv(pProgram, u.location, u.size, (const GLdouble *)value); + break; + case GL_DOUBLE_VEC2: + glProgramUniform2dv(pProgram, u.location, u.size, (const GLdouble *)value); + break; + case GL_DOUBLE_VEC3: + glProgramUniform3dv(pProgram, u.location, u.size, (const GLdouble *)value); + break; + case GL_DOUBLE_VEC4: + glProgramUniform4dv(pProgram, u.location, u.size, (const GLdouble *)value); + break; + + // Samplers, Ints and Bools + case GL_SAMPLER_1D: + case GL_SAMPLER_2D: + case GL_SAMPLER_3D: + case GL_SAMPLER_CUBE: + case GL_SAMPLER_1D_SHADOW: + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_1D_ARRAY: + case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_1D_ARRAY_SHADOW: + case GL_SAMPLER_2D_ARRAY_SHADOW: + case GL_SAMPLER_2D_MULTISAMPLE: + case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_SAMPLER_CUBE_SHADOW: + case GL_SAMPLER_BUFFER: + case GL_SAMPLER_2D_RECT: + case GL_SAMPLER_2D_RECT_SHADOW: + case GL_INT_SAMPLER_1D: + case GL_INT_SAMPLER_2D: + case GL_INT_SAMPLER_3D: + case GL_INT_SAMPLER_CUBE: + case GL_INT_SAMPLER_1D_ARRAY: + case GL_INT_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_MULTISAMPLE: + case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_INT_SAMPLER_BUFFER: + case GL_INT_SAMPLER_2D_RECT: + case GL_UNSIGNED_INT_SAMPLER_1D: + case GL_UNSIGNED_INT_SAMPLER_2D: + case GL_UNSIGNED_INT_SAMPLER_3D: + case GL_UNSIGNED_INT_SAMPLER_CUBE: + case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_BUFFER: + case GL_UNSIGNED_INT_SAMPLER_2D_RECT: + case GL_BOOL: + case GL_INT : + glProgramUniform1iv(pProgram, u.location, u.size, (const GLint *)value); + break; + case GL_BOOL_VEC2: + case GL_INT_VEC2: + glProgramUniform2iv(pProgram, u.location, u.size, (const GLint *)value); + break; + case GL_BOOL_VEC3: + case GL_INT_VEC3: + glProgramUniform3iv(pProgram, u.location, u.size, (const GLint *)value); + break; + case GL_BOOL_VEC4: + case GL_INT_VEC4: + glProgramUniform4iv(pProgram, u.location, u.size, (const GLint *)value); + break; + + // Unsigned ints + case GL_UNSIGNED_INT: + glProgramUniform1uiv(pProgram, u.location, u.size, (const GLuint *)value); + break; + case GL_UNSIGNED_INT_VEC2: + glProgramUniform2uiv(pProgram, u.location, u.size, (const GLuint *)value); + break; + case GL_UNSIGNED_INT_VEC3: + glProgramUniform3uiv(pProgram, u.location, u.size, (const GLuint *)value); + break; + case GL_UNSIGNED_INT_VEC4: + glProgramUniform4uiv(pProgram, u.location, u.size, (const GLuint *)value); + break; + + // Float Matrices + case GL_FLOAT_MAT2: + glProgramUniformMatrix2fv(pProgram, u.location, u.size, false, (const GLfloat *)value); + break; + case GL_FLOAT_MAT3: + glProgramUniformMatrix3fv(pProgram, u.location, u.size, false, (const GLfloat *)value); + break; + case GL_FLOAT_MAT4: + glProgramUniformMatrix4fv(pProgram, u.location, u.size, false, (const GLfloat *)value); + break; + case GL_FLOAT_MAT2x3: + glProgramUniformMatrix2x3fv(pProgram, u.location, u.size, false, (const GLfloat *)value); + break; + case GL_FLOAT_MAT2x4: + glProgramUniformMatrix2x4fv(pProgram, u.location, u.size, false, (const GLfloat *)value); + break; + case GL_FLOAT_MAT3x2: + glProgramUniformMatrix3x2fv(pProgram, u.location, u.size, false, (const GLfloat *)value); + break; + case GL_FLOAT_MAT3x4: + glProgramUniformMatrix3x4fv(pProgram, u.location, u.size, false, (const GLfloat *)value); + break; + case GL_FLOAT_MAT4x2: + glProgramUniformMatrix4x2fv(pProgram, u.location, u.size, false, (const GLfloat *)value); + break; + case GL_FLOAT_MAT4x3: + glProgramUniformMatrix4x3fv(pProgram, u.location, u.size, false, (const GLfloat *)value); + break; + + // Double Matrices + case GL_DOUBLE_MAT2: + glProgramUniformMatrix2dv(pProgram, u.location, u.size, false, (const GLdouble *)value); + break; + case GL_DOUBLE_MAT3: + glProgramUniformMatrix3dv(pProgram, u.location, u.size, false, (const GLdouble *)value); + break; + case GL_DOUBLE_MAT4: + glProgramUniformMatrix4dv(pProgram, u.location, u.size, false, (const GLdouble *)value); + break; + case GL_DOUBLE_MAT2x3: + glProgramUniformMatrix2x3dv(pProgram, u.location, u.size, false, (const GLdouble *)value); + break; + case GL_DOUBLE_MAT2x4: + glProgramUniformMatrix2x4dv(pProgram, u.location, u.size, false, (const GLdouble *)value); + break; + case GL_DOUBLE_MAT3x2: + glProgramUniformMatrix3x2dv(pProgram, u.location, u.size, false, (const GLdouble *)value); + break; + case GL_DOUBLE_MAT3x4: + glProgramUniformMatrix3x4dv(pProgram, u.location, u.size, false, (const GLdouble *)value); + break; + case GL_DOUBLE_MAT4x2: + glProgramUniformMatrix4x2dv(pProgram, u.location, u.size, false, (const GLdouble *)value); + break; + case GL_DOUBLE_MAT4x3: + glProgramUniformMatrix4x3dv(pProgram, u.location, u.size, false, (const GLdouble *)value); + break; + } +} + + +std::string +VSShaderLib::getShaderInfoLog(VSShaderLib::ShaderType st) { + + int infologLength = 0; + int charsWritten = 0; + char *infoLog; + + pResult = ""; + + if (pShader[st]) { + glGetShaderiv(pShader[st], GL_INFO_LOG_LENGTH,&infologLength); + + if (infologLength > 0) + { + infoLog = (char *)malloc(infologLength); + glGetShaderInfoLog(pShader[st], infologLength, &charsWritten, infoLog); + if (charsWritten) + pResult = infoLog; + else + pResult= "OK"; + free(infoLog); + } + } + else + pResult = "Shader not loaded"; + return pResult; +} + + +std::string +VSShaderLib::getProgramInfoLog() { + + int infologLength = 0; + int charsWritten = 0; + char *infoLog; + + pResult = ""; + + if (pProgram) { + + glGetProgramiv(pProgram, GL_INFO_LOG_LENGTH,&infologLength); + + if (infologLength > 0) + { + infoLog = (char *)malloc(infologLength); + glGetProgramInfoLog(pProgram, infologLength, &charsWritten, infoLog); + pResult = infoLog; + if (charsWritten) + pResult = infoLog; + else + pResult= "OK"; + free(infoLog); + } + } + return pResult; +} + + +bool +VSShaderLib::isProgramValid() { + + GLint b = GL_FALSE; + + if (pProgram) { + + glValidateProgram(pProgram); + glGetProgramiv(pProgram, GL_VALIDATE_STATUS,&b); + } + + return (b != GL_FALSE); +} + + +bool +VSShaderLib::isShaderCompiled(VSShaderLib::ShaderType aType) { + + GLint b = GL_FALSE; + + if (pShader[aType]) { + + glGetShaderiv(pShader[aType], GL_INFO_LOG_LENGTH, &b); + } + + return (b != GL_FALSE); +} + + +bool +VSShaderLib::isProgramLinked() { + + GLint b = GL_FALSE; + + if (pProgram) { + + glGetProgramiv(pProgram, GL_LINK_STATUS, &b); + } + + return (b != GL_FALSE); +} + + +std::string +VSShaderLib::getAllInfoLogs() { + + std::string s; + + for (int i = 0; i < VSShaderLib::COUNT_SHADER_TYPE; ++i) { + if (pShader[i]) { + getShaderInfoLog((VSShaderLib::ShaderType)i); + s += VSShaderLib::spStringShaderTypes[i] + ": " + pResult + "\n"; + } + } + + if (pProgram) { + getProgramInfoLog(); + s += "Program: " + pResult; + if (isProgramValid()) + s += " - Valid\n"; + else + s += " - Not Valid\n"; + } + + pResult = s; + return pResult; +} + + +// PRIVATE METHODS + +char * +VSShaderLib::textFileRead(std::string fileName) { + + + FILE *fp; + char *content = NULL; + + int count=0; + + if (fileName != "") { + fp = fopen(fileName.c_str(),"rt"); + + if (fp != NULL) { + + fseek(fp, 0, SEEK_END); + count = ftell(fp); + rewind(fp); + + if (count > 0) { + content = (char *)malloc(sizeof(char) * (count+1)); + count = fread(content,sizeof(char),count,fp); + content[count] = '\0'; + } + fclose(fp); + } + } + return content; +} + + +void +VSShaderLib::addBlocks() { + + int count, dataSize, actualLen, activeUnif, maxUniLength; + int uniType, uniSize, uniOffset, uniMatStride, uniArrayStride, auxSize; + char *name, *name2; + + UniformBlock block; + + glGetProgramiv(pProgram, GL_ACTIVE_UNIFORM_BLOCKS, &count); + + for (int i = 0; i < count; ++i) { + // Get buffers name + glGetActiveUniformBlockiv(pProgram, i, GL_UNIFORM_BLOCK_NAME_LENGTH, &actualLen); + name = (char *)malloc(sizeof(char) * actualLen); + glGetActiveUniformBlockName(pProgram, i, actualLen, NULL, name); + + if (!spBlocks.count(name)) { + // Get buffers size + block = spBlocks[name]; + glGetActiveUniformBlockiv(pProgram, i, GL_UNIFORM_BLOCK_DATA_SIZE, &dataSize); + //printf("DataSize:%d\n", dataSize); + glGenBuffers(1, &block.buffer); + glBindBuffer(GL_UNIFORM_BUFFER, block.buffer); + glBufferData(GL_UNIFORM_BUFFER, dataSize, NULL, GL_DYNAMIC_DRAW); + glUniformBlockBinding(pProgram, i, spBlockCount); + glBindBufferRange(GL_UNIFORM_BUFFER, spBlockCount, block.buffer, 0, dataSize); + + glGetActiveUniformBlockiv(pProgram, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &activeUnif); + + unsigned int *indices; + indices = (unsigned int *)malloc(sizeof(unsigned int) * activeUnif); + glGetActiveUniformBlockiv(pProgram, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, (int *)indices); + + glGetProgramiv(pProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniLength); + name2 = (char *)malloc(sizeof(char) * maxUniLength); + + for (int k = 0; k < activeUnif; ++k) { + + myBlockUniform bUni; + + glGetActiveUniformName(pProgram, indices[k], maxUniLength, &actualLen, name2); + glGetActiveUniformsiv(pProgram, 1, &indices[k], GL_UNIFORM_TYPE, &uniType); + glGetActiveUniformsiv(pProgram, 1, &indices[k], GL_UNIFORM_SIZE, &uniSize); + glGetActiveUniformsiv(pProgram, 1, &indices[k], GL_UNIFORM_OFFSET, &uniOffset); + glGetActiveUniformsiv(pProgram, 1, &indices[k], GL_UNIFORM_MATRIX_STRIDE, &uniMatStride); + glGetActiveUniformsiv(pProgram, 1, &indices[k], GL_UNIFORM_ARRAY_STRIDE, &uniArrayStride); + + if (uniArrayStride > 0) + auxSize = uniArrayStride * uniSize; + + else if (uniMatStride > 0) { + + switch(uniType) { + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT2x3: + case GL_FLOAT_MAT2x4: + case GL_DOUBLE_MAT2: + case GL_DOUBLE_MAT2x3: + case GL_DOUBLE_MAT2x4: + auxSize = 2 * uniMatStride; + break; + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT3x2: + case GL_FLOAT_MAT3x4: + case GL_DOUBLE_MAT3: + case GL_DOUBLE_MAT3x2: + case GL_DOUBLE_MAT3x4: + auxSize = 3 * uniMatStride; + break; + case GL_FLOAT_MAT4: + case GL_FLOAT_MAT4x2: + case GL_FLOAT_MAT4x3: + case GL_DOUBLE_MAT4: + case GL_DOUBLE_MAT4x2: + case GL_DOUBLE_MAT4x3: + auxSize = 4 * uniMatStride; + break; + } + } + else + auxSize = typeSize(uniType); + + bUni.offset = uniOffset; + bUni.type = uniType; + bUni.size = auxSize; + bUni.arrayStride = uniArrayStride; + + block.uniformOffsets[name2] = bUni; + + + } + free(name2); + + block.size = dataSize; + block.bindingIndex = spBlockCount; + spBlocks[name] = block; + spBlockCount++; + } + else + glUniformBlockBinding(pProgram, i, spBlocks[name].bindingIndex); + + } + +} + + +void +VSShaderLib::addUniforms() { + + int count; + GLsizei actualLen; + GLint size; + GLint uniArrayStride; + GLenum type; + char *name; + + int maxUniLength; + glGetProgramiv(pProgram, GL_ACTIVE_UNIFORMS, &count); + + glGetProgramiv(pProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniLength); + + name = (char *)malloc(sizeof(char) * maxUniLength); + + unsigned int loc; + for (int i = 0; i < count; ++i) { + + glGetActiveUniform(pProgram, i, maxUniLength, &actualLen, &size, &type, name); + // -1 indicates that is not an active uniform, although it may be present in a + // uniform block + loc = glGetUniformLocation(pProgram, name); + glGetActiveUniformsiv(pProgram, 1, &loc, GL_UNIFORM_ARRAY_STRIDE, &uniArrayStride); + if (loc != -1) + addUniform(name, type, size); + } + free(name); +} + + +void +VSShaderLib::addUniform(std::string name, GLenum type, unsigned int size) { + + myUniforms u; + u.type = type; + u.location = glGetUniformLocation(pProgram, name.c_str()); + u.size = size; + pUniforms[name] = u; +} + + +int +VSShaderLib::typeSize(int type) { + + int s; + + switch(type) { + + case GL_FLOAT: + s = sizeof(float); + break; + case GL_FLOAT_VEC2: + s = sizeof(float)*2; + break; + case GL_FLOAT_VEC3: + s = sizeof(float)*3; + break; + case GL_FLOAT_VEC4: + s = sizeof(float)*4; + break; + + // Doubles + case GL_DOUBLE: + s = sizeof(double); + break; + case GL_DOUBLE_VEC2: + s = sizeof(double) * 2; + break; + case GL_DOUBLE_VEC3: + s = sizeof(double) * 3; + break; + case GL_DOUBLE_VEC4: + s = sizeof(double) * 4; + break; + + // Samplers, Ints and Bools + case GL_SAMPLER_1D: + case GL_SAMPLER_2D: + case GL_SAMPLER_3D: + case GL_SAMPLER_CUBE: + case GL_SAMPLER_1D_SHADOW: + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_1D_ARRAY: + case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_1D_ARRAY_SHADOW: + case GL_SAMPLER_2D_ARRAY_SHADOW: + case GL_SAMPLER_2D_MULTISAMPLE: + case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_SAMPLER_CUBE_SHADOW: + case GL_SAMPLER_BUFFER: + case GL_SAMPLER_2D_RECT: + case GL_SAMPLER_2D_RECT_SHADOW: + case GL_INT_SAMPLER_1D: + case GL_INT_SAMPLER_2D: + case GL_INT_SAMPLER_3D: + case GL_INT_SAMPLER_CUBE: + case GL_INT_SAMPLER_1D_ARRAY: + case GL_INT_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_MULTISAMPLE: + case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_INT_SAMPLER_BUFFER: + case GL_INT_SAMPLER_2D_RECT: + case GL_UNSIGNED_INT_SAMPLER_1D: + case GL_UNSIGNED_INT_SAMPLER_2D: + case GL_UNSIGNED_INT_SAMPLER_3D: + case GL_UNSIGNED_INT_SAMPLER_CUBE: + case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_BUFFER: + case GL_UNSIGNED_INT_SAMPLER_2D_RECT: + case GL_BOOL: + case GL_INT : + s = sizeof(int); + break; + case GL_BOOL_VEC2: + case GL_INT_VEC2: + s = sizeof(int) * 2; + break; + case GL_BOOL_VEC3: + case GL_INT_VEC3: + s = sizeof(int) * 3; + break; + case GL_BOOL_VEC4: + case GL_INT_VEC4: + s = sizeof(int) * 4; + break; + + // Unsigned ints + case GL_UNSIGNED_INT: + s = sizeof(unsigned int); + break; + case GL_UNSIGNED_INT_VEC2: + s = sizeof(unsigned int) * 2; + break; + case GL_UNSIGNED_INT_VEC3: + s = sizeof(unsigned int) * 3; + break; + case GL_UNSIGNED_INT_VEC4: + s = sizeof(unsigned int) * 4; + break; + + // Float Matrices + case GL_FLOAT_MAT2: + s = sizeof(float) * 4; + break; + case GL_FLOAT_MAT3: + s = sizeof(float) * 9; + break; + case GL_FLOAT_MAT4: + s = sizeof(float) * 16; + break; + case GL_FLOAT_MAT2x3: + s = sizeof(float) * 6; + break; + case GL_FLOAT_MAT2x4: + s = sizeof(float) * 8; + break; + case GL_FLOAT_MAT3x2: + s = sizeof(float) * 6; + break; + case GL_FLOAT_MAT3x4: + s = sizeof(float) * 12; + break; + case GL_FLOAT_MAT4x2: + s = sizeof(float) * 8; + break; + case GL_FLOAT_MAT4x3: + s = sizeof(float) * 12; + break; + + // Double Matrices + case GL_DOUBLE_MAT2: + s = sizeof(double) * 4; + break; + case GL_DOUBLE_MAT3: + s = sizeof(double) * 9; + break; + case GL_DOUBLE_MAT4: + s = sizeof(double) * 16; + break; + case GL_DOUBLE_MAT2x3: + s = sizeof(double) * 6; + break; + case GL_DOUBLE_MAT2x4: + s = sizeof(double) * 8; + break; + case GL_DOUBLE_MAT3x2: + s = sizeof(double) * 6; + break; + case GL_DOUBLE_MAT3x4: + s = sizeof(double) * 12; + break; + case GL_DOUBLE_MAT4x2: + s = sizeof(double) * 8; + break; + case GL_DOUBLE_MAT4x3: + s = sizeof(double) * 12; + break; + default: return 0; + } + return s; +} + diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsShaderLib.h b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsShaderLib.h new file mode 100644 index 0000000..18d2527 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsShaderLib.h @@ -0,0 +1,241 @@ +/** ---------------------------------------------------------- + * \class VSShaderLib + * + * Lighthouse3D + * + * VSShaderLib - Very Simple Shader Library + * + * Full documentation at + * http://www.lighthouse3d.com/very-simple-libs + * + * This class aims at making life simpler + * when using shaders and uniforms + * + * \version 0.2.1 + * Added more attrib defs, namely + * tangents, bi tangents, and 4 custom + * + * version 0.2.0 + * Added methods to set uniforms + * Added methods to set blocks + * Renamed to VSShaderLib + * + * version 0.1.0 + * Initial Release + * + * This lib requires: + * + * GLEW (http://glew.sourceforge.net/) + * + ---------------------------------------------------------------*/ + + +#ifndef __VSShaderLib__ +#define __VSShaderLib__ + +#include +#include +#include +#include + + +class VSShaderLib +{ +public: + + /// Types of Vertex Attributes + enum AttribType { + VERTEX_COORD_ATTRIB, + NORMAL_ATTRIB, + TEXTURE_COORD_ATTRIB, + TANGENT_ATTRIB, + BITANGENT_ATTRIB, + VERTEX_ATTRIB1, + VERTEX_ATTRIB2, + VERTEX_ATTRIB3, + VERTEX_ATTRIB4 + }; + + /// Types of Shaders + enum ShaderType { + VERTEX_SHADER, + GEOMETRY_SHADER, + TESS_CONTROL_SHADER, + TESS_EVAL_SHADER, + FRAGMENT_SHADER, + COUNT_SHADER_TYPE + }; + + /// Just a helper define + static const int MAX_TEXTURES = 8; + + VSShaderLib(); + ~VSShaderLib(); + + /** Init should be called for every shader instance + * prior to any other function + */ + void init(); + + /** Loads the text in the file to the source of the specified shader + * + * \param st one of the enum values of ShaderType + * \param filename the file where the source is to be found + */ + void loadShader(VSShaderLib::ShaderType st, std::string fileName); + + /** bind a user-defined varying out variable to a + * fragment shader color number + * Note: linking is required for this operation to take effect + * (call method prepareProgram afterwards) + * + * \param index the fragment colour number + * \param the name of the fragment's shader variable + */ + void setProgramOutput(int index, std::string name); + + /** returns the fragment shader color number bound to + * a user-defined varying out variable + * + * Note: linking is required for this operation to take effect + * (call method prepareProgram afterwards) + * + * \param the name of the fragment's shader variable + * \returns the fragment colour number + */ + GLint getProgramOutput(std::string name); + + /** Defines semantics for the input vertex attributes. This is + * required for other libraries to know how to send data to the shader + * Note: linking is required for this operation to take effect + * (call method prepareProgram) + * + * \param the semantic of the attribute + * \param the name of the vertex attribute + */ + void setVertexAttribName(VSShaderLib::AttribType at, std::string name); + + /** Prepares program for usage. Links it and collects information + * about uniform variables and uniform blocks + */ + void prepareProgram(); + + /// generic function to set the uniform to value + void setUniform(std::string name, void *value); + /// For int and bool uniforms. Sets the uniform to the int value + void setUniform(std::string name, int value); + /// For float uniforms. Sets the uniform to the float value + void setUniform(std::string name, float value); + /// sets a uniform block as a whole + static void setBlock(std::string name, void *value); + /// sets a uniform inside a named block + static void setBlockUniform(std::string blockName, + std::string uniformName, + void *value); + /// sets an element of an array of uniforms inside a block + static void setBlockUniformArrayElement(std::string blockName, + std::string uniformName, + int arrayIndex, + void * value); + + /// returns the program index + GLuint getProgramIndex(); + /// returns a shader index + GLuint getShaderIndex(VSShaderLib::ShaderType); + + /// returns a string with a shader's infolog + std::string getShaderInfoLog(VSShaderLib::ShaderType); + /// returns a string with the program's infolog + std::string getProgramInfoLog(); + /// returns a string will all info logs + std::string getAllInfoLogs(); + /// returns GL_VALIDATE_STATUS for the program + bool isProgramValid(); + /// returns true if compiled, false otherwise + bool isShaderCompiled(VSShaderLib::ShaderType); + /// returns true if linked, false otherwise + bool isProgramLinked(); + + +protected: + + // AUX STRUCTURES + + /// stores information for uniforms + typedef struct uniforms { + GLenum type; + GLuint location; + GLuint size; + GLuint stride; + }myUniforms; + + /// stores information for block uniforms + typedef struct blockUniforms { + GLenum type; + GLuint offset; + GLuint size; + GLuint arrayStride; + } myBlockUniform; + + /// stores information for a block and its uniforms + class UniformBlock { + + public: + /// size of the uniform block + int size; + /// buffer bound to the index point + GLuint buffer; + /// binding index + GLuint bindingIndex; + /// uniforms information + std::map uniformOffsets; + }; + + // VARIABLES + + /// stores if init has been called + bool pInited; + + + /// blockCount is used to assign binding indexes + static int spBlockCount; + + /// Stores info on all blocks found + static std::map spBlocks; + + /// stores the OpenGL shader types + static GLenum spGLShaderTypes[VSShaderLib::COUNT_SHADER_TYPE]; + + /// stores the text string related to each type + static std::string spStringShaderTypes[VSShaderLib::COUNT_SHADER_TYPE]; + + /// aux string used to return the shaders infologs + std::string pResult; + + /// stores the shaders and program indices + GLuint pShader[VSShaderLib::COUNT_SHADER_TYPE], pProgram; + + /// stores info on the uniforms + std::map pUniforms; + + // AUX FUNCTIONS + + /// aux function to get info on the uniforms referenced by the shaders + void addUniforms(); + + /// aux function to store the info of a uniform + void addUniform(std::string name, GLenum type, unsigned int size); + + /// aux function to get info on the blocks referenced by the shaders + void addBlocks(); + + /// determines the size in bytes based on the OpenGL type + int typeSize(int type); + + /// aux function to read the shader's source code from file + char *textFileRead(std::string fileName); +}; + + + +#endif diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsTerrainLODSingleScaledLib.cpp b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsTerrainLODSingleScaledLib.cpp new file mode 100644 index 0000000..d64cca3 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsTerrainLODSingleScaledLib.cpp @@ -0,0 +1,386 @@ +/** ---------------------------------------------------------- + * \class VSTerrainLODLib + * + * Lighthouse3D + * + * VSTerrainLODLib - Very Simple Terrain LOD Lib + * + * \version 0.1.0 + * Initial Release + * + * This lib provides an interface for Assimp to load and render 3D models + * and performs simple resource managment + * + * Full documentation at + * http://www.lighthouse3d.com/very-simple-libs + * + ---------------------------------------------------------------*/ + +#include "vsTerrainLODSingleScaledLib.h" + +#include +#include +#include +#include + +#define PATCHSIZE 64 + +VSTerrainLODSingleScaledLib::VSTerrainLODSingleScaledLib(): + VSTerrainLib()//, mScaleFactor(1) +{ +} + + +VSTerrainLODSingleScaledLib::~VSTerrainLODSingleScaledLib() { + + glDeleteVertexArrays(1,&(mMesh.vao)); +// glDeleteTextures(1,&(myMeshes[i].texIndex)); + glDeleteBuffers(1,&(mMesh.uniformBlockIndex)); +} + + +//float +//VSTerrainLODSingleScaledLib::getHeight(int j , int i) { +// +// int iAux, jAux; +// +// iAux = (i / mScaleFactor); +// jAux = (j / mScaleFactor); +// +// if (iAux < 0) +// iAux = 0; +// else if (iAux >= (int)(mGridSizeX / mScaleFactor)) +// iAux = (mGridSizeX / mScaleFactor) - 1; +// +// if (jAux < 0) +// jAux = 0; +// else if (jAux >= (int)(mGridSizeZ / mScaleFactor)) +// jAux = (mGridSizeZ / (int)mScaleFactor) - 1; +// +// return(mHeights[(int)(iAux * mGridSizeX / mScaleFactor) + jAux] * mHeightStep / 65536); +//} +// +// +//float +//VSTerrainLODSingleScaledLib::getHeight(float x, float z) { +// +// +// int x1, x2,z1,z2; +// float xGrid, zGrid; +// float fracX, fracZ, ha, hb; +// +// xGrid = x/mGridSpacing + mGridSizeX * 0.5f - 0.5f; +// zGrid = z/mGridSpacing + mGridSizeZ * 0.5f - 0.5f; +// +// x1 = (int)floor(xGrid); +// x2 = x1 + 1; +// fracX = (xGrid - x1); +// +// z1 = (int)floor(zGrid); +// z2 = z1 + 1; +// fracZ = (zGrid - z1); +// +// ha = fracX * getHeight(x2,z1) + (1-fracX) * getHeight(x1,z1); +// hb = fracX * getHeight(x2,z2) + (1-fracX) * getHeight(x1,z2); +// +// return(fracZ * hb + (ha * (1-fracZ))); +//} + + +void +VSTerrainLODSingleScaledLib::setScaleFactor(int f) { + + mScaleFactor = f; +} + + +int +VSTerrainLODSingleScaledLib::getScaleFactor() { + + return mScaleFactor; +} + + +void +VSTerrainLODSingleScaledLib::render() { + + glPatchParameteri( GL_PATCH_VERTICES, 1 ); + + mVSML->pushMatrix(VSMathLib::MODEL); + mVSML->multMatrix(VSMathLib::MODEL, mMesh.transform); + mVSML->matricesToGL(); + + VSShaderLib::setBlock(mMaterialBlockName, &(mMesh.mat)); + // bind textures + for (int t = 0; t < VSShaderLib::MAX_TEXTURES; t++) { + if (mMesh.texUnits[t] != 0) { + glActiveTexture(GL_TEXTURE0 + t); + glBindTexture(GL_TEXTURE_2D, mMesh.texUnits[t]); + } + } + // bind VAO + glBindVertexArray(mMesh.vao); + glDrawArrays(mMesh.type,0,mMesh.numIndices); + + for (int t = 0; t < VSShaderLib::MAX_TEXTURES; t++) { + if (mMesh.texUnits[t] != 0) { + glActiveTexture(GL_TEXTURE0 + t); + glBindTexture(GL_TEXTURE_2D, 0); + } + } + glBindVertexArray(0); + + mVSML->popMatrix(VSMathLib::MODEL); +} + + +bool +VSTerrainLODSingleScaledLib::load(std::string heightMap) +{ + ILboolean success; + GLuint buffer; + + unsigned int imageID; + GLuint textureID; + + ilGenImages(1, &imageID); + + // Load Height Map + ilBindImage(imageID); /* Binding of DevIL image name */ + ilEnable(IL_ORIGIN_SET); + ilOriginFunc(IL_ORIGIN_LOWER_LEFT); + success = ilLoadImage((ILstring)heightMap.c_str()); + + if (!success) { + mLogError.addMessage("Couldn't load height map: %s", heightMap.c_str()); + /* The operation was not sucessfull hence free images */ + ilDeleteImages(1, &imageID); + return false; + } + + /* Convert image to LUMINANCE - 16 bits */ + ilConvertImage(IL_LUMINANCE, IL_UNSIGNED_SHORT); + mGridSizeX = ilGetInteger(IL_IMAGE_WIDTH); + mGridSizeZ = ilGetInteger(IL_IMAGE_HEIGHT); + unsigned char *heightsAux = (unsigned char *)ilGetData(); + + mHeights = (unsigned short *)malloc(sizeof(unsigned short) * mGridSizeX * mGridSizeZ); + memcpy(mHeights, heightsAux, sizeof(unsigned short) * mGridSizeX * mGridSizeZ); + + if (mHeightStep == 0.0f) + mHeightStep = 0.005f; + + /* Create and load heighmap texture to OpenGL */ + glGenTextures(1, &textureID); /* Texture name generation */ + glBindTexture(GL_TEXTURE_2D, textureID); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_R16,// GL_COMPRESSED_RED_RGTC1, + mGridSizeX, mGridSizeZ, + 0, GL_RED, GL_UNSIGNED_SHORT, + mHeights); + + glBindTexture(GL_TEXTURE_2D, 0); + mGridSizeX = (int)(mGridSizeX * mScaleFactor); + mGridSizeZ = (int)(mGridSizeZ * mScaleFactor); + + mMesh.texUnits[0] = textureID; + + if (mHeightStep == 0.0f) + mHeightStep = 0.005f; + + int patchSize = 1; + // We're assuming that the heightmap is a multiple of 64 and contains at least one patch + int nopX = (mGridSizeX / PATCHSIZE); + int nopZ = (mGridSizeZ / PATCHSIZE); + int numPatches = nopX * nopZ; + + + // Compute Roughness + float difH; + float *difs = (float *)malloc(sizeof(float) * nopX * nopZ); + + // First compute the average normal of the patch + float avgN[3], n0[3], n1[3], n2[3], n3[3]; + float p0[3], p1[3], p2[3], p3[3]; + float max=0.0f,min=1.0f; + for (int i = 0; i < nopZ; ++i) { + + for (int j = 0; j < nopX; ++j) { + + p0[0] = 0.0f; + p0[1] = getHeight(i*PATCHSIZE,j*PATCHSIZE); + p0[2] = 0.0f; + + p1[0] = 0.0f; + p1[1] = getHeight((i+1)*PATCHSIZE, j*PATCHSIZE); + p1[2] = mGridSpacing*PATCHSIZE; + + p2[0] = mGridSpacing*PATCHSIZE; + p2[1] = getHeight(i*PATCHSIZE,(j+1)*PATCHSIZE); + p2[2] = 0.0f; + + p3[0] = mGridSpacing*PATCHSIZE; + p3[1] = getHeight((i+1)*PATCHSIZE, (j+1)*PATCHSIZE); + p3[2] = mGridSpacing*PATCHSIZE; + + float p01[3], p02[3], p13[3], p23[3]; + + p01[0] = p1[0] - p0[0]; + p01[1] = p1[1] - p0[1]; + p01[2] = p1[2] - p0[2]; + + p02[0] = p2[0] - p0[0]; + p02[1] = p2[1] - p0[1]; + p02[2] = p2[2] - p0[2]; + + p13[0] = p3[0] - p1[0]; + p13[1] = p3[1] - p1[1]; + p13[2] = p3[2] - p1[2]; + + p23[0] = p3[0] - p2[0]; + p23[1] = p3[1] - p2[1]; + p23[2] = p3[2] - p2[2]; + + VSMathLib::crossProduct(p01,p02,n0); + VSMathLib::crossProduct(p23,p02,n2); + VSMathLib::crossProduct(p23,p13,n3); + VSMathLib::crossProduct(p01,p13,n1); + + VSMathLib::normalize(n0); + VSMathLib::normalize(n1); + VSMathLib::normalize(n2); + VSMathLib::normalize(n3); + + avgN[0] = n0[0] + n1[0] + n2[0] + n3[0]; + avgN[1] = n0[1] + n1[1] + n2[1] + n3[1]; + avgN[2] = n0[2] + n1[2] + n2[2] + n3[2]; + + VSMathLib::normalize(avgN); + + // Then compute the normal at each point and accumulate its difference to the average + + difH = 0.0f; + float normal[3], deltaHi, deltaHj; + float maxDif = 0.0f, minDif = 1.0f; + for (int k = 0; k < PATCHSIZE; ++k) + for (int l = 0; l < PATCHSIZE; ++l) { + + deltaHi = getHeight(j*PATCHSIZE+k, i*PATCHSIZE+l+1) - getHeight(j*PATCHSIZE+k, i*PATCHSIZE+l-1); + deltaHj = getHeight(j*PATCHSIZE+k+1, i*PATCHSIZE+l) - getHeight(j*PATCHSIZE+k-1, i*PATCHSIZE+l); + + normal[0] = -2 * mGridSpacing * deltaHi; + normal[1] = 4 * mGridSpacing * mGridSpacing; + normal[2] = - 2 * mGridSpacing * deltaHj; + + VSMathLib::normalize(normal); + float aux = VSMathLib::dotProduct(normal, avgN); + aux *= aux; + if (aux < minDif) minDif = aux; + if (aux > maxDif) maxDif = aux; + difH += aux; + + + } + difs[i*nopX + j] = minDif;//difH / (64*64); + if (difs[i*nopX + j] > max) max = difs[i*nopX + j]; + if (difs[i*nopX + j] < min) min = difs[i*nopX + j]; + } + } +// printf("\n%f %f\n", min,max); + glGenTextures(1, &textureID); /* Texture name generation */ + glBindTexture(GL_TEXTURE_2D, textureID); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + 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_R16F, + nopX, nopZ, + 0, GL_RED, GL_FLOAT, + difs); + glBindTexture(GL_TEXTURE_2D, 0); + mMesh.texUnits[1] = textureID; + + + + mMesh.numIndices = numPatches * patchSize; + float *vertices = (float *)malloc(sizeof(float) * 2 * mMesh.numIndices); + unsigned int *indices = (unsigned int *)malloc(sizeof(unsigned int) * numPatches * patchSize); + + int patchNumber; + for (int i = 0; i < nopX; ++i) { + + for (int j = 0; j < nopZ; ++j) { + + patchNumber = i * nopZ + j; + + vertices[(patchNumber * patchSize) * 2 ] = (i * PATCHSIZE ) * 1.0f / mGridSizeX ; + vertices[(patchNumber * patchSize) * 2 + 1] = (j * PATCHSIZE) * 1.0f/ mGridSizeZ ; + + } + } + + for (int i = 0; i < 12; ++i) + printf("%f ", vertices[i]); + + for (int i = 0 ; i < mMesh.numIndices; ++i) { + indices[i] = i; + } + + glGenVertexArrays(1, &(mMesh.vao)); + glBindVertexArray(mMesh.vao); + + // buffer for vertices + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, + sizeof(float) * (mMesh.numIndices) * 2, + vertices, + GL_STATIC_DRAW); + glEnableVertexAttribArray(VSShaderLib::VERTEX_COORD_ATTRIB); + glVertexAttribPointer(VSShaderLib::VERTEX_COORD_ATTRIB, 2, GL_FLOAT, 0, 0, 0); + + mMesh.mat.ambient[0] = 0.2f; + mMesh.mat.ambient[1] = 0.2f; + mMesh.mat.ambient[2] = 0.2f; + mMesh.mat.ambient[3] = 1.0f; + + mMesh.mat.diffuse[0] = 0.8f; + mMesh.mat.diffuse[1] = 0.8f; + mMesh.mat.diffuse[2] = 0.8f; + mMesh.mat.diffuse[3] = 1.0f; + + mMesh.mat.texCount = 0; + + mMesh.type = GL_PATCHES; + + mCenter[0] = (mGridSizeX * 0.5f * mGridSpacing); + mCenter[1] = 0.0f; + mCenter[2] = (mGridSizeZ * 0.5f * mGridSpacing); + + // set identity transform + mVSML->loadIdentity(VSMathLib::AUX0); + mVSML->translate(VSMathLib::AUX0, + -mCenter[0], 0.0f, -mCenter[2]); + memcpy(mMesh.transform, mVSML->get(VSMathLib::AUX0), sizeof(float) * 16); + + mCenter[0] = 0.5f; + mCenter[1] = 0.0f; + mCenter[2] = 0.5f; + +// pScaleFactor = 2.0f; + + /* Because we have already copied image data into texture data + we can release memory used by image. */ + ilDeleteImages(1, &imageID); + free(vertices); + free (indices); + + return true; +} + diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsTerrainLODSingleScaledLib.h b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsTerrainLODSingleScaledLib.h new file mode 100644 index 0000000..2c775e6 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsTerrainLODSingleScaledLib.h @@ -0,0 +1,57 @@ +/** ---------------------------------------------------------- + * \class VSTerrainLODLib + * + * Lighthouse3D + * + * Very Simple Terrain LOD Library + * + * \version 0.1.0 + * Initial Release + * + * This lib provides creates a terrain model based on a height map + * using dynamic tesselation as a LOD mechanism + * + * Requirements: Devil, VSML, VSLL and VSShaderLib, VSTerrainLib, VSRL + * + * Full documentation at + * http://www.lighthouse3d.com/very-simple-libs + * + ---------------------------------------------------------------*/ + + + +#ifndef __VSTerrainLODSingleScaledLib__ +#define __VSTerrainLODSingleScaledLib__ + +#include +#include +#include +#include + +#include + +#include "vsTerrainLib.h" + +class VSTerrainLODSingleScaledLib: public VSTerrainLib{ + +public: + + VSTerrainLODSingleScaledLib(); + ~VSTerrainLODSingleScaledLib(); + + virtual bool load(std::string filename); + virtual void render(); + + void setScaleFactor(int f); + int getScaleFactor(); +// virtual float getHeight( float x, float z); + +protected: + +// virtual float getHeight(int x, int z); + +// int mScaleFactor; + +}; + +#endif diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsTerrainLib.cpp b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsTerrainLib.cpp new file mode 100644 index 0000000..736383c --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsTerrainLib.cpp @@ -0,0 +1,437 @@ +/** ---------------------------------------------------------- + * \class VSTerrainLib + * + * Lighthouse3D + * + * Very Simple Terrain Library + * + * \version 0.1.0 + * Initial Release + * + * extends VSResourceLib + * + * Full documentation at + * http://www.lighthouse3d.com/very-simple-libs + * + ---------------------------------------------------------------*/ + +#include "vsTerrainLib.h" + +#include +#include +#include +#include + + + +VSTerrainLib::VSTerrainLib(): + mGridSizeX(0), + mGridSizeZ(0), + mGridSpacing(1.0f), + mHeightStep(0.0f), + mScaleFactor(1) + +{ + mVSML = VSMathLib::getInstance(); + mCenter[0] = 0.0f; + mCenter[1] = 0.0f; + mCenter[2] = 0.0f; + + for (int i = 0; i < VSShaderLib::MAX_TEXTURES; ++i) { + + mMesh.texUnits[i] = 0; + } + + /* initialization of DevIL */ + ilInit(); +} + + +VSTerrainLib::~VSTerrainLib() { + + // clear myMeshes stuff + + glDeleteVertexArrays(1,&(mMesh.vao)); + glDeleteBuffers(1,&(mMesh.uniformBlockIndex)); +} + + + + +void +VSTerrainLib::render () { + + mVSML->pushMatrix(VSMathLib::MODEL); + //mVSML->scale(mGridSizeX*mGridSpacing, 1.0f, mGridSizeZ*mGridSpacing); + //mVSML->translate(-mCenter[0], -mCenter[1], -mCenter[2]); + + mVSML->multMatrix(VSMathLib::MODEL, mMesh.transform); + mVSML->matricesToGL(); + + VSShaderLib::setBlock(mMaterialBlockName, &(mMesh.mat)); + // bind textures + for (int t = 0; t < VSShaderLib::MAX_TEXTURES; t++) { + if (mMesh.texUnits[t] != 0) { + glActiveTexture(GL_TEXTURE0 + t); + glBindTexture(GL_TEXTURE_2D, mMesh.texUnits[t]); + } + } + // bind VAO + glBindVertexArray(mMesh.vao); + glDrawElements(mMesh.type, mMesh.numIndices, GL_UNSIGNED_INT, 0); + + + for (int t = 0; t < VSShaderLib::MAX_TEXTURES; t++) { + if (mMesh.texUnits[t] != 0) { + glActiveTexture(GL_TEXTURE0 + t); + glBindTexture(GL_TEXTURE_2D, 0); + } + } + glBindVertexArray(0); + + mVSML->popMatrix(VSMathLib::MODEL); + +} + + + +// ---------------------------------------------------------------------------- + + +bool +VSTerrainLib::load(std::string heightMap) +{ + ILboolean success; + GLuint buffer; + + unsigned int imageID; + GLuint textureID; + + mScaleFactor = 1; + + ilGenImages(1, &imageID); + + // Load Height Map + ilBindImage(imageID); /* Binding of DevIL image name */ + ilEnable(IL_ORIGIN_SET); + ilOriginFunc(IL_ORIGIN_LOWER_LEFT); + success = ilLoadImage((ILstring)heightMap.c_str()); + + if (!success) { + mLogError.addMessage("Couldn't load height map: %s", heightMap.c_str()); + /* The operation was not sucessfull hence free images and textures */ + glDeleteTextures(1, &textureID); + ilDeleteImages(1, &imageID); + return false; + } + + /* Convert image to LUMINANCE - 16 bits */ + ilConvertImage(IL_LUMINANCE, IL_UNSIGNED_SHORT); + mGridSizeX = ilGetInteger(IL_IMAGE_WIDTH); + mGridSizeZ = ilGetInteger(IL_IMAGE_HEIGHT); + unsigned char *heightsAux = (unsigned char *)ilGetData(); + + mHeights = (unsigned short *)malloc(sizeof(unsigned short) * mGridSizeX * mGridSizeZ); + memcpy(mHeights, heightsAux, sizeof(unsigned short) * mGridSizeX * mGridSizeZ); + + if (mHeightStep == 0.0f) + mHeightStep = 0.005f; + + mMesh.numIndices = (mGridSizeX -1 ) * (mGridSizeZ - 1) * 6; + + float *vertices = (float *)malloc(sizeof(float) * 4 * mGridSizeX * mGridSizeZ); + + unsigned int *indices = (unsigned int *)malloc(sizeof(unsigned int) * mMesh.numIndices); + + for (unsigned int i = 0; i < mGridSizeX ; ++i) { + + for (unsigned int j = 0; j < mGridSizeZ; ++j) { + + vertices[(i * mGridSizeZ + j) * 4 + 0] = j / (1.0f * mGridSizeZ); + vertices[(i * mGridSizeZ + j) * 4 + 1] = getHeight((int)j,(int)i) ; + vertices[(i * mGridSizeZ + j) * 4 + 2] = i / (1.0f * mGridSizeX); + vertices[(i * mGridSizeZ + j) * 4 + 3] = 1.0f; + } + } + + // set the indices array. For each cell create indices for 2 triangles + for (unsigned int i = 0; i < mGridSizeX -1; ++i) { + for (unsigned int j = 0; j < mGridSizeZ - 1; ++j) { + + indices[(i * (mGridSizeZ -1) + j) * 6 + 0] = i * mGridSizeX + j; + indices[(i * (mGridSizeZ -1) + j) * 6 + 1] = (i+1) * mGridSizeX + j; + indices[(i * (mGridSizeZ -1) + j) * 6 + 2] = i * mGridSizeX + j + 1; + + indices[(i * (mGridSizeZ -1) + j) * 6 + 3] = (i+1) * mGridSizeX + j; + indices[(i * (mGridSizeZ -1) + j) * 6 + 4] = (i+1) * mGridSizeX + j + 1; + indices[(i * (mGridSizeZ -1) + j) * 6 + 5] = i * mGridSizeX + j + 1; + } + } + + unsigned int max = mGridSizeX > mGridSizeZ ? mGridSizeX : mGridSizeZ; + + glGenVertexArrays(1, &(mMesh.vao)); + glBindVertexArray(mMesh.vao); + + //GLuint aux; + //glGenBuffers(1,&aux); + //glBindBuffer(GL_ARRAY_BUFFER, aux); + //glBufferData(GL_ARRAY_BUFFER, + // sizeof(float) * 4 * mGridSizeX * mGridSizeZ, + // vertices, + // GL_STATIC_DRAW); + + //glGenBuffers(1,&aux); + //glBindBuffer(GL_ARRAY_BUFFER, aux); + //glBufferData(GL_ARRAY_BUFFER, + // sizeof(float) * 4 * mGridSizeX * mGridSizeZ, + // vertices, + // GL_STATIC_DRAW); + //glGenBuffers(1,&aux); + //glBindBuffer(GL_ARRAY_BUFFER, aux); + //glBufferData(GL_ARRAY_BUFFER, + // sizeof(float) * 4 * mGridSizeX * mGridSizeZ, + // vertices, + // GL_STATIC_DRAW); + //glGenBuffers(1,&aux); + //glBindBuffer(GL_ARRAY_BUFFER, aux); + //glBufferData(GL_ARRAY_BUFFER, + // sizeof(float) * 4 * mGridSizeX * mGridSizeZ, + // vertices, + // GL_STATIC_DRAW); + // buffer for vertices + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, + sizeof(float) * 4 * mGridSizeX * mGridSizeZ, + vertices, + GL_STATIC_DRAW); + glEnableVertexAttribArray(VSShaderLib::VERTEX_COORD_ATTRIB); + glVertexAttribPointer(VSShaderLib::VERTEX_COORD_ATTRIB, 4, GL_FLOAT, 0, 0, 0); + + //buffer for indices + glGenBuffers(1, &buffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + sizeof(unsigned int) * mMesh.numIndices, + indices, + GL_STATIC_DRAW); + + mMesh.mat.ambient[0] = 0.2f; + mMesh.mat.ambient[1] = 0.2f; + mMesh.mat.ambient[2] = 0.2f; + mMesh.mat.ambient[3] = 1.0f; + + mMesh.mat.diffuse[0] = 0.8f; + mMesh.mat.diffuse[1] = 0.8f; + mMesh.mat.diffuse[2] = 0.8f; + mMesh.mat.diffuse[3] = 1.0f; + + mMesh.mat.texCount = 0; + + mMesh.type = GL_TRIANGLES; + + mCenter[0] = 0.5f;//(mGridSizeX * 0.5f * mGridSpacing); + mCenter[1] = 0.0f; + mCenter[2] = 0.5f;//(mGridSizeZ * 0.5f * mGridSpacing); + + // set identity transform + mVSML->loadIdentity(VSMathLib::AUX0); + mVSML->scale(VSMathLib::AUX0, mGridSizeX*mGridSpacing, 1.0f, mGridSizeZ*mGridSpacing); + mVSML->translate(VSMathLib::AUX0, -mCenter[0], -mCenter[1], -mCenter[2]); + + memcpy(mMesh.transform, mVSML->get(VSMathLib::AUX0), sizeof(float) * 16); + + +// mScaleFactor = 2.0f;///mGridSizeX ; + + ilDeleteImage(imageID); + free (vertices); + free (indices); + + setNormals(); + + /* */ + + return true; +} + + +void +VSTerrainLib::setTextureCoordinates(int mode) { + + GLuint buffer; + float *tc = (float *)malloc(sizeof(float) * mGridSizeX * mGridSizeZ * 2); + + for (int i = 0; i < (int)mGridSizeX; ++i) + for (int j = 0; j < (int)mGridSizeZ; ++j) { + + if (mode == 0) { // REPEAT texture in each grid square + tc[(i*mGridSizeZ + j) * 2 + 0] = (float)( j); + tc[(i*mGridSizeZ + j) * 2 + 1] = (float)( j); + } + else { + tc[(i*mGridSizeZ + j) * 2 + 0] = j * 1.0f / mGridSizeZ; + tc[(i*mGridSizeZ + j) * 2 + 1] = i * 1.0f / mGridSizeX; + } + } + + glBindVertexArray(mMesh.vao); + + // buffer for textureCoordinates + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, + sizeof(float) * 2 * mGridSizeX * mGridSizeZ, + tc, + GL_STATIC_DRAW); + glEnableVertexAttribArray(VSShaderLib::TEXTURE_COORD_ATTRIB); + glVertexAttribPointer(VSShaderLib::TEXTURE_COORD_ATTRIB, 2, GL_FLOAT, 0, 0, 0); + + free (tc); +} + + +void +VSTerrainLib::setNormals() { + + float deltaHi, deltaHj; + float length; + GLuint buffer; + float *normals = (float *)malloc(sizeof(float) * mGridSizeX * mGridSizeZ * 3); + float aux[3]; + + for (int i = 0; i < (int)mGridSizeX; ++i) + for (int j = 0; j < (int)mGridSizeZ; ++j) { + + deltaHj = getHeight(j, i+1) - getHeight(j, i-1); + deltaHi = getHeight(j+1, i) - getHeight(j-1, i); + + aux[0] = -2 * 1.0f/(mGridSizeX) * deltaHj; + aux[1] = 4 * 1.0f/(mGridSizeX * mGridSizeZ); + aux[2] = 2 * 1.0f/(mGridSizeZ) * deltaHi; + + length = sqrt(aux[0] * aux[0] + aux[1] * aux[1] + aux[2] * aux[2]); + + if (deltaHi > 160) + int x=0; + + aux[0] /= length; + aux[1] /= length; + aux[2] /= length; + + normals[(i*mGridSizeZ + j) * 3 + 0] = aux[0]; + normals[(i*mGridSizeZ + j) * 3 + 1] = aux[1]; + normals[(i*mGridSizeZ + j) * 3 + 2] = aux[2]; + } + + glBindVertexArray(mMesh.vao); + + // buffer for normals + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, + sizeof(float) * 3 * mGridSizeX * mGridSizeZ, + normals, + GL_STATIC_DRAW); + glEnableVertexAttribArray(VSShaderLib::NORMAL_ATTRIB); + glVertexAttribPointer(VSShaderLib::NORMAL_ATTRIB, 3, GL_FLOAT, 0, 0, 0); + + free (normals); +} + + +float +VSTerrainLib::getHeight(int j , int i) { + + int iAux, jAux; + + iAux = (i / mScaleFactor); + jAux = (j / mScaleFactor); + + if (iAux < 0) + iAux = 0; + else if (iAux >= (int)(mGridSizeX / mScaleFactor)) + iAux = (mGridSizeX / mScaleFactor) - 1; + + if (jAux < 0) + jAux = 0; + else if (jAux >= (int)(mGridSizeZ / mScaleFactor)) + jAux = (mGridSizeZ / (int)mScaleFactor) - 1; + + return(mHeights[(int)(iAux * mGridSizeX / mScaleFactor) + jAux] * mHeightStep / 65536 ); + + //if (i < 0) + // i = 0; + //else if (i >= (int)(mGridSizeX / mScaleFactor)) + // i = mGridSizeX - 1; + + //if (j < 0) + // j = 0; + //else if (j >= (int)(mGridSizeZ / mScaleFactor)) + // j = mGridSizeZ - 1; + + //return(mHeights[i * mGridSizeX + j] * mHeightStep / 65536); +} + + +float +VSTerrainLib::getHeight(float x, float z) { + + + int x1, x2,z1,z2; + float xGrid, zGrid; + float fracX, fracZ, ha, hb; + + xGrid = x/mGridSpacing + mGridSizeX * 0.5f - 0.5f; + zGrid = z/mGridSpacing + mGridSizeZ * 0.5f - 0.5f; + + x1 = (int)floor(xGrid); + x2 = x1 + 1; + fracX = (xGrid - x1); + + z1 = (int)floor(zGrid); + z2 = z1 + 1; + fracZ = (zGrid - z1); + + ha = fracX * getHeight(x2,z1) + (1-fracX) * getHeight(x1,z1); + hb = fracX * getHeight(x2,z2) + (1-fracX) * getHeight(x1,z2); + + return(fracZ * hb + (ha * (1-fracZ))); +} + + +void +VSTerrainLib::addTexture(unsigned int unit, std::string filename) { + + mMesh.texUnits[unit] = loadRGBATexture(filename); + mMesh.mat.texCount++; +} + + +void +VSTerrainLib::setGridSpacing(float x) { + + mGridSpacing = x; +} + + +int +VSTerrainLib::getGridSize() { + + return mGridSizeX; +} + + +float +VSTerrainLib::getGridSpacing() { + + return mGridSpacing; +} + + +void +VSTerrainLib::setHeightStep(float f) { + + mHeightStep = f; +} \ No newline at end of file diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsTerrainLib.h b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsTerrainLib.h new file mode 100644 index 0000000..9eb1abb --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vsTerrainLib.h @@ -0,0 +1,80 @@ +/** ---------------------------------------------------------- + * \class VSTerrainLib + * + * Lighthouse3D + * + * Very Simple Terrain Library + * + * \version 0.1.0 + * Initial Release + * + * This lib provides creates a terrain model based on a height map + * + * Requirements: Devil, and tinyXML + * + * Full documentation at + * http://www.lighthouse3d.com/very-simple-libs + * + ---------------------------------------------------------------*/ + + + +#ifndef __VSTerrainLib__ +#define __VSTerrainLib__ + +#include +#include +#include +#include + +#include + +// include Resource Lib, from which it derives +#include "vsResourceLib.h" + + +class VSTerrainLib: public VSResourceLib{ + +public: + + VSTerrainLib(); + ~VSTerrainLib(); + + virtual bool load(std::string filename); + virtual void render(); + + virtual void addTexture(unsigned int unit, std::string filename); + + void setHeightStep(float f); + void setGridSpacing(float x); + float getGridSpacing(); + virtual float getHeight( float x, float z); + int getGridSize(); + + void setTextureCoordinates(int mode); + +protected: + void setNormals(); + + virtual float getHeight(int x, int z); + int mScaleFactor; + float mGridSpacing; + unsigned int mGridSizeX, mGridSizeZ; + float mHeightStep; + unsigned short *mHeights; + + struct MyMesh{ + + GLuint vao; + GLuint texUnits[MAX_TEXTURES]; + GLuint uniformBlockIndex; + float transform[16]; + int numIndices; + unsigned int type; + struct Material mat; + }; + + struct MyMesh mMesh; +}; + +#endif diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vslibs.h b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vslibs.h new file mode 100644 index 0000000..e31d4e1 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/OpenGLInsightsTessellation/vslibs.h @@ -0,0 +1,36 @@ +/** ---------------------------------------------------------- + * Very Simple Libraries + * + * From Lighthouse3D + * + * + * Full documentation at + * http://www.lighthouse3d.com/very-simple-libs + * + * + * These libs requires: + * GLEW (http://glew.sourceforge.net/) + * Devil (http://openil.sourceforge.net/) + * + ---------------------------------------------------------------*/ + + + +#ifdef _WIN32 + +#ifdef _DEBUG +#pragma comment(lib,"vsld.lib") +#else +#pragma comment(lib,"vsl.lib") +#endif + +#pragma comment(lib,"glew32.lib") +#endif + +#include "vsShaderLib.h" +#include "vsMathLib.h" +#include "vsLogLib.h" +#include "vsGLInfoLib.h" +#include "vsResourceLib.h" +#include "vsTerrainLib.h" +#include "vsTerrainLODSingleScaledLib.h" diff --git a/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/README.first.txt b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/README.first.txt new file mode 100644 index 0000000..f5a4627 --- /dev/null +++ b/Chapter 10 GPU Tessellation We Still Have a LOD of Terrain to Cover/README.first.txt @@ -0,0 +1,51 @@ +This demo shows the techniques described in the chapter +"GPU Tessellation: We still have a LOD of terrain to cover" +from the book "OpenGL Insights" + +The code is provided as is, without any warranties. + +The code must be edited to setup the terrain files (both texture and hight map) +and these should be squared and with dimensions that are multiple of 64. + +A makefile and a VS2010 project are included. + +This code depends on the following libs: + +- GLEW to enable OpenGL 4 functionality +- Devil to load the height map and texture +- FreeGLUT + +Once running the code, several settings can be tested, namely the +LOD mode, the pixels per triangle, and usage of culling. + +The terrain can also be viewed in wireframe so that the LOD effect can +be better grasped. + + + + + +Keys: + +LOD Mode +'y': Full tessellation +'t': Simple Tessellation +'r' : Set Roughness LOD + +Culling +'u': enable +'i': disable + +Pixels per Triangle: +use +/- to increment/decrement this value + +Polygon Mode +'l': GL_LINE +'f': GL_FILL + + +Have fun, + +António and Bruno +antonio.ramires@gmail.com +indie.mail@gmail.com \ No newline at end of file