Compare commits

...

98 Commits

Author SHA1 Message Date
Faerbit
3b25514233 Removing out gl_FragDepth as nvidia driver complains about it. 2016-04-15 10:44:26 +02:00
Faerbit
45d969c16e Removing -O2 flag because it breaks the windows build. 2015-06-04 11:52:44 +02:00
Faerbit
fe8b0a57cd Optimized scheduling once again. 2015-06-04 11:22:27 +02:00
Faerbit
3437ce6173 Updated glfw to version 3.1.1. 2015-06-03 23:15:52 +02:00
Faerbit
8452d18575 Fixing a bug in the scheduling. 2015-06-03 14:05:57 +02:00
Faerbit
4c40ddd12d Simplifying if condition. 2015-06-03 11:23:17 +02:00
Faerbit
00a08bf5f0 Fixing a crash when maxShadowRenderCount is set to one. 2015-06-03 02:25:47 +02:00
Faerbit
52ea40100f Correcting scheduling of shadows. 2015-06-03 02:18:31 +02:00
Faerbit
4ba056c6d9 Correctly intializing farPlane variable in Level. 2015-06-03 02:12:00 +02:00
Faerbit
67b44042bd Made getClosestLights output more lights to take advantage of the higher maxShadowSampleCount. 2015-06-02 21:37:58 +02:00
Faerbit
1ef8047f42 Implemented a function to check how high the maxShadowSampleCount should be. 2015-06-02 21:14:54 +02:00
Faerbit
b8114ebd91 Increasing maxShadowSampleCount to 26. 2015-06-02 21:14:22 +02:00
Faerbit
a6876f0872 Optimizing scheduling of shadow renders. 2015-06-02 20:46:21 +02:00
Faerbit
5f779ea3d5 Fixing moving shadows of flames once again. 2015-06-02 20:15:48 +02:00
Faerbit
bedc836cb0 Merge branch 'master' of github.com:Faerbit/Saxum 2015-06-02 19:33:23 +02:00
Faerbit
56ca9d694b Added a little bit of input validation. 2015-06-02 18:39:17 +02:00
Fabian
d752b34dfc Lowering default graphics options. 2015-06-02 17:43:41 +02:00
Faerbit
b55a5e1906 Merge branch 'shadow-renderqueue' 2015-06-02 17:39:08 +02:00
Faerbit
ea8e7b6048 Fixing the rendering of the shadows. Closes #10. 2015-06-02 17:36:55 +02:00
Faerbit
e8c1dee3b5 Improved scheduling of point lights for the render queue by fixing a bug. 2015-06-02 00:33:55 +02:00
Faerbit
819584ef15 Implemented updating of shadow render queue. Doesn't work satisfactory right now. (#10) 2015-06-02 00:18:22 +02:00
Faerbit
ea194309ef Moving shadows of flames correctly with wind. 2015-06-01 22:35:05 +02:00
Faerbit
b280ad8c12 Small performance optimization. 2015-06-01 16:17:37 +02:00
Faerbit
90dbd52aca Implemented rendering of shadow render queue (#10). 2015-06-01 15:47:30 +02:00
Faerbit
2a09c7f83c Fixing wrong shader getting used. 2015-06-01 13:35:23 +02:00
Faerbit
3fffa4c4ca Removing code meant for shadow-renderqueue branch. 2015-06-01 13:29:08 +02:00
Faerbit
592f84b548 Implemented the the initilization of the shadow render queue.(#10) 2015-06-01 10:48:56 +02:00
Faerbit
836f75d7fe Various cleanups. 2015-06-01 10:45:15 +02:00
Faerbit
f389aa2f4a Fixed pointlight shadows not getting rendered correctly. 2015-06-01 00:57:36 +02:00
Faerbit
4a35c4feba Increase maximum possible point light shadows to 15. 2015-05-31 21:31:31 +02:00
Faerbit
53e8e6d719 Fixing a memory leak by converting pointers to smart pointers. 2015-05-31 21:17:46 +02:00
Faerbit
b8db45fc7c Reenabled bias calculation depeding on distance. 2015-05-31 20:31:12 +02:00
Faerbit
34cac6f464 Moving torch because of shadow artifacts. 2015-05-31 18:46:44 +02:00
Faerbit
5dbf839f76 Reverting to old way when to sample the directional shadow, because of a bug introduced by this. 2015-05-31 17:51:11 +02:00
Faerbit
806182835f Changed wind direction because of flames clipping into the terrain. 2015-05-31 17:36:58 +02:00
Faerbit
52a36c9b18 Added additional directional shadow maps for better looking sun shadows. 2015-05-31 17:36:21 +02:00
Faerbit
1f1741effb Added poison sampling to point light shadows. Closes #11. 2015-05-31 16:34:14 +02:00
Faerbit
96f146d6f0 Adding optimization flags to release build. 2015-05-31 15:52:00 +02:00
Faerbit
23618a2fa8 Added additional torches to better light some previously too dark areas. 2015-05-31 15:42:21 +02:00
Faerbit
030f8b298a Increased the geometry resolution of the flames. 2015-05-31 15:23:54 +02:00
Faerbit
c8ba61ca56 Performance optimization for deciding when the directional shadow gets rendered. 2015-05-28 15:03:08 +02:00
Faerbit
a8ce6916e7 Refactored level.cc to use the new getSurroundingChunks function. 2015-05-28 11:23:54 +02:00
Faerbit
b110551db6 Added a parameter to getSurroundingChunks to limit the chunkRenderDistance. 2015-05-28 11:23:27 +02:00
Faerbit
9ea1630057 Fixed a bug in getSurroundingChunks. 2015-05-28 11:16:30 +02:00
Faerbit
32b9d6597e Enable debug symbols for debug compilation. 2015-05-28 10:42:12 +02:00
Faerbit
b6467a92a3 Added getSurroundingChunks method to level. 2015-05-27 10:27:08 +02:00
Faerbit
0bee5f915d Removing useless include. 2015-05-26 21:32:37 +02:00
Faerbit
536ffc899e Fixing game not getting scaled correctly in fullscreen. 2015-05-16 13:54:01 +02:00
Faerbit
a56907a956 Fixing crash in fullscreen. 2015-05-16 12:05:37 +02:00
Faerbit
5a1ab063b7 Removing last mutex. 2015-04-25 23:27:12 +02:00
Faerbit
a173e1b9eb Making constant variable constant. 2015-04-25 22:56:11 +02:00
Faerbit
95ce45c944 Make packaging fail if compilation failed. 2015-04-25 22:48:45 +02:00
Faerbit
faf19aa424 Should have been in the last commit. 2015-04-25 22:42:44 +02:00
Faerbit
9b89007674 Removing mutexes because threading is going to be implemented differently.(#6) 2015-04-25 22:38:44 +02:00
Faerbit
40dfbf33d9 Updating loading screen during loading. 2015-04-25 22:29:37 +02:00
Faerbit
96a8943cb7 Protected some functions of graphics with the init_mutex. 2015-04-12 21:56:04 +02:00
Faerbit
b52bef795a Added init mutex to graphics. 2015-04-12 21:51:11 +02:00
Faerbit
9b2ca4d1d3 Made sun brighter during sun rise. 2015-04-12 21:16:17 +02:00
Faerbit
93f790ec22 Simplifing object render method by givin the skydome day texture it's own texture unit. 2015-04-12 21:06:59 +02:00
Faerbit
9b57eb0df1 Moving resizing of loading screen to resize method. 2015-04-12 20:16:24 +02:00
Faerbit
2962acfded Made sun shine through the fog. 2015-03-27 15:05:01 +01:00
Faerbit
d642582956 Protecting some functions with the light_mutex. 2015-03-24 20:41:38 +01:00
Faerbit
127ee7a6ca Adding mutex to level. 2015-03-24 20:37:56 +01:00
Faerbit
fc2ce96771 Moving updateClosestLights() to level class. 2015-03-24 19:50:26 +01:00
Faerbit
2b2e05f009 Protecting all member functions of entity class with the mutex. 2015-03-24 19:12:33 +01:00
Faerbit
5546abd24a Adding mutex to entity class. 2015-03-24 19:09:39 +01:00
Faerbit
796db123b7 Removing useless assignment. 2015-03-24 19:09:14 +01:00
Faerbit
b39e6702cc Changing default init of camera. 2015-03-24 19:08:49 +01:00
Faerbit
6d167a2d2a Removing commented code. 2015-03-24 18:29:28 +01:00
Faerbit
319b57bf7a Removing useless assignment. 2015-03-22 13:49:25 +01:00
Faerbit
300f14c752 Fixing mismatching deallocation. 2015-03-22 13:25:43 +01:00
Faerbit
3de85042d0 Prettified sun rise. 2015-03-21 21:46:58 +01:00
Faerbit
2a2e89d445 Changed when light contributions are not taken into account. Increased FPS. 2015-03-21 20:55:21 +01:00
Faerbit
78972a87bf Fixed water plane not getting rendered after introducing rendering queue. 2015-03-21 19:02:24 +01:00
Faerbit
2a3f976b5e Slight fps increas by reducing the amount the point lights have to render. 2015-03-21 18:57:14 +01:00
Faerbit
1fd6058eaf Finshed work now sorting objects after loading. 2015-03-21 18:44:08 +01:00
Faerbit
a07a4bbb91 Commiting unfinished work. 2015-03-21 15:05:22 +01:00
Faerbit
2a0cb3ca1d Implemented a renderQueue which is sorted by materials. Not feasible. Closes #12. 2015-03-20 23:45:28 +01:00
Faerbit
795801faa6 Sped up the lookup of the texture unit. 2015-03-19 18:26:51 +01:00
Faerbit
3680abfba4 Loaded all textures at the beginning of the application. Closes #7. 2015-03-18 16:26:20 +01:00
Faerbit
09282f51fd Changing where uniform are set minimizing the communication with the gpu. 2015-03-18 09:14:09 +01:00
Faerbit
3a2156492e Removing useless light update. 2015-03-18 08:58:24 +01:00
Faerbit
43b752ee63 Implemented cross chunk objects. This concludes the chunk render implementation and closes #4. 2015-03-18 08:54:38 +01:00
Faerbit
f9212c9938 Increased renderdistance a bit to prevent popping of chunks. 2015-03-18 08:53:31 +01:00
Faerbit
79223b4c02 Do not render behind the skydome. 2015-03-17 19:10:23 +01:00
Faerbit
ac48ab8cc0 Now also using the correct chunks for the objects and rendering only the chunks which are necessary. 2015-03-17 14:54:18 +01:00
Faerbit
d0fed9a321 Now generating seperate terrain meshes for chunks. 2015-03-17 12:08:49 +01:00
Faerbit
a7fb739204 Removing useless variable. 2015-03-17 09:42:51 +01:00
Faerbit
7957b8b555 Reenabling fps display in release build. 2015-03-17 09:41:37 +01:00
Faerbit
498be94102 Added generation of chunks. 2015-03-17 09:39:42 +01:00
Faerbit
7b742e913f Introduced chunk class. 2015-03-16 16:58:50 +01:00
Faerbit
73f7ec6a70 Removing unsafe deleteObject function. 2015-03-16 16:15:12 +01:00
Faerbit
761d25e9c7 Removing unused lua scripts. 2015-03-16 16:14:22 +01:00
Faerbit
1dde41d5f4 Do not update objects which have a mass of zero and can therefore by definition not change position or rotation. 2015-03-16 16:05:36 +01:00
Faerbit
07e036451d Merge branch 'master' of github.com:Faerbit/Saxum 2015-03-16 15:26:40 +01:00
Faerbit
ab7d1c81df Adding parameters to the makeTrinagleMesh to control the area for which it creates the terrain. Also changing most unsigned ints to ints to make said more roboust in use. 2015-03-16 15:26:30 +01:00
Fabian
10a87be81f Gave a few infos about modding. 2015-03-15 23:15:25 +01:00
Fabian
ea21910255 Downloads are now available. 2015-03-15 23:14:13 +01:00
85 changed files with 1838 additions and 1337 deletions

View File

@ -53,8 +53,11 @@ ADD_DEFINITIONS(-DNO_SPACE_NAVIGATOR_SUPPORT)
#
# Lets the binary get written to a shared folder (which can be ignored by git).
# Will also set the run directory for QTCreator:
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -DSAXUM_DEBUG")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -DSAXUM_DEBUG")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -DSAXUM_DEBUG -g")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -DSAXUM_DEBUG -g")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -DNDEBUG")
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -DNDEBUG")
set(dir ${CMAKE_CURRENT_SOURCE_DIR}/binaries)
set(EXECUTABLE_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)

View File

@ -4,7 +4,7 @@ This is a Marble Puzzle/Exploration Game developed in the practical course
at the institute for Computer Graphics and Multimedia at the RWTH Aachen.
##Downloads
See [release page](https://github.com/Faerbit/Saxum/releases) for downloads(Coming soon(tm)).
See [release page](https://github.com/Faerbit/Saxum/releases) for downloads.
##Controls
You can control the camera by moving the mouse. You can zoom with the mouse wheel.
@ -21,5 +21,4 @@ In theory this should also compile on OS X. Since I do not own a Mac it is impos
If you get it compiling, please get in touch with me afterwards.
##Modding
In theory the game is highly moddable. If you're interested in this, please get in touch with me,
so I can explain the workflow to you.
In theory the game is highly moddable. For modding some knowledge in XML and Lua is required. If you're interested in this, please get in touch with me, so I can explain the workflow to you.

View File

@ -11,11 +11,11 @@
If you feel your game runs smooth enough you can increase them to
increase the visual quality. -->
<shadowCubeSize>1024</shadowCubeSize>
<shadowCubeSize>512</shadowCubeSize>
<farPlane>150.0</farPlane>
<maxShadowRenderCount>5</maxShadowRenderCount>
<maxShadowRenderCount>3</maxShadowRenderCount>
<!-- The following stuff is used to configure the application.
Do not change unless you know what you are doing. -->

View File

@ -5,6 +5,7 @@
<composition>
<typeID>20</typeID>
<ignoreHeightmap>false</ignoreHeightmap>
<crossesChunks>true</crossesChunks>
<object>
<modelPath>marbleSmooth.obj</modelPath>
<xOffset>0.0</xOffset>
@ -22,6 +23,7 @@
<composition>
<typeID>40</typeID>
<ignoreHeightmap>false</ignoreHeightmap>
<crossesChunks>true</crossesChunks>
<object>
<modelPath>block.obj</modelPath>
<xOffset>0.0</xOffset>
@ -39,6 +41,7 @@
<composition>
<typeID>60</typeID>
<ignoreHeightmap>false</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>column.obj</modelPath>
<xOffset>0.0</xOffset>
@ -56,6 +59,7 @@
<composition>
<typeID>80</typeID>
<ignoreHeightmap>false</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>torch.obj</modelPath>
<xOffset>0.0</xOffset>
@ -85,6 +89,7 @@
<composition>
<typeID>81</typeID>
<ignoreHeightmap>false</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>torch.obj</modelPath>
<xOffset>0.0</xOffset>
@ -129,6 +134,7 @@
<composition>
<typeID>100</typeID>
<ignoreHeightmap>false</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>column.obj</modelPath>
<xOffset>0.0</xOffset>
@ -168,6 +174,7 @@
<composition>
<typeID>120</typeID>
<ignoreHeightmap>false</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>switchInner.obj</modelPath>
<xOffset>0.0</xOffset>
@ -251,6 +258,7 @@
<composition>
<typeID>140</typeID>
<ignoreHeightmap>true</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>block.obj</modelPath>
<xOffset>0.0</xOffset>
@ -268,6 +276,7 @@
<composition>
<typeID>141</typeID>
<ignoreHeightmap>true</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>block.obj</modelPath>
<xOffset>0.0</xOffset>
@ -289,6 +298,7 @@
<composition>
<typeID>160</typeID>
<ignoreHeightmap>true</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>block.obj</modelPath>
<xOffset>0.0</xOffset>
@ -339,6 +349,7 @@
<composition>
<typeID>161</typeID>
<ignoreHeightmap>true</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>block.obj</modelPath>
<xOffset>0.0</xOffset>
@ -389,6 +400,7 @@
<composition>
<typeID>163</typeID>
<ignoreHeightmap>true</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>torch.obj</modelPath>
<xOffset>0.0</xOffset>
@ -462,6 +474,7 @@
<composition>
<typeID>164</typeID>
<ignoreHeightmap>true</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>torch.obj</modelPath>
<xOffset>-1.5</xOffset>
@ -535,6 +548,7 @@
<composition>
<typeID>180</typeID>
<ignoreHeightmap>true</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>simpleWall.obj</modelPath>
<xOffset>0.0</xOffset>
@ -552,6 +566,7 @@
<composition>
<typeID>181</typeID>
<ignoreHeightmap>true</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>simpleWall.obj</modelPath>
<xOffset>0.0</xOffset>
@ -569,6 +584,7 @@
<composition>
<typeID>200</typeID>
<ignoreHeightmap>false</ignoreHeightmap>
<crossesChunks>true</crossesChunks>
<object>
<modelPath>block.obj</modelPath>
<xOffset>0.0</xOffset>
@ -586,6 +602,7 @@
<composition>
<typeID>220</typeID>
<ignoreHeightmap>true</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>gate.obj</modelPath>
<xOffset>0.0</xOffset>
@ -603,6 +620,7 @@
<composition>
<typeID>221</typeID>
<ignoreHeightmap>true</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>gate.obj</modelPath>
<xOffset>0.0</xOffset>
@ -620,6 +638,7 @@
<composition>
<typeID>240</typeID>
<ignoreHeightmap>false</ignoreHeightmap>
<crossesChunks>true</crossesChunks>
<object>
<modelPath>movableBlock.obj</modelPath>
<xOffset>0.0</xOffset>
@ -637,6 +656,7 @@
<composition>
<typeID>245</typeID>
<ignoreHeightmap>false</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>brazier.obj</modelPath>
<xOffset>0.0</xOffset>
@ -654,6 +674,7 @@
<composition>
<typeID>250</typeID>
<ignoreHeightmap>false</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>hint.obj</modelPath>
<xOffset>0.0</xOffset>
@ -671,6 +692,7 @@
<composition>
<typeID>254</typeID>
<ignoreHeightmap>false</ignoreHeightmap>
<crossesChunks>false</crossesChunks>
<object>
<modelPath>exit.obj</modelPath>
<xOffset>0.0</xOffset>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -1,3 +1,183 @@
<composition>
<scale>1.0</scale>
<xRot>0.0</xRot>
<yRot>0.0</yRot>
<zRot>0.0</zRot>
<manualPos>false</manualPos>
<xPos>173.500000</xPos>
<yOffset>0.0</yOffset>
<zPos>159.500000</zPos>
<idGreen>1</idGreen>
<idBlue>120</idBlue>
<typeID>80</typeID>
<trigger>
<name>-</name>
<undo>false</undo>
<xPosition>0</xPosition>
<yPosition>0</yPosition>
<zPosition>0</zPosition>
<targetIdGreen>-</targetIdGreen>
<targetIdBlue>-</targetIdBlue>
<distance>1.0</distance>
<isBiggerThan>false</isBiggerThan>
<objectNum>0</objectNum>
<luaScript>-</luaScript>
<toChangeIdGreen>0</toChangeIdGreen>
<toChangeIdBlue>0</toChangeIdBlue>
<toChangeObjNum>0</toChangeObjNum>
</trigger>
</composition>
<composition>
<scale>1.0</scale>
<xRot>0.0</xRot>
<yRot>0.0</yRot>
<zRot>0.0</zRot>
<manualPos>false</manualPos>
<xPos>-107.500000</xPos>
<yOffset>0.0</yOffset>
<zPos>48.500000</zPos>
<idGreen>1</idGreen>
<idBlue>119</idBlue>
<typeID>80</typeID>
<trigger>
<name>-</name>
<undo>false</undo>
<xPosition>0</xPosition>
<yPosition>0</yPosition>
<zPosition>0</zPosition>
<targetIdGreen>-</targetIdGreen>
<targetIdBlue>-</targetIdBlue>
<distance>1.0</distance>
<isBiggerThan>false</isBiggerThan>
<objectNum>0</objectNum>
<luaScript>-</luaScript>
<toChangeIdGreen>0</toChangeIdGreen>
<toChangeIdBlue>0</toChangeIdBlue>
<toChangeObjNum>0</toChangeObjNum>
</trigger>
</composition>
<composition>
<scale>1.0</scale>
<xRot>0.0</xRot>
<yRot>0.0</yRot>
<zRot>0.0</zRot>
<manualPos>false</manualPos>
<xPos>-140.500000</xPos>
<yOffset>0.0</yOffset>
<zPos>16.500000</zPos>
<idGreen>1</idGreen>
<idBlue>118</idBlue>
<typeID>80</typeID>
<trigger>
<name>-</name>
<undo>false</undo>
<xPosition>0</xPosition>
<yPosition>0</yPosition>
<zPosition>0</zPosition>
<targetIdGreen>-</targetIdGreen>
<targetIdBlue>-</targetIdBlue>
<distance>1.0</distance>
<isBiggerThan>false</isBiggerThan>
<objectNum>0</objectNum>
<luaScript>-</luaScript>
<toChangeIdGreen>0</toChangeIdGreen>
<toChangeIdBlue>0</toChangeIdBlue>
<toChangeObjNum>0</toChangeObjNum>
</trigger>
</composition>
<composition>
<scale>1.0</scale>
<xRot>0.0</xRot>
<yRot>0.0</yRot>
<zRot>0.0</zRot>
<manualPos>false</manualPos>
<xPos>-158.500000</xPos>
<yOffset>0.0</yOffset>
<zPos>8.500000</zPos>
<idGreen>1</idGreen>
<idBlue>116</idBlue>
<typeID>80</typeID>
<trigger>
<name>-</name>
<undo>false</undo>
<xPosition>0</xPosition>
<yPosition>0</yPosition>
<zPosition>0</zPosition>
<targetIdGreen>-</targetIdGreen>
<targetIdBlue>-</targetIdBlue>
<distance>1.0</distance>
<isBiggerThan>false</isBiggerThan>
<objectNum>0</objectNum>
<luaScript>-</luaScript>
<toChangeIdGreen>0</toChangeIdGreen>
<toChangeIdBlue>0</toChangeIdBlue>
<toChangeObjNum>0</toChangeObjNum>
</trigger>
</composition>
<composition>
<scale>1.0</scale>
<xRot>0.0</xRot>
<yRot>0.0</yRot>
<zRot>0.0</zRot>
<manualPos>false</manualPos>
<xPos>-95.500000</xPos>
<yOffset>0.0</yOffset>
<zPos>70.500000</zPos>
<idGreen>1</idGreen>
<idBlue>111</idBlue>
<typeID>80</typeID>
<trigger>
<name>-</name>
<undo>false</undo>
<xPosition>0</xPosition>
<yPosition>0</yPosition>
<zPosition>0</zPosition>
<targetIdGreen>-</targetIdGreen>
<targetIdBlue>-</targetIdBlue>
<distance>1.0</distance>
<isBiggerThan>false</isBiggerThan>
<objectNum>0</objectNum>
<luaScript>-</luaScript>
<toChangeIdGreen>0</toChangeIdGreen>
<toChangeIdBlue>0</toChangeIdBlue>
<toChangeObjNum>0</toChangeObjNum>
</trigger>
</composition>
<composition>
<scale>1.0</scale>
<xRot>0.0</xRot>
<yRot>0.0</yRot>
<zRot>0.0</zRot>
<manualPos>false</manualPos>
<xPos>-215.500000</xPos>
<yOffset>0.0</yOffset>
<zPos>60.500000</zPos>
<idGreen>0</idGreen>
<idBlue>206</idBlue>
<typeID>80</typeID>
<trigger>
<name>-</name>
<undo>false</undo>
<xPosition>0</xPosition>
<yPosition>0</yPosition>
<zPosition>0</zPosition>
<targetIdGreen>-</targetIdGreen>
<targetIdBlue>-</targetIdBlue>
<distance>1.0</distance>
<isBiggerThan>false</isBiggerThan>
<objectNum>0</objectNum>
<luaScript>-</luaScript>
<toChangeIdGreen>0</toChangeIdGreen>
<toChangeIdBlue>0</toChangeIdBlue>
<toChangeObjNum>0</toChangeObjNum>
</trigger>
</composition>
<composition>
<scale>1.0</scale>
<xRot>0.0</xRot>
@ -448,36 +628,6 @@
</trigger>
</composition>
<composition>
<scale>1.0</scale>
<xRot>0.0</xRot>
<yRot>0.0</yRot>
<zRot>0.0</zRot>
<manualPos>false</manualPos>
<xPos>184.500000</xPos>
<yOffset>0.0</yOffset>
<zPos>159.500000</zPos>
<idGreen>1</idGreen>
<idBlue>109</idBlue>
<typeID>80</typeID>
<trigger>
<name>-</name>
<undo>false</undo>
<xPosition>0</xPosition>
<yPosition>0</yPosition>
<zPosition>0</zPosition>
<targetIdGreen>-</targetIdGreen>
<targetIdBlue>-</targetIdBlue>
<distance>1.0</distance>
<isBiggerThan>false</isBiggerThan>
<objectNum>0</objectNum>
<luaScript>-</luaScript>
<toChangeIdGreen>0</toChangeIdGreen>
<toChangeIdBlue>0</toChangeIdBlue>
<toChangeObjNum>0</toChangeObjNum>
</trigger>
</composition>
<composition>
<scale>1.0</scale>
<xRot>0.0</xRot>
@ -13259,7 +13409,7 @@
<rColour>1.0</rColour>
<gColour>1.0</gColour>
<bColour>0.9</bColour>
<intensity>0.6</intensity>
<intensity>0.7</intensity>
</directionalLight>
<terrain>

View File

@ -1,15 +0,0 @@
local global = require( "global" )
if(global.triggeredDeleteObject == nil) then
global.triggeredDeleteObject = false
end
function trigger(objectToChange)
if(global.triggeredDeleteObject == false) then
if(not level) then
print("No level found in Lua!")
return
end
level:deleteObject(objectToChange)
global.triggeredDeleteObject = true
print("deleteObject")
end
end

View File

@ -1,19 +0,0 @@
local global = require( "global" )
if(global.triggeredDeleteRandomObject == nil) then
global.triggeredDeleteRandomObject = false
end
function trigger(objectToChange)
if(global.triggeredDeleteRandomObject == false) then
if(not level) then
print("No level found in Lua!")
return
end
a = level:getObjectCount()
rand = math.random(0, a - 1)
level:deleteObject(rand)
global.triggeredDeleteRandomObject = true
print("deleteRandomObject")
end
end

View File

@ -1,29 +0,0 @@
local global = require( "global" )
if(global.triggeredOpenDoor1 == nil) then
global.triggeredOpenDoor1 = false
end
function trigger(objectToChange)
if(global.triggeredOpenDoor1 == false) then
if(not level) then
print("No level found in Lua!")
return
end
if(not global.openDoorCounter) then
global.openDoorCounter = 0
end
global.openDoorCounter = global.openDoorCounter + 1
if (global.openDoorCounter == 3) then
local strength = 1
local xPos = 0
local yPos = 0
local zPos = 0
level:moveObject(objectToChange, strength, xPos, yPos, zPos)
print("Opening the door")
end
global.triggeredOpenDoor1undo = false
global.triggeredOpenDoor1 = true
print("openDoor1")
end
end

View File

@ -1,20 +0,0 @@
local global = require( "global" )
if(global.triggeredOpenDoor1undo == nil) then
global.triggeredOpenDoor1undo = true
end
function trigger(objectToChange)
if(global.triggeredOpenDoor1undo == false) then
if(not level) then
print("No level found in Lua!")
return
end
if(global.triggeredOpenDoor1) then
global.openDoorCounter = global.openDoorCounter - 1
global.triggeredOpenDoor1 = false
end
global.triggeredOpenDoor1undo = true
print("openDoor1undo")
end
end

View File

@ -1,29 +0,0 @@
local global = require( "global" )
if(global.triggeredOpenDoor2 == nil) then
global.triggeredOpenDoor2 = false
end
function trigger(objectToChange)
if(global.triggeredOpenDoor2 == false) then
if(not level) then
print("No level found in Lua!")
return
end
if(not global.openDoorCounter) then
global.openDoorCounter = 0
end
global.openDoorCounter = global.openDoorCounter + 1
if (global.openDoorCounter == 3) then
local strength = 1
local xPos = 0
local yPos = 0
local zPos = 0
level:moveObject(objectToChange, strength, xPos, yPos, zPos)
print("Opening the door")
end
global.triggeredOpenDoor2undo = false
global.triggeredOpenDoor2 = true
print("openDoor2")
end
end

View File

@ -1,20 +0,0 @@
local global = require( "global" )
if(global.triggeredOpenDoor2undo == nil) then
global.triggeredOpenDoor2undo = true
end
function trigger(objectToChange)
if(global.triggeredOpenDoor2undo == false) then
if(not level) then
print("No level found in Lua!")
return
end
if(global.triggeredOpenDoor2) then
global.openDoorCounter = global.openDoorCounter - 1
global.triggeredOpenDoor2 = false
end
global.triggeredOpenDoor2undo = true
print("openDoor2undo")
end
end

View File

@ -1,29 +0,0 @@
local global = require( "global" )
if(global.triggeredOpenDoor3 == nil) then
global.triggeredOpenDoor3 = false
end
function trigger(objectToChange)
if(global.triggeredOpenDoor3 == false) then
if(not level) then
print("No level found in Lua!")
return
end
if(not global.openDoorCounter) then
global.openDoorCounter = 0
end
global.openDoorCounter = global.openDoorCounter + 1
if (global.openDoorCounter == 3) then
local strength = 1
local xPos = 0
local yPos = 0
local zPos = 0
level:moveObject(objectToChange, strength, xPos, yPos, zPos)
print("Opening the door")
end
global.triggeredOpenDoor3undo = false
global.triggeredOpenDoor3 = true
print("openDoor3")
end
end

View File

@ -1,20 +0,0 @@
local global = require( "global" )
if(global.triggeredOpenDoor3undo == nil) then
global.triggeredOpenDoor3undo = false
end
function trigger(objectToChange)
if(global.triggeredOpenDoor3undo == false) then
if(not level) then
print("No level found in Lua!")
return
end
if(global.triggeredOpenDoor3) then
global.openDoorCounter = global.openDoorCounter - 1
global.triggeredOpenDoor3 = false
end
global.triggeredOpenDoor3undo = true
print("openDoor3undo")
end
end

View File

@ -1,7 +1,5 @@
#version 150
out float gl_FragDepth;
void main() {
gl_FragDepth = gl_FragCoord.z;
}

View File

@ -4,8 +4,6 @@ in vec4 fragPosition;
uniform float farPlane;
out float gl_FragDepth;
void main() {
float nearPlane = 0.1;
float A = -(farPlane+nearPlane)/(farPlane-nearPlane);

View File

@ -3,7 +3,7 @@
uniform mat4 modelViewProjectionMatrix;
uniform float time;
uniform bool bottom;
uniform bool left;
uniform int circle_index;
uniform vec2 skew;
layout(points) in;
@ -75,19 +75,11 @@ void main() {
for (i; i<render_end; i+=step) {
float downRadius = radiusFunction(i);
float upRadius = radiusFunction(i+step);
float circle_end = 0.0;
int j = 0;
if (left) {
j = 0;
circle_end = resolution/2.0;
}
else {
j = int(resolution/2.0);
circle_end = resolution;
}
int j = int(resolution/2.0) * circle_index;
int circle_end = int(resolution/2.0) * (circle_index + 1);
for (j; j<circle_end; j++) {
float leftAngle = PI * 2.0 / resolution * j;
float rightAngle = PI * 2.0 / resolution * (j+1);
float leftAngle = PI * 2.0 / resolution / 4.0 * j;
float rightAngle = PI * 2.0 / resolution / 4.0 * (j+1);
vec4 offset = vec4(cos(rightAngle) * downRadius, i, -sin(rightAngle) * downRadius, 0.0);
gl_Position = gl_in[0].gl_Position + modelViewProjectionMatrix * offset;

View File

@ -6,6 +6,8 @@ in vec4 fragPosition;
in vec4 shadowCoord0;
in vec4 shadowCoord1;
in vec4 shadowCoord2;
in vec4 shadowCoord3;
in vec4 shadowCoord4;
out vec4 oColor;
@ -13,6 +15,8 @@ uniform sampler2D uTexture;
uniform sampler2DShadow shadowMap_directional0;
uniform sampler2DShadow shadowMap_directional1;
uniform sampler2DShadow shadowMap_directional2;
uniform sampler2DShadow shadowMap_directional3;
uniform sampler2DShadow shadowMap_directional4;
uniform samplerCubeShadow shadowMap_cube0;
uniform samplerCubeShadow shadowMap_cube1;
uniform samplerCubeShadow shadowMap_cube2;
@ -23,6 +27,22 @@ uniform samplerCubeShadow shadowMap_cube6;
uniform samplerCubeShadow shadowMap_cube7;
uniform samplerCubeShadow shadowMap_cube8;
uniform samplerCubeShadow shadowMap_cube9;
uniform samplerCubeShadow shadowMap_cube10;
uniform samplerCubeShadow shadowMap_cube11;
uniform samplerCubeShadow shadowMap_cube12;
uniform samplerCubeShadow shadowMap_cube13;
uniform samplerCubeShadow shadowMap_cube14;
uniform samplerCubeShadow shadowMap_cube15;
uniform samplerCubeShadow shadowMap_cube16;
uniform samplerCubeShadow shadowMap_cube17;
uniform samplerCubeShadow shadowMap_cube18;
uniform samplerCubeShadow shadowMap_cube19;
uniform samplerCubeShadow shadowMap_cube20;
uniform samplerCubeShadow shadowMap_cube21;
uniform samplerCubeShadow shadowMap_cube22;
uniform samplerCubeShadow shadowMap_cube23;
uniform samplerCubeShadow shadowMap_cube24;
uniform samplerCubeShadow shadowMap_cube25;
uniform vec3 ambientColor;
uniform float ambientFactor;
uniform float diffuseFactor;
@ -33,7 +53,7 @@ uniform int lightCount;
uniform int maxShadowRenderCount;
uniform vec3 directionalLightVector;
uniform vec3 directionalColor;
uniform float directionalIntensity;
uniform float targetDirectionalIntensity;
uniform vec3 lightSources[32];
uniform vec3 lightColors[32];
uniform float lightIntensities[32];
@ -67,6 +87,25 @@ vec2 poissonDisk[16] = vec2[](
vec2( 0.14383161, -0.14100790 )
);
vec3 poissonDisk3D[16] = vec3[] (
vec3( 0.541140674379, -0.67854138769, 0.482325914183 ),
vec3( -0.427608163826, 0.79190057714, -0.403470341832 ),
vec3( -0.226067542852, -0.628594453842, -0.661035377645 ),
vec3( -0.811708612677, -0.0340861134035, 0.580406649804 ),
vec3( 0.731005386334, 0.0695021546098, -0.606146385926 ),
vec3( 0.213076426293, 0.6269493206, 0.744636925499 ),
vec3( -0.124461723355, 0.0768244304602, 0.0386785336463 ),
vec3( -0.945249148757, 0.00944808073483, -0.318861658446 ),
vec3( 0.802723394956, 0.124750583818, 0.273800670393 ),
vec3( -0.0571970562351, -0.156203447559, 0.908410256437 ),
vec3( -0.442066534087, -0.709699743423, 0.232493422739 ),
vec3( -0.317263286361, 0.194934041517, -0.923816906742 ),
vec3( 0.381481981953, 0.798989636516, -0.0466460997255 ),
vec3( -0.42752547127, 0.597430401925, 0.374108050255 ),
vec3( 0.12603138305, -0.980780120028, -0.120190366913 ),
vec3( 0.470540545819, -0.633374601042, -0.585070778068 )
);
float flickerFunction(int index) {
float windPower = length(movement);
if (windPower < 0.8) {
@ -121,27 +160,33 @@ vec3 sunColor(float dot){
return mix(directionalColor, vec3(fogColorRise), riseFactor);
}
float sampleDirectionalShadow(sampler2DShadow shadowMap, vec4 shadowCoord, float maxBias ) {
float sunIntensity(float dot) {
return targetDirectionalIntensity * sin(2*dot);
}
float sampleDirectionalShadow(sampler2DShadow shadowMap, vec4 shadowCoord, float maxBias, float intensity) {
float visibility = 1.0;
const float stretching = 650.0;
float bias = 0.001*tan(acos(clamp(dot(vNormal, -directionalLightVector), 0.0, 1.0)));
bias = clamp(bias, 0.0, maxBias);
for (int i=0; i<4; i++) {
visibility -= directionalIntensity/16*(1.0-texture(shadowMap, vec3(shadowCoord.xy + poissonDisk[i]/stretching, shadowCoord.z - bias)));
visibility -= intensity/16*(1.0-texture(shadowMap, vec3(shadowCoord.xy + poissonDisk[i]/stretching, shadowCoord.z - bias)));
}
if (visibility == 1.0-(directionalIntensity/16)*4)
if (visibility == 1.0-(intensity/16)*4)
{
visibility = 1.0-directionalIntensity;
visibility = 1.0-intensity;
}
else if (visibility != 1.0) {
for (int i=0; i<12; i++) {
visibility -= directionalIntensity/16*(1.0-texture(shadowMap, vec3(shadowCoord.xy + poissonDisk[i]/stretching, shadowCoord.z - bias)));
visibility -= intensity/16*(1.0-texture(shadowMap, vec3(shadowCoord.xy + poissonDisk[i]/stretching, shadowCoord.z - bias)));
}
}
return visibility;
}
float samplePointShadow(samplerCubeShadow shadowMap, vec3 lightDirection) {
float samplePointShadow(samplerCubeShadow shadowMap, vec3 lightDirection, float intensity) {
const float stretching = 10.0;
float visibility = 1.0;
float nearPlane = 0.1;
float A = -(farPlane+nearPlane)/(farPlane-nearPlane);
float B = -2*(farPlane*nearPlane)/(farPlane - nearPlane);
@ -149,7 +194,19 @@ float samplePointShadow(samplerCubeShadow shadowMap, vec3 lightDirection) {
float bias = 0.001*tan(acos(clamp(dot(vNormal, normalize(lightDirection)), 0.0, 1.0)));
bias = clamp(bias, 0.0, 0.001);
bias *= 1/length(lightDirection)*8;
return texture(shadowMap, vec4(lightDirection , compValue - bias));
for (int i=0; i<4; i++) {
visibility -= intensity/16*(1.0-texture(shadowMap, vec4(lightDirection + poissonDisk3D[i]/stretching, compValue - bias)));
}
if (visibility == 1.0-(intensity/16)*4)
{
visibility = 1.0-intensity;
}
else if (visibility != 1.0) {
for (int i=0; i<12; i++) {
visibility -= intensity/16*(1.0-texture(shadowMap, vec4(lightDirection + poissonDisk3D[i]/stretching, compValue - bias)));
}
}
return visibility;
}
float distanceToBorder(vec2 vector) {
@ -167,87 +224,161 @@ void main()
// direction lighting
float sunAngle = -1.0;
if(length(directionalLightVector)>0.0f) {
vec3 directionalVector = normalize(directionalLightVector);
sunAngle = dot(vec3(0.0, 1.0, 0.0), directionalVector);
if ( sunAngle > -0.6) {
float directionalVisibility = 1.0f;
if (distanceToBorder(shadowCoord1.xy) <= 0.5 && distanceToBorder(shadowCoord1.xy) > 0.2) {
if (distanceToBorder(shadowCoord0.xy) <= 0.5 && distanceToBorder(shadowCoord0.xy) > 0.2) {
directionalVisibility = sampleDirectionalShadow(shadowMap_directional0, shadowCoord0, 0.001);
vec3 directionalVector = normalize(directionalLightVector);
sunAngle = dot(vec3(0.0, 1.0, 0.0), directionalVector);
if(sunAngle > 0.0) {
float directionalVisibility = 1.0f;
float directionalIntensity = sunIntensity(sunAngle);
if (distanceToBorder(shadowCoord3.xy) <= 0.5 && distanceToBorder(shadowCoord3.xy) > 0.2) {
if (distanceToBorder(shadowCoord2.xy) <= 0.5 && distanceToBorder(shadowCoord2.xy) > 0.2) {
if (distanceToBorder(shadowCoord1.xy) <= 0.5 && distanceToBorder(shadowCoord1.xy) > 0.2) {
if (distanceToBorder(shadowCoord0.xy) <= 0.5 && distanceToBorder(shadowCoord0.xy) > 0.2) {
directionalVisibility = sampleDirectionalShadow(shadowMap_directional0, shadowCoord0, 0.001, directionalIntensity);
}
else if (distanceToBorder(shadowCoord0.xy) <= 0.5 && distanceToBorder(shadowCoord0.xy) > 0.0) {
float directionalVisibility0 = sampleDirectionalShadow(shadowMap_directional0, shadowCoord0, 0.001, directionalIntensity);
float directionalVisibility1 = sampleDirectionalShadow(shadowMap_directional1, shadowCoord1, 0.001, directionalIntensity);
directionalVisibility = mix(directionalVisibility0, directionalVisibility1, distanceToBorder(shadowCoord0.xy) * 5);
}
else {
directionalVisibility = sampleDirectionalShadow(shadowMap_directional1, shadowCoord1, 0.001, directionalIntensity);
}
}
else if (distanceToBorder(shadowCoord0.xy) <= 0.5 && distanceToBorder(shadowCoord0.xy) > 0.0) {
float directionalVisibility0 = sampleDirectionalShadow(shadowMap_directional0, shadowCoord0, 0.001);
float directionalVisibility1 = sampleDirectionalShadow(shadowMap_directional1, shadowCoord1, 0.002);
directionalVisibility = mix(directionalVisibility0, directionalVisibility1, distanceToBorder(shadowCoord0.xy) * 5);
else if (distanceToBorder(shadowCoord1.xy) <= 0.5 && distanceToBorder(shadowCoord1.xy) > 0.0) {
float directionalVisibility1 = sampleDirectionalShadow(shadowMap_directional1, shadowCoord1, 0.001, directionalIntensity);
float directionalVisibility2 = sampleDirectionalShadow(shadowMap_directional2, shadowCoord2, 0.002, directionalIntensity);
directionalVisibility = mix(directionalVisibility1, directionalVisibility2, distanceToBorder(shadowCoord1.xy) * 5);
}
else {
directionalVisibility = sampleDirectionalShadow(shadowMap_directional1, shadowCoord1, 0.002);
directionalVisibility = sampleDirectionalShadow(shadowMap_directional2, shadowCoord2, 0.002, directionalIntensity);
}
}
else if (distanceToBorder(shadowCoord1.xy) <= 0.5 && distanceToBorder(shadowCoord1.xy) > 0.0) {
float directionalVisibility1 = sampleDirectionalShadow(shadowMap_directional1, shadowCoord1, 0.01);
float directionalVisibility2 = sampleDirectionalShadow(shadowMap_directional2, shadowCoord2, 0.01);
directionalVisibility = mix(directionalVisibility1, directionalVisibility2, distanceToBorder(shadowCoord1.xy) * 5);
else if (distanceToBorder(shadowCoord2.xy) <= 0.5 && distanceToBorder(shadowCoord2.xy) > 0.0) {
float directionalVisibility2 = sampleDirectionalShadow(shadowMap_directional2, shadowCoord2, 0.002, directionalIntensity);
float directionalVisibility3 = sampleDirectionalShadow(shadowMap_directional3, shadowCoord3, 0.005, directionalIntensity);
directionalVisibility = mix(directionalVisibility2, directionalVisibility3, distanceToBorder(shadowCoord2.xy) * 5);
}
else {
directionalVisibility = sampleDirectionalShadow(shadowMap_directional2, shadowCoord2, 0.01);
directionalVisibility = sampleDirectionalShadow(shadowMap_directional3, shadowCoord3, 0.005, directionalIntensity);
}
diffuseColor += clamp(dot(normalize(vNormal), directionalVector)
*diffuseFactor*directionalIntensity*sunColor(sunAngle), 0.0, 1.0)*directionalVisibility;
vec3 cameraVector = normalize(camera - vec3(fragPosition));
specularColor += clamp(pow((dot((cameraVector+directionalVector),normalize(vNormal))/
(length(cameraVector+directionalVector)*length(normalize(vNormal)))),shininess), 0.0, 1.0)
*specularFactor*directionalIntensity*sunColor(sunAngle)*directionalVisibility;
}
else if (distanceToBorder(shadowCoord3.xy) <= 0.5 && distanceToBorder(shadowCoord3.xy) > 0.0) {
float directionalVisibility3 = sampleDirectionalShadow(shadowMap_directional3, shadowCoord3, 0.005, directionalIntensity);
float directionalVisibility4 = sampleDirectionalShadow(shadowMap_directional4, shadowCoord4, 0.01, directionalIntensity);
directionalVisibility = mix(directionalVisibility3, directionalVisibility4, distanceToBorder(shadowCoord3.xy) * 5);
}
else {
directionalVisibility = sampleDirectionalShadow(shadowMap_directional4, shadowCoord4, 0.01, directionalIntensity);
}
diffuseColor += clamp(dot(normalize(vNormal), directionalVector)
*diffuseFactor*directionalIntensity*sunColor(sunAngle), 0.0, 1.0)*directionalVisibility;
vec3 cameraVector = normalize(camera - vec3(fragPosition));
specularColor += clamp(pow((dot((cameraVector+directionalVector),normalize(vNormal))/
(length(cameraVector+directionalVector)*length(normalize(vNormal)))),shininess), 0.0, 1.0)
*specularFactor*directionalIntensity*sunColor(sunAngle)*directionalVisibility;
}
// point lights
float visibility = 1.0;
for(int i = 0; i<lightCount; i++) {
vec3 lightDirection = vec3(fragPosition) - lightSources[i];
vec3 lightPos = vec3(0.0, 0.0, 0.0);
if (isFlame[i] == true) {
lightPos = vec3(lightSources[i].x - 0.75*movement.y , lightSources[i].y, lightSources[i].z + 0.75*movement.x);
}
else {
lightPos = lightSources[i];
}
vec3 lightDirection = vec3(fragPosition) - lightPos;
float distance = length(lightDirection);
float pointVisibility = 1.0f;
// only take lights into account with meaningful contribution
if (distance < farPlane) {
float intensity = 0.0f;
if (isFlame[i] == true) {
intensity = clamp(exp(-(1/(lightIntensities[i] + flickerFunction(i)))*distance), 0.0, 1.0);
}
else {
intensity = clamp(exp(-(1/lightIntensities[i])*distance), 0.0, 1.0);
}
if (intensity > 0.005) {
if (i == 0 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube0, lightDirection);
pointVisibility = samplePointShadow(shadowMap_cube0, lightDirection, intensity);
}
if (i == 1 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube1, lightDirection);
pointVisibility = samplePointShadow(shadowMap_cube1, lightDirection, intensity);
}
if (i == 2 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube2, lightDirection);
pointVisibility = samplePointShadow(shadowMap_cube2, lightDirection, intensity);
}
if (i == 3 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube3, lightDirection);
pointVisibility = samplePointShadow(shadowMap_cube3, lightDirection, intensity);
}
if (i == 4 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube4, lightDirection);
pointVisibility = samplePointShadow(shadowMap_cube4, lightDirection, intensity);
}
if (i == 5 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube5, lightDirection);
pointVisibility = samplePointShadow(shadowMap_cube5, lightDirection, intensity);
}
if (i == 6 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube6, lightDirection);
pointVisibility = samplePointShadow(shadowMap_cube6, lightDirection, intensity);
}
if (i == 7 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube7, lightDirection);
pointVisibility = samplePointShadow(shadowMap_cube7, lightDirection, intensity);
}
if (i == 8 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube8, lightDirection);
pointVisibility = samplePointShadow(shadowMap_cube8, lightDirection, intensity);
}
if (i == 9 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube9, lightDirection);
pointVisibility = samplePointShadow(shadowMap_cube9, lightDirection, intensity);
}
vec3 lightVector = normalize(lightSources[i]-vec3(fragPosition));
float intensity = 0.0f;
if (isFlame[i] == true) {
intensity = clamp(exp(-(1/(lightIntensities[i] + flickerFunction(i)))*distance), 0.0, 1.0);
if (i == 10 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube10, lightDirection, intensity);
}
else {
intensity = clamp(exp(-(1/lightIntensities[i])*distance), 0.0, 1.0);
if (i == 11 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube11, lightDirection, intensity);
}
if (i == 12 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube12, lightDirection, intensity);
}
if (i == 13 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube13, lightDirection, intensity);
}
if (i == 14 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube14, lightDirection, intensity);
}
if (i == 15 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube15, lightDirection, intensity);
}
if (i == 16 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube16, lightDirection, intensity);
}
if (i == 17 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube17, lightDirection, intensity);
}
if (i == 18 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube18, lightDirection, intensity);
}
if (i == 19 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube19, lightDirection, intensity);
}
if (i == 20 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube20, lightDirection, intensity);
}
if (i == 21 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube21, lightDirection, intensity);
}
if (i == 22 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube22, lightDirection, intensity);
}
if (i == 23 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube23, lightDirection, intensity);
}
if (i == 24 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube24, lightDirection, intensity);
}
if (i == 25 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube25, lightDirection, intensity);
}
vec3 lightVector = normalize(lightPos-vec3(fragPosition));
diffuseColor += clamp(dot(normalize(vNormal), lightVector)
*diffuseFactor*intensity*lightColors[i]*pointVisibility, 0.0, 1.0);
vec3 cameraVector = normalize(camera - vec3(fragPosition));

View File

@ -14,6 +14,8 @@ out vec4 fragPosition;
out vec4 shadowCoord0;
out vec4 shadowCoord1;
out vec4 shadowCoord2;
out vec4 shadowCoord3;
out vec4 shadowCoord4;
void main()
{
@ -23,5 +25,7 @@ void main()
shadowCoord0 = shadowMVPs[0] * vec4(aPosition, 1.0);
shadowCoord1 = shadowMVPs[1] * vec4(aPosition, 1.0);
shadowCoord2 = shadowMVPs[2] * vec4(aPosition, 1.0);
shadowCoord3 = shadowMVPs[3] * vec4(aPosition, 1.0);
shadowCoord4 = shadowMVPs[4] * vec4(aPosition, 1.0);
gl_Position = modelViewProjectionMatrix * vec4(aPosition, 1.0);
}

View File

@ -6,7 +6,7 @@ in vec4 sunPosition;
out vec4 oColor;
uniform sampler2D uTexture;
uniform sampler2D dayTexture;
uniform sampler2D nightTexture;
uniform float farPlane;
uniform vec4 fogColorDay;
@ -61,13 +61,13 @@ vec3 sunColorFunc(float dot) {
else {
riseFactor = cos(2*dot);
}
return mix(sunColor, vec3(fogColorRise), riseFactor);
return mix(sunColor, vec3(fogColorRise)*1.4, riseFactor);
}
void main() {
vec4 textureColor = vec4(0.0, 0.0, 0.0, 1.0);
float sunAngle = -dot(normalize(directionalVector), vec3(0.0, 1.0, 0.0));
vec4 dayColor = texture(uTexture, vTexCoord);
vec4 dayColor = texture(dayTexture, vTexCoord);
if (sunAngle >= 0.0) {
textureColor = mix(dayColor, texture(nightTexture, vTexCoord), sunAngle);
}
@ -80,8 +80,8 @@ void main() {
fogFactor *= clamp((1.0-((fragPosition.y-40.0)/30.0)), 0.0, 1.0);
if (distanceToSun < sunSize) {
float sunIntensity = clamp(0.3*exp(1/(distanceToSun/sunSize))-exp(1.0)*0.3, 0.0, 1.0);
vec4 color = mix(textureColor, vec4(sunColorFunc(sunAngle), sunIntensity), sunIntensity);
oColor = mix(color, fogColor(-sunAngle), fogFactor);
vec4 fogcolor = mix(textureColor, fogColor(-sunAngle), fogFactor);
oColor = mix(fogcolor, vec4(sunColorFunc(sunAngle), sunIntensity), sunIntensity*sin(2*(-sunAngle)));
}
else {
oColor = mix(textureColor, fogColor(-sunAngle), fogFactor);

38
extern/glfw/CMake/AppleInfo.plist vendored Normal file
View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${APPLE_GUI_EXECUTABLE}</string>
<key>CFBundleGetInfoString</key>
<string>${APPLE_GUI_INFO_STRING}</string>
<key>CFBundleIconFile</key>
<string>${APPLE_GUI_ICON}</string>
<key>CFBundleIdentifier</key>
<string>${APPLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>${APPLE_GUI_LONG_VERSION_STRING}</string>
<key>CFBundleName</key>
<string>${APPLE_GUI_BUNDLE_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${APPLE_GUI_SHORT_VERSION_STRING}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${APPLE_GUI_BUNDLE_VERSION}</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>LSRequiresCarbon</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>${APPLE_GUI_COPYRIGHT}</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>

View File

@ -1,19 +0,0 @@
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "glfw" for configuration "Release"
set_property(TARGET glfw APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(glfw PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libglfw3.a"
)
list(APPEND _IMPORT_CHECK_TARGETS glfw )
list(APPEND _IMPORT_CHECK_FILES_FOR_glfw "${_IMPORT_PREFIX}/lib/libglfw3.a" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)

View File

@ -1,84 +0,0 @@
# Generated by CMake 3.1.3
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
message(FATAL_ERROR "CMake >= 2.6.0 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.6)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_targetsDefined)
set(_targetsNotDefined)
set(_expectedTargets)
foreach(_expectedTarget glfw)
list(APPEND _expectedTargets ${_expectedTarget})
if(NOT TARGET ${_expectedTarget})
list(APPEND _targetsNotDefined ${_expectedTarget})
endif()
if(TARGET ${_expectedTarget})
list(APPEND _targetsDefined ${_expectedTarget})
endif()
endforeach()
if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT "${_targetsDefined}" STREQUAL "")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
endif()
unset(_targetsDefined)
unset(_targetsNotDefined)
unset(_expectedTargets)
# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
# Create imported target glfw
add_library(glfw STATIC IMPORTED)
# Load information for each installed configuration.
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
file(GLOB CONFIG_FILES "${_DIR}/glfwTargets-*.cmake")
foreach(f ${CONFIG_FILES})
include(${f})
endforeach()
# Cleanup temporary variables.
set(_IMPORT_PREFIX)
# Loop over all imported files and verify that they actually exist
foreach(target ${_IMPORT_CHECK_TARGETS} )
foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
if(NOT EXISTS "${file}" )
message(FATAL_ERROR "The imported target \"${target}\" references the file
\"${file}\"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
\"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
endif()
endforeach()
unset(_IMPORT_CHECK_FILES_FOR_${target})
endforeach()
unset(_IMPORT_CHECK_TARGETS)
# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)

View File

@ -10,7 +10,7 @@ endif()
set(GLFW_VERSION_MAJOR "3")
set(GLFW_VERSION_MINOR "1")
set(GLFW_VERSION_PATCH "0")
set(GLFW_VERSION_PATCH "1")
set(GLFW_VERSION_EXTRA "")
set(GLFW_VERSION "${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}")
set(GLFW_VERSION_FULL "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA}")
@ -273,33 +273,33 @@ if (_GLFW_X11)
list(APPEND glfw_PKG_DEPS "xinerama")
# Check for XInput (high-resolution cursor motion)
if (NOT X11_Xinput_FOUND)
message(FATAL_ERROR "The XInput library and headers were not found")
endif()
if (X11_Xinput_FOUND)
list(APPEND glfw_INCLUDE_DIRS "${X11_Xinput_INCLUDE_PATH}")
list(APPEND glfw_PKG_DEPS "xi")
list(APPEND glfw_INCLUDE_DIRS "${X11_Xinput_INCLUDE_PATH}")
if (X11_Xinput_LIB)
list(APPEND glfw_LIBRARIES "${X11_Xinput_LIB}")
else()
# Backwards compatibility (bug in CMake 2.8.7)
list(APPEND glfw_LIBRARIES Xi)
endif()
if (X11_Xinput_LIB)
list(APPEND glfw_LIBRARIES "${X11_Xinput_LIB}")
else()
# Backwards compatibility (bug in CMake 2.8.7)
list(APPEND glfw_LIBRARIES Xi)
set(_GLFW_HAS_XINPUT TRUE)
endif()
list(APPEND glfw_PKG_DEPS "xi")
# Check for Xf86VidMode (fallback gamma control)
if (NOT X11_xf86vmode_FOUND)
message(FATAL_ERROR "The Xf86VidMode library and headers were not found")
endif()
if (X11_xf86vmode_FOUND)
list(APPEND glfw_INCLUDE_DIRS "${X11_xf86vmode_INCLUDE_PATH}")
list(APPEND glfw_PKG_DEPS "xxf86vm")
list(APPEND glfw_INCLUDE_DIRS "${X11_xf86vmode_INCLUDE_PATH}")
list(APPEND glfw_PKG_DEPS "xxf86vm")
if (X11_Xxf86vm_LIB)
list(APPEND glfw_LIBRARIES "${X11_Xxf86vm_LIB}")
else()
# Backwards compatibility (see CMake bug 0006976)
list(APPEND glfw_LIBRARIES Xxf86vm)
endif()
if (X11_Xxf86vm_LIB)
list(APPEND glfw_LIBRARIES "${X11_Xxf86vm_LIB}")
else()
# Backwards compatibility (see CMake bug 0006976)
list(APPEND glfw_LIBRARIES Xxf86vm)
set(_GLFW_HAS_XF86VM TRUE)
endif()
# Check for Xkb (X keyboard extension)

135
extern/glfw/README.md vendored
View File

@ -6,10 +6,8 @@ GLFW is a free, Open Source, multi-platform library for OpenGL and OpenGL ES
application development. It provides a simple, platform-independent API for
creating windows and contexts, reading input, handling events, etc.
Version 3.1 adds improved documentation, support for custom system cursors, file
drop events, main thread wake-up, window frame size retrieval, floating windows,
character input with modifier keys, single buffered windows, build improvements
and fixes for a large number of bugs.
Version 3.1.1 adds fixes for a number of bugs that together affect all supported
platforms, most notably workarounds for bugs in some popular window managers.
If you are new to GLFW, you may find the
[introductory tutorial](http://www.glfw.org/docs/latest/quick.html) for GLFW
@ -65,110 +63,26 @@ GLFW bundles a number of dependencies in the `deps/` directory.
## Changelog
- Added `GLFWcursor` custom system cursor handle
- Added `glfwCreateCursor`, `glfwCreateStandardCursor`, `glfwDestroyCursor` and
`glfwSetCursor` for managing system cursor images
- Added `GLFWimage` struct for passing 32-bit RGBA images
- Added monitor and adapter identifier access to native API
- Added `glfwSetDropCallback` and `GLFWdropfun` for receiving dropped files
- Added `glfwPostEmptyEvent` for allowing secondary threads to cause
`glfwWaitEvents` to return
- Added `empty` test program for verifying posting of empty events
- Added `glfwSetCharModsCallback` for receiving character events with modifiers
- Added `glfwGetWindowFrameSize` for retrieving the size of the frame around
the client area of a window
- Added `GLFW_AUTO_ICONIFY` for controlling whether full screen windows
automatically iconify (and restore the previous video mode) on focus loss
- Added `GLFW_DONT_CARE` for indicating that any value is acceptable
- Added `GLFW_DOUBLEBUFFER` for controlling whether to use double buffering
- Added `GLFW_CONTEXT_RELEASE_BEHAVIOR` and values
`GLFW_ANY_RELEASE_BEHAVIOR`, `GLFW_RELEASE_BEHAVIOR_FLUSH` and
`GLFW_RELEASE_BEHAVIOR_NONE` for `GL_KHR_context_flush_control` support
- Added `GLFW_INCLUDE_ES31` for including the OpenGL ES 3.1 header
- Added `GLFW_FLOATING` for creating always-on-top windowed mode windows
- Added `GLFW_FOCUSED` window hint for controlling initial input focus
- Added *partial and experimental* support for Wayland
- Added *partial and experimental* support for Mir
- Changed the window state attributes (focused, iconified and visible) to query
the system directly
- Changed the default of `GLFW_REFRESH_RATE` to `GLFW_DONT_CARE` to maintain
the default behavior
- Changed static library to build as position independent code for easier use
from the Rust language
- Changed `glfwGetCursorPos` to query the system directly for all cursor modes
except captured mode
- Bugfix: The debug context attribute was set from `GL_ARB_debug_output` even
when a debug context had not been requested
- Bugfix: The particles example was not linked against the threading library
- Bugfix: The cursor was not positioned over newly created full screen windows
- Bugfix: The queried cursor position was not always up-to-date
- Bugfix: `glfwExtensionSupported` always failed for OpenGL ES 3.0 and later if
the library was compiled for OpenGL ES
- [Cocoa] Added `_GLFW_USE_RETINA` to control whether windows will use the full
resolution on Retina displays
- [Cocoa] Made content view subclass of `NSOpenGLView`
- [Cocoa] Bugfix: Using a 1x1 cursor for hidden mode caused some screen
recorders to fail
- [Cocoa] Bugfix: Some Core Foundation objects were leaked during joystick
enumeration and termination
- [Cocoa] Bugfix: One copy of each display name string was leaked
- [Cocoa] Bugfix: Monitor enumeration caused a segfault if no `NSScreen` was
found for a given `CGDisplay`
- [Cocoa] Bugfix: Modifier key events were lost if the corresponding modifier
bit field was unchanged
- [Cocoa] Bugfix: Joystick enumeration took hundreds of ms on some systems
- [Cocoa] Bugfix: The cursor was hidden when the user resized a GLFW window
- [Cocoa] Bugfix: The 10.10 Yosemite OpenGL 4.1 profile token was not used
- [Cocoa] Bugfix: The generic software OpenGL renderer could be selected under
certain conditions
- [Cocoa] Bugfix: The virtual cursor jumped unpredictably when entering
disabled cursor mode
- [Win32] Enabled generation of pkg-config file for MinGW
- [Win32] Removed option to require explicitly linking against `winmm.dll`
- [Win32] Bugfix: Failure to load winmm or its functions was not reported to
the error callback
- [Win32] Bugfix: Some keys were reported based on the current layout instead
of their physical location
- [Win32] Bugfix: Maximized hidden windows were restored by `glfwShowWindow`
- [Win32] Bugfix: Context re-creation was not triggered by sRGB hint
- [Win32] Bugfix: Full screen windows were incorrectly sized and placed on some
systems
- [Win32] Bugfix: Gamma ramp functions acted on entire desktop instead of the
specified monitor
- [Win32] Bugfix: The wrong incorrect physical size was returned for
non-primary monitors
- [Win32] Bugfix: X-axis scroll offsets were inverted
- [Win32] Bugfix: The Optimus HPG forcing variable was not correctly exported
- [Win32] Bugfix: The iconified window state attribute was not always updated
- [Win32] Bugfix: Previously focused windows with disabled cursor mode and that
had been iconified by Win+D were not visible when restored
- [Win32] Bugfix: The virtual cursor jumped unpredictably when entering
disabled cursor mode
- [X11] Added run-time support for systems lacking the XKB extension
- [X11] Made GLX 1.3 the minimum supported version
- [X11] Replaced `XRRGetScreenResources` with `XRRGetScreenResourcesCurrent`
for monitor property retrieval
- [X11] Bugfix: The case of finding no usable CRTCs was not detected
- [X11] Bugfix: Detection of broken Nvidia RandR gamma support did not verify
that at least one CRTC was present
- [X11] Bugfix: A stale `_NET_SUPPORTING_WM_CHECK` root window property would
cause an uncaught `BadWindow` error
- [X11] Bugfix: No check was made for the presence of GLX 1.3 when
`GLX_SGIX_fbconfig` was unavailable
- [X11] Bugfix: The message type of ICCCM protocol events was not checked
- [X11] Bugfix: `glfwDestroyWindow` did not flush the output buffer
- [X11] Bugfix: Window frame interactions were reported as focus events
- [X11] Bugfix: Workaround for legacy Compiz caused flickering during resize
- [X11] Bugfix: The name pointer of joysticks were not cleared on disconnection
- [X11] Bugfix: Video mode resolutions and monitor physical sizes were not
corrected for rotated CRTCs
- [X11] Bugfix: Unicode character input ignored dead keys
- [X11] Bugfix: X-axis scroll offsets were inverted
- [X11] Bugfix: Full screen override redirect windows were not always
positioned over the specified monitor
- [X11] Bugfix: Character input did not work for the default `"C"` locale
- [X11] Bugfix: Joysticks connected after `glfwInit` were not detected
(temporary inotify solution until proper libudev solution)
- Made library compilation fail if any header option macros are defined
- Removed support for LCC and Borland C++
- Bugfix: `glfwSetTime` silently accepted invalid values
- [Cocoa] Bugfix: `NSHighResolutionCapable` was not enabled for test and
example programs
- [Cocoa] Bugfix: Sleeping monitors were not included in the monitor list
- [Cocoa] Bugfix: `glfwSetWindowSize` did not change the video mode for full
screen windows
- [X11] Added support for Cygwin-X
- [X11] Made XInput2 optional at compile-time
- [X11] Made Xxf86vm optional at compile-time
- [X11] Bugfix: Moved `_NET_REQUEST_FRAME_EXTENTS` request to
`glfwGetWindowFrameSize` and added protocol-breaking timeout
as a workaround for broken support in Unity, Fluxbox and Xfwm
- [X11] Bugfix: Mouse button `GLFW_MOUSE_BUTTON_4` was never used
- [X11] Bugfix: `glfwTerminate` could close an unrelated file descriptor
- [X11] Bugfix: Some WMs (KWM, Fluxbox) did not respect cursor redefinition
- [WGL] Bugfix: The context flags debug bit was not set for OpenGL ES
- [GLX] Bugfix: The context flags debug bit was not set for OpenGL ES
- [EGL] Bugfix: The context flags debug bit was not set for OpenGL ES
## Contact
@ -216,6 +130,7 @@ skills.
- Michael Dickens
- Jonathan Dummer
- Ralph Eastwood
- Siavash Eliasi
- Michael Fogleman
- Gerald Franz
- GeO4d
@ -241,8 +156,10 @@ skills.
- Hans Mackowiak
- Kyle McDonald
- David Medlock
- Bryce Mehring
- Jonathan Mercier
- Marcel Metz
- Jonathan Miller
- Kenneth Miller
- Bruce Mitchener
- Jack Moffitt
@ -260,6 +177,7 @@ skills.
- Pieroman
- Jorge Rodriguez
- Ed Ropple
- Aleksey Rybalkin
- Riku Salminen
- Brandon Schaefer
- Sebastian Schuberth
@ -276,6 +194,7 @@ skills.
- Nathan Sweet
- TTK-Bandit
- Sergey Tikhomirov
- A. Tombs
- Samuli Tuomola
- urraka
- Jari Vetoniemi

View File

@ -1,3 +1,4 @@
#include <stdio.h>
#include <string.h>
#include <glad/glad.h>
@ -687,10 +688,34 @@ static void find_extensionsGL(void) {
}
static void find_coreGL(void) {
const char *v = (const char *)glGetString(GL_VERSION);
int major = v[0] - '0';
int minor = v[2] - '0';
GLVersion.major = major; GLVersion.minor = minor;
/* Thank you @elmindreda
* https://github.com/elmindreda/greg/blob/master/templates/greg.c.in#L176
* https://github.com/glfw/glfw/blob/master/src/context.c#L36
*/
int i, major, minor;
const char* version;
const char* prefixes[] = {
"OpenGL ES-CM ",
"OpenGL ES-CL ",
"OpenGL ES ",
NULL
};
version = (const char*) glGetString(GL_VERSION);
if (!version) return;
for (i = 0; prefixes[i]; i++) {
const size_t length = strlen(prefixes[i]);
if (strncmp(version, prefixes[i], length) == 0) {
version += length;
break;
}
}
sscanf(version, "%d.%d", &major, &minor);
GLVersion.major = major; GLVersion.minor = minor;
GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1;
GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1;
GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1;
@ -704,10 +729,11 @@ static void find_coreGL(void) {
GLAD_GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3;
}
void gladLoadGLLoader(GLADloadproc load) {
int gladLoadGLLoader(GLADloadproc load) {
GLVersion.major = 0; GLVersion.minor = 0;
glGetString = (PFNGLGETSTRINGPROC)load("glGetString");
if(glGetString == NULL) return;
if(glGetString == NULL) return 0;
if(glGetString(GL_VERSION) == NULL) return 0;
find_coreGL();
load_GL_VERSION_1_0(load);
load_GL_VERSION_1_1(load);
@ -722,7 +748,6 @@ void gladLoadGLLoader(GLADloadproc load) {
load_GL_VERSION_3_2(load);
find_extensionsGL();
return;
return GLVersion.major != 0 || GLVersion.minor != 0;
}

View File

@ -22,15 +22,17 @@
#define APIENTRYP APIENTRY *
#endif
extern struct gladGLversionStruct {
int major;
int minor;
} GLVersion;
#ifdef __cplusplus
extern "C" {
#endif
struct gladGLversionStruct {
int major;
int minor;
};
extern struct gladGLversionStruct GLVersion;
typedef void* (* GLADloadproc)(const char *name);
#ifndef GLAPI
@ -58,7 +60,7 @@ typedef void* (* GLADloadproc)(const char *name);
# define GLAPI extern
# endif
#endif
GLAPI void gladLoadGLLoader(GLADloadproc);
GLAPI int gladLoadGLLoader(GLADloadproc);
#include <stddef.h>
#include <KHR/khrplatform.h>
@ -836,11 +838,13 @@ typedef GLintptr GLvdpauSurfaceNV;
#define GL_UNIFORM_BUFFER_START 0x8A29
#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C
#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32
#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
@ -859,6 +863,7 @@ typedef GLintptr GLvdpauSurfaceNV;
#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45
#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
#define GL_INVALID_INDEX 0xFFFFFFFF
#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001

View File

@ -41,7 +41,9 @@ if (APPLE)
set_target_properties(Wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave")
set_target_properties(Boing Gears Heightmap Particles Simple SplitView Wave PROPERTIES
FOLDER "GLFW3/Examples")
FOLDER "GLFW3/Examples"
MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/AppleInfo.plist")
else()
# Set boring names for executables
add_executable(boing WIN32 boing.c)

View File

@ -371,7 +371,9 @@ static void framebufferSizeFun(GLFWwindow* window, int w, int h)
static void windowRefreshFun(GLFWwindow* window)
{
do_redraw = 1;
drawAllViews();
glfwSwapBuffers(window);
do_redraw = 0;
}
@ -485,15 +487,7 @@ int main(void)
{
// Only redraw if we need to
if (do_redraw)
{
// Draw all views
drawAllViews();
// Swap buffers
glfwSwapBuffers(window);
do_redraw = 0;
}
windowRefreshFun(window);
// Wait for new events
glfwWaitEvents();

View File

@ -68,28 +68,17 @@ extern "C" {
/*************************************************************************
* Global definitions
* Compiler- and platform-specific preprocessor work
*************************************************************************/
/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */
/* Please report any problems that you find with your compiler, which may
* be solved in this section! There are several compilers that I have not
* been able to test this file with yet.
*
* First: If we are we on Windows, we want a single define for it (_WIN32)
* (Note: For Cygwin the compiler flag -mwin32 should be used, but to
* make sure that things run smoothly for Cygwin users, we add __CYGWIN__
* to the list of "valid Win32 identifiers", which removes the need for
* -mwin32)
/* If we are we on Windows, we want a single define for it.
*/
#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__))
#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__))
#define _WIN32
#endif /* _WIN32 */
/* In order for extension support to be portable, we need to define an
* OpenGL function call method. We use the keyword APIENTRY, which is
* defined for Win32. (Note: Windows also needs this for <GL/gl.h>)
/* It is customary to use APIENTRY for OpenGL function pointer declarations on
* all platforms. Additionally, the Windows OpenGL header needs APIENTRY.
*/
#ifndef APIENTRY
#ifdef _WIN32
@ -99,44 +88,23 @@ extern "C" {
#endif
#endif /* APIENTRY */
/* The following three defines are here solely to make some Windows-based
* <GL/gl.h> files happy. Theoretically we could include <windows.h>, but
* it has the major drawback of severely polluting our namespace.
/* Some Windows OpenGL headers need this.
*/
/* Under Windows, we need WINGDIAPI defined */
#if !defined(WINGDIAPI) && defined(_WIN32)
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__)
/* Microsoft Visual C++, Borland C++ Builder and Pelles C */
#define WINGDIAPI __declspec(dllimport)
#elif defined(__LCC__)
/* LCC-Win32 */
#define WINGDIAPI __stdcall
#else
/* Others (e.g. MinGW, Cygwin) */
#define WINGDIAPI extern
#endif
#define WINGDIAPI __declspec(dllimport)
#define GLFW_WINGDIAPI_DEFINED
#endif /* WINGDIAPI */
/* Some <GL/glu.h> files also need CALLBACK defined */
/* Some Windows GLU headers need this.
*/
#if !defined(CALLBACK) && defined(_WIN32)
#if defined(_MSC_VER)
/* Microsoft Visual C++ */
#if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS)
#define CALLBACK __stdcall
#else
#define CALLBACK
#endif
#else
/* Other Windows compilers */
#define CALLBACK __stdcall
#endif
#define CALLBACK __stdcall
#define GLFW_CALLBACK_DEFINED
#endif /* CALLBACK */
/* Most GL/glu.h variants on Windows need wchar_t
* OpenGL/gl.h blocks the definition of ptrdiff_t by glext.h on OS X */
/* Most Windows GLU headers need wchar_t.
* The OS X OpenGL header blocks the definition of ptrdiff_t by glext.h.
*/
#if !defined(GLFW_INCLUDE_NONE)
#include <stddef.h>
#endif
@ -197,7 +165,7 @@ extern "C" {
* version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW
* configuration header when compiling the DLL version of the library.
*/
#error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined"
#error "You may not have both GLFW_DLL and _GLFW_BUILD_DLL defined"
#endif
/* GLFWAPI is used to declare public API functions for export
@ -208,11 +176,7 @@ extern "C" {
#define GLFWAPI __declspec(dllexport)
#elif defined(_WIN32) && defined(GLFW_DLL)
/* We are calling GLFW as a Win32 DLL */
#if defined(__LCC__)
#define GLFWAPI extern
#else
#define GLFWAPI __declspec(dllimport)
#endif
#define GLFWAPI __declspec(dllimport)
#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL)
/* We are building GLFW as a shared / dynamic library */
#define GLFWAPI __attribute__((visibility("default")))
@ -221,8 +185,6 @@ extern "C" {
#define GLFWAPI
#endif
/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */
/*************************************************************************
* GLFW API tokens
@ -249,7 +211,7 @@ extern "C" {
* API changes.
* @ingroup init
*/
#define GLFW_VERSION_REVISION 0
#define GLFW_VERSION_REVISION 1
/*! @} */
/*! @name Key and button actions
@ -558,7 +520,9 @@ extern "C" {
/*! @brief GLFW could not find support for the requested client API on the
* system.
*
* GLFW could not find support for the requested client API on the system.
* GLFW could not find support for the requested client API on the system. If
* emitted by functions other than @ref glfwCreateWindow, no supported client
* API was found.
*
* @par Analysis
* The installed graphics driver does not support the requested client API, or
@ -575,8 +539,8 @@ extern "C" {
#define GLFW_API_UNAVAILABLE 0x00010006
/*! @brief The requested OpenGL or OpenGL ES version is not available.
*
* The requested OpenGL or OpenGL ES version (including any requested profile
* or context option) is not available on this machine.
* The requested OpenGL or OpenGL ES version (including any requested context
* or framebuffer hints) is not available on this machine.
*
* @par Analysis
* The machine does not support your requirements. If your application is
@ -598,7 +562,8 @@ extern "C" {
* specific categories.
*
* @par Analysis
* A bug in GLFW or the underlying operating system. Report the bug to our
* A bug or configuration error in GLFW, the underlying operating system or
* its drivers, or a lack of required resources. Report the issue to our
* [issue tracker](https://github.com/glfw/glfw/issues).
*/
#define GLFW_PLATFORM_ERROR 0x00010008
@ -988,7 +953,7 @@ typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int);
*
* @param[in] window The window that received the event.
* @param[in] count The number of dropped files.
* @param[in] names The UTF-8 encoded path names of the dropped files.
* @param[in] paths The UTF-8 encoded file and/or directory path names.
*
* @sa glfwSetDropCallback
*
@ -1462,7 +1427,8 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
/*! @brief Generates a gamma ramp and sets it for the specified monitor.
*
* This function generates a 256-element gamma ramp from the specified exponent
* and then calls @ref glfwSetGammaRamp with it.
* and then calls @ref glfwSetGammaRamp with it. The value must be a finite
* number greater than zero.
*
* @param[in] monitor The monitor whose gamma ramp to set.
* @param[in] gamma The desired exponent.
@ -1512,7 +1478,10 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
* @param[in] monitor The monitor whose gamma ramp to set.
* @param[in] ramp The gamma ramp to use.
*
* @note Gamma ramp sizes other than 256 are not supported by all hardware.
* @remarks Gamma ramp sizes other than 256 are not supported by all platforms
* or graphics hardware.
*
* @remarks __Windows:__ The gamma ramp size must be 256.
*
* @par Pointer Lifetime
* The specified gamma ramp is copied before this function returns.
@ -1648,6 +1617,13 @@ GLFWAPI void glfwWindowHint(int target, int hint);
* The menu bar can be disabled with a
* [compile-time option](@ref compile_options_osx).
*
* @remarks __OS X:__ On OS X 10.10 and later the window frame will not be
* rendered at full resolution on Retina displays unless the
* `NSHighResolutionCapable` key is enabled in the application bundle's
* `Info.plist`. For more information, see
* [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html)
* in the Mac Developer Library.
*
* @remarks __X11:__ There is no mechanism for setting the window icon yet.
*
* @remarks __X11:__ Some window managers will not respect the placement of
@ -3136,10 +3112,15 @@ GLFWAPI double glfwGetTime(void);
/*! @brief Sets the GLFW timer.
*
* This function sets the value of the GLFW timer. It then continues to count
* up from that value.
* up from that value. The value must be a positive finite number less than
* or equal to 18446744073.0, which is approximately 584.5 years.
*
* @param[in] time The new value, in seconds.
*
* @remarks The upper limit of the timer is calculated as
* floor((2<sup>64</sup> - 1) / 10<sup>9</sup>) and is due to implementations
* storing nanoseconds in 64 bits. The limit may be increased in the future.
*
* @par Thread Safety
* This function may only be called from the main thread.
*
@ -3243,14 +3224,14 @@ GLFWAPI void glfwSwapBuffers(GLFWwindow* window);
* @param[in] interval The minimum number of screen updates to wait for
* until the buffers are swapped by @ref glfwSwapBuffers.
*
* @note This function is not called during window creation, leaving the swap
* interval set to whatever is the default on that platform. This is done
* @remarks This function is not called during context creation, leaving the
* swap interval set to whatever is the default on that platform. This is done
* because some swap interval extensions used by GLFW do not allow the swap
* interval to be reset to zero once it has been set to a non-zero value.
*
* @note Some GPU drivers do not honor the requested swap interval, either
* because of user settings that override the request or due to bugs in the
* driver.
* @remarks Some GPU drivers do not honor the requested swap interval, either
* because of a user setting that overrides the application's request or due to
* bugs in the driver.
*
* @par Thread Safety
* This function may be called from any thread.
@ -3267,9 +3248,9 @@ GLFWAPI void glfwSwapInterval(int interval);
/*! @brief Returns whether the specified extension is available.
*
* This function returns whether the specified
* [API extension](@ref context_glext) is supported by the current OpenGL or
* OpenGL ES context. It searches both for OpenGL and OpenGL ES extension and
* platform-specific context creation API extensions.
* [client API extension](@ref context_glext) is supported by the current
* OpenGL or OpenGL ES context. It searches both for OpenGL and OpenGL ES
* extension and platform-specific context creation API extensions.
*
* A context must be current on the calling thread. Calling this function
* without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.
@ -3298,7 +3279,7 @@ GLFWAPI int glfwExtensionSupported(const char* extension);
* context.
*
* This function returns the address of the specified
* [client API or extension function](@ref context_glext), if it is supported
* [core or extension function](@ref context_glext), if it is supported
* by the current context.
*
* A context must be current on the calling thread. Calling this function
@ -3308,9 +3289,13 @@ GLFWAPI int glfwExtensionSupported(const char* extension);
* @return The address of the function, or `NULL` if the function is
* unavailable or an [error](@ref error_handling) occurred.
*
* @note The addresses of a given function is not guaranteed to be the same
* @remarks The addresses of a given function is not guaranteed to be the same
* between contexts.
*
* @remarks This function may return a non-`NULL` address despite the
* associated version or extension not being available. Always check the
* context version or extension string presence first.
*
* @par Pointer Lifetime
* The returned function pointer is valid until the context is destroyed or the
* library is terminated.

View File

@ -57,7 +57,8 @@ static char* getDisplayName(CGDirectDisplayID displayID)
(const void**) &value))
{
// This may happen if a desktop Mac is running headless
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to retrieve display name");
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to retrieve display name");
CFRelease(info);
return strdup("Unknown");
@ -263,9 +264,6 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
{
int j;
if (CGDisplayIsAsleep(displays[i]))
continue;
CGDirectDisplayID screenDisplayID = CGDisplayMirrorsDisplay(displays[i]);
if (screenDisplayID == kCGNullDirectDisplay)
screenDisplayID = displays[i];

View File

@ -592,17 +592,17 @@ static int translateKey(unsigned int key)
if (count)
{
NSEnumerator* e = [files objectEnumerator];
char** names = calloc(count, sizeof(char*));
char** paths = calloc(count, sizeof(char*));
int i;
for (i = 0; i < count; i++)
names[i] = strdup([[e nextObject] UTF8String]);
paths[i] = strdup([[e nextObject] UTF8String]);
_glfwInputDrop(window, count, (const char**) names);
_glfwInputDrop(window, count, (const char**) paths);
for (i = 0; i < count; i++)
free(names[i]);
free(names);
free(paths[i]);
free(paths);
}
return YES;
@ -990,7 +990,10 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{
[window->ns.object setContentSize:NSMakeSize(width, height)];
if (window->monitor)
enterFullscreenMode(window);
else
[window->ns.object setContentSize:NSMakeSize(width, height)];
}
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
@ -1208,7 +1211,8 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
cursor->ns.object = getStandardCursor(shape);
if (!cursor->ns.object)
{
_glfwInputError(GLFW_INVALID_ENUM, "Cocoa: Invalid standard cursor");
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to retrieve standard cursor");
return GL_FALSE;
}
@ -1252,7 +1256,8 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
if (![[pasteboard types] containsObject:NSStringPboardType])
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, NULL);
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"Cocoa: Failed to retrieve string from pasteboard");
return NULL;
}

View File

@ -89,7 +89,7 @@ GLboolean _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
if (ctxconfig->api != GLFW_OPENGL_API &&
ctxconfig->api != GLFW_OPENGL_ES_API)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid client API requested");
_glfwInputError(GLFW_INVALID_ENUM, "Invalid client API");
return GL_FALSE;
}
@ -104,16 +104,13 @@ GLboolean _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
// OpenGL 1.x series ended with version 1.5
// OpenGL 2.x series ended with version 2.1
// OpenGL 3.x series ended with version 3.3
// For now, let everything else through
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid OpenGL version %i.%i requested",
"Invalid OpenGL version %i.%i",
ctxconfig->major, ctxconfig->minor);
return GL_FALSE;
}
else
{
// For now, let everything else through
}
if (ctxconfig->profile)
{
@ -121,7 +118,7 @@ GLboolean _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
ctxconfig->profile != GLFW_OPENGL_COMPAT_PROFILE)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid OpenGL profile requested");
"Invalid OpenGL profile");
return GL_FALSE;
}
@ -132,8 +129,7 @@ GLboolean _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
// and above
_glfwInputError(GLFW_INVALID_VALUE,
"Context profiles only exist for "
"OpenGL version 3.2 and above");
"Context profiles are only defined for OpenGL version 3.2 and above");
return GL_FALSE;
}
}
@ -142,8 +138,7 @@ GLboolean _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
{
// Forward-compatible contexts are only defined for OpenGL version 3.0 and above
_glfwInputError(GLFW_INVALID_VALUE,
"Forward compatibility only exist for OpenGL "
"version 3.0 and above");
"Forward-compatibility is only defined for OpenGL version 3.0 and above");
return GL_FALSE;
}
}
@ -156,30 +151,11 @@ GLboolean _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
// OpenGL ES 1.0 is the smallest valid version
// OpenGL ES 1.x series ended with version 1.1
// OpenGL ES 2.x series ended with version 2.0
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid OpenGL ES version %i.%i requested",
ctxconfig->major, ctxconfig->minor);
return GL_FALSE;
}
else
{
// For now, let everything else through
}
if (ctxconfig->profile)
{
// OpenGL ES does not support profiles
_glfwInputError(GLFW_INVALID_VALUE,
"Context profiles are not supported by OpenGL ES");
return GL_FALSE;
}
if (ctxconfig->forward)
{
// OpenGL ES does not support forward-compatibility
_glfwInputError(GLFW_INVALID_VALUE,
"Forward compatibility is not supported by OpenGL ES");
"Invalid OpenGL ES version %i.%i",
ctxconfig->major, ctxconfig->minor);
return GL_FALSE;
}
}
@ -189,8 +165,8 @@ GLboolean _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
if (ctxconfig->robustness != GLFW_NO_RESET_NOTIFICATION &&
ctxconfig->robustness != GLFW_LOSE_CONTEXT_ON_RESET)
{
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid context robustness mode requested");
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid context robustness mode");
return GL_FALSE;
}
}
@ -200,8 +176,8 @@ GLboolean _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
if (ctxconfig->release != GLFW_RELEASE_BEHAVIOR_NONE &&
ctxconfig->release != GLFW_RELEASE_BEHAVIOR_FLUSH)
{
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid context release behavior requested");
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid context release behavior");
return GL_FALSE;
}
}

View File

@ -47,33 +47,25 @@ static const char* getErrorString(EGLint error)
case EGL_BAD_ALLOC:
return "EGL failed to allocate resources for the requested operation";
case EGL_BAD_ATTRIBUTE:
return "An unrecognized attribute or attribute value was passed "
"in the attribute list";
return "An unrecognized attribute or attribute value was passed in the attribute list";
case EGL_BAD_CONTEXT:
return "An EGLContext argument does not name a valid EGL "
"rendering context";
return "An EGLContext argument does not name a valid EGL rendering context";
case EGL_BAD_CONFIG:
return "An EGLConfig argument does not name a valid EGL frame "
"buffer configuration";
return "An EGLConfig argument does not name a valid EGL frame buffer configuration";
case EGL_BAD_CURRENT_SURFACE:
return "The current surface of the calling thread is a window, pixel "
"buffer or pixmap that is no longer valid";
return "The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid";
case EGL_BAD_DISPLAY:
return "An EGLDisplay argument does not name a valid EGL display "
"connection";
return "An EGLDisplay argument does not name a valid EGL display connection";
case EGL_BAD_SURFACE:
return "An EGLSurface argument does not name a valid surface "
"configured for GL rendering";
return "An EGLSurface argument does not name a valid surface configured for GL rendering";
case EGL_BAD_MATCH:
return "Arguments are inconsistent";
case EGL_BAD_PARAMETER:
return "One or more argument values are invalid";
case EGL_BAD_NATIVE_PIXMAP:
return "A NativePixmapType argument does not refer to a valid "
"native pixmap";
return "A NativePixmapType argument does not refer to a valid native pixmap";
case EGL_BAD_NATIVE_WINDOW:
return "A NativeWindowType argument does not refer to a valid "
"native window";
return "A NativeWindowType argument does not refer to a valid native window";
case EGL_CONTEXT_LOST:
return "The application must destroy all contexts and reinitialise";
}
@ -309,7 +301,7 @@ int _glfwCreateContext(_GLFWwindow* window,
{
if (!eglBindAPI(EGL_OPENGL_ES_API))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to bind OpenGL ES: %s",
getErrorString(eglGetError()));
return GL_FALSE;
@ -319,7 +311,7 @@ int _glfwCreateContext(_GLFWwindow* window,
{
if (!eglBindAPI(EGL_OPENGL_API))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to bind OpenGL: %s",
getErrorString(eglGetError()));
return GL_FALSE;
@ -339,11 +331,11 @@ int _glfwCreateContext(_GLFWwindow* window,
if (ctxconfig->forward)
flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
if (ctxconfig->debug)
flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
}
if (ctxconfig->debug)
flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
if (ctxconfig->robustness)
{
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
@ -389,7 +381,7 @@ int _glfwCreateContext(_GLFWwindow* window,
if (window->egl.context == EGL_NO_CONTEXT)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"EGL: Failed to create context: %s",
getErrorString(eglGetError()));
return GL_FALSE;

View File

@ -5,7 +5,7 @@ libdir=${exec_prefix}/lib
Name: GLFW
Description: A multi-platform library for OpenGL, window and input
Version: 3.1.0
Version: 3.1.1
URL: http://www.glfw.org/
Requires.private: x11 xrandr xinerama xi xxf86vm xcursor gl
Libs: -L${libdir} -lglfw3

View File

@ -4,7 +4,7 @@
# GLFW3_LIBRARY_DIR, folder in which the GLFW library is located
# GLFW3_LIBRARY, library to link against to use GLFW
set(GLFW3_VERSION "3.1.0")
set(GLFW3_VERSION "3.1.1")
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######

View File

@ -9,16 +9,16 @@
# The variable CVF_VERSION must be set before calling configure_file().
set(PACKAGE_VERSION "3.1.0")
set(PACKAGE_VERSION "3.1.1")
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
if("3.1.0" MATCHES "^([0-9]+)\\.")
if("3.1.1" MATCHES "^([0-9]+)\\.")
set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
else()
set(CVF_VERSION_MAJOR "3.1.0")
set(CVF_VERSION_MAJOR "3.1.1")
endif()
if("${PACKAGE_FIND_VERSION_MAJOR}" STREQUAL "${CVF_VERSION_MAJOR}")

View File

@ -62,6 +62,10 @@
// Define this to 1 to force use of high-performance GPU on Optimus systems
/* #undef _GLFW_USE_OPTIMUS_HPG */
// Define this to 1 if the XInput X11 extension is available
#define _GLFW_HAS_XINPUT
// Define this to 1 if the Xxf86vm X11 extension is available
#define _GLFW_HAS_XF86VM
// Define this to 1 if glXGetProcAddress is available
#define _GLFW_HAS_GLXGETPROCADDRESS
// Define this to 1 if glXGetProcAddressARB is available

View File

@ -62,6 +62,10 @@
// Define this to 1 to force use of high-performance GPU on Optimus systems
#cmakedefine _GLFW_USE_OPTIMUS_HPG
// Define this to 1 if the XInput X11 extension is available
#cmakedefine _GLFW_HAS_XINPUT
// Define this to 1 if the Xxf86vm X11 extension is available
#cmakedefine _GLFW_HAS_XF86VM
// Define this to 1 if glXGetProcAddress is available
#cmakedefine _GLFW_HAS_GLXGETPROCADDRESS
// Define this to 1 if glXGetProcAddressARB is available

View File

@ -175,7 +175,7 @@ int _glfwInitContextAPI(void)
_glfw.glx.libGL = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL);
if (!_glfw.glx.libGL)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to find libGL");
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: Failed to find libGL");
return GL_FALSE;
}
#endif
@ -320,8 +320,7 @@ int _glfwCreateContext(_GLFWwindow* window,
!_glfw.glx.EXT_create_context_es2_profile)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"GLX: OpenGL ES requested but "
"GLX_EXT_create_context_es2_profile is unavailable");
"GLX: OpenGL ES requested but GLX_EXT_create_context_es2_profile is unavailable");
return GL_FALSE;
}
}
@ -331,8 +330,7 @@ int _glfwCreateContext(_GLFWwindow* window,
if (!_glfw.glx.ARB_create_context)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"GLX: Forward compatibility requested but "
"GLX_ARB_create_context_profile is unavailable");
"GLX: Forward compatibility requested but GLX_ARB_create_context_profile is unavailable");
return GL_FALSE;
}
}
@ -343,8 +341,7 @@ int _glfwCreateContext(_GLFWwindow* window,
!_glfw.glx.ARB_create_context_profile)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"GLX: An OpenGL profile requested but "
"GLX_ARB_create_context_profile is unavailable");
"GLX: An OpenGL profile requested but GLX_ARB_create_context_profile is unavailable");
return GL_FALSE;
}
}
@ -360,9 +357,6 @@ int _glfwCreateContext(_GLFWwindow* window,
if (ctxconfig->forward)
flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
if (ctxconfig->debug)
flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
if (ctxconfig->profile)
{
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
@ -374,6 +368,9 @@ int _glfwCreateContext(_GLFWwindow* window,
else
mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
if (ctxconfig->debug)
flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
if (ctxconfig->robustness)
{
if (_glfw.glx.ARB_create_context_robustness)
@ -454,7 +451,7 @@ int _glfwCreateContext(_GLFWwindow* window,
if (!window->glx.context)
{
_glfwInputXError(GLFW_PLATFORM_ERROR, "GLX: Failed to create context");
_glfwInputXError(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context");
return GL_FALSE;
}

View File

@ -46,7 +46,7 @@ static void setCursorMode(_GLFWwindow* window, int newMode)
newMode != GLFW_CURSOR_HIDDEN &&
newMode != GLFW_CURSOR_DISABLED)
{
_glfwInputError(GLFW_INVALID_ENUM, NULL);
_glfwInputError(GLFW_INVALID_ENUM, "Invalid cursor mode");
return;
}
@ -216,10 +216,10 @@ void _glfwInputCursorEnter(_GLFWwindow* window, int entered)
window->callbacks.cursorEnter((GLFWwindow*) window, entered);
}
void _glfwInputDrop(_GLFWwindow* window, int count, const char** names)
void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths)
{
if (window->callbacks.drop)
window->callbacks.drop((GLFWwindow*) window, count, names);
window->callbacks.drop((GLFWwindow*) window, count, paths);
}
@ -242,7 +242,7 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
case GLFW_STICKY_MOUSE_BUTTONS:
return window->stickyMouseButtons;
default:
_glfwInputError(GLFW_INVALID_ENUM, NULL);
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode");
return 0;
}
}
@ -265,7 +265,7 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
setStickyMouseButtons(window, value ? GL_TRUE : GL_FALSE);
break;
default:
_glfwInputError(GLFW_INVALID_ENUM, NULL);
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode");
break;
}
}
@ -278,7 +278,7 @@ GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
if (key < 0 || key > GLFW_KEY_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, "The specified key is invalid");
_glfwInputError(GLFW_INVALID_ENUM, "Invalid key");
return GLFW_RELEASE;
}
@ -301,7 +301,7 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button)
if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM,
"The specified mouse button is invalid");
"Invalid mouse button");
return GLFW_RELEASE;
}
@ -384,6 +384,17 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (shape != GLFW_ARROW_CURSOR &&
shape != GLFW_IBEAM_CURSOR &&
shape != GLFW_CROSSHAIR_CURSOR &&
shape != GLFW_HAND_CURSOR &&
shape != GLFW_HRESIZE_CURSOR &&
shape != GLFW_VRESIZE_CURSOR)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor");
return NULL;
}
cursor = calloc(1, sizeof(_GLFWcursor));
cursor->next = _glfw.cursorListHead;
_glfw.cursorListHead = cursor;
@ -518,7 +529,7 @@ GLFWAPI int glfwJoystickPresent(int joy)
if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, NULL);
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick");
return 0;
}
@ -533,7 +544,7 @@ GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count)
if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, NULL);
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick");
return NULL;
}
@ -548,7 +559,7 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count)
if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, NULL);
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick");
return NULL;
}
@ -561,7 +572,7 @@ GLFWAPI const char* glfwGetJoystickName(int joy)
if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, NULL);
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick");
return NULL;
}
@ -591,6 +602,13 @@ GLFWAPI double glfwGetTime(void)
GLFWAPI void glfwSetTime(double time)
{
_GLFW_REQUIRE_INIT();
if (time != time || time < 0.0 || time > 18446744073.0)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid time");
return;
}
_glfwPlatformSetTime(time);
}

View File

@ -33,7 +33,18 @@
#include "glfw_config.h"
#endif
#define _GLFW_VERSION_NUMBER "3.1.0"
#define _GLFW_VERSION_NUMBER "3.1.1"
#if defined(GLFW_INCLUDE_GLCOREARB) || \
defined(GLFW_INCLUDE_ES1) || \
defined(GLFW_INCLUDE_ES2) || \
defined(GLFW_INCLUDE_ES3) || \
defined(GLFW_INCLUDE_NONE) || \
defined(GLFW_INCLUDE_GLEXT) || \
defined(GLFW_INCLUDE_GLU) || \
defined(GLFW_DLL)
#error "You may not define any header option macros when compiling GLFW"
#endif
#if defined(_GLFW_USE_OPENGL)
// This is the default for glfw3.h

View File

@ -277,11 +277,13 @@ void _glfwTerminateJoysticks(void)
regfree(&_glfw.linux_js.regex);
if (_glfw.linux_js.watch > 0)
close(_glfw.linux_js.watch);
if (_glfw.linux_js.inotify > 0)
{
if (_glfw.linux_js.watch > 0)
inotify_rm_watch(_glfw.linux_js.inotify, _glfw.linux_js.watch);
close(_glfw.linux_js.inotify);
}
#endif // __linux__
}

View File

@ -65,7 +65,7 @@ int _glfwPlatformInit(void)
if (error)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Failed to create event mutex: %s\n",
"Mir: Failed to create event mutex: %s",
strerror(error));
return GL_FALSE;
}

View File

@ -127,12 +127,12 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}

View File

@ -470,7 +470,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (wndconfig->width > mode.width || wndconfig->height > mode.height)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Requested surface size is to large (%i %i)",
"Mir: Requested surface size too large: %ix%i",
wndconfig->width, wndconfig->height);
return GL_FALSE;
@ -502,13 +502,13 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
@ -516,19 +516,19 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
int* right, int* bottom)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
@ -552,39 +552,39 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
void _glfwPlatformHideWindow(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
void _glfwPlatformShowWindow(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
int _glfwPlatformWindowFocused(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
return GL_FALSE;
}
int _glfwPlatformWindowIconified(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
return GL_FALSE;
}
int _glfwPlatformWindowVisible(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
return GL_FALSE;
}
@ -628,7 +628,7 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
int xhot, int yhot)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
return GL_FALSE;
}
@ -636,7 +636,7 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
return GL_FALSE;
}
@ -644,43 +644,43 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
void _glfwPlatformApplyCursorMode(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s!", __PRETTY_FUNCTION__);
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
return NULL;
}

View File

@ -28,6 +28,7 @@
#include "internal.h"
#include <math.h>
#include <float.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
@ -385,10 +386,9 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
_GLFW_REQUIRE_INIT();
if (gamma <= 0.f)
if (gamma != gamma || gamma <= 0.f || gamma > FLT_MAX)
{
_glfwInputError(GLFW_INVALID_VALUE,
"Gamma value must be greater than zero");
_glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value");
return;
}

View File

@ -42,7 +42,7 @@ int _glfwInitContextAPI(void)
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
if (_glfw.nsgl.framework == NULL)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
_glfwInputError(GLFW_API_UNAVAILABLE,
"NSGL: Failed to locate OpenGL framework");
return GL_FALSE;
}
@ -76,8 +76,7 @@ int _glfwCreateContext(_GLFWwindow* window,
if (ctxconfig->major == 3 && ctxconfig->minor < 2)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: The targeted version of OS X does not "
"support OpenGL 3.0 or 3.1");
"NSGL: The targeted version of OS X does not support OpenGL 3.0 or 3.1");
return GL_FALSE;
}
@ -86,18 +85,14 @@ int _glfwCreateContext(_GLFWwindow* window,
if (!ctxconfig->forward)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: The targeted version of OS X only "
"supports OpenGL 3.2 and later versions if they "
"are forward-compatible");
"NSGL: The targeted version of OS X only supports forward-compatible contexts for OpenGL 3.2 and above");
return GL_FALSE;
}
if (ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: The targeted version of OS X only "
"supports OpenGL 3.2 and later versions if they "
"use the core profile");
"NSGL: The targeted version of OS X only supports core profile contexts for OpenGL 3.2 and above");
return GL_FALSE;
}
}
@ -106,8 +101,7 @@ int _glfwCreateContext(_GLFWwindow* window,
if (ctxconfig->major > 2)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: The targeted version of OS X does not "
"support OpenGL version 3.0 or above");
"NSGL: The targeted version of OS X does not support OpenGL version 3.0 or above");
return GL_FALSE;
}
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
@ -232,7 +226,7 @@ int _glfwCreateContext(_GLFWwindow* window,
shareContext:share];
if (window->nsgl.context == nil)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: Failed to create OpenGL context");
return GL_FALSE;
}

View File

@ -167,12 +167,6 @@ static GLboolean choosePixelFormat(_GLFWwindow* window,
NULL);
}
if (!nativeCount)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "WGL: No pixel formats found");
return GL_FALSE;
}
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
usableCount = 0;
@ -325,7 +319,7 @@ int _glfwInitContextAPI(void)
_glfw.wgl.opengl32.instance = LoadLibraryW(L"opengl32.dll");
if (!_glfw.wgl.opengl32.instance)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to load opengl32.dll");
_glfwInputError(GLFW_PLATFORM_ERROR, "WGL: Failed to load opengl32.dll");
return GL_FALSE;
}
@ -367,7 +361,7 @@ int _glfwCreateContext(_GLFWwindow* window,
if (!window->wgl.dc)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to retrieve DC for window");
"WGL: Failed to retrieve DC for window");
return GL_FALSE;
}
@ -377,15 +371,14 @@ int _glfwCreateContext(_GLFWwindow* window,
if (!DescribePixelFormat(window->wgl.dc, pixelFormat, sizeof(pfd), &pfd))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to retrieve PFD for selected pixel "
"format");
"WGL: Failed to retrieve PFD for selected pixel format");
return GL_FALSE;
}
if (!SetPixelFormat(window->wgl.dc, pixelFormat, &pfd))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to set selected pixel format");
"WGL: Failed to set selected pixel format");
return GL_FALSE;
}
@ -398,9 +391,6 @@ int _glfwCreateContext(_GLFWwindow* window,
if (ctxconfig->forward)
flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
if (ctxconfig->debug)
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
if (ctxconfig->profile)
{
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
@ -412,6 +402,9 @@ int _glfwCreateContext(_GLFWwindow* window,
else
mask |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT;
if (ctxconfig->debug)
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
if (ctxconfig->robustness)
{
if (window->wgl.ARB_create_context_robustness)
@ -478,7 +471,7 @@ int _glfwCreateContext(_GLFWwindow* window,
window->wgl.context = wglCreateContext(window->wgl.dc);
if (!window->wgl.context)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Failed to create OpenGL context");
return GL_FALSE;
}
@ -488,8 +481,7 @@ int _glfwCreateContext(_GLFWwindow* window,
if (!wglShareLists(share, window->wgl.context))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to enable sharing with specified "
"OpenGL context");
"WGL: Failed to enable sharing with specified OpenGL context");
return GL_FALSE;
}
}
@ -535,9 +527,7 @@ int _glfwAnalyzeContext(const _GLFWwindow* window,
if (!window->wgl.ARB_create_context)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: A forward compatible OpenGL context "
"requested but WGL_ARB_create_context is "
"unavailable");
"WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable");
return _GLFW_RECREATION_IMPOSSIBLE;
}
@ -549,8 +539,7 @@ int _glfwAnalyzeContext(const _GLFWwindow* window,
if (!window->wgl.ARB_create_context_profile)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: OpenGL profile requested but "
"WGL_ARB_create_context_profile is unavailable");
"WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");
return _GLFW_RECREATION_IMPOSSIBLE;
}
@ -570,8 +559,7 @@ int _glfwAnalyzeContext(const _GLFWwindow* window,
!window->wgl.EXT_create_context_es2_profile)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"WGL: OpenGL ES requested but "
"WGL_ARB_create_context_es2_profile is unavailable");
"WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable");
return _GLFW_RECREATION_IMPOSSIBLE;
}

View File

@ -30,11 +30,6 @@
#include <stdlib.h>
#include <malloc.h>
#ifdef __BORLANDC__
// With the Borland C++ compiler, we want to disable FPU exceptions
#include <float.h>
#endif // __BORLANDC__
#if defined(_GLFW_USE_OPTIMUS_HPG)
@ -335,12 +330,6 @@ int _glfwPlatformInit(void)
if (_glfw_SetProcessDPIAware)
_glfw_SetProcessDPIAware();
#ifdef __BORLANDC__
// With the Borland C++ compiler, we want to disable FPU exceptions
// (this is recommended for OpenGL applications under Windows)
_control87(MCW_EM, MCW_EM);
#endif
if (!_glfwRegisterWindowClass())
return GL_FALSE;
@ -381,8 +370,6 @@ const char* _glfwPlatformGetVersionString(void)
" MinGW"
#elif defined(_MSC_VER)
" VisualC"
#elif defined(__BORLANDC__)
" BorlandC"
#endif
#if defined(_GLFW_BUILD_DLL)
" DLL"

View File

@ -144,7 +144,7 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
if (!name)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Failed to convert string to UTF-8");
"Win32: Failed to convert string to UTF-8");
continue;
}

View File

@ -584,7 +584,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
int i;
const int count = DragQueryFileW(hDrop, 0xffffffff, NULL, 0);
char** names = calloc(count, sizeof(char*));
char** paths = calloc(count, sizeof(char*));
// Move the mouse to the position of the drop
DragQueryPoint(hDrop, &pt);
@ -596,16 +596,16 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
WCHAR* buffer = calloc(length + 1, sizeof(WCHAR));
DragQueryFileW(hDrop, i, buffer, length + 1);
names[i] = _glfwCreateUTF8FromWideString(buffer);
paths[i] = _glfwCreateUTF8FromWideString(buffer);
free(buffer);
}
_glfwInputDrop(window, count, (const char**) names);
_glfwInputDrop(window, count, (const char**) paths);
for (i = 0; i < count; i++)
free(names[i]);
free(names);
free(paths[i]);
free(paths);
DragFinish(hDrop);
return 0;
@ -679,7 +679,7 @@ static int createWindow(_GLFWwindow* window,
if (!wideTitle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert title to wide string");
"Win32: Failed to convert window title to UTF-16");
return GL_FALSE;
}
@ -862,7 +862,7 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
if (!wideTitle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert title to wide string");
"Win32: Failed to convert window title to UTF-16");
return;
}
@ -1168,18 +1168,12 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
{
LPCWSTR native = translateCursorShape(shape);
if (!native)
{
_glfwInputError(GLFW_INVALID_ENUM, "Win32: Invalid standard cursor");
return GL_FALSE;
}
cursor->win32.handle = CopyCursor(LoadCursorW(NULL, native));
cursor->win32.handle =
CopyCursor(LoadCursorW(NULL, translateCursorShape(shape)));
if (!cursor->win32.handle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to retrieve shared cursor");
"Win32: Failed to create standard cursor");
return GL_FALSE;
}
@ -1219,8 +1213,7 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
if (!wideString)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert clipboard string to "
"wide string");
"Win32: Failed to convert string to UTF-16");
return;
}
@ -1259,12 +1252,6 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
{
HANDLE stringHandle;
if (!IsClipboardFormatAvailable(CF_UNICODETEXT))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, NULL);
return NULL;
}
if (!OpenClipboard(window->win32.handle))
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard");
@ -1276,8 +1263,8 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
{
CloseClipboard();
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to retrieve clipboard data");
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"Win32: Failed to convert clipboard to string");
return NULL;
}

View File

@ -394,7 +394,7 @@ GLFWAPI void glfwWindowHint(int target, int hint)
_glfw.hints.release = hint;
break;
default:
_glfwInputError(GLFW_INVALID_ENUM, NULL);
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint");
break;
}
}
@ -479,7 +479,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos)
if (window->monitor)
{
_glfwInputError(GLFW_INVALID_VALUE,
"Full screen windows cannot be positioned");
"Full screen windows cannot be moved");
return;
}
@ -624,7 +624,7 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
return window->context.release;
}
_glfwInputError(GLFW_INVALID_ENUM, NULL);
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute");
return 0;
}

View File

@ -479,11 +479,13 @@ static GLboolean initExtensions(void)
"_MOTIF_WM_HINTS",
False);
#if defined(_GLFW_HAS_XF86VM)
// Check for XF86VidMode extension
_glfw.x11.vidmode.available =
XF86VidModeQueryExtension(_glfw.x11.display,
&_glfw.x11.vidmode.eventBase,
&_glfw.x11.vidmode.errorBase);
#endif /*_GLFW_HAS_XF86VM*/
// Check for RandR extension
_glfw.x11.randr.available =
@ -535,6 +537,7 @@ static GLboolean initExtensions(void)
_glfw.x11.xinerama.available = GL_TRUE;
}
#if defined(_GLFW_HAS_XINPUT)
if (XQueryExtension(_glfw.x11.display,
"XInputExtension",
&_glfw.x11.xi.majorOpcode,
@ -551,6 +554,7 @@ static GLboolean initExtensions(void)
_glfw.x11.xi.available = GL_TRUE;
}
}
#endif /*_GLFW_HAS_XINPUT*/
// Check if Xkb is supported on this display
_glfw.x11.xkb.versionMajor = 1;
@ -583,7 +587,7 @@ static GLboolean initExtensions(void)
detectEWMH();
// Find or create string format atoms
_glfw.x11._NULL = XInternAtom(_glfw.x11.display, "NULL", False);
_glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
_glfw.x11.UTF8_STRING =
XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
_glfw.x11.COMPOUND_STRING =
@ -710,6 +714,8 @@ Cursor _glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
int _glfwPlatformInit(void)
{
// HACK: If the current locale is C, apply the environment's locale
// This is done because the C locale breaks character input
if (strcmp(setlocale(LC_CTYPE, NULL), "C") == 0)
setlocale(LC_CTYPE, "");
@ -718,7 +724,7 @@ int _glfwPlatformInit(void)
_glfw.x11.display = XOpenDisplay(NULL);
if (!_glfw.x11.display)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "X11: Failed to open X display");
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to open X display");
return GL_FALSE;
}

View File

@ -432,6 +432,7 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
XRRFreeGamma(gamma);
}
#if defined(_GLFW_HAS_XF86VM)
else if (_glfw.x11.vidmode.available)
{
int size;
@ -443,6 +444,7 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
_glfw.x11.screen,
ramp->size, ramp->red, ramp->green, ramp->blue);
}
#endif /*_GLFW_HAS_XF86VM*/
}
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
@ -458,6 +460,7 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
XRRSetCrtcGamma(_glfw.x11.display, monitor->x11.crtc, gamma);
XRRFreeGamma(gamma);
}
#if defined(_GLFW_HAS_XF86VM)
else if (_glfw.x11.vidmode.available)
{
XF86VidModeSetGammaRamp(_glfw.x11.display,
@ -467,6 +470,7 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
(unsigned short*) ramp->green,
(unsigned short*) ramp->blue);
}
#endif /*_GLFW_HAS_XF86VM*/
}

View File

@ -37,21 +37,25 @@
#include <X11/Xatom.h>
#include <X11/Xcursor/Xcursor.h>
// The Xf86VidMode extension provides fallback gamma control
#include <X11/extensions/xf86vmode.h>
// The XRandR extension provides mode setting and gamma control
#include <X11/extensions/Xrandr.h>
// The XInput2 extension provides improved input events
#include <X11/extensions/XInput2.h>
// The Xkb extension provides improved keyboard support
#include <X11/XKBlib.h>
// The Xinerama extension provides legacy monitor indices
#include <X11/extensions/Xinerama.h>
#if defined(_GLFW_HAS_XINPUT)
// The XInput2 extension provides improved input events
#include <X11/extensions/XInput2.h>
#endif
#if defined(_GLFW_HAS_XF86VM)
// The Xf86VidMode extension provides fallback gamma control
#include <X11/extensions/xf86vmode.h>
#endif
#include "posix_tls.h"
#if defined(_GLFW_GLX)
@ -156,18 +160,12 @@ typedef struct _GLFWlibraryX11
Atom CLIPBOARD;
Atom CLIPBOARD_MANAGER;
Atom SAVE_TARGETS;
Atom _NULL;
Atom NULL_;
Atom UTF8_STRING;
Atom COMPOUND_STRING;
Atom ATOM_PAIR;
Atom GLFW_SELECTION;
struct {
GLboolean available;
int eventBase;
int errorBase;
} vidmode;
struct {
GLboolean available;
int eventBase;
@ -188,15 +186,6 @@ typedef struct _GLFWlibraryX11
int versionMinor;
} xkb;
struct {
GLboolean available;
int majorOpcode;
int eventBase;
int errorBase;
int versionMajor;
int versionMinor;
} xi;
struct {
int count;
int timeout;
@ -215,6 +204,25 @@ typedef struct _GLFWlibraryX11
int versionMinor;
} xinerama;
#if defined(_GLFW_HAS_XINPUT)
struct {
GLboolean available;
int majorOpcode;
int eventBase;
int errorBase;
int versionMajor;
int versionMinor;
} xi;
#endif /*_GLFW_HAS_XINPUT*/
#if defined(_GLFW_HAS_XF86VM)
struct {
GLboolean available;
int eventBase;
int errorBase;
} vidmode;
#endif /*_GLFW_HAS_XF86VM*/
} _GLFWlibraryX11;

View File

@ -28,6 +28,7 @@
#include "internal.h"
#include <X11/cursorfont.h>
#include <X11/Xmd.h>
#include <sys/select.h>
@ -57,6 +58,22 @@ typedef struct
#define MWM_HINTS_DECORATIONS (1L << 1)
// Wait for data to arrive
//
void selectDisplayConnection(struct timeval* timeout)
{
fd_set fds;
const int fd = ConnectionNumber(_glfw.x11.display);
FD_ZERO(&fds);
FD_SET(fd, &fds);
// select(1) is used instead of an X function like XNextEvent, as the
// wait inside those are guarded by the mutex protecting the display
// struct, locking out other threads from using X (including GLX)
select(fd + 1, &fds, NULL, NULL, timeout);
}
// Returns whether the window is iconified
//
static int getWindowState(_GLFWwindow* window)
@ -183,11 +200,12 @@ static void changeWindowState(_GLFWwindow* window, Atom state, int action)
}
// Splits and translates a text/uri-list into separate file paths
// NOTE: This function destroys the provided string
//
static char** parseUriList(char* text, int* count)
{
const char* prefix = "file://";
char** names = NULL;
char** paths = NULL;
char* line;
*count = 0;
@ -196,7 +214,7 @@ static char** parseUriList(char* text, int* count)
{
text = NULL;
if (*line == '#')
if (line[0] == '#')
continue;
if (strncmp(line, prefix, strlen(prefix)) == 0)
@ -204,27 +222,27 @@ static char** parseUriList(char* text, int* count)
(*count)++;
char* name = calloc(strlen(line) + 1, 1);
names = realloc(names, *count * sizeof(char*));
names[*count - 1] = name;
char* path = calloc(strlen(line) + 1, 1);
paths = realloc(paths, *count * sizeof(char*));
paths[*count - 1] = path;
while (*line)
{
if (line[0] == '%' && line[1] && line[2])
{
const char digits[3] = { line[1], line[2], '\0' };
*name = strtol(digits, NULL, 16);
*path = strtol(digits, NULL, 16);
line += 2;
}
else
*name = *line;
*path = *line;
name++;
path++;
line++;
}
}
return names;
return paths;
}
// Create the X11 window (and its colormap)
@ -411,6 +429,7 @@ static GLboolean createWindow(_GLFWwindow* window,
XFree(hint);
}
#if defined(_GLFW_HAS_XINPUT)
if (_glfw.x11.xi.available)
{
// Select for XInput2 events
@ -425,6 +444,7 @@ static GLboolean createWindow(_GLFWwindow* window,
XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1);
}
#endif /*_GLFW_HAS_XINPUT*/
if (_glfw.x11.XdndAware)
{
@ -435,27 +455,6 @@ static GLboolean createWindow(_GLFWwindow* window,
PropModeReplace, (unsigned char*) &version, 1);
}
if (_glfw.x11.NET_REQUEST_FRAME_EXTENTS)
{
// Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to
// function before the window is mapped
XEvent event;
memset(&event, 0, sizeof(event));
event.type = ClientMessage;
event.xclient.window = window->x11.handle;
event.xclient.format = 32; // Data is 32-bit longs
event.xclient.message_type = _glfw.x11.NET_REQUEST_FRAME_EXTENTS;
XSendEvent(_glfw.x11.display,
_glfw.x11.root,
False,
SubstructureNotifyMask | SubstructureRedirectMask,
&event);
XIfEvent(_glfw.x11.display, &event, isFrameExtentsEvent, (XPointer) window);
}
if (wndconfig->floating && !wndconfig->monitor)
{
if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_ABOVE)
@ -629,7 +628,7 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
XChangeProperty(_glfw.x11.display,
request->requestor,
request->property,
_glfw.x11._NULL,
_glfw.x11.NULL_,
32,
PropModeReplace,
NULL,
@ -701,33 +700,35 @@ static void pushSelectionToManager(_GLFWwindow* window)
{
XEvent event;
if (!XCheckIfEvent(_glfw.x11.display, &event, isSelectionEvent, NULL))
continue;
switch (event.type)
while (XCheckIfEvent(_glfw.x11.display, &event, isSelectionEvent, NULL))
{
case SelectionRequest:
handleSelectionRequest(&event);
break;
case SelectionClear:
handleSelectionClear(&event);
break;
case SelectionNotify:
switch (event.type)
{
if (event.xselection.target == _glfw.x11.SAVE_TARGETS)
{
// This means one of two things; either the selection was
// not owned, which means there is no clipboard manager, or
// the transfer to the clipboard manager has completed
// In either case, it means we are done here
return;
}
case SelectionRequest:
handleSelectionRequest(&event);
break;
break;
case SelectionClear:
handleSelectionClear(&event);
break;
case SelectionNotify:
{
if (event.xselection.target == _glfw.x11.SAVE_TARGETS)
{
// This means one of two things; either the selection was
// not owned, which means there is no clipboard manager, or
// the transfer to the clipboard manager has completed
// In either case, it means we are done here
return;
}
break;
}
}
}
selectDisplayConnection(NULL);
}
}
@ -1007,7 +1008,7 @@ static void processEvent(XEvent *event)
// Additional buttons after 7 are treated as regular buttons
// We subtract 4 to fill the gap left by scroll input above
_glfwInputMouseClick(window,
event->xbutton.button - 4,
event->xbutton.button - Button1 - 4,
GLFW_PRESS,
mods);
}
@ -1045,7 +1046,7 @@ static void processEvent(XEvent *event)
// Additional buttons after 7 are treated as regular buttons
// We subtract 4 to fill the gap left by scroll input above
_glfwInputMouseClick(window,
event->xbutton.button - 4,
event->xbutton.button - Button1 - 4,
GLFW_RELEASE,
mods);
}
@ -1054,6 +1055,11 @@ static void processEvent(XEvent *event)
case EnterNotify:
{
// HACK: This is a workaround for WMs (KWM, Fluxbox) that otherwise
// ignore the defined cursor for hidden cursor mode
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
hideCursor(window);
_glfwInputCursorEnter(window, GL_TRUE);
break;
}
@ -1216,13 +1222,13 @@ static void processEvent(XEvent *event)
if (result)
{
int i, count;
char** names = parseUriList(data, &count);
char** paths = parseUriList(data, &count);
_glfwInputDrop(window, count, (const char**) names);
_glfwInputDrop(window, count, (const char**) paths);
for (i = 0; i < count; i++)
free(names[i]);
free(names);
free(paths[i]);
free(paths);
}
XFree(data);
@ -1309,6 +1315,7 @@ static void processEvent(XEvent *event)
case DestroyNotify:
return;
#if defined(_GLFW_HAS_XINPUT)
case GenericEvent:
{
if (event->xcookie.extension == _glfw.x11.xi.majorOpcode &&
@ -1354,6 +1361,7 @@ static void processEvent(XEvent *event)
XFreeEventData(_glfw.x11.display, &event->xcookie);
break;
}
#endif /*_GLFW_HAS_XINPUT*/
default:
{
@ -1447,8 +1455,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
if (window->x11.handle)
{
if (window->x11.handle ==
XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD))
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==
window->x11.handle)
{
pushSelectionToManager(window);
}
@ -1596,6 +1604,56 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
if (_glfw.x11.NET_FRAME_EXTENTS == None)
return;
if (!_glfwPlatformWindowVisible(window) &&
_glfw.x11.NET_REQUEST_FRAME_EXTENTS)
{
// Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to
// function before the window is mapped
double base;
XEvent event;
memset(&event, 0, sizeof(event));
event.type = ClientMessage;
event.xclient.window = window->x11.handle;
event.xclient.format = 32; // Data is 32-bit longs
event.xclient.message_type = _glfw.x11.NET_REQUEST_FRAME_EXTENTS;
XSendEvent(_glfw.x11.display,
_glfw.x11.root,
False,
SubstructureNotifyMask | SubstructureRedirectMask,
&event);
// HACK: Poll with timeout for the required response instead of blocking
// This is done because some window managers (at least Unity,
// Fluxbox and Xfwm) failed to send the required response
// They have been fixed but broken versions are still in the wild
// If you are affected by this and your window manager is NOT
// listed above, PLEASE report it to their and our issue trackers
base = _glfwPlatformGetTime();
while (!XCheckIfEvent(_glfw.x11.display,
&event,
isFrameExtentsEvent,
(XPointer) window))
{
double remaining;
struct timeval timeout;
remaining = 0.5 + base - _glfwPlatformGetTime();
if (remaining <= 0.0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: The window manager has a broken _NET_REQUEST_FRAME_EXTENTS implementation; please report this issue");
return;
}
timeout.tv_sec = 0;
timeout.tv_usec = (long) (remaining * 1e6);
selectDisplayConnection(&timeout);
}
}
if (_glfwGetWindowProperty(window->x11.handle,
_glfw.x11.NET_FRAME_EXTENTS,
XA_CARDINAL,
@ -1621,9 +1679,8 @@ void _glfwPlatformIconifyWindow(_GLFWwindow* window)
{
// Override-redirect windows cannot be iconified or restored, as those
// tasks are performed by the window manager
_glfwInputError(GLFW_API_UNAVAILABLE,
"X11: Iconification of full screen windows requires "
"a WM that supports EWMH");
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Iconification of full screen windows requires a WM that supports EWMH");
return;
}
@ -1637,9 +1694,8 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
{
// Override-redirect windows cannot be iconified or restored, as those
// tasks are performed by the window manager
_glfwInputError(GLFW_API_UNAVAILABLE,
"X11: Iconification of full screen windows requires "
"a WM that supports EWMH");
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Iconification of full screen windows requires a WM that supports EWMH");
return;
}
@ -1708,19 +1764,7 @@ void _glfwPlatformPollEvents(void)
void _glfwPlatformWaitEvents(void)
{
if (!XPending(_glfw.x11.display))
{
fd_set fds;
const int fd = ConnectionNumber(_glfw.x11.display);
FD_ZERO(&fds);
FD_SET(fd, &fds);
// select(1) is used instead of an X function like XNextEvent, as the
// wait inside those are guarded by the mutex protecting the display
// struct, locking out other threads from using X (including GLX)
if (select(fd + 1, &fds, NULL, NULL, NULL) < 0)
return;
}
selectDisplayConnection(NULL);
_glfwPlatformPollEvents();
}
@ -1734,7 +1778,7 @@ void _glfwPlatformPostEmptyEvent(void)
event.type = ClientMessage;
event.xclient.window = window->x11.handle;
event.xclient.format = 32; // Data is 32-bit longs
event.xclient.message_type = _glfw.x11._NULL;
event.xclient.message_type = _glfw.x11.NULL_;
XSendEvent(_glfw.x11.display, window->x11.handle, False, 0, &event);
XFlush(_glfw.x11.display);
@ -1796,14 +1840,8 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
{
const unsigned int native = translateCursorShape(shape);
if (!native)
{
_glfwInputError(GLFW_INVALID_ENUM, "X11: Invalid standard cursor");
return GL_FALSE;
}
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display,
translateCursorShape(shape));
if (!cursor->x11.handle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@ -1846,7 +1884,7 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
window->x11.handle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to become owner of the clipboard selection");
"X11: Failed to become owner of clipboard selection");
}
}
@ -1883,7 +1921,7 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
// XCheckTypedEvent is used instead of XIfEvent in order not to lock
// other threads out from the display during the entire wait period
while (!XCheckTypedEvent(_glfw.x11.display, SelectionNotify, &event))
;
selectDisplayConnection(NULL);
if (event.xselection.property == None)
continue;
@ -1909,7 +1947,7 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
if (_glfw.x11.clipboardString == NULL)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"X11: Failed to convert selection to string");
"X11: Failed to convert clipboard to string");
}
return _glfw.x11.clipboardString;

View File

@ -1,5 +1,5 @@
link_libraries(glfw "${OPENGL_glu_LIBRARY}")
link_libraries(glfw)
if (BUILD_SHARED_LIBS)
add_definitions(-DGLFW_DLL)
@ -28,7 +28,7 @@ add_executable(gamma gamma.c ${GETOPT})
add_executable(glfwinfo glfwinfo.c ${GETOPT})
add_executable(iconify iconify.c ${GETOPT})
add_executable(joysticks joysticks.c)
add_executable(modes modes.c ${GETOPT})
add_executable(monitors monitors.c ${GETOPT})
add_executable(peter peter.c)
add_executable(reopen reopen.c)
add_executable(cursor cursor.c)
@ -62,7 +62,7 @@ target_link_libraries(threads "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}")
set(WINDOWS_BINARIES accuracy empty sharing tearing threads title windows cursoranim)
set(CONSOLE_BINARIES clipboard defaults events fsaa gamma glfwinfo
iconify joysticks modes peter reopen cursor)
iconify joysticks monitors peter reopen cursor)
set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
FOLDER "GLFW3/Tests")
@ -76,6 +76,7 @@ endif()
if (APPLE)
set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION_FULL})
MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION_FULL}
MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/AppleInfo.plist")
endif()

View File

@ -27,7 +27,6 @@
//
//========================================================================
#define GLFW_INCLUDE_GLU
#include <GLFW/glfw3.h>
#include <stdio.h>

View File

@ -398,7 +398,7 @@ static void char_mods_callback(GLFWwindow* window, unsigned int codepoint, int m
get_mods_name(mods));
}
static void drop_callback(GLFWwindow* window, int count, const char** names)
static void drop_callback(GLFWwindow* window, int count, const char** paths)
{
int i;
Slot* slot = glfwGetWindowUserPointer(window);
@ -407,7 +407,7 @@ static void drop_callback(GLFWwindow* window, int count, const char** names)
counter++, slot->number, glfwGetTime());
for (i = 0; i < count; i++)
printf(" %i: \"%s\"\n", i, names[i]);
printf(" %i: \"%s\"\n", i, paths[i]);
}
static void monitor_callback(GLFWmonitor* monitor, int event)

View File

@ -110,7 +110,7 @@ static void draw_joystick(Joystick* j, int x, int y, int width, int height)
static void draw_joysticks(GLFWwindow* window)
{
int i, width, height;
int i, width, height, offset = 0;
glfwGetFramebufferSize(window, &width, &height);
@ -126,8 +126,9 @@ static void draw_joysticks(GLFWwindow* window)
if (j->present)
{
draw_joystick(j,
0, i * height / joystick_count,
0, offset * height / joystick_count,
width, height / joystick_count);
offset++;
}
}
}

View File

@ -1,5 +1,5 @@
//========================================================================
// Video mode test
// Monitor information tool
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
@ -23,7 +23,8 @@
//
//========================================================================
//
// This test enumerates or verifies video modes
// This test prints monitor and video mode information or verifies video
// modes
//
//========================================================================
@ -43,8 +44,8 @@ enum Mode
static void usage(void)
{
printf("Usage: modes [-t]\n");
printf(" modes -h\n");
printf("Usage: monitors [-t]\n");
printf(" monitors -h\n");
}
static const char* format_mode(const GLFWvidmode* mode)

View File

@ -22,7 +22,7 @@ void Application::init()
}
void Application::initLevel() {
this->level = Level(levelXmlPath);
this->level = Level(levelXmlPath, farPlane);
level.getPhysics()->init(geometryPath);
// Don't change this!
ignoredMouseUpdates = 0;
@ -35,7 +35,7 @@ void Application::initLevel() {
level.load();
Loader loader = Loader();
loader.load(levelXmlPath, &level, compositionsPath, scriptPath, geometryPath, texturePath, heightmapPath);
loader.load(levelXmlPath, &level, compositionsPath, scriptPath, geometryPath, texturePath, heightmapPath, &graphics);
graphics.init(&level);
// just in case: check for errors

View File

@ -7,8 +7,7 @@ Camera::Camera(glm::vec2 rotation, float distance) {
}
Camera::Camera() {
rotation = glm::vec2(0.0f, 0.0f);
distance = 5.0f;
Camera(glm::vec2(0.0f, 0.0f), 5.0f);
}
Camera::~Camera() {

36
game/chunk.cc Normal file
View File

@ -0,0 +1,36 @@
#include "chunk.hh"
Chunk::Chunk() {
}
Chunk::~Chunk() {
for(unsigned int i = 0; i<objects.size(); i++) {
delete objects.at(i);
}
}
void Chunk::render(SharedShaderProgram shader, bool lightingPass,
glm::mat4* viewProjcetionMatrix, std::vector<glm::mat4>* additionalMatrices) {
for(unsigned int i = 0; i<objects.size(); i++) {
objects.at(i)->render(shader, lightingPass, viewProjcetionMatrix, additionalMatrices);
}
}
void Chunk::addObject(Object* object) {
objects.push_back(object);
}
void Chunk::sortObjects(int textureCount) {
// init
sortedObjects = std::vector<std::vector<Object*>>(textureCount);
for(unsigned int i = 0; i<sortedObjects.size(); i++) {
sortedObjects.at(i) = std::vector<Object*>();
}
for(unsigned int i = 0; i<objects.size(); i++){
sortedObjects.at(objects.at(i)->getMaterial()->getTextureUnit() - 2).push_back(objects.at(i));
}
}
std::vector<std::vector<Object*>>* Chunk::getSortedObjects() {
return &sortedObjects;
}

20
game/chunk.hh Normal file
View File

@ -0,0 +1,20 @@
#pragma once
#include <ACGL/OpenGL/Objects.hh>
#include "object.hh"
using namespace ACGL::OpenGL;
class Chunk {
public:
Chunk();
~Chunk();
void render(SharedShaderProgram shader, bool lightingPass,
glm::mat4* viewProjcetionMatrix, std::vector<glm::mat4>* additionalMatrices=0);
void addObject(Object* object);
void sortObjects(int textureCount);
std::vector<std::vector<Object*>>* getSortedObjects();
private:
std::vector<Object*> objects;
std::vector<std::vector<Object*>> sortedObjects;
};

View File

@ -42,14 +42,11 @@ void Flame::render(SharedShaderProgram shader, glm::mat4 viewProjectionMatrix, f
shader->setUniform("withColor", withColor);
shader->setUniform("time", time);
shader->setUniform("skew", skewing);
shader->setUniform("bottom", true);
shader->setUniform("left", true);
vao->render();
shader->setUniform("left", false);
vao->render();
shader->setUniform("bottom", false);
shader->setUniform("left", true);
vao->render();
shader->setUniform("left", false);
vao->render();
for (int i = 0; i<8; i++) {
shader->setUniform("bottom", true);
shader->setUniform("circle_index", i);
vao->render();
shader->setUniform("bottom", false);
vao->render();
}
}

View File

@ -12,6 +12,7 @@ using namespace ACGL::OpenGL;
const double lightUpdateDelay = 0.5f;
const double windUpdateDelay = 0.5f;
const int maxShadowSampleCount = 26;
Graphics::Graphics(glm::uvec2 windowSize, float nearPlane,
float farPlane, int cube_size,
@ -20,9 +21,24 @@ Graphics::Graphics(glm::uvec2 windowSize, float nearPlane,
std::string screenContinuePath) {
this->windowSize = windowSize;
this->nearPlane = nearPlane;
this->farPlane = farPlane;
this->cube_size = cube_size;
this->maxShadowRenderCount = maxShadowRenderCount;
if (farPlane > 0) {
this->farPlane = farPlane;
}
else {
this->farPlane = 0;
}
if (cube_size > 0) {
this->cube_size = cube_size;
}
else {
this->cube_size = 0;
}
if (maxShadowRenderCount < maxShadowSampleCount) {
this->maxShadowRenderCount = maxShadowRenderCount;
}
else {
this->maxShadowRenderCount = 0;
}
this->loadingScreenPath = screenPath;
this->loadingScreenContinuePath = screenContinuePath;
gameStart = false;
@ -35,7 +51,6 @@ Graphics::Graphics(glm::uvec2 windowSize, float nearPlane,
Graphics::Graphics() {
}
void Graphics::init(Level* level) {
// save Level
this->level = level;
@ -49,15 +64,13 @@ void Graphics::init(Level* level) {
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
glEnable(GL_MULTISAMPLE);
// update lights on creation
lastLightUpdate = -lightUpdateDelay;
lastLightUpdate = 0;
lastWindUpdate = - windUpdateDelay;
windTarget = 0.0f;
wind = glm::vec2(0.0f, 0.0f);
windDirection = glm::vec2(-1.0f, -1.0f);
windDirectionTarget = glm::vec2(-1.0f, -1.0f);
windDirection = glm::vec2(1.0f, 1.0f);
windDirectionTarget = glm::vec2(1.0f, 1.0f);
textureMovementPosition = glm::vec2(0.0, 0.0);
// construct VAO to give shader correct Attribute locations
@ -127,8 +140,8 @@ void Graphics::init(Level* level) {
level->getPhysics()->getWorld()->setDebugDrawer(&debugDrawer);
depth_directionalMaps = std::vector<SharedTexture2D>(3);
framebuffer_directional = std::vector<SharedFrameBufferObject>(3);
depth_directionalMaps = std::vector<SharedTexture2D>(5);
framebuffer_directional = std::vector<SharedFrameBufferObject>(5);
for (unsigned int i = 0; i<depth_directionalMaps.size(); i++) {
depth_directionalMaps.at(i) = SharedTexture2D( new Texture2D(windowSize, GL_DEPTH_COMPONENT24));
depth_directionalMaps.at(i)->setMinFilter(GL_NEAREST);
@ -144,10 +157,8 @@ void Graphics::init(Level* level) {
framebuffer_directional.at(i)->validate();
}
// always generate and bind 10 cube maps, because otherwise the shader won't work
depth_cubeMaps = std::vector<ACGL::OpenGL::SharedTextureCubeMap>(10);
// always generate and bind all cube maps, because otherwise the shader won't work
depth_cubeMaps = std::vector<ACGL::OpenGL::SharedTextureCubeMap>(maxShadowSampleCount);
for (unsigned int i = 0; i<depth_cubeMaps.size(); i++) {
depth_cubeMaps.at(i) = SharedTextureCubeMap(new TextureCubeMap(glm::vec2(cube_size, cube_size), GL_DEPTH_COMPONENT24));
depth_cubeMaps.at(i)->setMinFilter(GL_NEAREST);
@ -182,43 +193,85 @@ void Graphics::init(Level* level) {
bindTextureUnits();
updateClosestLights();
// set shader variables that stay the same across the runtime of the application
skydomeShader->use();
skydomeShader->setUniform("farPlane", farPlane);
skydomeShader->setUniform("skydomeSize", level->getSkydomeSize());
skydomeShader->setUniform("fogColorDay", level->getFogColourDay());
skydomeShader->setUniform("fogColorRise", level->getFogColourRise());
skydomeShader->setUniform("fogColorNight", level->getFogColourNight());
skydomeShader->setUniform("sunColor", level->getDirectionalLight()->getColour());
lightingShader->use();
lightingShader->setUniform("farPlane", farPlane);
lightingShader->setUniform("fogColorDay", level->getFogColourDay());
lightingShader->setUniform("fogColorRise", level->getFogColourRise());
lightingShader->setUniform("fogColorNight", level->getFogColourNight());
lightingShader->setUniform("ambientColor", level->getAmbientLight());
if(level->getDirectionalLight()) {
lightingShader->setUniform("directionalLightVector",
level->getDirectionalLight()->getPosition());
lightingShader->setUniform("directionalColor",
level->getDirectionalLight()->getColour());
lightingShader->setUniform("targetDirectionalIntensity",
level->getDirectionalLight()->getIntensity());
}
depthCubeShader->use();
depthCubeShader->setUniform("farPlane", farPlane);
level->sortObjects(Material::getAllTextures()->size());
#ifdef SAXUM_DEBUG
std::cout << "There were " << Material::getAllTextures()->size()
<< " materials used in this level." << std::endl;
cout << "There are " << level->checkMaxSurroundingLights() << " max surrounding lights." << endl;
#endif
initShadowRenderQueue();
updateLights();
}
void Graphics::bindTextureUnits(){
unsigned int textureCount = Material::getAllTextures()->size();
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &number_of_texture_units);
printf("Your graphics card supports %d texture units.\n", number_of_texture_units);
// Exit if we need more texture units
if (number_of_texture_units < (int)textureCount + maxShadowSampleCount + 9) {
printf("You need at least %d texture units to run this application. Exiting\n", textureCount + maxShadowSampleCount + 9);
exit(-1);
}
loadingShader->use();
loadingShader->setTexture("screen", loadingScreen, 0);
loadingShader->setTexture("screenContinue", loadingContinueScreen, 1);
lightingShader->use();
for(unsigned int i = 0; i<Material::getAllTextures()->size(); i++) {
lightingShader->setTexture("uTexture", Material::getAllTextures()->at(i), i+2);
}
for (unsigned int i = 0; i<depth_directionalMaps.size(); i++) {
// start with texture unit 1 because the first is reserved for the texture
lightingShader->setTexture("shadowMap_directional" + std::to_string(i), depth_directionalMaps.at(i), i+1);
lightingShader->setTexture("shadowMap_directional" + std::to_string(i), depth_directionalMaps.at(i), textureCount + i + 2);
}
if (level->getLights()->size() > 0) {
for(unsigned int i = 0; i<depth_cubeMaps.size(); i++){
// start with texture unit 4 because the first four are used by the texture and the directional shadow map
lightingShader->setTexture("shadowMap_cube" + std::to_string(i), depth_cubeMaps.at(i), i+4);
lightingShader->setTexture("shadowMap_cube" + std::to_string(i), depth_cubeMaps.at(i), textureCount + i + 7);
}
}
flamePostShader->use();
flamePostShader->setTexture("light_fbo", light_fbo_color_texture, 14);
flamePostShader->setTexture("light_fbo", light_fbo_color_texture, textureCount + maxShadowSampleCount + 7);
skydomeShader->use();
skydomeShader->setTexture("nightTexture", level->getSkydome()->getNightTexture()->getReference(), 15);
skydomeShader->setTexture("dayTexture", level->getSkydome()->getDayTexture(), textureCount + maxShadowSampleCount + 8);
skydomeShader->setTexture("nightTexture", level->getSkydome()->getNightTexture(), textureCount + maxShadowSampleCount + 9);
loadingShader->use();
loadingShader->setTexture("screen", loadingScreen, 16);
loadingShader->setTexture("screenContinue", loadingContinueScreen, 17);
printf("This application used %d texture units.\n", textureCount + maxShadowSampleCount + 9);
}
void Graphics::renderLoadingScreen() {
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &number_of_texture_units);
printf("Your graphics card supports %d texture units.\n", number_of_texture_units);
// Exit if we need more texture units
if (number_of_texture_units < 18) {
printf("You need at least 18 texture units to run this application. Exiting\n");
exit(-1);
}
loadingScreen = Texture2DFileManager::the()->get(Texture2DCreator(loadingScreenPath));
loadingScreen->generateMipmaps();
loadingScreen->setMinFilter(GL_NEAREST_MIPMAP_LINEAR);
@ -272,8 +325,8 @@ void Graphics::renderLoadingScreen() {
.attributeLocations(fullscreen_quad_loading->getAttributeLocations()).create();
loadingShader->use();
loadingShader->setUniform("time", 0.0f);
loadingShader->setTexture("screen", loadingScreen, 16);
loadingShader->setTexture("screenContinue", loadingContinueScreen, 17);
loadingShader->setTexture("screen", loadingScreen, 0);
loadingShader->setTexture("screenContinue", loadingContinueScreen, 1);
fullscreen_quad_loading->render();
}
@ -286,41 +339,9 @@ void Graphics::render(double time)
if (!gameStart) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, windowSize.x, windowSize.y);
loadingShader->use();
loadingShader->setUniform("time", float(time));
float quadData[24];
if (loadingScreenWidth/loadingScreenHeight < ((float)windowSize.x)/((float)windowSize.y)) {
float quadTemp[24] ={
-(((float)windowSize.y*loadingScreenWidth)/((float)windowSize.x*loadingScreenHeight)), 1.0f, 0.0f, 1.0f,
(((float)windowSize.y*loadingScreenWidth)/((float)windowSize.x*loadingScreenHeight)), 1.0f, 1.0f, 1.0f,
(((float)windowSize.y*loadingScreenWidth)/((float)windowSize.x*loadingScreenHeight)), -1.0f, 1.0f, 0.0f,
(((float)windowSize.y*loadingScreenWidth)/((float)windowSize.x*loadingScreenHeight)), -1.0f, 1.0f, 0.0f,
-(((float)windowSize.y*loadingScreenWidth)/((float)windowSize.x*loadingScreenHeight)), -1.0f, 0.0f, 0.0f,
-(((float)windowSize.y*loadingScreenWidth)/((float)windowSize.x*loadingScreenHeight)), 1.0f, 0.0f, 1.0f
};
for(int i = 0; i<24; i++) {
quadData[i] = quadTemp[i];
}
}
else {
float quadTemp[24] = {
-1.0f, ((float)windowSize.x*loadingScreenHeight)/((float)windowSize.y*loadingScreenWidth), 0.0f, 1.0f,
1.0f, ((float)windowSize.x*loadingScreenHeight)/((float)windowSize.y*loadingScreenWidth), 1.0f, 1.0f,
1.0f, -((float)windowSize.x*loadingScreenHeight)/((float)windowSize.y*loadingScreenWidth), 1.0f, 0.0f,
1.0f, -((float)windowSize.x*loadingScreenHeight)/((float)windowSize.y*loadingScreenWidth), 1.0f, 0.0f,
-1.0f, -((float)windowSize.x*loadingScreenHeight)/((float)windowSize.y*loadingScreenWidth), 0.0f, 0.0f,
-1.0f, ((float)windowSize.x*loadingScreenHeight)/((float)windowSize.y*loadingScreenWidth), 0.0f, 1.0f
};
for(int i = 0; i<24; i++) {
quadData[i] = quadTemp[i];
}
}
fullscreen_quad_ab_loading->setDataElements(6, quadData);
fullscreen_quad_loading = SharedVertexArrayObject(new VertexArrayObject);
fullscreen_quad_loading->attachAllAttributes(fullscreen_quad_ab_loading);
fullscreen_quad_loading->render();
}
else {
@ -334,11 +355,35 @@ void Graphics::render(double time)
// At first render shadows
std::vector<glm::mat4> depthViewProjectionMatrices = std::vector<glm::mat4>(framebuffer_directional.size());
if (renderShadows) {
// update priorities
for(unsigned int i = 0; i<shadowRenderQueue.size(); i++) {
shadowRenderQueue.at(i).currentPriority += shadowRenderQueue.at(i).priority;
}
// schedule lights with highest priority
// tuple : Light, currentPriority, slot
std::vector<std::tuple<std::shared_ptr<Light>, int, int>> renderQueue =
std::vector<std::tuple<std::shared_ptr<Light>, int, int>>(maxShadowRenderCount);
for(unsigned int i = 0; i<shadowRenderQueue.size(); i++) {
for(unsigned int j = 0; j<renderQueue.size(); j++){
if (shadowRenderQueue.at(i).currentPriority > std::get<1>(renderQueue.at(j))){
if (renderQueue.at(j) != renderQueue.back()) {
renderQueue.at(j+1) = renderQueue.at(j);
}
renderQueue.at(j) = std::make_tuple(shadowRenderQueue.at(i).light, shadowRenderQueue.at(i).currentPriority, i);
break;
}
}
}
// reset currentPriority
for(unsigned int i = 0; i<renderQueue.size(); i++) {
shadowRenderQueue.at(std::get<2>(renderQueue.at(i))).currentPriority = 0;
}
depthCubeShader->use();
depthCubeShader->setUniform("farPlane", farPlane);
// render depth textures for point lights
glViewport(0, 0, cube_size, cube_size);
glm::mat4 depthProjectionMatrix_pointlights = glm::perspective(1.571f, (float)cube_size/(float)cube_size, 0.1f, farPlane);
depthCubeShader->use();
glm::mat4 depthProjectionMatrix_pointlights = glm::perspective(1.571f, (float)cube_size/(float)cube_size, 0.1f, 50.0f);
glm::vec3 looking_directions[6] = {glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f),
glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, 0.0f, -1.0f)};
glm::vec3 upvectors[6] = {glm::vec3(0.0f, -1.0f, 0.0f),glm::vec3(0.0f, -1.0f, 0.0f),glm::vec3(0.0f, 0.0f, -1.0f),
@ -346,53 +391,69 @@ void Graphics::render(double time)
framebuffer_cube->bind();
for (unsigned int i_pointlight = 0; i_pointlight<closestLights.size() && i_pointlight < maxShadowRenderCount; i_pointlight++) {
// render each side of the cube
for (int i_face = 0; i_face<6; i_face++) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i_face, depth_cubeMaps.at(i_pointlight)->getObjectName(), 0);
glClear(GL_DEPTH_BUFFER_BIT);
glm::mat4 viewMatrix = glm::lookAt(closestLights.at(i_pointlight).getPosition(),
closestLights.at(i_pointlight).getPosition() + looking_directions[i_face], upvectors[i_face]);
glm::mat4 depthViewProjectionMatrix_face = depthProjectionMatrix_pointlights * viewMatrix;
std::vector<glm::mat4> viewMatrixVector = std::vector<glm::mat4>();
viewMatrixVector.push_back(viewMatrix);
level->render(depthCubeShader, false, &depthViewProjectionMatrix_face, &viewMatrixVector);
if (!framebuffer_cube->isFrameBufferObjectComplete()) {
printf("Framebuffer incomplete, unknown error occured during shadow generation!\n");
for (unsigned int i_pointlight = 0; i_pointlight < renderQueue.size(); i_pointlight++) {
// check if queue points to a existing light
if (std::get<0>(renderQueue.at(i_pointlight))) {
// render each side of the cube
glm::vec3 position = glm::vec3(0.0f);
if (std::get<0>(renderQueue.at(i_pointlight))->isFlame()) {
position = std::get<0>(renderQueue.at(i_pointlight))->getPosition();
position = glm::vec3(position.x - 0.75f*wind.y, position.y, position.z + 0.75f*wind.x);
}
else {
position = std::get<0>(renderQueue.at(i_pointlight))->getPosition();
}
for (int i_face = 0; i_face<6; i_face++) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i_face,
depth_cubeMaps.at(std::get<2>(renderQueue.at(i_pointlight)))->getObjectName(), 0);
glClear(GL_DEPTH_BUFFER_BIT);
glm::mat4 viewMatrix = glm::lookAt(position, position + looking_directions[i_face], upvectors[i_face]);
glm::mat4 depthViewProjectionMatrix_face = depthProjectionMatrix_pointlights * viewMatrix;
std::vector<glm::mat4> viewMatrixVector = std::vector<glm::mat4>(1);
viewMatrixVector.at(0) = viewMatrix;
level->render(depthCubeShader, false, std::get<0>(renderQueue.at(i_pointlight))->getPosition(), 1, &depthViewProjectionMatrix_face, &viewMatrixVector);
if (!framebuffer_cube->isFrameBufferObjectComplete()) {
printf("Framebuffer incomplete, unknown error occured during shadow generation!\n");
}
}
}
}
// render depth textures for sun
depthShader->use();
glViewport(0, 0, windowSize.x, windowSize.y);
// render depth textures for sun
float sunAngle = glm::dot(glm::vec3(0.0f, 1.0f, 0.0f), glm::normalize(level->getDirectionalLight()->getPosition()));
glm::vec3 sunVector = (level->getCameraCenter()->getPosition() + level->getDirectionalLight()->getPosition());
for (unsigned int i = 0; i<framebuffer_directional.size(); i++) {
framebuffer_directional.at(i)->bind();
glClear(GL_DEPTH_BUFFER_BIT);
if (sunAngle > -0.6f) {
float projection_size = 0.0f;
switch(i) {
case 0:
projection_size = 10.0f;
break;
case 1:
projection_size = 30.0f;
break;
case 2:
projection_size = farPlane/1.5f;
break;
}
depthViewProjectionMatrices.at(i) = glm::ortho<float>(-projection_size, projection_size, -projection_size, projection_size, -farPlane/1.5f, farPlane/1.5f) *
glm::lookAt(sunVector, level->getCameraCenter()->getPosition(), glm::vec3(0,1,0));
level->render(depthShader, false, &depthViewProjectionMatrices.at(i));
if (!framebuffer_directional.at(i)->isFrameBufferObjectComplete()) {
printf("Framebuffer incomplete, unknown error occured during shadow generation!\n");
}
if (sunAngle > 0.0f) {
depthShader->use();
for (unsigned int i = 0; i<framebuffer_directional.size(); i++) {
framebuffer_directional.at(i)->bind();
glClear(GL_DEPTH_BUFFER_BIT);
float projection_size = 0.0f;
switch(i) {
case 0:
projection_size = 10.0f;
break;
case 1:
projection_size = 20.0f;
break;
case 2:
projection_size = 40.0f;
break;
case 3:
projection_size = 60.0f;
break;
case 4:
projection_size = farPlane/1.5f;
break;
}
depthViewProjectionMatrices.at(i) = glm::ortho<float>(-projection_size, projection_size, -projection_size, projection_size, -farPlane/1.5f, farPlane/1.5f) *
glm::lookAt(sunVector, level->getCameraCenter()->getPosition(), glm::vec3(0,1,0));
level->render(depthShader, false, level->getCameraCenter()->getPosition(), -1, &depthViewProjectionMatrices.at(i));
if (!framebuffer_directional.at(i)->isFrameBufferObjectComplete()) {
printf("Framebuffer incomplete, unknown error occured during shadow generation!\n");
}
}
}
}
@ -437,15 +498,9 @@ void Graphics::render(double time)
//render skydome
skydomeShader->use();
// set fog Parameters
skydomeShader->setUniform("farPlane", farPlane);
skydomeShader->setUniform("skydomeSize", level->getSkydomeSize());
skydomeShader->setUniform("fogColorDay", level->getFogColourDay());
skydomeShader->setUniform("fogColorRise", level->getFogColourRise());
skydomeShader->setUniform("fogColorNight", level->getFogColourNight());
skydomeShader->setUniform("cameraCenter", level->getCameraCenter()->getPosition());
skydomeShader->setUniform("directionalVector", level->getDirectionalLight()->getPosition());
skydomeShader->setUniform("sunColor", level->getDirectionalLight()->getColour());
level->getSkydome()->render(skydomeShader, false, true, &lightingViewProjectionMatrix);
level->getSkydome()->render(skydomeShader, false, &lightingViewProjectionMatrix);
lightingShader->use();
@ -462,16 +517,14 @@ void Graphics::render(double time)
depthBiasVPs.at(i) = biasMatrix * depthViewProjectionMatrices.at(i);
}
lightingShader->setUniform("farPlane", farPlane);
// set fog Parameters
lightingShader->setUniform("fogColorDay", level->getFogColourDay());
lightingShader->setUniform("fogColorRise", level->getFogColourRise());
lightingShader->setUniform("fogColorNight", level->getFogColourNight());
lightingShader->setUniform("cameraCenter", level->getCameraCenter()->getPosition());
if(level->getDirectionalLight()) {
lightingShader->setUniform("directionalLightVector",
level->getDirectionalLight()->getPosition());
}
// set Material Parameters
lightingShader->setUniform("ambientColor", level->getAmbientLight());
lightingShader->setUniform("camera", level->getPhysics()->getCameraPosition());
textureMovementPosition += wind/5.0f;
lightingShader->setUniform("movingTextureOffset", textureMovementPosition);
@ -481,7 +534,49 @@ void Graphics::render(double time)
if (renderWorld) {
// render the level
level->render(lightingShader, true, &lightingViewProjectionMatrix, &depthBiasVPs);
level->enqueueObjects(this);
for (unsigned int i = 0; i<Material::getAllTextures()->size(); i++) {
bool parametersSet = false;
for(unsigned int j = 0; j<renderQueue.size(); j++) {
if(renderQueue.at(j)->at(i).size() != 0) {
if (!parametersSet) {
parametersSet = true;
Material* material = renderQueue.at(j)->at(i).at(0)->getMaterial();
if (material->isMoving()) {
lightingShader->setUniform("movingTexture", true);
}
else {
lightingShader->setUniform("movingTexture", false);
}
lightingShader->setUniform("uTexture", material->getTextureUnit());
lightingShader->setUniform("ambientFactor", material->getAmbientFactor());
lightingShader->setUniform("diffuseFactor", material->getDiffuseFactor());
lightingShader->setUniform("specularFactor", material->getSpecularFactor());
lightingShader->setUniform("shininess", material->getShininess());
}
for(unsigned int k = 0; k<renderQueue.at(j)->at(i).size(); k++) {
renderQueue.at(j)->at(i).at(k)->render(lightingShader, true, &lightingViewProjectionMatrix, &depthBiasVPs);
}
}
}
}
// render water plane last for correct transparency
if (level->getWaterPlane()) {
Material* material = level->getWaterPlane()->getMaterial();
if (material->isMoving()) {
lightingShader->setUniform("movingTexture", true);
}
else {
lightingShader->setUniform("movingTexture", false);
}
lightingShader->setUniform("uTexture", material->getTextureUnit());
lightingShader->setUniform("ambientFactor", material->getAmbientFactor());
lightingShader->setUniform("diffuseFactor", material->getDiffuseFactor());
lightingShader->setUniform("specularFactor", material->getSpecularFactor());
lightingShader->setUniform("shininess", material->getShininess());
level->getWaterPlane()->render(lightingShader, true, &lightingViewProjectionMatrix, &depthBiasVPs);
}
renderQueue.clear();
}
if (renderDebug) {
@ -495,7 +590,7 @@ void Graphics::render(double time)
}
debug_ab->setDataElements(data_count/6, debugData);
debugDrawer.clearData();
delete debugData;
delete[] debugData;
debugShader->use();
debugShader->setUniform("viewProjectionMatrix", lightingViewProjectionMatrix);
debug_vao->render();
@ -551,77 +646,92 @@ void Graphics::render(double time)
}
}
bool Graphics::compareLightDistances(Light a, Light b) {
if (glm::distance(this->level->getCameraCenter()->getPosition(), a.getPosition()) <
glm::distance(this->level->getCameraCenter()->getPosition(), b.getPosition())) {
return true;
}
else {
return false;
}
}
void Graphics::updateClosestLights() {
closestLights = std::vector<Light>(*level->getLights());
std::sort(closestLights.begin(),
closestLights.end(),
[this](Light a, Light b) {return compareLightDistances(a, b); });
if (level->getLights()->size() > 15) {
closestLights = std::vector<Light>(&closestLights[0],
&closestLights[15]);
}
}
void Graphics::updateLights() {
updateClosestLights();
if (closestLights.size() > 0) {
std::vector<std::shared_ptr<Light>> oldClosestLights = std::vector<std::shared_ptr<Light>>(*closestLights);
closestLights = level->getClosestLights(maxShadowSampleCount);
if (closestLights->size() > 0) {
lightingShader->use();
lightingShader->setUniform("lightCount", (int) closestLights.size());
lightingShader->setUniform("maxShadowRenderCount", std::min((int) closestLights.size(), (int)maxShadowRenderCount));
lightingShader->setUniform("lightCount", (int) closestLights->size());
lightingShader->setUniform("maxShadowRenderCount", min((int)closestLights->size(), maxShadowSampleCount));
// find new closest lights for the shadow render queue
unsigned int i = 0;
std::vector<std::shared_ptr<Light>> compareClosestLights = std::vector<std::shared_ptr<Light>>(*closestLights);
while(i<oldClosestLights.size()) {
bool found = false;
for(unsigned int j = 0; j<compareClosestLights.size(); j++) {
if (oldClosestLights.at(i) == compareClosestLights.at(j)){
found = true;
compareClosestLights.erase(compareClosestLights.begin() + j);
break;
}
}
if (found) {
oldClosestLights.erase(oldClosestLights.begin() + i);
}
else {
i++;
}
}
assert(oldClosestLights.size() == compareClosestLights.size());
// replace old lights with the new ones in the shadow render queue
for(unsigned int i = 0; i<oldClosestLights.size(); i++) {
for(unsigned int j = 0; j<shadowRenderQueue.size(); j++) {
if(oldClosestLights.at(i) == shadowRenderQueue.at(j).light) {
shadowRenderQueue.at(j).light = compareClosestLights.at(i);
// 15000 is larger priority than any light can get during one tick
shadowRenderQueue.at(j).currentPriority = 15000;
}
}
}
// update priority of the shadow render queue
for(unsigned int i = 0; i<shadowRenderQueue.size(); i++) {
float distance = glm::distance(level->getCameraCenter()->getPosition(), shadowRenderQueue.at(i).light->getPosition());
shadowRenderQueue.at(i).priority = (int) 100*std::exp(5.0f - 0.1f * distance);
}
// Build light position array
glm::vec3 lightSources[closestLights.size()];
for(unsigned int i = 0; i<closestLights.size(); i++) {
lightSources[i] = closestLights.at(i).getPosition();
glm::vec3 lightSources[shadowRenderQueue.size()];
for(unsigned int i = 0; i<shadowRenderQueue.size(); i++) {
lightSources[i] = shadowRenderQueue.at(i).light->getPosition();
}
glUniform3fv(lightingShader->getUniformLocation("lightSources"),
sizeof(lightSources), (GLfloat*) lightSources);
// Build light colour array
glm::vec3 lightColours[closestLights.size()];
for(unsigned int i = 0; i<closestLights.size(); i++) {
lightColours[i] = closestLights.at(i).getColour();
glm::vec3 lightColours[shadowRenderQueue.size()];
for(unsigned int i = 0; i<shadowRenderQueue.size(); i++) {
lightColours[i] = shadowRenderQueue.at(i).light->getColour();
}
glUniform3fv(lightingShader->getUniformLocation("lightColors"),
sizeof(lightColours), (GLfloat*) lightColours);
// Build light attenuation array
float lightIntensities[closestLights.size()];
for(unsigned int i = 0; i<closestLights.size(); i++) {
lightIntensities[i] = closestLights.at(i).getIntensity();
float lightIntensities[shadowRenderQueue.size()];
for(unsigned int i = 0; i<shadowRenderQueue.size(); i++) {
lightIntensities[i] = shadowRenderQueue.at(i).light->getIntensity();
}
glUniform1fv(lightingShader->getUniformLocation("lightIntensities"),
sizeof(lightIntensities), (GLfloat*) lightIntensities);
}
// set directional Light
if(level->getDirectionalLight()) {
lightingShader->setUniform("directionalLightVector",
level->getDirectionalLight()->getPosition());
lightingShader->setUniform("directionalColor",
level->getDirectionalLight()->getColour());
lightingShader->setUniform("directionalIntensity",
level->getDirectionalLight()->getIntensity());
}
bool isFlame[closestLights.size()];
closestFlames = std::vector<Flame*>();
for (unsigned int i = 0; i<closestLights.size(); i++) {
if (closestLights.at(i).isFlame()) {
closestFlames.push_back(closestLights.at(i).getFlame());
isFlame[i] = true;
}
else {
isFlame[i] = false;
bool isFlame[shadowRenderQueue.size()];
closestFlames = std::vector<Flame*>();
for(unsigned int i = 0; i<shadowRenderQueue.size(); i++) {
if (shadowRenderQueue.at(i).light->isFlame()) {
closestFlames.push_back(shadowRenderQueue.at(i).light->getFlame());
isFlame[i] = true;
}
else {
isFlame[i] = false;
}
}
glUniform1iv(lightingShader->getUniformLocation("isFlame"), sizeof(isFlame), (GLint*) isFlame);
}
glUniform1iv(lightingShader->getUniformLocation("isFlame"), sizeof(isFlame), (GLint*) isFlame);
}
void Graphics::saveWindowSize(glm::uvec2 windowSize) {
this->windowSize = windowSize;
}
void Graphics::resize(glm::uvec2 windowSize) {
@ -636,6 +746,41 @@ void Graphics::resize(glm::uvec2 windowSize) {
flamePostShader->setUniform("windowSizeY", int(windowSize.y));
bindTextureUnits();
}
else {
float quadData[24];
if (loadingScreenWidth/loadingScreenHeight < ((float)windowSize.x)/((float)windowSize.y)) {
float quadTemp[24] ={
-(((float)windowSize.y*loadingScreenWidth)/((float)windowSize.x*loadingScreenHeight)), 1.0f, 0.0f, 1.0f,
(((float)windowSize.y*loadingScreenWidth)/((float)windowSize.x*loadingScreenHeight)), 1.0f, 1.0f, 1.0f,
(((float)windowSize.y*loadingScreenWidth)/((float)windowSize.x*loadingScreenHeight)), -1.0f, 1.0f, 0.0f,
(((float)windowSize.y*loadingScreenWidth)/((float)windowSize.x*loadingScreenHeight)), -1.0f, 1.0f, 0.0f,
-(((float)windowSize.y*loadingScreenWidth)/((float)windowSize.x*loadingScreenHeight)), -1.0f, 0.0f, 0.0f,
-(((float)windowSize.y*loadingScreenWidth)/((float)windowSize.x*loadingScreenHeight)), 1.0f, 0.0f, 1.0f
};
for(int i = 0; i<24; i++) {
quadData[i] = quadTemp[i];
}
}
else {
float quadTemp[24] = {
-1.0f, ((float)windowSize.x*loadingScreenHeight)/((float)windowSize.y*loadingScreenWidth), 0.0f, 1.0f,
1.0f, ((float)windowSize.x*loadingScreenHeight)/((float)windowSize.y*loadingScreenWidth), 1.0f, 1.0f,
1.0f, -((float)windowSize.x*loadingScreenHeight)/((float)windowSize.y*loadingScreenWidth), 1.0f, 0.0f,
1.0f, -((float)windowSize.x*loadingScreenHeight)/((float)windowSize.y*loadingScreenWidth), 1.0f, 0.0f,
-1.0f, -((float)windowSize.x*loadingScreenHeight)/((float)windowSize.y*loadingScreenWidth), 0.0f, 0.0f,
-1.0f, ((float)windowSize.x*loadingScreenHeight)/((float)windowSize.y*loadingScreenWidth), 0.0f, 1.0f
};
for(int i = 0; i<24; i++) {
quadData[i] = quadTemp[i];
}
}
fullscreen_quad_ab_loading->setDataElements(6, quadData);
fullscreen_quad_loading = SharedVertexArrayObject(new VertexArrayObject);
fullscreen_quad_loading->attachAllAttributes(fullscreen_quad_ab_loading);
}
}
glm::mat4 Graphics::buildViewMatrix(Level* level) {
@ -721,3 +866,42 @@ void Graphics::setRenderWorld(bool state) {
bool Graphics::getRenderWorld() {
return renderWorld;
}
void Graphics::enqueueObjects(std::vector<std::vector<Object*>>* queue){
renderQueue.push_back(queue);
}
void Graphics::initShadowRenderQueue() {
closestLights = level->getClosestLights(maxShadowSampleCount);
int maxLights = min((int)closestLights->size(), maxShadowSampleCount);
shadowRenderQueue = std::vector<ShadowRenderQueueSlot>(maxLights);
glViewport(0, 0, cube_size, cube_size);
glm::mat4 depthProjectionMatrix_pointlights = glm::perspective(1.571f, (float)cube_size/(float)cube_size, 0.1f, 50.0f);
glm::vec3 looking_directions[6] = {glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f),
glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, 0.0f, -1.0f)};
glm::vec3 upvectors[6] = {glm::vec3(0.0f, -1.0f, 0.0f),glm::vec3(0.0f, -1.0f, 0.0f),glm::vec3(0.0f, 0.0f, -1.0f),
glm::vec3(0.0f, 0.0f, -1.0f),glm::vec3(0.0f, -1.0f, 0.0f),glm::vec3(0.0f, -1.0f, 0.0f)};
framebuffer_cube->bind();
for(unsigned int i = 0; i<shadowRenderQueue.size(); i++){
shadowRenderQueue.at(i).light = closestLights->at(i);
shadowRenderQueue.at(i).currentPriority = 0;
// render depth textures for point lights
depthCubeShader->use();
// render each side of the cube
for (int i_face = 0; i_face<6; i_face++) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i_face, depth_cubeMaps.at(i)->getObjectName(), 0);
glClear(GL_DEPTH_BUFFER_BIT);
glm::mat4 viewMatrix = glm::lookAt(shadowRenderQueue.at(i).light->getPosition(),
shadowRenderQueue.at(i).light->getPosition() + looking_directions[i_face], upvectors[i_face]);
glm::mat4 depthViewProjectionMatrix_face = depthProjectionMatrix_pointlights * viewMatrix;
std::vector<glm::mat4> viewMatrixVector = std::vector<glm::mat4>();
viewMatrixVector.push_back(viewMatrix);
level->render(depthCubeShader, false, shadowRenderQueue.at(i).light->getPosition(), 1, &depthViewProjectionMatrix_face, &viewMatrixVector);
if (!framebuffer_cube->isFrameBufferObjectComplete()) {
printf("Framebuffer incomplete, unknown error occured during shadow generation!\n");
}
}
}
}

View File

@ -11,6 +11,12 @@
using namespace ACGL::OpenGL;
struct ShadowRenderQueueSlot{
shared_ptr<Light> light;
int priority;
int currentPriority;
};
class Graphics {
public:
Graphics(glm::uvec2 windowSize, float nearPlane, float farPlane, int cube_size,
@ -33,11 +39,11 @@ class Graphics {
bool getRenderFlames();
bool getRenderDebug();
bool getRenderWorld();
void enqueueObjects(std::vector<std::vector<Object*>>* queue);
void saveWindowSize(glm::uvec2 windowSize);
private:
void bindTextureUnits();
void updateLights();
void updateClosestLights();
bool compareLightDistances(Light a, Light b);
void saveDepthBufferToDisk(int face, std::string);
double lastLightUpdate;
double lastWindUpdate;
@ -53,7 +59,7 @@ class Graphics {
std::string loadingScreenContinuePath;
SharedTexture2D loadingScreen;
SharedTexture2D loadingContinueScreen;
std::vector<Light> closestLights;
std::vector<shared_ptr<Light>>* closestLights;
std::vector<Flame*> closestFlames;
SharedShaderProgram loadingShader;
SharedShaderProgram lightingShader;
@ -88,7 +94,9 @@ class Graphics {
SharedArrayBuffer debug_ab;
SharedVertexArrayObject debug_vao;
SharedShaderProgram debugShader;
std::vector<std::vector<std::vector<Object*>>*> renderQueue;
std::vector<ShadowRenderQueueSlot> shadowRenderQueue;
void initShadowRenderQueue();
};
#endif

View File

@ -2,11 +2,12 @@
#include "loader.hh"
#include <string>
Level::Level(std::string xmlFilePath){
Level::Level(std::string xmlFilePath, float farPlane) {
// default value
skydomeSize = 50.0f;
physics = Physics();
this->xmlFilePath = xmlFilePath;
this->farPlane = farPlane;
}
Level::Level() {
@ -16,9 +17,6 @@ Level::~Level() {
if (luaState!=nullptr) {
lua_close(luaState);
}
for(unsigned int i = 0; i<objects.size(); i++) {
delete(objects.at(i));
}
delete(waterPlane);
}
@ -35,7 +33,6 @@ void Level::load() {
//Expose the class Level and its functions to Lua
luabridge::getGlobalNamespace(luaState)
.beginClass<Level>("Level")
.addFunction("deleteObject", &Level::deleteObject)
.addFunction("getObjectCount", &Level::getPhysicsObjectsVectorSize)
.addFunction("moveObject", &Level::moveObject)
.addFunction("resetPlayer", &Level::resetPlayer)
@ -54,18 +51,98 @@ void Level::load() {
this->camera = Camera(glm::vec2(-0.8f, 0.0f), 3.0f);
}
void Level::render(ACGL::OpenGL::SharedShaderProgram shader, bool lightingPass,
glm::mat4* viewProjectionMatrix, std::vector<glm::mat4>* shadowVPs) {
for(unsigned int i = 0; i<objects.size(); i++) {
if (lightingPass) {
objects.at(i)->render(shader, lightingPass, true, viewProjectionMatrix, shadowVPs);
int Level::checkMaxSurroundingLights() {
int maxSurroundingLights = 0;
for(unsigned int i = 0; i<lights.size(); i++) {
int thisSurroundingLights = 0;
for(unsigned int j = 0; j<lights.size(); j++) {
if (glm::distance(lights.at(i)->getPosition(), lights.at(j)->getPosition()) < skydomeSize) {
thisSurroundingLights++;
}
}
else {
objects.at(i)->render(shader, lightingPass, false, viewProjectionMatrix, shadowVPs);
if (thisSurroundingLights > maxSurroundingLights) {
maxSurroundingLights = thisSurroundingLights;
}
}
if (lightingPass && waterPlane) {
waterPlane->render(shader, lightingPass, true, viewProjectionMatrix, shadowVPs);
return maxSurroundingLights;
}
void Level::render(ACGL::OpenGL::SharedShaderProgram shader, bool lightingPass,
glm::vec3 center, int chunkRenderDistance, glm::mat4* viewProjectionMatrix,
std::vector<glm::mat4>* shadowVPs) {
std::vector<Chunk*> nearChunks = getSurroundingChunks(center, chunkRenderDistance);
for(unsigned int i = 0; i<nearChunks.size(); i++) {
nearChunks.at(i)->render(shader, lightingPass, viewProjectionMatrix, shadowVPs);
}
for (unsigned int i = 0; i<crossChunkObjects.size(); i++) {
crossChunkObjects.at(i)->render(shader, lightingPass, viewProjectionMatrix, shadowVPs);
}
}
void Level::enqueueObjects(Graphics* graphics) {
std::vector<Chunk*> nearChunks = getSurroundingChunks(cameraCenter->getPosition(), -1);
for(unsigned int i = 0; i<nearChunks.size(); i++) {
graphics->enqueueObjects(nearChunks.at(i)->getSortedObjects());
}
graphics->enqueueObjects(&sortedCrossChunkObjects);
}
std::vector<Chunk*> Level::getSurroundingChunks(glm::vec3 center, int chunkRenderDistance) {
int renderDistance = 0;
if (chunkRenderDistance < 0) {
if ((int)farPlane % chunkSize == 0) {
renderDistance = (((int)skydomeSize)+chunkSize/2)/chunkSize;
}
else {
renderDistance = ((((int)skydomeSize)+chunkSize/2)/chunkSize) + 1;
}
}
else {
renderDistance = chunkRenderDistance;
}
int xPosition = ((int)center.x + (terrain.getHeightmapWidth()/2))/chunkSize;
int zPosition = ((int)center.z + (terrain.getHeightmapHeight()/2))/chunkSize;
int xStart = xPosition - renderDistance;
unsigned int xEnd = xPosition + renderDistance;
int zStart = zPosition - renderDistance;
unsigned int zEnd = zPosition + renderDistance;
if (xStart < 0) {
xStart = 0;
}
if (zStart < 0) {
zStart = 0;
}
if (xEnd >= chunks.size()) {
xEnd = chunks.size()-1;
}
if (zEnd >= chunks.at(0).size()) {
zEnd = chunks.at(0).size()-1;
}
std::vector<Chunk*> vector = std::vector<Chunk*>((xEnd - xStart + 1)*(zEnd - zStart + 1));
int counter = 0;
for(unsigned int i = xStart; i<=xEnd; i++) {
for(unsigned int j = zStart; j<=zEnd; j++) {
vector.at(counter) = &chunks.at(i).at(j);
counter++;
}
}
return vector;
}
void Level::sortObjects(int textureCount) {
for(unsigned int i = 0; i<chunks.size(); i++) {
for(unsigned int j = 0; j<chunks.at(i).size(); j++) {
chunks.at(i).at(j).sortObjects(textureCount);
}
}
// init
sortedCrossChunkObjects = std::vector<std::vector<Object*>>(textureCount);
for(unsigned int i = 0; i<sortedCrossChunkObjects.size(); i++) {
sortedCrossChunkObjects.at(i) = std::vector<Object*>();
}
for(unsigned int i = 0; i<crossChunkObjects.size(); i++) {
sortedCrossChunkObjects.at(crossChunkObjects.at(i)->getMaterial()->getTextureUnit() - 2)
.push_back(crossChunkObjects.at(i));
}
}
@ -80,7 +157,7 @@ void Level::update(float runTimeSinceLastUpdate, float runTime, glm::vec2 mouseD
mouseDelta.x=mouseDelta.y=0;
}
int runs = 4;
const int runs = 4;
if(i>=20)
{
@ -152,7 +229,7 @@ glm::vec3 Level::getAmbientLight() {
return ambientLight;
}
std::vector<Light>* Level::getLights() {
std::vector<shared_ptr<Light>>* Level::getLights() {
return &lights;
}
@ -192,8 +269,8 @@ float Level::getSkydomeSize() {
return this->skydomeSize;
}
std::vector<Object*>* Level::getObjects() {
return &objects;
std::vector<Object*>* Level::getAllObjects() {
return &allObjects;
}
std::vector<Object*>* Level::getPhysicsObjects() {
@ -206,17 +283,6 @@ void Level::moveObject(int objectIndex, float strength, float xPos, float yPos,
physics.addPositionConstraint(objectIndex, strength, position);
}
//should not be used since objects does not get synchronized and deletion is not implemented in pyhsics
void Level::deleteObject(int objectIndex){
physicsObjects.erase(physicsObjects.begin() + objectIndex);
for(unsigned int i = 0; i<triggers.size(); i++) {
if(triggers.at(i).deleteNotification(objectIndex)){
triggers.erase(triggers.begin() + i);
i--;
}
}
}
void Level::resetPlayer(){
Loader loader = Loader();
glm::vec3 newPosition = loader.reloadPlayerPosition(xmlFilePath, this);
@ -240,8 +306,20 @@ void Level::setSkydomeObject(Skydome object){
this->skydome = object;
}
void Level::addObject(Object* object) {
objects.push_back(object);
void Level::addObject(Object* object, bool crossesChunks) {
allObjects.push_back(object);
if (crossesChunks) {
crossChunkObjects.push_back(object);
}
else {
int xPosition = ((int)object->getPosition().x + (terrain.getHeightmapWidth()/2))/chunkSize;
int zPosition = ((int)object->getPosition().z + (terrain.getHeightmapHeight()/2))/chunkSize;
chunks.at(xPosition).at(zPosition).addObject(object);
}
}
void Level::addToSpecificChunk(Object* object, int xPosition, int zPosition) {
chunks.at(xPosition).at(zPosition).addObject(object);
}
void Level::addPhysicsObject(Object* object) {
@ -279,10 +357,6 @@ Physics* Level::getPhysics() {
return &physics;
}
unsigned int Level::getObjectsVectorSize() {
return objects.size();
}
unsigned int Level::getPhysicsObjectsVectorSize() {
return physicsObjects.size();
}
@ -292,7 +366,8 @@ void Level::setCameraCenter(Object* object) {
}
void Level::addLight(Light light) {
this->lights.push_back(light);
shared_ptr<Light> add_light = shared_ptr<Light>(new Light(light));
this->lights.push_back(add_light);
}
void Level::preloadLightPosition(float xPos, float yPos, float zPos){
@ -301,7 +376,7 @@ void Level::preloadLightPosition(float xPos, float yPos, float zPos){
void Level::addLightByParameters(float redColour, float greenColour, float blueColour, float intensity, float flameYOffset, float flameHeight, float flameWidth){
glm::vec3 colour = glm::vec3(redColour, greenColour, blueColour);
this->lights.push_back(Light(nextLightPosition, colour, intensity, flameYOffset, flameHeight, flameWidth));
this->addLight(Light(nextLightPosition, colour, intensity, flameYOffset, flameHeight, flameWidth));
}
void Level::deleteFourLights(){
@ -349,3 +424,61 @@ void Level::printPosition() {
printf("Player position: %2.2f, %2.2f, %2.2f\n", cameraCenter->getPosition().x,
cameraCenter->getPosition().y, cameraCenter->getPosition().z);
}
void Level::generateChunks(int chunkSize) {
this->chunkSize = chunkSize;
int numberChunksX = 0;
if (terrain.getHeightmapWidth() % chunkSize == 0) {
numberChunksX = terrain.getHeightmapWidth()/chunkSize;
}
else {
numberChunksX = (terrain.getHeightmapWidth()/chunkSize) + 1;
}
int numberChunksZ = 0;
if (terrain.getHeightmapHeight() % chunkSize == 0) {
numberChunksZ = terrain.getHeightmapHeight()/chunkSize;
}
else {
numberChunksZ = (terrain.getHeightmapHeight()/chunkSize) + 1;
}
chunks = std::vector<std::vector<Chunk>> (numberChunksX);
for(int i = 0; i<numberChunksX; i++) {
std::vector<Chunk> zChunks = std::vector<Chunk>(numberChunksZ);
for(int j = 0; j<numberChunksZ; j++) {
zChunks.at(j) = Chunk();
}
chunks.at(i) = zChunks;
}
}
std::vector<std::vector<Chunk>>* Level::getChunks() {
return &chunks;
}
Object* Level::getWaterPlane() {
return waterPlane;
}
bool Level::compareLightDistances(shared_ptr<Light> a, shared_ptr<Light> b) {
if (glm::distance(cameraCenter->getPosition(), a->getPosition()) <
glm::distance(cameraCenter->getPosition(), b->getPosition())) {
return true;
}
else {
return false;
}
}
std::vector<shared_ptr<Light>>* Level::getClosestLights(unsigned int maximumAmount) {
closestLights = std::vector<shared_ptr<Light>>(lights);
std::sort(closestLights.begin(),
closestLights.end(),
[this](shared_ptr<Light> a, shared_ptr<Light> b) {return compareLightDistances(a, b); });
if (lights.size() > maximumAmount) {
closestLights = std::vector<shared_ptr<Light>>(&closestLights[0],
&closestLights[maximumAmount]);
}
// sort pointers for faster comparisons
std::sort(closestLights.begin(), closestLights.end());
return &closestLights;
}

View File

@ -12,6 +12,7 @@
#include "trigger.hh"
#include "skydome.hh"
#include "keyboardState.hh"
#include "chunk.hh"
extern "C" {
#include "lua.h"
@ -20,19 +21,23 @@ extern "C" {
}
#include "LuaBridge.h"
// forward declaration
class Graphics;
class Level {
public:
Level(std::string xmlFilePath);
Level(std::string xmlFilePath, float farPlane);
Level();
~Level();
void load();
void update(float runTimeSinceLastUpdate, float runTime, glm::vec2 mouseDelta,
KeyboardState* keyboardState);
void render(ACGL::OpenGL::SharedShaderProgram shader, bool lightingPass,
glm::mat4* viewProjectionMatrix, std::vector<glm::mat4>* shadowVPs=0);
glm::vec3 center, int chunkRenderDistance, glm::mat4* viewProjectionMatrix,
std::vector<glm::mat4>* shadowVPs=0);
glm::vec3 getAmbientLight();
Light* getDirectionalLight();
std::vector<Light>* getLights();
std::vector<shared_ptr<Light>>* getLights();
Object* getCameraCenter();
Camera* getCamera();
glm::vec3 getCameraPosition();
@ -42,14 +47,14 @@ class Level {
void setSkydomeSize(float size);
float getSkydomeSize();
void setWaterPlane(Object* water);
Object* getWaterPlane();
Skydome* getSkydome();
std::vector<Object*>* getObjects();
std::vector<Object*>* getAllObjects();
std::vector<Object*>* getPhysicsObjects();
void deleteObject(int objectIndex);
void moveObject(int objectIndex, float strength, float xPos, float yPos, float zPos);
void setStrength(float strength);
void setSkydomeObject(Skydome object);
void addObject(Object* object);
void addObject(Object* object, bool crossesChunks);
void addPhysicsObject(Object* object);
void setAmbientLight(glm::vec3 colour);
void setFogColourDay(glm::vec4 colour);
@ -57,13 +62,14 @@ class Level {
void setFogColourNight(glm::vec4 colour);
void setDirectionalLight(Light light);
void setSunDirection(float x, float y, float z);
Physics* getPhysics();
unsigned int getObjectsVectorSize();
unsigned int getPhysicsObjectsVectorSize();
Physics* getPhysics();
void setCameraCenter(Object* object);
void addLight(Light light);
void preloadLightPosition(float xPos, float yPos, float zPos);
void addLightByParameters(float redColour, float greenColour, float blueColour, float intensity, float flameYOffset, float flameHeight, float flameWidth);
void addLightByParameters(float redColour, float greenColour,
float blueColour, float intensity, float flameYOffset,
float flameHeight, float flameWidth);
void deleteFourLights();
void addTrigger(Trigger trigger);
lua_State* getLuaState();
@ -75,19 +81,31 @@ class Level {
void activateEndgame();
void setTerrain(Terrain terrain);
void printPosition();
void generateChunks(int chunkSize);
std::vector<std::vector<Chunk>>* getChunks();
void addToSpecificChunk(Object* object, int xPosition, int zPosition);
void enqueueObjects(Graphics* graphics);
void sortObjects(int textureCount);
std::vector<shared_ptr<Light>>* getClosestLights(unsigned int maximumAmount);
int checkMaxSurroundingLights();
private:
std::vector<Chunk*> getSurroundingChunks(glm::vec3 center, int chunkRenderDistance);
lua_State* luaState=nullptr;
std::vector<Object*> objects;
std::vector<Object*> crossChunkObjects;
std::vector<std::vector<Object*>> sortedCrossChunkObjects;
std::vector<Object*> allObjects;
std::vector<Object*> physicsObjects;
std::vector<Light> lights;
std::vector<std::vector<Chunk>> chunks;
std::vector<shared_ptr<Light>> lights;
std::vector<shared_ptr<Light>> closestLights;
std::vector<Trigger> triggers;
Object* waterPlane;
Object* waterPlane=nullptr;
glm::vec3 ambientLight;
glm::vec4 fogColourDay;
glm::vec4 fogColourRise;
glm::vec4 fogColourNight;
Light directionalLight;
Object* cameraCenter;
Object* cameraCenter=nullptr;
int playerIndex;
Skydome skydome;
Physics physics;
@ -97,6 +115,9 @@ class Level {
float strength;
std::string xmlFilePath;
glm::vec3 nextLightPosition;
int chunkSize;
float farPlane;
bool compareLightDistances(shared_ptr<Light> a, shared_ptr<Light> b);
};
#endif

View File

@ -1,7 +1,10 @@
#include "loader.hh"
#include "main.hh"
#include <ACGL/OpenGL/Objects/VertexArrayObject.hh>
using namespace tinyxml2;
const int chunkSize = 25;
Loader::Loader() {
}
@ -55,7 +58,7 @@ void Loader::loadConfig(Application* application) {
}
void Loader::load(std::string filePath, Level* level, std::string compositionsPath, std::string scriptPath,
std::string globalGeometryPath, std::string globalTexturePath, std::string heightmapPath) {
std::string globalGeometryPath, std::string globalTexturePath, std::string heightmapPath, Graphics* graphics) {
struct stat buf;
//Loading from xml:
XMLDocument* doc = new XMLDocument();
@ -80,9 +83,10 @@ void Loader::load(std::string filePath, Level* level, std::string compositionsPa
}
Terrain terrain = Terrain(levelHeightmapPath);
level->setTerrain(terrain);
// Because object gets copied a lot load it when it has reached it's final destination
// Because object gets copied a lot, load it when it has reached it's final destination
level->getTerrain()->load();
Model terrainModel = Model(level->getTerrain()->getModel());
// generate appropriate amount of chunks depending on the heightmap size.
level->generateChunks(chunkSize);
std::string terrainTexture = queryString(terrainElement, "texture");
float terrainAmbientFactor = queryFloat(terrainElement, "ambientFactor");
float terrainDiffuseFactor = queryFloat(terrainElement, "diffuseFactor");
@ -94,10 +98,15 @@ void Loader::load(std::string filePath, Level* level, std::string compositionsPa
exit(-1);
}
Material terrainMaterial = Material(terrainTexture, terrainAmbientFactor, terrainDiffuseFactor, terrainSpecularFactor, terrainShininess);
Object* terrainObject = new Object(terrainModel, terrainMaterial,
glm::vec3(-0.5*((float)level->getTerrain()->getHeightmapHeight()-1), 0.0f, -0.5f*((float)level->getTerrain()->getHeightmapWidth()-1)),
glm::vec3(0.0f, 0.0f, 0.0f), true);
level->addObject(terrainObject);
for (unsigned int i = 0; i<level->getChunks()->size(); i++) {
for (unsigned int j = 0; j<level->getChunks()->at(i).size(); j++) {
Model terrainModel = Model(level->getTerrain()->makeTriangleMesh(i*chunkSize, j*chunkSize, (i+1)*chunkSize+1, (j+1)*chunkSize+1));
Object* terrainObject = new Object(terrainModel, terrainMaterial,
glm::vec3(-0.5*((float)level->getTerrain()->getHeightmapHeight()-1), 0.0f, -0.5f*((float)level->getTerrain()->getHeightmapWidth()-1)),
glm::vec3(0.0f, 0.0f, 0.0f), true);
level->addToSpecificChunk(terrainObject, i, j);
}
}
level->getPhysics()->addTerrain(level->getTerrain()->getHeightmapWidth(), level->getTerrain()->getHeightmapHeight(), level->getTerrain()->getHeightmap());
//load the skydome
@ -115,15 +124,13 @@ void Loader::load(std::string filePath, Level* level, std::string compositionsPa
std::cout << "The texture file " << skydomeTexturePath << " does not exist." << std::endl;
exit(-1);
}
Material skydomeMaterial = Material(skydomeTexture, 1.0f, 0.0f, 0.0f, 0.0f);
std::string nightTexture = queryString(skydomeElement, "nightTexture");
std::string nightTexturePath = "../" + globalTexturePath + nightTexture;
if(stat(nightTexturePath.c_str(), &buf) != 0){
std::cout << "The texture file " << nightTexturePath << " does not exist." << std::endl;
exit(-1);
}
Material nightMaterial = Material(nightTexture, 1.0f, 0.0f, 0.0f, 0.0f);
Skydome skydomeObject = Skydome(skydomeModel, skydomeMaterial, nightMaterial);
Skydome skydomeObject = Skydome(skydomeModel, skydomeTexture, nightTexture);
level->setSkydomeObject(skydomeObject);
//load the waterPlane
@ -220,6 +227,13 @@ void Loader::load(std::string filePath, Level* level, std::string compositionsPa
int compositionType = queryInt(composition, "typeID");
//corect composition found
if(thisType == compositionType){
// update loading screen
glfwPollEvents();
graphics->render(0.0f);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glfwSwapBuffers(window);
typeExists = true;
//iterate over all objects of the composition
XMLElement* xmlObject = composition->FirstChildElement("object");
@ -286,7 +300,8 @@ void Loader::load(std::string filePath, Level* level, std::string compositionsPa
objectRot[2] = queryFloat(xmlObject, "zRot");
objectRot *= 0.0174532925; //transform degrees to radians
Object* object = new Object(model, material, objectPosition, compRot+objectRot, renderable);
level->addObject(object);
bool crossesChunks = queryBool(composition, "crossesChunks");
level->addObject(object, crossesChunks);
//add object to physics
std::string physicType = queryString(objectData, "physicType");
@ -301,7 +316,9 @@ void Loader::load(std::string filePath, Level* level, std::string compositionsPa
if (physicType.compare("Player") == 0){
float radius = queryFloat(objectData, "radius");
radius *= objectScale*compScale;
level->addPhysicsObject(object);
if (mass != 0.0f) {
level->addPhysicsObject(object);
}
level->getPhysics()->addPlayer(friction, radius, *object, mass, dampningL, dampningA, level->getPhysicsObjectsVectorSize());
}else if (physicType.compare("Box") == 0){
float width = queryFloat(objectData, "width");
@ -310,7 +327,9 @@ void Loader::load(std::string filePath, Level* level, std::string compositionsPa
width *= objectScale*compScale;
height *= objectScale*compScale;
length *= objectScale*compScale;
level->addPhysicsObject(object);
if (mass != 0.0f) {
level->addPhysicsObject(object);
}
level->getPhysics()->addBox(width, height, length, *object, mass, dampningL, dampningA, level->getPhysicsObjectsVectorSize(), rotate);
}else if (physicType.compare("Button") == 0){
float width = queryFloat(objectData, "width");
@ -319,10 +338,14 @@ void Loader::load(std::string filePath, Level* level, std::string compositionsPa
width *= objectScale*compScale;
height *= objectScale*compScale;
length *= objectScale*compScale;
level->addPhysicsObject(object);
if (mass != 0.0f) {
level->addPhysicsObject(object);
}
level->getPhysics()->addButton(width, height, length, *object, mass, dampningL, dampningA, level->getPhysicsObjectsVectorSize(), rotate);
}else if (physicType.compare("TriangleMesh") == 0){
level->addPhysicsObject(object);
if (mass != 0.0f) {
level->addPhysicsObject(object);
}
level->getPhysics()->addTriangleMeshBody(*object, modelPath, mass, dampningL, dampningA, level->getPhysicsObjectsVectorSize(), objectScale*compScale, rotate);
}else if (physicType.compare("None") == 0){
@ -333,7 +356,7 @@ void Loader::load(std::string filePath, Level* level, std::string compositionsPa
//create an identifier for this object
std::vector<int> objectIdentifier = std::vector<int>(5);
objectIdentifier[0] = level->getObjectsVectorSize()-1;
objectIdentifier[0] = level->getAllObjects()->size()-1;
if (physicType.compare("None") == 0){
objectIdentifier[1] = 0;
}else{

View File

@ -12,7 +12,7 @@ class Loader {
void loadConfig(Application* application);
void load(std::string filePath, Level* level, std::string compositionsPath,
std::string scriptPath, std::string geometryPath, std::string texturePath,
std::string heightmapPath);
std::string heightmapPath, Graphics* graphics);
glm::vec3 reloadPlayerPosition(std::string filePath, Level* level);
private:
float queryFloat(XMLElement* element, const char* attribute);

View File

@ -4,6 +4,9 @@
#include <sstream>
#include "keyboardState.hh"
Application app;
GLFWwindow* window;
static void resizeCallback(GLFWwindow* window, int newWidth, int newHeight)
{
// store the new window size and adjust the viewport:
@ -122,7 +125,7 @@ bool createWindow()
glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits);
glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits);
glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate);
app.getGraphics()->resize(glm::uvec2(mode->width, mode->height));
app.getGraphics()->saveWindowSize(glm::uvec2(mode->width, mode->height));
window = glfwCreateWindow(mode->width, mode->height, "Saxum", glfwGetPrimaryMonitor(), NULL);
if (!window) {
@ -168,6 +171,7 @@ int main( int argc, char *argv[] )
glfwSwapInterval( 0 );
app.init();
app.getGraphics()->resize(app.getGraphics()->getWindowSize());
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
glfwSwapBuffers(window);
app.initLevel();
@ -190,16 +194,14 @@ int main( int argc, char *argv[] )
double now = glfwGetTime()- startTimeInSeconds;
#ifdef SAXUM_DEBUG
if (showNextFPS <= now) {
std::stringstream sstream (std::stringstream::in | std::stringstream::out);
sstream << std::setprecision(1) << std::fixed
<< "Saxum" << " - FPS: " << frameCount / (now-showNextFPS + FPSdelay) << " " << 1000 * (now-showNextFPS + FPSdelay)/frameCount << " msec";
glfwSetWindowTitle(window, sstream.str().c_str() );
showNextFPS = now + FPSdelay;
frameCount = 0;
}
#endif
if (showNextFPS <= now) {
std::stringstream sstream (std::stringstream::in | std::stringstream::out);
sstream << std::setprecision(1) << std::fixed
<< "Saxum" << " - FPS: " << frameCount / (now-showNextFPS + FPSdelay) << " " << 1000 * (now-showNextFPS + FPSdelay)/frameCount << " msec";
glfwSetWindowTitle(window, sstream.str().c_str() );
showNextFPS = now + FPSdelay;
frameCount = 0;
}
if (app.isGameStarted()) {
static float gameStart = now;
if (app.isLocked() && app.getIgnoredMouseUpdates() == 0) {

View File

@ -1,8 +1,6 @@
#ifndef MAIN_HH_INCLUDED
#define MAIN_HH_INCLUDED
#pragma once
#include "application.hh"
Application app;
GLFWwindow* window;
#endif
extern Application app;
extern GLFWwindow* window;

View File

@ -1,5 +1,8 @@
#include "material.hh"
std::set<SharedTexture2D> Material::allTexturesSet = std::set<SharedTexture2D>();
std::vector<SharedTexture2D> Material::allTexturesVector = std::vector<SharedTexture2D>();
Material::Material(std::string filePath, float ambientFactor, float diffuseFactor,
float specularFactor, float shininess, bool movingTexture) {
reference = ACGL::OpenGL::Texture2DFileManager::the()->get(ACGL::OpenGL::Texture2DCreator(filePath));
@ -11,6 +14,15 @@ Material::Material(std::string filePath, float ambientFactor, float diffuseFacto
this->specularFactor = specularFactor;
this->shininess = shininess;
this->movingTexture = movingTexture;
unsigned int textureCount = allTexturesSet.size();
allTexturesSet.insert(reference);
if (allTexturesSet.size() != textureCount) {
allTexturesVector.push_back(reference);
}
textureUnit = std::distance(Material::getAllTextures()->begin(),
std::find(std::begin(*Material::getAllTextures()),
// first two texture units are used by the loading screen
std::end(*Material::getAllTextures()), reference)) + 2;
}
Material::Material() {
@ -42,3 +54,11 @@ float Material::getShininess() {
bool Material::isMoving(){
return movingTexture;
}
std::vector<SharedTexture2D>* Material::getAllTextures() {
return &allTexturesVector;
}
int Material::getTextureUnit() {
return textureUnit;
}

View File

@ -2,30 +2,39 @@
#define MATERIAL_HH_INCLUDED
#include <string>
#include <set>
#include <ACGL/OpenGL/Creator/Texture2DCreator.hh>
#include <ACGL/OpenGL/Data/TextureLoadStore.hh>
#include <ACGL/OpenGL/Managers.hh>
using namespace ACGL::OpenGL;
class Material{
public:
Material(std::string filePath, float ambientFactor,
float diffuseFactor, float specularFactor, float shininess, bool movingTexture = false);
Material();
ACGL::OpenGL::SharedTexture2D getReference();
SharedTexture2D getReference();
~Material();
float getAmbientFactor();
float getDiffuseFactor();
float getSpecularFactor();
float getShininess();
bool isMoving();
static std::vector<SharedTexture2D>* getAllTextures();
static std::vector<Material*>* getAllMaterials();
int getTextureUnit();
private:
int textureUnit;
ACGL::OpenGL::SharedTexture2D reference;
float ambientFactor;
float diffuseFactor;
float specularFactor;
float shininess;
bool movingTexture;
static std::set<SharedTexture2D> allTexturesSet;
static std::vector<SharedTexture2D> allTexturesVector;
};
#endif

View File

@ -14,28 +14,14 @@ Object::~Object() {
}
void Object::render(ACGL::OpenGL::SharedShaderProgram shader, bool lightingPass,
bool texturePass, glm::mat4* viewProjectionMatrix,
glm::mat4* viewProjectionMatrix,
std::vector<glm::mat4>* additionalMatrices) {
if (!renderable) {
return;
}
glm::mat4 modelMatrix = glm::translate(getPosition()) * getRotation() * glm::scale<float>(glm::vec3(model.getScale()));
if(texturePass) {
if (material.isMoving()) {
shader->setUniform("movingTexture", true);
}
else {
shader->setUniform("movingTexture", false);
}
shader->setTexture("uTexture", material.getReference(), 0);
shader->setUniform("modelMatrix", modelMatrix);
}
shader->setUniform("modelMatrix", modelMatrix);
if (lightingPass) {
// set lightning parameters for this object
shader->setUniform("ambientFactor", material.getAmbientFactor());
shader->setUniform("diffuseFactor", material.getDiffuseFactor());
shader->setUniform("specularFactor", material.getSpecularFactor());
shader->setUniform("shininess", material.getShininess());
// set model matrix
shader->setUniform("modelMatrix", modelMatrix);
// set shadowMVPs
@ -56,3 +42,7 @@ void Object::render(ACGL::OpenGL::SharedShaderProgram shader, bool lightingPass,
// draw
model.getReference()->render();
}
Material* Object::getMaterial() {
return &material;
}

View File

@ -16,8 +16,9 @@ class Object : public Entity {
Object();
~Object();
void render(ACGL::OpenGL::SharedShaderProgram shader, bool lightingPass,
bool texturePass, glm::mat4* viewProjcetionMatrix,
glm::mat4* viewProjcetionMatrix,
std::vector<glm::mat4>* additionalMatrices=0);
Material* getMaterial();
private:
Model model;
Material material;

View File

@ -133,8 +133,10 @@ void Physics::addPositionConstraint(int bodyIndice, float strength, glm::vec3 po
//players and objects
void Physics::addPlayer(float friction, float rad, Entity entity, float mass, float dampningL, float dampningA, unsigned indice)
{
if(bodies.size() == indice)
throw std::invalid_argument( "Bodies out of Sync" ); //these error are to ensure that level can always communicate with physics without having to worry about synching errors
if (mass != 0.0f) {
if(bodies.size() == indice)
throw std::invalid_argument( "Bodies out of Sync: Before adding Player" ); //these error are to ensure that level can always communicate with physics without having to worry about synching errors
}
btSphereShape* sphere = new btSphereShape(rad); //the first thing we need for a rigid body is the shape
btVector3 inertia(0,0,0);
@ -160,13 +162,17 @@ void Physics::addPlayer(float friction, float rad, Entity entity, float mass, fl
world->addRigidBody(playerBall,COL_OBJECTS,COL_OBJECTS|COL_OBJECTS_NO_TERRAIN|COL_TERRAIN); //then we add the rigid body to the wiorld, allowing it to be simulated
bodies.push_back(playerBall); //next we add the rigid body to our own list (for cleanup and for synchronitaation with level)
if (mass != 0.0f) {
bodies.push_back(playerBall); //next we add the rigid body to our own list (for cleanup and for synchronitaation with level)
}
//note, while we can always access playerBall through its global name, we add it to this array for synchronization purposes
playerBall->setSleepingThresholds(0,0); //in a final step we make sure that the body never is removed from the active rigid bodies
if(bodies.size() != indice)
throw std::invalid_argument( "Bodies out of Sync" ); //one last check to make sure level and physics are in synch
if (mass != 0.0f) {
if(bodies.size() != indice)
throw std::invalid_argument( "Bodies out of Sync: After adding Player" ); //one last check to make sure level and physics are in synch
}
addCamera(); //now that the player exists add a camera for the player
}
@ -202,9 +208,10 @@ void Physics::addTerrain(int width, int length, float** heightData) //The terrai
void Physics::addConvexBody(Entity entity, std::string path, float mass, float dampningL, float dampningA, unsigned indice, float scaling, bool rotate)
{
if(bodies.size() == indice)
throw std::invalid_argument( "Bodies out of Sync" );
if (mass != 0.0f) {
if(bodies.size() == indice)
throw std::invalid_argument( "Bodies out of Sync: Before adding Convex Body" );
}
SharedGeometryData geometry = loadGeometryData("../" + geometryPath + path);
@ -252,7 +259,9 @@ void Physics::addConvexBody(Entity entity, std::string path, float mass, float d
body->setDamping(dampningL,dampningA);
bodies.push_back(body);
if (mass != 0.0f) {
bodies.push_back(body);
}
world->addRigidBody(body,COL_OBJECTS, objectsPhysicsCollision);
@ -261,14 +270,18 @@ void Physics::addConvexBody(Entity entity, std::string path, float mass, float d
body->setAngularFactor(btVector3(0,0,0));
}
if(bodies.size() != indice)
throw std::invalid_argument( "Bodies out of Sync" );
if (mass != 0.0f) {
if(bodies.size() != indice)
throw std::invalid_argument( "Bodies out of Sync: After adding Convex Body" );
}
}
void Physics::addTriangleMeshBody(Entity entity, std::string path, float mass, float dampningL, float dampningA,unsigned indice,float scaling, bool rotate)
{
if(bodies.size() == indice)
throw std::invalid_argument( "Bodies out of Sync" );
if (mass != 0.0f) {
if(bodies.size() == indice)
throw std::invalid_argument( "Bodies out of Sync: Before adding Triangle Mesh Body" );
}
SharedGeometryData geometry = loadGeometryData("../" + geometryPath + path);
@ -317,7 +330,9 @@ void Physics::addTriangleMeshBody(Entity entity, std::string path, float mass, f
body->setDamping(dampningL,dampningA);
bodies.push_back(body);
if (mass != 0.0f) {
bodies.push_back(body);
}
world->addRigidBody(body,COL_OBJECTS, objectsPhysicsCollision);
@ -326,15 +341,18 @@ void Physics::addTriangleMeshBody(Entity entity, std::string path, float mass, f
body->setAngularFactor(btVector3(0,0,0));
}
if(bodies.size() != indice)
throw std::invalid_argument( "Bodies out of Sync" );
if (mass != 0.0f) {
if(bodies.size() != indice)
throw std::invalid_argument( "Bodies out of Sync: After adding Triangle Mesh Body" );
}
}
void Physics::addButton(float width, float height, float length, Entity entity, float mass, float dampningL, float dampningA, unsigned indice,bool rotate)
{
if(bodies.size() == indice)
throw std::invalid_argument( "Bodies out of Sync" );
if (mass != 0.0f) {
if(bodies.size() == indice)
throw std::invalid_argument( "Bodies out of Sync: Before adding Button" );
}
btBoxShape* box = new btBoxShape(btVector3(width/2,height/2,length/2));
@ -358,22 +376,28 @@ void Physics::addButton(float width, float height, float length, Entity entity,
world->addRigidBody(body,COL_OBJECTS_NO_TERRAIN, specialPhysicsCollision); //the specialPhysicsCollision allows these objects to not collide with the terrain
bodies.push_back(body);
if (mass != 0.0f) {
bodies.push_back(body);
}
if(!rotate)
{
body->setAngularFactor(btVector3(0,0,0));
}
if(bodies.size() != indice)
throw std::invalid_argument( "Bodies out of Sync" );
if (mass != 0.0f) {
if(bodies.size() != indice)
throw std::invalid_argument( "Bodies out of Sync: After adding Button" );
}
}
void Physics::addBox(float width, float height, float length, Entity entity, float mass, float dampningL, float dampningA, unsigned indice,bool rotate)
{
//similar to other constructors
if(bodies.size() == indice)
throw std::invalid_argument( "Bodies out of Sync" );
if (mass != 0.0f) {
if(bodies.size() == indice)
throw std::invalid_argument( "Bodies out of Sync: Before adding Box" );
}
glm::quat glmQuat = glm::quat_cast(entity.getRotation());
btBoxShape* box = new btBoxShape(btVector3(width/2,height/2,length/2));
@ -394,21 +418,27 @@ void Physics::addBox(float width, float height, float length, Entity entity, flo
world->addRigidBody(body,COL_OBJECTS, objectsPhysicsCollision);
bodies.push_back(body);
if (mass != 0.0f) {
bodies.push_back(body);
}
if(!rotate)
{
body->setAngularFactor(btVector3(0,0,0));
}
if(bodies.size() != indice)
throw std::invalid_argument( "Bodies out of Sync" );
if (mass != 0.0f) {
if(bodies.size() != indice)
throw std::invalid_argument( "Bodies out of Sync: After adding Box" );
}
}
void Physics::addSphere(float rad, Entity entity, float mass, float dampningL, float dampningA, unsigned indice,bool rotate)
{
if(bodies.size() == indice) //(user's initial) height, not the actual height. More...
throw std::invalid_argument( "Bodies out of Sync" );
if (mass != 0.0f) {
if(bodies.size() == indice) //(user's initial) height, not the actual height. More...
throw std::invalid_argument( "Bodies out of Sync: Before adding Sphere" );
}
btSphereShape* sphere = new btSphereShape(rad);
btVector3 inertia(0,0,0);
@ -429,7 +459,9 @@ void Physics::addSphere(float rad, Entity entity, float mass, float dampningL, f
world->addRigidBody(body,COL_OBJECTS, objectsPhysicsCollision);
bodies.push_back(body);
if (mass != 0.0f) {
bodies.push_back(body);
}
if(!rotate)//rotate lets certain objects get inertia (0,0,0) (not rotateable)
{
@ -438,14 +470,15 @@ void Physics::addSphere(float rad, Entity entity, float mass, float dampningL, f
body->setSleepingThresholds(0,0);
if(bodies.size() != indice)
throw std::invalid_argument( "Bodies out of Sync" );
if (mass != 0.0f) {
if(bodies.size() != indice)
throw std::invalid_argument( "Bodies out of Sync: After adding Sphere" );
}
}
void Physics::prepareCollisionDetection()
{
playerTerrainCol = playerObjectColision = false;
int numManifods = world->getDispatcher()->getNumManifolds();
}
bool Physics::playerWithGround()

View File

@ -1,13 +1,19 @@
#include "skydome.hh"
#include <ACGL/OpenGL/Creator/Texture2DCreator.hh>
Skydome::Skydome(Model model, Material material, Material nightTexture) :
Object(model, material, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), true){
this->nightTexture = nightTexture;
Skydome::Skydome(Model model, string dayTexturePath, string nightTexturePath) :
Object(model, Material(), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), true) {
this->dayTexture = Texture2DFileManager::the()->get(Texture2DCreator(dayTexturePath));
this->nightTexture = Texture2DFileManager::the()->get(Texture2DCreator(nightTexturePath));
}
Skydome::Skydome() {
}
Material* Skydome::getNightTexture() {
return &nightTexture;
SharedTexture2D Skydome::getDayTexture() {
return dayTexture;
}
SharedTexture2D Skydome::getNightTexture() {
return nightTexture;
}

View File

@ -1,11 +1,18 @@
#pragma once
#include "object.hh"
#include <ACGL/OpenGL/Objects.hh>
class Skydome : public Object {
using namespace ACGL::OpenGL;
using namespace std;
class Skydome : public Object{
public:
Skydome(Model model, Material material, Material nightTexture);
Skydome(Model model, string dayTexturePath, string nightTexturePath);
Skydome();
Material* getNightTexture();
SharedTexture2D getNightTexture();
SharedTexture2D getDayTexture();
private:
Material nightTexture;
SharedTexture2D nightTexture;
SharedTexture2D dayTexture;
};

View File

@ -14,35 +14,50 @@ Terrain::~Terrain() {
void Terrain::load() {
std::vector<unsigned char> image; //the raw pixels
unsigned error = lodepng::decode(image, heightmapWidth, heightmapHeight, heightmapFilePath);
unsigned int heightmapHeightLoading = 0;
unsigned int heightmapWidthLoading = 0;
unsigned error = lodepng::decode(image, heightmapWidthLoading, heightmapHeightLoading, heightmapFilePath);
if (error) {
std::cout << "Decoder error " << error << " from Terrain::load: " << lodepng_error_text(error) << std::endl;
}
this->heightmapHeight = heightmapHeightLoading;
this->heightmapWidth = heightmapWidthLoading;
this->heightmap = new float*[this->heightmapWidth]; //initialize the heightmap
for(unsigned int columnNum = 0; columnNum < this->heightmapWidth; columnNum++){ //read in the heightmap
for(int columnNum = 0; columnNum < this->heightmapWidth; columnNum++){ //read in the heightmap
this->heightmap[columnNum] = new float[this->heightmapHeight];
for(unsigned int rowNum = 0; rowNum < this->heightmapHeight; rowNum++){
for(int rowNum = 0; rowNum < this->heightmapHeight; rowNum++){
this->heightmap[columnNum][rowNum] = (float)(image[(rowNum*heightmapWidth+columnNum)*4]) / 6; //<--heightmap is scaled here
}
}
this->makeTriangleMesh();
heightmapChanged = false; //no need to make a TriangleMesh again before rendering
}
void Terrain::makeTriangleMesh(){
SharedVertexArrayObject Terrain::makeTriangleMesh(int startX, int startZ, int endX, int endZ) {
if (startX < 0) {
startX = 0;
}
if (startZ < 0) {
startZ = 0;
}
if (endX > heightmapWidth) {
endX = heightmapWidth;
}
if (endZ > heightmapHeight) {
endZ = heightmapHeight;
}
ACGL::OpenGL::SharedArrayBuffer ab = std::make_shared<ACGL::OpenGL::ArrayBuffer>();
SharedArrayBuffer ab = SharedArrayBuffer(new ArrayBuffer());
SharedVertexArrayObject vao = SharedVertexArrayObject(new VertexArrayObject());
// Do NOT change the order of this!
ab->defineAttribute("aPosition", GL_FLOAT, 3);
ab->defineAttribute("aTexCoord", GL_FLOAT, 2);
ab->defineAttribute("aNormal", GL_FLOAT, 3);
unsigned int rowNum=0, columnNum=0, dataCount=0, floatsPerVertex=8; //initializing:
int rowNum = startX, columnNum = startZ, dataCount=0, floatsPerVertex=8; //initializing:
bool movingRight = true, isUp = true;
int numVertices = (this->heightmapHeight - 1) * (this->heightmapWidth * 2 + 1) + 1;
int numVertices = ((endX - startX) - 1) * ((endZ - startZ) * 2 + 1) + 1;
float* abData = new float[numVertices * floatsPerVertex];
while(rowNum < this->heightmapHeight){ //traversing the Triangle Strip!
while(rowNum < endX){ //traversing the Triangle Strip!
set_abData(abData, dataCount, rowNum, columnNum);
dataCount += floatsPerVertex;
if (isUp){
@ -50,7 +65,7 @@ void Terrain::makeTriangleMesh(){
isUp = false;
}
else if (movingRight) {
if (columnNum == this->heightmapWidth - 1) {
if (columnNum == endZ - 1) {
set_abData(abData, dataCount, rowNum, columnNum);
dataCount += floatsPerVertex;
set_abData(abData, dataCount, rowNum, columnNum);
@ -65,7 +80,7 @@ void Terrain::makeTriangleMesh(){
}
}
else {
if (columnNum == 0){
if (columnNum == startZ){
set_abData(abData, dataCount, rowNum, columnNum);
dataCount += floatsPerVertex;
set_abData(abData, dataCount, rowNum, columnNum);
@ -82,16 +97,16 @@ void Terrain::makeTriangleMesh(){
}
ab->setDataElements(numVertices, abData);
delete abData;
this->triangleMesh = std::make_shared<ACGL::OpenGL::VertexArrayObject>();
this->triangleMesh->bind();
this->triangleMesh->setMode(GL_TRIANGLE_STRIP);
this->triangleMesh->attachAllAttributes(ab);
delete[] abData;
vao->bind();
vao->setMode(GL_TRIANGLE_STRIP);
vao->attachAllAttributes(ab);
return vao;
}
void Terrain::set_abData(float* abData, unsigned int dataCount, unsigned int rowNum, unsigned int columnNum){
void Terrain::set_abData(float* abData, int dataCount, int rowNum, int columnNum){
//set Position
abData[dataCount] = (float)rowNum;
abData[dataCount+1] = heightmap[rowNum][columnNum];
@ -135,18 +150,14 @@ void Terrain::set_abData(float* abData, unsigned int dataCount, unsigned int row
}
}
Model Terrain::getModel(){
return Model(this->triangleMesh);
}
float** Terrain::getHeightmap(){
return this->heightmap;
}
unsigned int Terrain::getHeightmapHeight(){
int Terrain::getHeightmapHeight(){
return this->heightmapHeight;
}
unsigned int Terrain::getHeightmapWidth(){
int Terrain::getHeightmapWidth(){
return this->heightmapWidth;
}

View File

@ -5,6 +5,9 @@
#include "material.hh"
#include <ACGL/OpenGL/Objects/VertexArrayObject.hh>
#include "model.hh"
using namespace ACGL::OpenGL;
class Terrain {
public:
Terrain(std::string heightmapFilePath);
@ -12,20 +15,16 @@ class Terrain {
~Terrain();
void load();
void render();
Model getModel();
float** getHeightmap();
unsigned int getHeightmapHeight();
unsigned int getHeightmapWidth();
int getHeightmapHeight();
int getHeightmapWidth();
SharedVertexArrayObject makeTriangleMesh(int startX, int startZ, int endX, int endZ);
private:
Material material;
std::string heightmapFilePath;
unsigned int heightmapHeight, heightmapWidth;
int heightmapHeight, heightmapWidth;
float** heightmap; //can be accessed like 'float[][]'
bool heightmapChanged;
ACGL::OpenGL::SharedVertexArrayObject triangleMesh;
void makeTriangleMesh();
void set_abData(float* abData, unsigned int dataCount, unsigned int rowNum, unsigned int columnNum);
void set_abData(float* abData, int dataCount, int rowNum, int columnNum);
};
#endif

View File

@ -33,3 +33,5 @@ then
zip -9r "Saxum_${platform^}.zip" "Saxum_${platform^}"
rm -rf "Saxum_${platform^}"
fi
exit $rc