List of commits:
Subject Hash Author Date (UTC)
Refactor FG3 to allow separate compilation eb1bb8bbc8c60169c2bbd789b38c608b4bb9cbab mse 2022-08-03 22:30:45
Fix menu bugs and bump to v0.7.11 ae193263f4b8461c299f6db66f130beae94724cc mse 2022-07-07 04:52:30
Bump version to 0.7.10 5f70f1aba48d3df67d5e4a70d9595e92aeac4afb mse 2022-05-11 10:54:09
ADV-style text advance 5fbb734d07a2dcf0162245b5afc6b5b4b9021b6f mse 2022-04-12 12:25:24
Switch interaction to mouse-up 345ce8d1ea9755f51365a2676cce0415f9cf68c2 mse 2022-04-10 21:07:15
Use gradient for text backdrop 6ad98cdaf4df37e8b24d9c1e8e2f9b0e904da9aa mse 2022-04-10 13:04:29
Improve vn button highlight 51b2c6c07b0cfb0efdb8cdf5cbeba49ef54d9ccb mse 2022-04-09 06:54:39
Darken the screen when drawing a menu with non-VN text 8f3bcee6d57817ea8c1dd999c68cb129dea1550c mse 2022-04-08 16:01:52
Upgrade the UI 45561487af001c5a790343690a792faeb14945d4 mse 2022-04-06 23:45:31
Progress on getting Emscripten builds working again (almost) e4276b7823027c7ac3a3afe30c3c30241f1c6642 mse 2022-04-01 11:16:56
Bump to version 0.7.9 1c93b011603bd953df0628fa39c586c11eeb7138 mse 2022-03-30 08:31:00
Some progress on Android support dd2d0eb6d4ee42149b605526ce304e67243d90b4 mse 2022-03-20 00:28:35
Android support (work in progress) a8f26dd2d83d66fb8e3b634991084fbdc9faa640 mse 2022-03-19 20:08:09
Add IFGOSUB db52bc04bac0af4d668696580b1312920a47d9e5 mse 2022-03-19 17:11:36
Remove Poco from the makefile e6274074304b40f0eaae0e591acadc604388fbaa mse 2022-03-19 17:00:54
Disable texture wrapping in VN 75ed1c845f4643fa4e012f22f5a2bbeacca9d51e mse 2022-03-18 21:39:00
Menu improvements 2ee4efdb3fedb69cbf56711841fc961bd1b4877c mse 2022-03-17 19:32:45
Menu navigation fixes 362878a56a72a43f671d4c6022e53ce124a0cf99 mse 2022-03-17 18:47:50
Rewrite VN engine 4c88d574d4f72794ab17fb5ecdc57fbd2a93cb7e mse 2022-03-16 07:19:06
Add commandKey() function 066858b9a80610248bed69ac7095129a9f142a78 mse 2022-03-14 00:05:46
Commit eb1bb8bbc8c60169c2bbd789b38c608b4bb9cbab - Refactor FG3 to allow separate compilation
Author: mse
Author date (UTC): 2022-08-03 22:30
Committer name: mse
Committer date (UTC): 2022-08-03 22:30
Parent(s): ae193263f4b8461c299f6db66f130beae94724cc
Signer:
Signing key:
Signing status: N
Tree: 5958f39f37c67f73aafc7ec3cb280605bec056a2
File Lines added Lines deleted
confec.cpp 9 5
include/fg3/fg3.h 499 279
include/fworld.h 5 5
File confec.cpp changed (mode: 100644) (index 87c44a7..09280a1)
... ... FILE *FileOpen( const char* filename, const char* modes );
50 50 #include <fg2/linalg.h> #include <fg2/linalg.h>
51 51 #define fgl fg2 #define fgl fg2
52 52 #else #else
53 #define FG3_IMPLEMENTATION
53 54 #include <SDL2/SDL.h> #include <SDL2/SDL.h>
54 55 #include <fg3/fg3.h> #include <fg3/fg3.h>
55 56 #include <fg3/linalg.h> #include <fg3/linalg.h>
 
... ... void DrawFloorParticles(){
4871 4872 linalg::vec<double,3>( gib.x, -gib.y, gib.z ) linalg::vec<double,3>( gib.x, -gib.y, gib.z )
4872 4873 ), ),
4873 4874 linalg::scaling_matrix( linalg::vec<double,3>( 0.05, 0.05, 0.04 ) ) linalg::scaling_matrix( linalg::vec<double,3>( 0.05, 0.05, 0.04 ) )
4874 )
4875 ),
4876 linalg::identity
4875 4877 ); );
4876 4878 } }
4877 4879 auto viewMat = world.viewMat; auto viewMat = world.viewMat;
 
... ... void DrawFloorParticles(){
4890 4892 auto old_pipeline = fgl::drawPipeline; auto old_pipeline = fgl::drawPipeline;
4891 4893 fgl::setPipeline( sunlitInstancePipeline ); fgl::setPipeline( sunlitInstancePipeline );
4892 4894 fgl::setTexture( fgl::blankTexture, 0 ); fgl::setTexture( fgl::blankTexture, 0 );
4893 ib.draw( fgl::cubeMesh, viewMat, projMat );
4895 ib.draw( fgl::cubeMesh, viewMat, projMat, fgl::getLightMatrix() );
4894 4896 ib.clear(); ib.clear();
4895 4897 // Set fog to its old color. // Set fog to its old color.
4896 4898 fgl::setFog( old_fog ); fgl::setFog( old_fog );
 
... ... void DrawParticles(){
4906 4908 linalg::mul( linalg::mul(
4907 4909 linalg::translation_matrix( linalg::vec<double,3>( gib.x, -gib.y, gib.z ) ), linalg::translation_matrix( linalg::vec<double,3>( gib.x, -gib.y, gib.z ) ),
4908 4910 linalg::scaling_matrix( linalg::vec<double,3>( 0.05, 0.05, 0.05 ) ) linalg::scaling_matrix( linalg::vec<double,3>( 0.05, 0.05, 0.05 ) )
4909 )
4911 ),
4912 linalg::identity
4910 4913 ); );
4911 4914 } }
4912 4915 // Create an instance for each raindrop. // Create an instance for each raindrop.
 
... ... void DrawParticles(){
4919 4922 linalg::vec<double,3>( drop.x, -drop.y, drop.z ) linalg::vec<double,3>( drop.x, -drop.y, drop.z )
4920 4923 ), ),
4921 4924 linalg::scaling_matrix( linalg::vec<double,3>( 0.05, 0.05, 0.15 ) ) linalg::scaling_matrix( linalg::vec<double,3>( 0.05, 0.05, 0.15 ) )
4922 )
4925 ),
4926 linalg::identity
4923 4927 ); );
4924 4928 } }
4925 4929 auto viewMat = world.viewMat; auto viewMat = world.viewMat;
 
... ... void DrawParticles(){
4938 4942 auto old_pipeline = fgl::drawPipeline; auto old_pipeline = fgl::drawPipeline;
4939 4943 fgl::setPipeline( sunlitInstancePipeline ); fgl::setPipeline( sunlitInstancePipeline );
4940 4944 fgl::setTexture( fgl::blankTexture, 0 ); fgl::setTexture( fgl::blankTexture, 0 );
4941 ib.draw( fgl::cubeMesh, viewMat, projMat );
4945 ib.draw( fgl::cubeMesh, viewMat, projMat, fgl::getLightMatrix() );
4942 4946 ib.clear(); ib.clear();
4943 4947 // Set fog to its old color. // Set fog to its old color.
4944 4948 fgl::setFog( old_fog ); fgl::setFog( old_fog );
File include/fg3/fg3.h changed (mode: 100644) (index 7d9c6dc..a515b1c)
8 8 #if defined(__APPLE__) #if defined(__APPLE__)
9 9 # include <TargetConditionals.h> # include <TargetConditionals.h>
10 10 # if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE==1 # if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE==1
11 # define GLAD_GLES2_IMPLEMENTATION
11 # ifdef FG3_IMPLEMENTATION
12 # define GLAD_GLES2_IMPLEMENTATION
13 # endif
12 14 # include "glad_gles2.h" # include "glad_gles2.h"
13 15 # else # else
14 # define GLAD_GL_IMPLEMENTATION
16 # ifdef FG3_IMPLEMENTATION
17 # define GLAD_GL_IMPLEMENTATION
18 # endif
15 19 # include "glad_gl.h" # include "glad_gl.h"
16 20 # endif # endif
17 21 #elif defined(__ANDROID__) #elif defined(__ANDROID__)
18 # define GLAD_GLES2_IMPLEMENTATION
22 # ifdef FG3_IMPLEMENTATION
23 # define GLAD_GLES2_IMPLEMENTATION
24 # endif
19 25 # include "glad_gles2.h" # include "glad_gles2.h"
20 26 #else #else
21 # define GLAD_GL_IMPLEMENTATION
27 # ifdef FG3_IMPLEMENTATION
28 # define GLAD_GL_IMPLEMENTATION
29 # endif
22 30 # include "glad_gl.h" # include "glad_gl.h"
23 31 #endif #endif
24 32
 
34 42 #include <string> #include <string>
35 43 #include <vector> #include <vector>
36 44
37 namespace fg3
38 {
39
40 bool verbose = true;
41
42 45 #ifndef _VERBOUT_ #ifndef _VERBOUT_
43 46 #define _VERBOUT_ if( verbose ) std::cout #define _VERBOUT_ if( verbose ) std::cout
44 47 #endif #endif
 
... ... bool verbose = true;
47 50 #define _ERROUT_ std::cerr #define _ERROUT_ std::cerr
48 51 #endif #endif
49 52
50 #ifdef GLAD_GL
51 const GLchar* shaderHeader = R"(
52 #version 330
53 )";
54 #else // GLES
55 const GLchar* shaderHeader = R"(
56 #version 300 es
57 precision highp float;
58 )";
59 #endif
60
61 // vec2/3 can become vec4 automatically
62 // https://stackoverflow.com/questions/18935203/shader-position-vec4-or-vec3
63
64 const GLchar* unlitVert = R"(
65 uniform mat4 u_matrices[6]; // 0:mvp 1:mv 2:m 3:normal 4:texture 5:light
66 layout(location = 0) in vec4 a_Position;
67 layout(location = 1) in vec4 a_Normal;
68 layout(location = 2) in vec4 a_Tangent;
69 layout(location = 3) in vec4 a_UV;
70 out vec2 v_UV;
71 out vec4 v_RelativePos;
72 void main(){
73 v_UV = vec2( u_matrices[4] * a_UV );
74 v_RelativePos = u_matrices[1] * a_Position;
75 gl_Position = u_matrices[0] * a_Position;
76 }
77 )";
78
79 const GLchar* unlitFrag = R"(
80 uniform sampler2D u_texture;
81 uniform vec4 u_fog;
82 uniform vec3 u_camera;
83 in vec2 v_UV;
84 in vec4 v_RelativePos;
85 layout(location = 0) out vec4 fragColor;
86 void main(){
87 vec4 texColor = texture( u_texture, v_UV );
88 if( texColor.a < 0.001 ) discard;
89 if( u_fog.a > 0.0 ){
90 float fogFactor = 1.0 - clamp( 1.0 / exp( length( v_RelativePos ) * u_fog.a ), 0.0, 1.0 );
91 fragColor = vec4( mix( texColor.rgb, u_fog.rgb, fogFactor ), texColor.a );
92 }else{
93 fragColor = texColor;
94 }
95 }
96 )";
97
98 std::vector<std::string> unlitSamplers = { "u_texture" };
99
100 const GLchar* colorModFrag = R"(
101 uniform sampler2D u_texture;
102 uniform vec4 u_fog;
103 uniform vec3 u_camera;
104 in vec2 v_UV;
105 in vec4 v_RelativePos;
106 layout(location = 0) out vec4 fragColor;
107 void main(){
108 vec4 texColor = texture( u_texture, v_UV );
109 if( texColor.a < 0.001 ) discard;
110 fragColor = texColor * u_fog;
111 }
112 )";
113
114 std::vector<std::string> colorModSamplers = { "u_texture" };
115
116 // Instanced arrays are used for instancing.
117 // https://learnopengl.com/Advanced-OpenGL/Instancing
118
119 const GLchar* unlitInstanceVert = R"(
120 uniform mat4 u_matrices[3]; // 0:view 1:projection 2:light
121 layout(location = 0) in vec4 a_Position;
122 layout(location = 1) in vec4 a_Normal;
123 layout(location = 2) in vec4 a_Tangent;
124 layout(location = 3) in vec4 a_UV;
125 layout(location = 4) in vec4 a_Color;
126 layout(location = 5) in mat4 a_ModelMat;
127 layout(location = 9) in mat4 a_TexMat;
128 out vec2 v_UV;
129 out vec4 v_Color;
130 out vec4 v_RelativePos;
131 void main(){
132 v_UV = vec2( a_TexMat * a_UV );
133 v_Color = a_Color;
134 mat4 mv = u_matrices[0] * a_ModelMat;
135 v_RelativePos = mv * a_Position;
136 gl_Position = u_matrices[1] * mv * a_Position;
137 }
138 )";
139
140 const GLchar* unlitInstanceFrag = R"(
141 uniform sampler2D u_texture;
142 uniform vec4 u_fog;
143 in vec2 v_UV;
144 in vec4 v_Color;
145 in vec4 v_RelativePos;
146 layout(location = 0) out vec4 fragColor;
147 void main(){
148 vec4 texColor = texture( u_texture, v_UV ) * v_Color;
149 if( texColor.a < 0.001 ) discard;
150 if( u_fog.a > 0.0 ){
151 float fogFactor = 1.0 - clamp( 1.0 / exp( length( v_RelativePos ) * u_fog.a ), 0.0, 1.0 );
152 fragColor = vec4( mix( texColor.rgb, u_fog.rgb, fogFactor ), texColor.a );
153 }else{
154 fragColor = texColor;
155 }
156 }
157 )";
158
159 std::vector<std::string> unlitInstanceSamplers = { "u_texture" };
160
161 const GLchar* skyboxVert = R"(
162 uniform mat4 u_matrices[6]; // 0:mvp 1:mv 2:m 3:normal 4:texture 5:light
163 layout(location = 0) in vec4 a_Position;
164 layout(location = 1) in vec4 a_Normal;
165 layout(location = 2) in vec4 a_Tangent;
166 layout(location = 3) in vec4 a_UV;
167 out vec3 v_STR;
168 void main(){
169 v_STR = a_Position.xyz;
170 vec4 pos = u_matrices[0] * a_Position;
171 gl_Position = pos.xyww;
172 }
173 )";
174
175 const GLchar* skyboxFrag = R"(
176 uniform samplerCube u_cubemap;
177 uniform vec4 u_fog;
178 uniform vec3 u_camera;
179 in vec3 v_STR;
180 layout(location = 0) out vec4 fragColor;
181 void main(){
182 fragColor = texture( u_cubemap, v_STR );
183 }
184 )";
185
186 std::vector<std::string> skyboxSamplers = { "u_cubemap" };
187
188 const GLchar* irradianceFrag = R"(
189 uniform samplerCube u_cubemap;
190 uniform vec4 u_fog;
191 uniform vec3 u_camera;
192 in vec3 v_STR;
193 layout(location = 0) out vec4 fragColor;
194 const float PI = 3.1415927;
195 mat4 rotationMatrix( vec3 axis, float angle ){
196 axis = normalize( axis );
197 float s = sin( angle );
198 float c = cos( angle );
199 float oc = 1.0 - c;
200 return mat4( mat3(
201 oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
202 oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
203 oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c
204 ) );
205 }
206 vec3 getIrradiance( vec3 normal ){
207 float grain = 0.05;
208 vec3 irradiance = vec3( 0.0 );
209 vec3 up = vec3( 0.0, 1.0, 0.0 );
210 vec3 right = normalize( cross( normal, up ) );
211 float index = 0.0;
212 for( float longi = 0.0; longi <= PI * 0.5; longi += grain ){
213 mat4 trl = rotationMatrix( right, longi );
214 for( float azi = 0.0; azi <= PI * 2.0; azi += grain ){
215 mat4 tra = rotationMatrix( normal, azi );
216 vec3 sampleVec = ( tra * trl * vec4( normal, 1.0 ) ).xyz;
217 irradiance += texture( u_cubemap, sampleVec ).rgb * sin( longi ) * cos( longi );
218 index += 1.0;
219 }
220 }
221 float hemispherePDF = 1.0 / ( 2.0 * PI );
222 irradiance /= index * hemispherePDF;
223 return irradiance;
224 }
225 void main(){
226 vec3 N = normalize( v_STR );
227 fragColor = vec4( getIrradiance( N ) / PI, 1.0 );
228 }
229 )";
230
231 std::vector<std::string> irradianceSamplers = { "u_cubemap" };
53 namespace fg3
54 {
232 55
233 56 struct Display { struct Display {
234 57 bool success; bool success;
 
... ... struct Display {
237 60 std::string title; std::string title;
238 61 }; };
239 62
240 Display newDisplay = { false, 0, 0, "" };
63 static const Display newDisplay = { false, 0, 0, "" };
241 64
242 65 struct Color { struct Color {
243 66 GLfloat r; GLfloat r;
 
... ... struct Color {
246 69 GLfloat a; GLfloat a;
247 70 }; };
248 71
249 Color newColor = { 1.0f, 1.0f, 1.0f, 1.0f };
250
251 Color fogColor = { 0.0f, 0.0f, 0.0f, 0.0f };
72 static const Color newColor = { 1.0f, 1.0f, 1.0f, 1.0f };
252 73
253 74 struct Texture { struct Texture {
254 75 bool success; bool success;
 
... ... struct Texture {
260 81 GLenum type; GLenum type;
261 82 }; };
262 83
263 Texture newTexture = { false, 0, 0, 0, 0, false, 0 };
264
265 Texture blankTexture = { false, 0, 0, 0, 0, false, 0 };
84 static const Texture newTexture = { false, 0, 0, 0, 0, false, 0 };
266 85
267 86 struct Framebuffer { struct Framebuffer {
268 87 bool success; bool success;
 
... ... struct Framebuffer {
277 96 GLsizei multisample; GLsizei multisample;
278 97 }; };
279 98
280 Framebuffer newFramebuffer = { false, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
99 static const Framebuffer newFramebuffer = { false, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
281 100
282 101 struct Vertex { struct Vertex {
283 102 GLfloat Position[3]; GLfloat Position[3];
 
... ... struct Vertex {
286 105 GLfloat UV[2]; GLfloat UV[2];
287 106 }; };
288 107
289 Vertex newVertex = {
108 static const Vertex newVertex = {
290 109 { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f },
291 110 { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f },
292 111 { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f },
 
... ... struct Pipeline {
311 130 std::vector<GLuint> slots; std::vector<GLuint> slots;
312 131 }; };
313 132
314 Pipeline
315 newPipeline = { false, 0, 0, 0, 0, 0, 0, 0, 0, {} },
316 drawPipeline = { false, 0, 0, 0, 0, 0, 0, 0, 0, {} },
317 unlitPipeline = { false, 0, 0, 0, 0, 0, 0, 0, 0, {} },
318 colorModPipeline = { false, 0, 0, 0, 0, 0, 0, 0, 0, {} },
319 unlitInstancePipeline = { false, 0, 0, 0, 0, 0, 0, 0, 0, {} },
320 skyboxPipeline = { false, 0, 0, 0, 0, 0, 0, 0, 0, {} },
321 irradiancePipeline = { false, 0, 0, 0, 0, 0, 0, 0, 0, {} };
133 static const Pipeline newPipeline = { false, 0, 0, 0, 0, 0, 0, 0, 0, {} };
322 134
323 135 struct Mesh { struct Mesh {
324 136 bool success; bool success;
 
... ... struct Mesh {
333 145 GLfloat zmax; GLfloat zmax;
334 146 }; };
335 147
336 Mesh newMesh = { false, {}, {}, { 0, 0, 0 }, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
337
338 Mesh planeMesh = { false, {}, {}, { 0, 0, 0 }, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
339
340 Mesh cubeMesh = { false, {}, {}, { 0, 0, 0 }, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
148 static const Mesh newMesh = { false, {}, {}, { 0, 0, 0 }, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
149
150 // Define stb_truetype types without the header to make cross-TU cleanup work.
151 #ifndef __STB_INCLUDE_STB_TRUETYPE_H__
152 struct stbtt_pack_context {
153 void *user_allocator_context;
154 void *pack_info;
155 int width;
156 int height;
157 int stride_in_bytes;
158 int padding;
159 int skip_missing;
160 unsigned int h_oversample, v_oversample;
161 unsigned char *pixels;
162 void *nodes;
163 };
164 // private structure
165 typedef struct
166 {
167 unsigned char *data;
168 int cursor;
169 int size;
170 } stbtt__buf;
171 struct stbtt_fontinfo
172 {
173 void * userdata;
174 unsigned char * data; // pointer to .ttf file
175 int fontstart; // offset of start of font
176
177 int numGlyphs; // number of glyphs, needed for range checking
178
179 int loca,head,glyf,hhea,hmtx,kern,gpos,svg; // table locations as offset from start of .ttf
180 int index_map; // a cmap mapping for our chosen character encoding
181 int indexToLocFormat; // format needed to map from glyph index to glyph
182
183 stbtt__buf cff; // cff font data
184 stbtt__buf charstrings; // the charstring index
185 stbtt__buf gsubrs; // global charstring subroutines index
186 stbtt__buf subrs; // private charstring subroutines index
187 stbtt__buf fontdicts; // array of font dicts
188 stbtt__buf fdselect; // map from glyph to fontdict
189 };
190 typedef struct
191 {
192 unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
193 float xoff,yoff,xadvance;
194 float xoff2,yoff2;
195 } stbtt_packedchar;
196 #endif
341 197
342 198 struct Font { struct Font {
343 199 Texture texture; Texture texture;
 
... ... struct Font {
349 205 std::vector<unsigned char> buffer; std::vector<unsigned char> buffer;
350 206 std::vector<unsigned char> atlas; std::vector<unsigned char> atlas;
351 207 bool needSync; bool needSync;
352 #ifdef __STB_INCLUDE_STB_TRUETYPE_H__
353 208 stbtt_pack_context pc; stbtt_pack_context pc;
354 209 stbtt_fontinfo info; stbtt_fontinfo info;
355 210 std::vector<stbtt_packedchar> packedChars; std::vector<stbtt_packedchar> packedChars;
356 #else
357 void* pc;
358 void* info;
359 std::vector<void*> packedChars;
360 #endif
361 211 }; };
362 212
363 Font newFont = { newTexture, newMesh, 0.0f, 0.0f, {}, {}, {}, {}, false, {}, {}, {} };
213 static const Font newFont = { newTexture, newMesh, 0.0f, 0.0f, {}, {}, {}, {}, false, {}, {}, {} };
364 214
365 // Globals.
366 linalg::mat<double,4,4> texMatrix = linalg::identity, lightMatrix = linalg::identity;
215 // Functions.
216
217 std::u32string utf8ToUtf32( std::string in );
218 linalg::vec<double,4> eulerToQuat( double aX, double aY, double aZ );
219 linalg::vec<double,4> directionToQuat( linalg::vec<double,3> forward, linalg::vec<double,3> up );
220 double wrapAngle( double a );
221 Color rgb( float r, float g, float b );
222 void cls( Color col, bool clearDepth = true );
223 Mesh loadMesh( std::vector<Vertex> &vertices, std::vector<Index> &indices, bool streaming = false );
224 void updateMesh( Mesh &mesh, std::vector<Vertex> &vertices, std::vector<Index> &indices, bool streaming = false );
225 void uploadModelTransforms( const linalg::mat<double,4,4> &modelMat, const linalg::mat<double,4,4> &viewMat, const linalg::mat<double,4,4> &projMat );
226 void drawMesh( Mesh &mesh, linalg::mat<double,4,4> modelMat, linalg::mat<double,4,4> viewMat, linalg::mat<double,4,4> projMat );
227 void normalizeVertices( std::vector<Vertex> &verts );
228 Mesh loadOBJ( std::string filepath );
229 Mesh loadPLY( std::string filepath );
230 void freeMesh( Mesh &mesh );
231 Mesh getPlaneMesh();
232 Mesh getCubeMesh();
233 Texture loadTexture( const GLvoid* data, GLsizei width, GLsizei height, unsigned int channels, bool mipmap = true, bool filter = true );
234 Texture loadCubemap( std::vector<GLvoid*> faces, GLsizei width, GLsizei height, unsigned int channels, bool mipmap = true, bool filter = true );
235 void freeTexture( Texture &tex );
236 void updateTexture( Texture &tex, const GLvoid* data );
237 void updateCubemap( Texture &tex, std::vector<GLvoid*> faces );
238 void updateCubemapFace( Texture &tex, const GLvoid* data, unsigned int face );
239 void setTexture( Texture tex, GLuint texSlot );
240 Texture getBlankTexture();
241 void setFog( Color col );
242 Color getFog();
243 void setMetallicFactor( GLfloat f );
244 void setRoughnessFactor( GLfloat f );
245 void setBaseColorFactor( Color col );
246 void setEmissiveFactor( GLfloat r, GLfloat g, GLfloat b );
247 void setPipeline( Pipeline pipeline );
248 Pipeline getPipeline();
249 Pipeline getUnlitPipeline();
250 Pipeline getColorModPipeline();
251 Pipeline getUnlitInstancePipeline();
252 Pipeline getSkyboxPipeline();
253 Pipeline getIrradiancePipeline();
254 void setTextureMatrix( linalg::mat<double,4,4> texMat );
255 linalg::mat<double,4,4> getTextureMatrix();
256 void setLightMatrix( linalg::mat<double,4,4> lightMat );
257 linalg::mat<double,4,4> getLightMatrix();
258 Framebuffer createFramebuffer( GLsizei width, GLsizei height, bool cubemap = false, GLenum internalFmt = GL_RGB, GLsizei multisample = 0 );
259 void resizeFramebuffer( Framebuffer &fb, GLsizei width, GLsizei height, GLsizei multisample = 0 );
260 Texture getFramebufferTexture( Framebuffer &fb );
261 void setFramebuffer( Framebuffer fb = newFramebuffer );
262 void drawFramebuffer( Framebuffer &fb, bool draw_z = false );
263 Framebuffer getIrradianceFramebuffer( Texture in_cubemap, Framebuffer fb = newFramebuffer );
264 void drawSkybox( Texture &tex, linalg::mat<double,4,4> view, linalg::mat<double,4,4> proj, Color tint = newColor );
265 int compileShader( GLuint shader );
266 int linkProgram( GLuint programObject );
267 Pipeline loadPipeline( const GLchar* vertSrc, const GLchar* fragSrc, std::vector<std::string> samplers = {} );
268 Display createDisplay( unsigned int width, unsigned int height, std::string title, int multisamples = 4, bool HiDPI = true, bool vsync = true );
269 void focusDisplay();
270 int getMouseX();
271 int getMouseY();
272 Display getDisplay();
273 unsigned int getDisplayWidth();
274 unsigned int getDisplayHeight();
275 double deltaTime();
276 void syncEvents();
277 void sync();
278 void setTextInput( int x = 0, int y = 0, int w = 0, int h = 0 );
279 int upKey();
280 int downKey();
281 int leftKey();
282 int rightKey();
283 int shiftKey();
284 int commandKey();
285 int controlKey();
286 int enterKey();
287 int escapeKey();
288 int spaceKey();
289 int tabKey();
290 int charKey( char key );
291 int upPad();
292 int downPad();
293 int leftPad();
294 int rightPad();
295 int selectButton();
296 int startButton();
297 int aButton();
298 int bButton();
299 int xButton();
300 int yButton();
301 int left1();
302 int right1();
303 float left2();
304 float right2();
305 int leftStick();
306 int rightStick();
307 float leftStickX();
308 float leftStickY();
309 float rightStickX();
310 float rightStickY();
311 int mouseButton( int button );
312 void showMouse( bool show );
313 void trapMouse( bool trap );
314 void hapticRumble( float strength, unsigned int length );
315 void end();
316 void packFontRange( Font &font, int cpStart, int cpEnd );
317 int getCharacterIndex( int cp, Font &font );
318 Font loadFont( std::string fileName, float fontSize, int oversampleX, int oversampleY,
319 bool prepack = true, int atlasWidth = 512, int atlasHeight = 512 );
320 float getTextWidthUtf32( std::u32string codepoints, Font &font );
321 float getTextWidth( std::string text, Font &font );
322 void drawTextUtf32( std::u32string codepoints, Font &font, float posX, float posY, float scale, int align = 0, float wordWrap = 0.0f );
323 void drawText( std::string text, Font &font, float posX, float posY, float scale, int align = 0, float wordWrap = 0.0f );
367 324
368 325 // Instancing. // Instancing.
369 326 struct InstanceAttributes { struct InstanceAttributes {
 
... ... struct InstanceAttributes {
372 329 GLfloat texMat[16]; GLfloat texMat[16];
373 330 }; };
374 331
375 // Used by testDraw.
376 void setPipeline( Pipeline pipeline );
377 void setTexture( Texture tex, GLuint texSlot );
378
379 332 class InstanceBuffer { class InstanceBuffer {
380 333 public: public:
381 334 GLuint vbo = 0; GLuint vbo = 0;
382 335 std::vector<InstanceAttributes> attributes; std::vector<InstanceAttributes> attributes;
383 336
384 void push( const Color &color, linalg::mat<double,4,4> modelMat ){
337 void push( const Color &color, linalg::mat<double,4,4> modelMat, linalg::mat<double,4,4> texMat ){
385 338 attributes.push_back( { attributes.push_back( {
386 339 color, { color, {
387 340 (GLfloat)modelMat[0][0], (GLfloat)modelMat[0][1], (GLfloat)modelMat[0][2], (GLfloat)modelMat[0][3], (GLfloat)modelMat[0][0], (GLfloat)modelMat[0][1], (GLfloat)modelMat[0][2], (GLfloat)modelMat[0][3],
388 341 (GLfloat)modelMat[1][0], (GLfloat)modelMat[1][1], (GLfloat)modelMat[1][2], (GLfloat)modelMat[1][3], (GLfloat)modelMat[1][0], (GLfloat)modelMat[1][1], (GLfloat)modelMat[1][2], (GLfloat)modelMat[1][3],
389 342 (GLfloat)modelMat[2][0], (GLfloat)modelMat[2][1], (GLfloat)modelMat[2][2], (GLfloat)modelMat[2][3], (GLfloat)modelMat[2][0], (GLfloat)modelMat[2][1], (GLfloat)modelMat[2][2], (GLfloat)modelMat[2][3],
390 343 (GLfloat)modelMat[3][0], (GLfloat)modelMat[3][1], (GLfloat)modelMat[3][2], (GLfloat)modelMat[3][3] }, { (GLfloat)modelMat[3][0], (GLfloat)modelMat[3][1], (GLfloat)modelMat[3][2], (GLfloat)modelMat[3][3] }, {
391 (GLfloat)texMatrix[0][0], (GLfloat)texMatrix[0][1], (GLfloat)texMatrix[0][2], (GLfloat)texMatrix[0][3],
392 (GLfloat)texMatrix[1][0], (GLfloat)texMatrix[1][1], (GLfloat)texMatrix[1][2], (GLfloat)texMatrix[1][3],
393 (GLfloat)texMatrix[2][0], (GLfloat)texMatrix[2][1], (GLfloat)texMatrix[2][2], (GLfloat)texMatrix[2][3],
394 (GLfloat)texMatrix[3][0], (GLfloat)texMatrix[3][1], (GLfloat)texMatrix[3][2], (GLfloat)texMatrix[3][3] }
344 (GLfloat)texMat[0][0], (GLfloat)texMat[0][1], (GLfloat)texMat[0][2], (GLfloat)texMat[0][3],
345 (GLfloat)texMat[1][0], (GLfloat)texMat[1][1], (GLfloat)texMat[1][2], (GLfloat)texMat[1][3],
346 (GLfloat)texMat[2][0], (GLfloat)texMat[2][1], (GLfloat)texMat[2][2], (GLfloat)texMat[2][3],
347 (GLfloat)texMat[3][0], (GLfloat)texMat[3][1], (GLfloat)texMat[3][2], (GLfloat)texMat[3][3] }
395 348 } ); } );
396 349 } }
397 350
 
... ... class InstanceBuffer {
402 355 glBufferData( GL_ARRAY_BUFFER, attributes.size() * sizeof(InstanceAttributes), attributes.data(), GL_STREAM_DRAW ); glBufferData( GL_ARRAY_BUFFER, attributes.size() * sizeof(InstanceAttributes), attributes.data(), GL_STREAM_DRAW );
403 356 } }
404 357
405 void draw( Mesh &mesh, linalg::mat<double,4,4> viewMat, linalg::mat<double,4,4> projMat ){
358 void draw( Mesh &mesh, linalg::mat<double,4,4> viewMat, linalg::mat<double,4,4> projMat, linalg::mat<double,4,4> lightMat ){
406 359 if( attributes.empty() || !mesh.success || !vbo ) return; if( attributes.empty() || !mesh.success || !vbo ) return;
407 360
408 361 // Bind the VBO. // Bind the VBO.
 
... ... class InstanceBuffer {
421 374 (GLfloat)projMat[1][0], (GLfloat)projMat[1][1], (GLfloat)projMat[1][2], (GLfloat)projMat[1][3], (GLfloat)projMat[1][0], (GLfloat)projMat[1][1], (GLfloat)projMat[1][2], (GLfloat)projMat[1][3],
422 375 (GLfloat)projMat[2][0], (GLfloat)projMat[2][1], (GLfloat)projMat[2][2], (GLfloat)projMat[2][3], (GLfloat)projMat[2][0], (GLfloat)projMat[2][1], (GLfloat)projMat[2][2], (GLfloat)projMat[2][3],
423 376 (GLfloat)projMat[3][0], (GLfloat)projMat[3][1], (GLfloat)projMat[3][2], (GLfloat)projMat[3][3], (GLfloat)projMat[3][0], (GLfloat)projMat[3][1], (GLfloat)projMat[3][2], (GLfloat)projMat[3][3],
424 (GLfloat)lightMatrix[0][0], (GLfloat)lightMatrix[0][1], (GLfloat)lightMatrix[0][2], (GLfloat)lightMatrix[0][3],
425 (GLfloat)lightMatrix[1][0], (GLfloat)lightMatrix[1][1], (GLfloat)lightMatrix[1][2], (GLfloat)lightMatrix[1][3],
426 (GLfloat)lightMatrix[2][0], (GLfloat)lightMatrix[2][1], (GLfloat)lightMatrix[2][2], (GLfloat)lightMatrix[2][3],
427 (GLfloat)lightMatrix[3][0], (GLfloat)lightMatrix[3][1], (GLfloat)lightMatrix[3][2], (GLfloat)lightMatrix[3][3],
377 (GLfloat)lightMat[0][0], (GLfloat)lightMat[0][1], (GLfloat)lightMat[0][2], (GLfloat)lightMat[0][3],
378 (GLfloat)lightMat[1][0], (GLfloat)lightMat[1][1], (GLfloat)lightMat[1][2], (GLfloat)lightMat[1][3],
379 (GLfloat)lightMat[2][0], (GLfloat)lightMat[2][1], (GLfloat)lightMat[2][2], (GLfloat)lightMat[2][3],
380 (GLfloat)lightMat[3][0], (GLfloat)lightMat[3][1], (GLfloat)lightMat[3][2], (GLfloat)lightMat[3][3]
428 381 }; };
429 382
430 glUniformMatrix4fv( drawPipeline.u_matrices, 3, GL_FALSE, glmats );
383 glUniformMatrix4fv( getPipeline().u_matrices, 3, GL_FALSE, glmats );
431 384
432 385 // Switch graphics memory to the VAO. // Switch graphics memory to the VAO.
433 386 glBindVertexArray( mesh.vao[0] ); glBindVertexArray( mesh.vao[0] );
 
... ... class InstanceBuffer {
468 421 for( int z = -5; z < 5; z++ ){ for( int z = -5; z < 5; z++ ){
469 422 push( push(
470 423 (Color){ ( x + 6 ) * 0.09f, ( y + 6 ) * 0.09f, 0.0f, 1.0f }, (Color){ ( x + 6 ) * 0.09f, ( y + 6 ) * 0.09f, 0.0f, 1.0f },
471 linalg::translation_matrix( linalg::vec<double,3>( x * 3.0, y * 3.0, z * 3.0 ) )
424 linalg::translation_matrix( linalg::vec<double,3>( x * 3.0, y * 3.0, z * 3.0 ) ),
425 linalg::identity
472 426 ); );
473 427 } }
474 428 } }
 
... ... class InstanceBuffer {
476 430 // Upload attributes. // Upload attributes.
477 431 upload(); upload();
478 432 // Draw the instance buffer. // Draw the instance buffer.
479 auto old_pipeline = drawPipeline;
480 setPipeline( unlitInstancePipeline );
481 setTexture( blankTexture, 0 );
482 draw( cubeMesh, viewMat, projMat );
433 auto old_pipeline = getPipeline();
434 setPipeline( getUnlitInstancePipeline() );
435 setTexture( getBlankTexture(), 0 );
436 Mesh cube = getCubeMesh();
437 draw( cube, viewMat, projMat, linalg::identity );
483 438 clear(); clear();
484 439 setPipeline( old_pipeline ); setPipeline( old_pipeline );
485 440 } }
 
... ... class InstanceBuffer {
489 444 } }
490 445 }; };
491 446
447 // Implementation begins here.
448
449 #ifdef FG3_IMPLEMENTATION
450
451 // TODO: Don't use a global verbose flag.
452 bool verbose = false;
453
454 // Globals.
455
456 #ifdef GLAD_GL
457 static const GLchar* shaderHeader = R"(
458 #version 330
459 )";
460 #else // GLES
461 static const GLchar* shaderHeader = R"(
462 #version 300 es
463 precision highp float;
464 )";
465 #endif
466
467 // vec2/3 can become vec4 automatically
468 // https://stackoverflow.com/questions/18935203/shader-position-vec4-or-vec3
469
470 static const GLchar* unlitVert = R"(
471 uniform mat4 u_matrices[6]; // 0:mvp 1:mv 2:m 3:normal 4:texture 5:light
472 layout(location = 0) in vec4 a_Position;
473 layout(location = 1) in vec4 a_Normal;
474 layout(location = 2) in vec4 a_Tangent;
475 layout(location = 3) in vec4 a_UV;
476 out vec2 v_UV;
477 out vec4 v_RelativePos;
478 void main(){
479 v_UV = vec2( u_matrices[4] * a_UV );
480 v_RelativePos = u_matrices[1] * a_Position;
481 gl_Position = u_matrices[0] * a_Position;
482 }
483 )";
484
485 static const GLchar* unlitFrag = R"(
486 uniform sampler2D u_texture;
487 uniform vec4 u_fog;
488 uniform vec3 u_camera;
489 in vec2 v_UV;
490 in vec4 v_RelativePos;
491 layout(location = 0) out vec4 fragColor;
492 void main(){
493 vec4 texColor = texture( u_texture, v_UV );
494 if( texColor.a < 0.001 ) discard;
495 if( u_fog.a > 0.0 ){
496 float fogFactor = 1.0 - clamp( 1.0 / exp( length( v_RelativePos ) * u_fog.a ), 0.0, 1.0 );
497 fragColor = vec4( mix( texColor.rgb, u_fog.rgb, fogFactor ), texColor.a );
498 }else{
499 fragColor = texColor;
500 }
501 }
502 )";
503
504 static const std::vector<std::string> unlitSamplers = { "u_texture" };
505
506 static const GLchar* colorModFrag = R"(
507 uniform sampler2D u_texture;
508 uniform vec4 u_fog;
509 uniform vec3 u_camera;
510 in vec2 v_UV;
511 in vec4 v_RelativePos;
512 layout(location = 0) out vec4 fragColor;
513 void main(){
514 vec4 texColor = texture( u_texture, v_UV );
515 if( texColor.a < 0.001 ) discard;
516 fragColor = texColor * u_fog;
517 }
518 )";
519
520 static const std::vector<std::string> colorModSamplers = { "u_texture" };
521
522 // Instanced arrays are used for instancing.
523 // https://learnopengl.com/Advanced-OpenGL/Instancing
524
525 static const GLchar* unlitInstanceVert = R"(
526 uniform mat4 u_matrices[3]; // 0:view 1:projection 2:light
527 layout(location = 0) in vec4 a_Position;
528 layout(location = 1) in vec4 a_Normal;
529 layout(location = 2) in vec4 a_Tangent;
530 layout(location = 3) in vec4 a_UV;
531 layout(location = 4) in vec4 a_Color;
532 layout(location = 5) in mat4 a_ModelMat;
533 layout(location = 9) in mat4 a_TexMat;
534 out vec2 v_UV;
535 out vec4 v_Color;
536 out vec4 v_RelativePos;
537 void main(){
538 v_UV = vec2( a_TexMat * a_UV );
539 v_Color = a_Color;
540 mat4 mv = u_matrices[0] * a_ModelMat;
541 v_RelativePos = mv * a_Position;
542 gl_Position = u_matrices[1] * mv * a_Position;
543 }
544 )";
545
546 static const GLchar* unlitInstanceFrag = R"(
547 uniform sampler2D u_texture;
548 uniform vec4 u_fog;
549 in vec2 v_UV;
550 in vec4 v_Color;
551 in vec4 v_RelativePos;
552 layout(location = 0) out vec4 fragColor;
553 void main(){
554 vec4 texColor = texture( u_texture, v_UV ) * v_Color;
555 if( texColor.a < 0.001 ) discard;
556 if( u_fog.a > 0.0 ){
557 float fogFactor = 1.0 - clamp( 1.0 / exp( length( v_RelativePos ) * u_fog.a ), 0.0, 1.0 );
558 fragColor = vec4( mix( texColor.rgb, u_fog.rgb, fogFactor ), texColor.a );
559 }else{
560 fragColor = texColor;
561 }
562 }
563 )";
564
565 static const std::vector<std::string> unlitInstanceSamplers = { "u_texture" };
566
567 static const GLchar* skyboxVert = R"(
568 uniform mat4 u_matrices[6]; // 0:mvp 1:mv 2:m 3:normal 4:texture 5:light
569 layout(location = 0) in vec4 a_Position;
570 layout(location = 1) in vec4 a_Normal;
571 layout(location = 2) in vec4 a_Tangent;
572 layout(location = 3) in vec4 a_UV;
573 out vec3 v_STR;
574 void main(){
575 v_STR = a_Position.xyz;
576 vec4 pos = u_matrices[0] * a_Position;
577 gl_Position = pos.xyww;
578 }
579 )";
580
581 static const GLchar* skyboxFrag = R"(
582 uniform samplerCube u_cubemap;
583 uniform vec4 u_fog;
584 uniform vec3 u_camera;
585 in vec3 v_STR;
586 layout(location = 0) out vec4 fragColor;
587 void main(){
588 fragColor = texture( u_cubemap, v_STR );
589 }
590 )";
591
592 static const std::vector<std::string> skyboxSamplers = { "u_cubemap" };
593
594 static const GLchar* irradianceFrag = R"(
595 uniform samplerCube u_cubemap;
596 uniform vec4 u_fog;
597 uniform vec3 u_camera;
598 in vec3 v_STR;
599 layout(location = 0) out vec4 fragColor;
600 const float PI = 3.1415927;
601 mat4 rotationMatrix( vec3 axis, float angle ){
602 axis = normalize( axis );
603 float s = sin( angle );
604 float c = cos( angle );
605 float oc = 1.0 - c;
606 return mat4( mat3(
607 oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
608 oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
609 oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c
610 ) );
611 }
612 vec3 getIrradiance( vec3 normal ){
613 float grain = 0.05;
614 vec3 irradiance = vec3( 0.0 );
615 vec3 up = vec3( 0.0, 1.0, 0.0 );
616 vec3 right = normalize( cross( normal, up ) );
617 float index = 0.0;
618 for( float longi = 0.0; longi <= PI * 0.5; longi += grain ){
619 mat4 trl = rotationMatrix( right, longi );
620 for( float azi = 0.0; azi <= PI * 2.0; azi += grain ){
621 mat4 tra = rotationMatrix( normal, azi );
622 vec3 sampleVec = ( tra * trl * vec4( normal, 1.0 ) ).xyz;
623 irradiance += texture( u_cubemap, sampleVec ).rgb * sin( longi ) * cos( longi );
624 index += 1.0;
625 }
626 }
627 float hemispherePDF = 1.0 / ( 2.0 * PI );
628 irradiance /= index * hemispherePDF;
629 return irradiance;
630 }
631 void main(){
632 vec3 N = normalize( v_STR );
633 fragColor = vec4( getIrradiance( N ) / PI, 1.0 );
634 }
635 )";
636
637 static const std::vector<std::string> irradianceSamplers = { "u_cubemap" };
638
639 Color fogColor = { 0.0f, 0.0f, 0.0f, 0.0f };
640
641 Texture blankTexture = { false, 0, 0, 0, 0, false, 0 };
642
643 Pipeline
644 drawPipeline = { false, 0, 0, 0, 0, 0, 0, 0, 0, {} },
645 unlitPipeline = { false, 0, 0, 0, 0, 0, 0, 0, 0, {} },
646 colorModPipeline = { false, 0, 0, 0, 0, 0, 0, 0, 0, {} },
647 unlitInstancePipeline = { false, 0, 0, 0, 0, 0, 0, 0, 0, {} },
648 skyboxPipeline = { false, 0, 0, 0, 0, 0, 0, 0, 0, {} },
649 irradiancePipeline = { false, 0, 0, 0, 0, 0, 0, 0, 0, {} };
650
651 Mesh planeMesh = { false, {}, {}, { 0, 0, 0 }, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
652
653 Mesh cubeMesh = { false, {}, {}, { 0, 0, 0 }, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
654
655 linalg::mat<double,4,4> texMatrix = linalg::identity, lightMatrix = linalg::identity;
656
492 657 // TODO: SFML mouse wheel. // TODO: SFML mouse wheel.
493 658 int mouseX = 0, mouseY = 0, mouseMoveX = 0, mouseMoveY = 0, mouseWheel = 0; int mouseX = 0, mouseY = 0, mouseMoveX = 0, mouseMoveY = 0, mouseWheel = 0;
494 659 bool mouseTrapped = false; bool mouseTrapped = false;
 
... ... Color rgb( float r, float g, float b ){
603 768 return col; return col;
604 769 } }
605 770
606 // Used by cls.
607 void drawMesh( Mesh &mesh, linalg::mat<double,4,4> modelMat, linalg::mat<double,4,4> viewMat, linalg::mat<double,4,4> projMat );
608 void setPipeline( Pipeline pipeline );
609
610 void cls( Color col, bool clearDepth = true ){
771 void cls( Color col, bool clearDepth ){
611 772 if( clearDepth ){ if( clearDepth ){
612 773 // GL_DEPTH_BUFFER_BIT is not usually problematic. // GL_DEPTH_BUFFER_BIT is not usually problematic.
613 774 glClear( GL_DEPTH_BUFFER_BIT ); glClear( GL_DEPTH_BUFFER_BIT );
 
... ... void cls( Color col, bool clearDepth = true ){
636 797 setPipeline( p ); setPipeline( p );
637 798 } }
638 799
639 Mesh loadMesh( std::vector<Vertex> &vertices, std::vector<Index> &indices, bool streaming = false ){
800 Mesh loadMesh( std::vector<Vertex> &vertices, std::vector<Index> &indices, bool streaming ){
640 801 Mesh mesh = newMesh; Mesh mesh = newMesh;
641 802
642 803 if( vertices.size() > 0 ){ if( vertices.size() > 0 ){
 
... ... Mesh loadMesh( std::vector<Vertex> &vertices, std::vector<Index> &indices, bool
718 879 return mesh; return mesh;
719 880 } }
720 881
721 void updateMesh( Mesh &mesh, std::vector<Vertex> &vertices, std::vector<Index> &indices, bool streaming = false ){
882 void updateMesh( Mesh &mesh, std::vector<Vertex> &vertices, std::vector<Index> &indices, bool streaming ){
722 883 // switch graphics memory to the VAO // switch graphics memory to the VAO
723 884 glBindVertexArray( mesh.vao[0] ); glBindVertexArray( mesh.vao[0] );
724 885
 
... ... void freeMesh( Mesh &mesh ){
1071 1232 mesh = newMesh; mesh = newMesh;
1072 1233 } }
1073 1234
1074 Texture loadTexture( const GLvoid* data, GLsizei width, GLsizei height, unsigned int channels, bool mipmap = true, bool filter = true ){
1235 Mesh getPlaneMesh(){
1236 return planeMesh;
1237 }
1238
1239 Mesh getCubeMesh(){
1240 return cubeMesh;
1241 }
1242
1243 Texture loadTexture( const GLvoid* data, GLsizei width, GLsizei height, unsigned int channels, bool mipmap, bool filter ){
1075 1244 Texture tex = newTexture; Texture tex = newTexture;
1076 1245 if( !data ) return tex; if( !data ) return tex;
1077 1246
 
... ... Texture loadTexture( const GLvoid* data, GLsizei width, GLsizei height, unsigned
1148 1317 return tex; return tex;
1149 1318 } }
1150 1319
1151 Texture loadCubemap( std::vector<GLvoid*> faces, GLsizei width, GLsizei height, unsigned int channels, bool mipmap = true, bool filter = true ){
1320 Texture loadCubemap( std::vector<GLvoid*> faces, GLsizei width, GLsizei height, unsigned int channels, bool mipmap, bool filter ){
1152 1321 Texture tex = newTexture; Texture tex = newTexture;
1153 1322 if( faces.size() != 6 ) return tex; if( faces.size() != 6 ) return tex;
1154 1323
 
... ... void setTexture( Texture tex, GLuint texSlot ){
1310 1479 } }
1311 1480 } }
1312 1481
1482 Texture getBlankTexture(){
1483 return blankTexture;
1484 }
1485
1313 1486 void setFog( Color col ){ void setFog( Color col ){
1314 1487 glUniform4f( drawPipeline.u_fog, col.r, col.g, col.b, col.a ); glUniform4f( drawPipeline.u_fog, col.r, col.g, col.b, col.a );
1315 1488 fogColor = col; fogColor = col;
1316 1489 } }
1317 1490
1491 Color getFog(){
1492 return fogColor;
1493 }
1494
1318 1495 void setMetallicFactor( GLfloat f ){ void setMetallicFactor( GLfloat f ){
1319 1496 glUniform1f( drawPipeline.u_metallicFactor, f ); glUniform1f( drawPipeline.u_metallicFactor, f );
1320 1497 } }
 
... ... Pipeline getPipeline(){
1346 1523 return drawPipeline; return drawPipeline;
1347 1524 } }
1348 1525
1526 Pipeline getUnlitPipeline(){
1527 return unlitPipeline;
1528 }
1529
1530 Pipeline getColorModPipeline(){
1531 return colorModPipeline;
1532 }
1533 Pipeline getUnlitInstancePipeline(){
1534 return unlitInstancePipeline;
1535 }
1536
1537 Pipeline getSkyboxPipeline(){
1538 return skyboxPipeline;
1539 }
1540
1541 Pipeline getIrradiancePipeline(){
1542 return irradiancePipeline;
1543 }
1544
1349 1545 void setTextureMatrix( linalg::mat<double,4,4> texMat ){ void setTextureMatrix( linalg::mat<double,4,4> texMat ){
1350 1546 texMatrix = texMat; texMatrix = texMat;
1351 1547 } }
1352 1548
1549 linalg::mat<double,4,4> getTextureMatrix(){
1550 return texMatrix;
1551 }
1552
1353 1553 void setLightMatrix( linalg::mat<double,4,4> lightMat ){ void setLightMatrix( linalg::mat<double,4,4> lightMat ){
1354 1554 lightMatrix = lightMat; lightMatrix = lightMat;
1355 1555 } }
1356 1556
1357 Framebuffer createFramebuffer( GLsizei width, GLsizei height, bool cubemap = false, GLenum internalFmt = GL_RGB, GLsizei multisample = 0 ){
1557 linalg::mat<double,4,4> getLightMatrix(){
1558 return lightMatrix;
1559 }
1560
1561 Framebuffer createFramebuffer( GLsizei width, GLsizei height, bool cubemap, GLenum internalFmt, GLsizei multisample ){
1358 1562 // https://stackoverflow.com/questions/46535341 // https://stackoverflow.com/questions/46535341
1359 1563 // This framebuffer API does not currently support mipmapping. // This framebuffer API does not currently support mipmapping.
1360 1564
 
... ... Framebuffer createFramebuffer( GLsizei width, GLsizei height, bool cubemap = fal
1363 1567 glBindFramebuffer( GL_FRAMEBUFFER, fb.fbo ); glBindFramebuffer( GL_FRAMEBUFFER, fb.fbo );
1364 1568
1365 1569 // Multisample textures are not available in core GLES 3.0. // Multisample textures are not available in core GLES 3.0.
1366 #ifdef GLAD_GLES2_IMPLEMENTATION
1570 #ifdef GLAD_GLES2
1367 1571 multisample = 0; multisample = 0;
1368 1572 fb.texture_type = cubemap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D; fb.texture_type = cubemap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
1369 1573 #else #else
 
... ... Framebuffer createFramebuffer( GLsizei width, GLsizei height, bool cubemap = fal
1423 1627 glTexParameteri( fb.texture_type, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); glTexParameteri( fb.texture_type, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
1424 1628 }else{ }else{
1425 1629 // Create a blank surface. // Create a blank surface.
1426 #ifdef GLAD_GL_IMPLEMENTATION
1630 #ifdef GLAD_GL
1427 1631 if( fb.texture_type == GL_TEXTURE_2D_MULTISAMPLE ) if( fb.texture_type == GL_TEXTURE_2D_MULTISAMPLE )
1428 1632 glTexImage2DMultisample( GL_TEXTURE_2D_MULTISAMPLE, multisample, internalFmt, width, height, GL_TRUE ); glTexImage2DMultisample( GL_TEXTURE_2D_MULTISAMPLE, multisample, internalFmt, width, height, GL_TRUE );
1429 1633 else else
 
... ... Framebuffer createFramebuffer( GLsizei width, GLsizei height, bool cubemap = fal
1444 1648 glBindTexture( fb.texture_type, 0 ); glBindTexture( fb.texture_type, 0 );
1445 1649
1446 1650 if( cubemap if( cubemap
1447 #ifdef GLAD_GL_IMPLEMENTATION
1651 #ifdef GLAD_GL
1448 1652 || fb.texture_type == GL_TEXTURE_2D_MULTISAMPLE || fb.texture_type == GL_TEXTURE_2D_MULTISAMPLE
1449 1653 #endif #endif
1450 1654 ){ ){
 
... ... Framebuffer createFramebuffer( GLsizei width, GLsizei height, bool cubemap = fal
1453 1657 // Create a depth renderbuffer. // Create a depth renderbuffer.
1454 1658 glGenRenderbuffers( 1, &fb.rbo ); glGenRenderbuffers( 1, &fb.rbo );
1455 1659 glBindRenderbuffer( GL_RENDERBUFFER, fb.rbo ); glBindRenderbuffer( GL_RENDERBUFFER, fb.rbo );
1456 #ifdef GLAD_GL_IMPLEMENTATION
1660 #ifdef GLAD_GL
1457 1661 if( fb.texture_type == GL_TEXTURE_2D_MULTISAMPLE ) if( fb.texture_type == GL_TEXTURE_2D_MULTISAMPLE )
1458 1662 glRenderbufferStorageMultisample( GL_RENDERBUFFER, multisample, GL_DEPTH_COMPONENT32F, width, height ); glRenderbufferStorageMultisample( GL_RENDERBUFFER, multisample, GL_DEPTH_COMPONENT32F, width, height );
1459 1663 else else
 
... ... Framebuffer createFramebuffer( GLsizei width, GLsizei height, bool cubemap = fal
1484 1688
1485 1689 GLenum glerr; GLenum glerr;
1486 1690 while( ( glerr = glGetError() ) != GL_NO_ERROR ){ while( ( glerr = glGetError() ) != GL_NO_ERROR ){
1487 fprintf( stderr, "OpenGL error: %d\n", (int)glerr );
1691 printf( "OpenGL error: 0x%.4X\n", glerr );
1488 1692 } }
1489 1693
1490 1694 fb.width = width; fb.width = width;
 
... ... Framebuffer createFramebuffer( GLsizei width, GLsizei height, bool cubemap = fal
1493 1697 return fb; return fb;
1494 1698 } }
1495 1699
1496 void resizeFramebuffer( Framebuffer &fb, GLsizei width, GLsizei height, GLsizei multisample = 0 ){
1497 #ifdef GLAD_GLES2_IMPLEMENTATION
1700 void resizeFramebuffer( Framebuffer &fb, GLsizei width, GLsizei height, GLsizei multisample ){
1701 #ifdef GLAD_GLES2
1498 1702 multisample = 0; multisample = 0;
1499 1703 #endif #endif
1500 1704
 
... ... void resizeFramebuffer( Framebuffer &fb, GLsizei width, GLsizei height, GLsizei
1543 1747 } }
1544 1748 }else{ }else{
1545 1749 // Resize the texture. // Resize the texture.
1546 #ifdef GLAD_GL_IMPLEMENTATION
1750 #ifdef GLAD_GL
1547 1751 if( fb.texture_type == GL_TEXTURE_2D_MULTISAMPLE ) if( fb.texture_type == GL_TEXTURE_2D_MULTISAMPLE )
1548 1752 glTexImage2DMultisample( GL_TEXTURE_2D_MULTISAMPLE, multisample, fb.texture_fmt, width, height, GL_TRUE ); glTexImage2DMultisample( GL_TEXTURE_2D_MULTISAMPLE, multisample, fb.texture_fmt, width, height, GL_TRUE );
1549 1753 else else
 
... ... void resizeFramebuffer( Framebuffer &fb, GLsizei width, GLsizei height, GLsizei
1555 1759 glBindTexture( fb.texture_type, 0 ); glBindTexture( fb.texture_type, 0 );
1556 1760
1557 1761 if( fb.texture_type == GL_TEXTURE_CUBE_MAP if( fb.texture_type == GL_TEXTURE_CUBE_MAP
1558 #ifdef GLAD_GL_IMPLEMENTATION
1762 #ifdef GLAD_GL
1559 1763 || fb.texture_type == GL_TEXTURE_2D_MULTISAMPLE || fb.texture_type == GL_TEXTURE_2D_MULTISAMPLE
1560 1764 #endif #endif
1561 1765 ){ ){
 
... ... void resizeFramebuffer( Framebuffer &fb, GLsizei width, GLsizei height, GLsizei
1563 1767 glDeleteRenderbuffers( 1, &fb.rbo ); glDeleteRenderbuffers( 1, &fb.rbo );
1564 1768 glGenRenderbuffers( 1, &fb.rbo ); glGenRenderbuffers( 1, &fb.rbo );
1565 1769 glBindRenderbuffer( GL_RENDERBUFFER, fb.rbo ); glBindRenderbuffer( GL_RENDERBUFFER, fb.rbo );
1566 #ifdef GLAD_GL_IMPLEMENTATION
1770 #ifdef GLAD_GL
1567 1771 if( fb.texture_type == GL_TEXTURE_2D_MULTISAMPLE ) if( fb.texture_type == GL_TEXTURE_2D_MULTISAMPLE )
1568 1772 glRenderbufferStorageMultisample( GL_RENDERBUFFER, multisample, GL_DEPTH_COMPONENT32F, width, height ); glRenderbufferStorageMultisample( GL_RENDERBUFFER, multisample, GL_DEPTH_COMPONENT32F, width, height );
1569 1773 else else
 
... ... Texture getFramebufferTexture( Framebuffer &fb ){
1597 1801 return tex; return tex;
1598 1802 } }
1599 1803
1600 // Used by setFramebuffer
1601 Display getDisplay();
1602
1603 void setFramebuffer( Framebuffer fb = newFramebuffer ){
1804 void setFramebuffer( Framebuffer fb ){
1604 1805 // Set the drawing target to the framebuffer or the screen. // Set the drawing target to the framebuffer or the screen.
1605 1806 if( fb.success ){ if( fb.success ){
1606 1807 glBindFramebuffer( GL_FRAMEBUFFER, fb.fbo ); glBindFramebuffer( GL_FRAMEBUFFER, fb.fbo );
 
... ... void setFramebuffer( Framebuffer fb = newFramebuffer ){
1612 1813 } }
1613 1814 } }
1614 1815
1615 void drawFramebuffer( Framebuffer &fb, bool draw_z = false ){
1816 void drawFramebuffer( Framebuffer &fb, bool draw_z ){
1616 1817 if( !fb.success ) return; if( !fb.success ) return;
1617 1818 if( fb.multisample > 0 ){ if( fb.multisample > 0 ){
1618 1819 // Blit and rely on OpenGL to resolve samples. // Blit and rely on OpenGL to resolve samples.
 
... ... void drawFramebuffer( Framebuffer &fb, bool draw_z = false ){
1642 1843 } }
1643 1844 } }
1644 1845
1645 Framebuffer getIrradianceFramebuffer( Texture in_cubemap, Framebuffer fb = newFramebuffer ){
1846 Framebuffer getIrradianceFramebuffer( Texture in_cubemap, Framebuffer fb ){
1646 1847 if( !fb.success ) fb = createFramebuffer( 32, 32, true ); if( !fb.success ) fb = createFramebuffer( 32, 32, true );
1647 1848 setFramebuffer( fb ); setFramebuffer( fb );
1648 1849
 
... ... Framebuffer getIrradianceFramebuffer( Texture in_cubemap, Framebuffer fb = newFr
1694 1895 return fb; return fb;
1695 1896 } }
1696 1897
1697 void drawSkybox( Texture &tex, linalg::mat<double,4,4> view, linalg::mat<double,4,4> proj, Color tint = newColor ){
1898 void drawSkybox( Texture &tex, linalg::mat<double,4,4> view, linalg::mat<double,4,4> proj, Color tint ){
1698 1899 if( !skyboxPipeline.success ) return; if( !skyboxPipeline.success ) return;
1699 1900 auto old_pipeline = drawPipeline; auto old_pipeline = drawPipeline;
1700 1901 setPipeline( skyboxPipeline ); setPipeline( skyboxPipeline );
 
... ... int linkProgram( GLuint programObject ){
1788 1989 return 1; return 1;
1789 1990 } }
1790 1991
1791 Pipeline loadPipeline( const GLchar* vertSrc, const GLchar* fragSrc, std::vector<std::string> samplers = {} ){
1992 Pipeline loadPipeline( const GLchar* vertSrc, const GLchar* fragSrc, std::vector<std::string> samplers ){
1792 1993 Pipeline pipeline = newPipeline; Pipeline pipeline = newPipeline;
1793 1994
1794 1995 GLuint vert; GLuint vert;
 
... ... Pipeline loadPipeline( const GLchar* vertSrc, const GLchar* fragSrc, std::vector
1834 2035 return pipeline; return pipeline;
1835 2036 } }
1836 2037
1837 Display createDisplay( unsigned int width, unsigned int height, std::string title, int multisamples = 4, bool HiDPI = true, bool vsync = true ){
2038 Display createDisplay( unsigned int width, unsigned int height, std::string title, int multisamples, bool HiDPI, bool vsync ){
1838 2039 // Opens a window with a GL context. // Opens a window with a GL context.
1839 2040 // Display display = createDisplay( 800, 600, "Title" ); // Display display = createDisplay( 800, 600, "Title" );
1840 2041
 
... ... Display createDisplay( unsigned int width, unsigned int height, std::string titl
2014 2215 glDepthFunc( GL_LEQUAL ); glDepthFunc( GL_LEQUAL );
2015 2216 glDepthMask( GL_TRUE ); glDepthMask( GL_TRUE );
2016 2217 // Multisample textures and seamless cubemaps are not available in core GLES 3.0. // Multisample textures and seamless cubemaps are not available in core GLES 3.0.
2017 #ifdef GLAD_GL_IMPLEMENTATION
2218 #ifdef GLAD_GL
2018 2219 glEnable( GL_MULTISAMPLE ); glEnable( GL_MULTISAMPLE );
2019 2220 glEnable( GL_TEXTURE_CUBE_MAP_SEAMLESS ); glEnable( GL_TEXTURE_CUBE_MAP_SEAMLESS );
2020 2221 #endif #endif
 
... ... Display createDisplay( unsigned int width, unsigned int height, std::string titl
2140 2341 return disp; return disp;
2141 2342 } }
2142 2343
2344 void focusDisplay(){
2345 #ifdef SDL_MAJOR_VERSION
2346 SDL_HideWindow( window );
2347 SDL_ShowWindow( window );
2348 SDL_RaiseWindow( window );
2349 #endif
2350 // TODO: SFML.
2351 }
2352
2353 int getMouseX(){
2354 return mouseX;
2355 }
2356
2357 int getMouseY(){
2358 return mouseY;
2359 }
2360
2143 2361 #ifdef SDL_MAJOR_VERSION #ifdef SDL_MAJOR_VERSION
2144 2362
2145 2363 Display getDisplay(){ Display getDisplay(){
 
... ... void sync(){
2264 2482 syncEvents(); syncEvents();
2265 2483 } }
2266 2484
2267 void setTextInput( int x = 0, int y = 0, int w = 0, int h = 0 ){
2485 void setTextInput( int x, int y, int w, int h ){
2268 2486 // https://wiki.libsdl.org/Tutorials/TextInput // https://wiki.libsdl.org/Tutorials/TextInput
2269 2487 if( x || y || w || h ){ if( x || y || w || h ){
2270 2488 if( !SDL_IsTextInputActive() ) if( !SDL_IsTextInputActive() )
 
... ... int getCharacterIndex( int cp, Font &font ){
2654 2872 } }
2655 2873
2656 2874 Font loadFont( std::string fileName, float fontSize, int oversampleX, int oversampleY, Font loadFont( std::string fileName, float fontSize, int oversampleX, int oversampleY,
2657 bool prepack = true, int atlasWidth = 512, int atlasHeight = 512 ){
2875 bool prepack, int atlasWidth, int atlasHeight ){
2658 2876 Font font = newFont; Font font = newFont;
2659 2877
2660 2878 FILE* file = fopen( fileName.c_str(), "rb" ); FILE* file = fopen( fileName.c_str(), "rb" );
 
... ... float getTextWidth( std::string text, Font &font ){
2727 2945 return getTextWidthUtf32( utf8ToUtf32( text ), font ); return getTextWidthUtf32( utf8ToUtf32( text ), font );
2728 2946 } }
2729 2947
2730 void drawTextUtf32( std::u32string codepoints, Font &font, float posX, float posY, float scale, int align = 0, float wordWrap = 0.0f ){
2948 void drawTextUtf32( std::u32string codepoints, Font &font, float posX, float posY, float scale, int align, float wordWrap ){
2731 2949 // align modes -- 0: left, 1: center, 2: right // align modes -- 0: left, 1: center, 2: right
2732 2950
2733 2951 Texture &tex = font.texture; Texture &tex = font.texture;
 
... ... void drawTextUtf32( std::u32string codepoints, Font &font, float posX, float pos
2844 3062 texMatrix = oldTexMatrix; texMatrix = oldTexMatrix;
2845 3063 } }
2846 3064
2847 void drawText( std::string text, Font &font, float posX, float posY, float scale, int align = 0, float wordWrap = 0.0f ){
3065 void drawText( std::string text, Font &font, float posX, float posY, float scale, int align, float wordWrap ){
2848 3066 // align modes -- 0: left, 1: center, 2: right // align modes -- 0: left, 1: center, 2: right
2849 3067
2850 3068 if( !font.texture.success ) return; if( !font.texture.success ) return;
 
... ... int getCharacterIndex( int cp, Font &font ){
2863 3081 } }
2864 3082
2865 3083 Font loadFont( std::string fileName, float fontSize, int oversampleX, int oversampleY, Font loadFont( std::string fileName, float fontSize, int oversampleX, int oversampleY,
2866 bool prepack = true, int atlasWidth = 512, int atlasHeight = 512 ){
3084 bool prepack, int atlasWidth, int atlasHeight ){
2867 3085 _ERROUT_ << "Include stb_truetype.h before fg3.h to load TrueType fonts.\n" << std::endl; _ERROUT_ << "Include stb_truetype.h before fg3.h to load TrueType fonts.\n" << std::endl;
2868 3086 return newFont; return newFont;
2869 3087 } }
 
... ... float getTextWidth( std::string text, Font &font ){
2876 3094 return 0.0f; return 0.0f;
2877 3095 } }
2878 3096
2879 void drawTextUtf32( std::u32string codepoints, Font &font, float posX, float posY, float scale, int align = 0, float wordWrap = 0.0f ){
3097 void drawTextUtf32( std::u32string codepoints, Font &font, float posX, float posY, float scale, int align, float wordWrap ){
2880 3098 return; return;
2881 3099 } }
2882 3100
2883 void drawText( std::string text, Font &font, float posX, float posY, float scale, int align = 0, float wordWrap = 0.0f ){
3101 void drawText( std::string text, Font &font, float posX, float posY, float scale, int align, float wordWrap ){
2884 3102 return; return;
2885 3103 } }
2886 3104
2887 3105 #endif // __STB_INCLUDE_STB_TRUETYPE_H__ #endif // __STB_INCLUDE_STB_TRUETYPE_H__
2888 3106
3107 #endif // FG3_IMPLEMENTATION
3108
2889 3109 } // namespace fg3 } // namespace fg3
2890 3110
2891 3111 #endif // FG3_H #endif // FG3_H
File include/fworld.h changed (mode: 100755) (index a85836b..880c6f8)
... ... void World::drawSprite( fgl::Texture &tex, double posX, double posY, double imag
1488 1488 posX += (double)sourceW * 0.5 * imageScale; posX += (double)sourceW * 0.5 * imageScale;
1489 1489 posY += (double)sourceH * 0.5 * imageScale; posY += (double)sourceH * 0.5 * imageScale;
1490 1490 // Sorry, but this over-stretching thing is the only way to hide tile seams on low-precision OpenGL implementations. // Sorry, but this over-stretching thing is the only way to hide tile seams on low-precision OpenGL implementations.
1491 fgl::texMatrix = linalg::mul(
1491 fgl::setTextureMatrix( linalg::mul(
1492 1492 linalg::translation_matrix( linalg::vec<double,3>( linalg::translation_matrix( linalg::vec<double,3>(
1493 1493 (double)sourceX / (double)tex.width + 0.0001, (double)sourceX / (double)tex.width + 0.0001,
1494 1494 (double)sourceY / (double)tex.height + 0.0001, (double)sourceY / (double)tex.height + 0.0001,
 
... ... void World::drawSprite( fgl::Texture &tex, double posX, double posY, double imag
1499 1499 (double)sourceH / (double)tex.height * ( flipY ? -0.995 : 0.995 ), (double)sourceH / (double)tex.height * ( flipY ? -0.995 : 0.995 ),
1500 1500 1.0 1.0
1501 1501 ) ) ) )
1502 );
1502 ) );
1503 1503 linalg::mat<double,4,4> m = linalg::mul( linalg::mat<double,4,4> m = linalg::mul(
1504 1504 linalg::translation_matrix( linalg::vec<double,3>( linalg::translation_matrix( linalg::vec<double,3>(
1505 1505 posX / (double)screenHeight * 2.0 - (double)screenWidth / (double)screenHeight, posX / (double)screenHeight * 2.0 - (double)screenWidth / (double)screenHeight,
 
... ... void World::drawSprite( fgl::Texture &tex, double posX, double posY, double imag
1527 1527 //linalg::scaling_matrix( linalg::vec<double,3>( (double)screenHeight / (double)screenWidth, 1.0, 1.0 ) ) //linalg::scaling_matrix( linalg::vec<double,3>( (double)screenHeight / (double)screenWidth, 1.0, 1.0 ) )
1528 1528 linalg::perspective_matrix( 68.5 * 0.01745, (double)screenWidth / (double)screenHeight, 0.1, 44.0 ) linalg::perspective_matrix( 68.5 * 0.01745, (double)screenWidth / (double)screenHeight, 0.1, 44.0 )
1529 1529 ); );
1530 fgl::texMatrix = linalg::identity;
1530 fgl::setTextureMatrix( linalg::identity );
1531 1531 }else{ }else{
1532 1532 // Draw instanced. // Draw instanced.
1533 instanceBuf.push( fgl::fogColor, m );
1533 instanceBuf.push( fgl::fogColor, m, fgl::getTextureMatrix() );
1534 1534 } }
1535 1535 } }
1536 1536
 
... ... void World::drawMapLayer( size_t pos ){
1715 1715 // Draw and clear the instance buffer. // Draw and clear the instance buffer.
1716 1716 instanceBuf.upload(); instanceBuf.upload();
1717 1717 auto projMat = linalg::perspective_matrix( 68.5 * 0.01745, (double)screenWidth / (double)screenHeight, 0.1, 44.0 ); auto projMat = linalg::perspective_matrix( 68.5 * 0.01745, (double)screenWidth / (double)screenHeight, 0.1, 44.0 );
1718 instanceBuf.draw( fgl::planeMesh, viewMat, projMat );
1718 instanceBuf.draw( fgl::planeMesh, viewMat, projMat, fgl::getLightMatrix() );
1719 1719 instanceBuf.clear(); instanceBuf.clear();
1720 1720
1721 1721 // Set fog to its old color. // Set fog to its old color.
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/mse/ConfectionerEngine

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/mse/ConfectionerEngine

Clone this repository using git:
git clone git://git.rocketgit.com/user/mse/ConfectionerEngine

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main