File include/fgc.h changed (mode: 100644) (index bad0078..37c0681) |
... |
... |
FGCMesh fgcLoadOBJ( const char* filePath ){ |
994 |
994 |
return mesh; |
return mesh; |
995 |
995 |
} |
} |
996 |
996 |
|
|
997 |
|
size_t nverts = 0, ninds = 0, verts_capacity = 1, inds_capacity = 1; |
|
998 |
|
FGCVertex *verts = realloc( NULL, sizeof(FGCVertex) ); |
|
999 |
|
FGCIndex *inds = realloc( NULL, sizeof(FGCIndex) ); |
|
1000 |
|
|
|
1001 |
997 |
typedef struct { GLfloat x, y, z; } float3; // 12 bytes |
typedef struct { GLfloat x, y, z; } float3; // 12 bytes |
1002 |
998 |
typedef struct { GLfloat u, v; } float2; // 8 bytes |
typedef struct { GLfloat u, v; } float2; // 8 bytes |
1003 |
999 |
typedef struct { int v1, vt1, vn1, v2, vt2, vn2, v3, vt3, vn3; } obdex; // 36+ bytes |
typedef struct { int v1, vt1, vn1, v2, vt2, vn2, v3, vt3, vn3; } obdex; // 36+ bytes |
|
... |
... |
FGCMesh fgcLoadOBJ( const char* filePath ){ |
1006 |
1002 |
// This hack keeps the code simple and readable without stretchy buffers. |
// This hack keeps the code simple and readable without stretchy buffers. |
1007 |
1003 |
static const size_t array_capacity = 99999; |
static const size_t array_capacity = 99999; |
1008 |
1004 |
size_t nobj_v = 0; |
size_t nobj_v = 0; |
1009 |
|
float3 *obj_v = malloc(array_capacity); |
|
|
1005 |
|
float3 *obj_v = malloc(sizeof(float3) * array_capacity); |
1010 |
1006 |
size_t nobj_vn = 0; |
size_t nobj_vn = 0; |
1011 |
|
float3 *obj_vn = malloc(array_capacity); |
|
|
1007 |
|
float3 *obj_vn = malloc(sizeof(float3) * array_capacity); |
1012 |
1008 |
size_t nobj_vt = 0; |
size_t nobj_vt = 0; |
1013 |
|
float2 *obj_vt = malloc(array_capacity); |
|
|
1009 |
|
float2 *obj_vt = malloc(sizeof(float2) * array_capacity); |
1014 |
1010 |
size_t nobj_f = 0; |
size_t nobj_f = 0; |
1015 |
|
obdex *obj_f = malloc(array_capacity); |
|
|
1011 |
|
obdex *obj_f = malloc(sizeof(obdex) * array_capacity); |
1016 |
1012 |
|
|
1017 |
1013 |
char ln[1024]; |
char ln[1024]; |
1018 |
1014 |
|
|
|
... |
... |
FGCMesh fgcLoadOBJ( const char* filePath ){ |
1061 |
1057 |
num_numbers++; |
num_numbers++; |
1062 |
1058 |
if(*p){ |
if(*p){ |
1063 |
1059 |
fprintf(stderr, "Failed to parse OBJ. Malformed number in %s\n", filePath); |
fprintf(stderr, "Failed to parse OBJ. Malformed number in %s\n", filePath); |
1064 |
|
free(verts); |
|
1065 |
|
free(inds); |
|
1066 |
1060 |
free(obj_v); |
free(obj_v); |
1067 |
1061 |
free(obj_vn); |
free(obj_vn); |
1068 |
1062 |
free(obj_vt); |
free(obj_vt); |
|
... |
... |
FGCMesh fgcLoadOBJ( const char* filePath ){ |
1075 |
1069 |
} |
} |
1076 |
1070 |
} |
} |
1077 |
1071 |
// Append data to arrays. |
// Append data to arrays. |
1078 |
|
if( type == 1 && num_numbers >= 4 && nobj_v < array_capacity ){ |
|
|
1072 |
|
if( type == 1 && num_numbers >= 3 && nobj_v < array_capacity ){ |
1079 |
1073 |
obj_v[nobj_v] = (float3){ numbers[0], numbers[1], numbers[2] }; |
obj_v[nobj_v] = (float3){ numbers[0], numbers[1], numbers[2] }; |
1080 |
1074 |
nobj_v++; |
nobj_v++; |
1081 |
|
}else if( type == 2 && num_numbers >= 3 && nobj_vt < array_capacity ){ |
|
|
1075 |
|
}else if( type == 2 && num_numbers >= 2 && nobj_vt < array_capacity ){ |
1082 |
1076 |
// Flip the vertical texture coordinate. |
// Flip the vertical texture coordinate. |
1083 |
1077 |
obj_vt[nobj_vt] = (float2){ numbers[0], 1.0f - numbers[1] }; |
obj_vt[nobj_vt] = (float2){ numbers[0], 1.0f - numbers[1] }; |
1084 |
1078 |
nobj_vt++; |
nobj_vt++; |
1085 |
|
}else if( type == 3 && num_numbers >= 4 && nobj_vn < array_capacity ){ |
|
|
1079 |
|
}else if( type == 3 && num_numbers >= 3 && nobj_vn < array_capacity ){ |
1086 |
1080 |
obj_vn[nobj_vn] = (float3){ numbers[0], numbers[1], numbers[2] }; |
obj_vn[nobj_vn] = (float3){ numbers[0], numbers[1], numbers[2] }; |
1087 |
1081 |
nobj_vn++; |
nobj_vn++; |
1088 |
|
}else if( type == 4 && num_numbers >= 10 && nobj_f < array_capacity ){ |
|
|
1082 |
|
}else if( type == 4 && num_numbers >= 9 && nobj_f < array_capacity ){ |
1089 |
1083 |
obj_f[nobj_f] = (obdex){ |
obj_f[nobj_f] = (obdex){ |
1090 |
1084 |
(int)numbers[0], |
(int)numbers[0], |
1091 |
1085 |
(int)numbers[1], |
(int)numbers[1], |
|
... |
... |
FGCMesh fgcLoadOBJ( const char* filePath ){ |
1112 |
1106 |
printf( "Faces: %lu\n", nobj_f ); |
printf( "Faces: %lu\n", nobj_f ); |
1113 |
1107 |
} |
} |
1114 |
1108 |
|
|
1115 |
|
/* |
|
1116 |
|
// Group vertex attributes by texture coordinates. |
|
1117 |
|
std::vector<Vertex> verts( obj_vt.size() ); |
|
1118 |
|
std::vector<Index> inds; |
|
1119 |
|
|
|
1120 |
|
for( obdex f : obj_f ){ |
|
1121 |
|
Index a = f.vt1 - 1, b = f.vt2 - 1, c = f.vt3 - 1; |
|
1122 |
|
verts[ a ] = { |
|
1123 |
|
{ obj_v[ f.v1 - 1 ].x, obj_v[ f.v1 - 1 ].y, obj_v[ f.v1 - 1 ].z }, |
|
1124 |
|
{ obj_vn[ f.vn1 - 1 ].x, obj_vn[ f.vn1 - 1 ].y, obj_vn[ f.vn1 - 1 ].z }, |
|
1125 |
|
{ 0.0f, 0.0f, 0.0f }, |
|
1126 |
|
{ obj_vt[ a ].u, obj_vt[ a ].v } |
|
1127 |
|
}; |
|
1128 |
|
verts[ b ] = { |
|
1129 |
|
{ obj_v[ f.v2 - 1 ].x, obj_v[ f.v2 - 1 ].y, obj_v[ f.v2 - 1 ].z }, |
|
1130 |
|
{ obj_vn[ f.vn2 - 1 ].x, obj_vn[ f.vn2 - 1 ].y, obj_vn[ f.vn2 - 1 ].z }, |
|
1131 |
|
{ 0.0f, 0.0f, 0.0f }, |
|
1132 |
|
{ obj_vt[ b ].u, obj_vt[ b ].v } |
|
1133 |
|
}; |
|
1134 |
|
verts[ c ] = { |
|
1135 |
|
{ obj_v[ f.v3 - 1 ].x, obj_v[ f.v3 - 1 ].y, obj_v[ f.v3 - 1 ].z }, |
|
1136 |
|
{ obj_vn[ f.vn3 - 1 ].x, obj_vn[ f.vn3 - 1 ].y, obj_vn[ f.vn3 - 1 ].z }, |
|
1137 |
|
{ 0.0f, 0.0f, 0.0f }, |
|
1138 |
|
{ obj_vt[ c ].u, obj_vt[ c ].v } |
|
1139 |
|
}; |
|
1140 |
|
Index i[3] = { a, b, c }; |
|
1141 |
|
inds.insert( std::end( inds ), std::begin( i ), std::end( i ) ); |
|
|
1109 |
|
// Create a vertex for each index. Inefficient but effective. |
|
1110 |
|
size_t nverts = nobj_f * 3, ninds = nobj_f * 3; |
|
1111 |
|
FGCVertex *verts = malloc(sizeof(FGCVertex) * nverts); |
|
1112 |
|
FGCIndex *inds = malloc(sizeof(FGCIndex) * ninds); |
|
1113 |
|
FGCIndex idx = 0; |
|
1114 |
|
for( size_t h = 0; h < nobj_f; h++ ){ |
|
1115 |
|
obdex f = obj_f[h]; |
|
1116 |
|
for( int i = 0; i < 3; i++ ){ |
|
1117 |
|
int v = ((int*)&f)[i * 3] - 1; |
|
1118 |
|
int vt = ((int*)&f)[i * 3 + 1] - 1; |
|
1119 |
|
int vn = ((int*)&f)[i * 3 + 2] - 1; |
|
1120 |
|
verts[idx] = (FGCVertex){ |
|
1121 |
|
{obj_v[v].x, obj_v[v].y, obj_v[v].z}, |
|
1122 |
|
{obj_vn[vn].x, obj_vn[vn].y, obj_vn[vn].z}, |
|
1123 |
|
{obj_vt[vt].u, obj_vt[vt].v} |
|
1124 |
|
}; |
|
1125 |
|
inds[idx] = idx; |
|
1126 |
|
idx++; |
|
1127 |
|
} |
1142 |
1128 |
} |
} |
1143 |
|
*/ |
|
|
1129 |
|
|
1144 |
1130 |
free(obj_v); |
free(obj_v); |
1145 |
1131 |
free(obj_vn); |
free(obj_vn); |
1146 |
1132 |
free(obj_vt); |
free(obj_vt); |
File src/cfps.c changed (mode: 100644) (index c46d082..18516b0) |
6 |
6 |
#define ZONE_DATA FGCColor backFog, backSky, foreFog, foreSky; |
#define ZONE_DATA FGCColor backFog, backSky, foreFog, foreSky; |
7 |
7 |
#include <zone.h> |
#include <zone.h> |
8 |
8 |
|
|
9 |
|
FGCTexture tex_cyan, tex_paused, tex_wall; |
|
|
9 |
|
FGCMesh mesh_pagoda; |
|
10 |
|
|
|
11 |
|
FGCTexture tex_cyan, tex_paused, tex_wall, tex_pagoda; |
10 |
12 |
|
|
11 |
13 |
mat4 viewMat, projMat; |
mat4 viewMat, projMat; |
12 |
14 |
|
|
13 |
15 |
double cameraAngleX = 0.0, cameraAngleY = 0.0; |
double cameraAngleX = 0.0, cameraAngleY = 0.0; |
14 |
|
vec3 cameraPosition = {0.0, 1.5, 3.0}; |
|
|
16 |
|
vec3 cameraPosition = {0.0, 1.5, 14.5}; |
15 |
17 |
|
|
16 |
18 |
double meshAngle = 0.0; |
double meshAngle = 0.0; |
17 |
19 |
|
|
|
... |
... |
const char* skyLitFrag = |
72 |
74 |
"void main(){ \n" |
"void main(){ \n" |
73 |
75 |
" vec4 baseColor = texture(u_texture, v_UV); \n" |
" vec4 baseColor = texture(u_texture, v_UV); \n" |
74 |
76 |
" if(baseColor.a < 0.001) discard; \n" |
" if(baseColor.a < 0.001) discard; \n" |
75 |
|
" float rough = 0.4; \n" |
|
|
77 |
|
" float rough = 0.5; \n" |
76 |
78 |
" vec3 N = normalize(v_Normal); \n" |
" vec3 N = normalize(v_Normal); \n" |
77 |
79 |
" vec3 V = normalize(u_camera - v_Position); \n" |
" vec3 V = normalize(u_camera - v_Position); \n" |
78 |
80 |
" vec3 R = reflect(-V, N); \n" |
" vec3 R = reflect(-V, N); \n" |
|
... |
... |
void Render(double d){ |
294 |
296 |
// Draw opaque. |
// Draw opaque. |
295 |
297 |
glDisable(GL_BLEND); |
glDisable(GL_BLEND); |
296 |
298 |
|
|
|
299 |
|
// Draw pagoda. |
|
300 |
|
glDisable(GL_CULL_FACE); |
|
301 |
|
fgcSetTexture(tex_pagoda, 0); |
|
302 |
|
mat4 objMat = mat4SetScaleXYZ(VEC3(6.0, 6.0, 6.0)); |
|
303 |
|
fgcDrawMesh(&mesh_pagoda, objMat, viewMat, projMat); |
|
304 |
|
|
|
305 |
|
// Draw spinning cube and floor. |
|
306 |
|
glEnable(GL_CULL_FACE); |
297 |
307 |
fgcSetTexture(tex_wall, 0); |
fgcSetTexture(tex_wall, 0); |
298 |
|
mat4 cubemat = mat4Translate( |
|
|
308 |
|
objMat = mat4Translate( |
299 |
309 |
mat4SetRotationQuaternion(fgcEulerToQuat(0.67, meshAngle, 0.67)), |
mat4SetRotationQuaternion(fgcEulerToQuat(0.67, meshAngle, 0.67)), |
300 |
310 |
VEC3(0.0, 0.9, 0.0)); |
VEC3(0.0, 0.9, 0.0)); |
301 |
|
fgcDrawMesh(&fgcCubeMesh, cubemat, viewMat, projMat); |
|
|
311 |
|
fgcDrawMesh(&fgcCubeMesh, objMat, viewMat, projMat); |
302 |
312 |
fgcTexMatrix = mat4SetScaleXYZ(VEC3(16.0, 16.0, 16.0)); |
fgcTexMatrix = mat4SetScaleXYZ(VEC3(16.0, 16.0, 16.0)); |
303 |
313 |
fgcDrawMesh(&fgcPlaneMesh, mat4Scale(mat4SetRotationX(-1.570796), 32.0), viewMat, projMat); |
fgcDrawMesh(&fgcPlaneMesh, mat4Scale(mat4SetRotationX(-1.570796), 32.0), viewMat, projMat); |
304 |
314 |
fgcTexMatrix = MAT4_IDEN; |
fgcTexMatrix = MAT4_IDEN; |
|
... |
... |
int main(){ |
332 |
342 |
printf("Built with glibc %d.%d\n", __GLIBC__, __GLIBC_MINOR__); |
printf("Built with glibc %d.%d\n", __GLIBC__, __GLIBC_MINOR__); |
333 |
343 |
#endif |
#endif |
334 |
344 |
|
|
|
345 |
|
fgcVerbose = true; |
|
346 |
|
|
335 |
347 |
FGCDisplayInfo disp = fgcCreateDisplay(1024, 576, "cfps", 0, false, true); |
FGCDisplayInfo disp = fgcCreateDisplay(1024, 576, "cfps", 0, false, true); |
336 |
348 |
if(!disp.success) return 0; |
if(!disp.success) return 0; |
337 |
349 |
|
|
|
... |
... |
int main(){ |
356 |
368 |
// Create the gbuffer. |
// Create the gbuffer. |
357 |
369 |
gbuffer = fgcCreateFramebuffer(fgcGetDisplayWidth(), fgcGetDisplayHeight(), false, GL_RGB, 0); |
gbuffer = fgcCreateFramebuffer(fgcGetDisplayWidth(), fgcGetDisplayHeight(), false, GL_RGB, 0); |
358 |
370 |
|
|
|
371 |
|
mesh_pagoda = fgcLoadOBJ("base/pagoda.obj"); |
|
372 |
|
|
359 |
373 |
tex_cyan = fgcLoadSolidColorTexture((FGCColor){0.0, 1.0, 1.0, 1.0}); |
tex_cyan = fgcLoadSolidColorTexture((FGCColor){0.0, 1.0, 1.0, 1.0}); |
360 |
374 |
tex_paused = fgcLoadTexture("base/paused.png", true, true); |
tex_paused = fgcLoadTexture("base/paused.png", true, true); |
361 |
375 |
tex_wall = fgcLoadTexture("base/wall.png", true, true); |
tex_wall = fgcLoadTexture("base/wall.png", true, true); |
|
376 |
|
tex_pagoda = fgcLoadTexture("base/pagoda.png", true, true); |
362 |
377 |
|
|
363 |
378 |
// Create the lowest-priority zone with +/- 100km extents. |
// Create the lowest-priority zone with +/- 100km extents. |
364 |
379 |
ZoneAdd((Zone){(FGCColor){0.0, 0.2, 0.35, 0.05}, |
ZoneAdd((Zone){(FGCColor){0.0, 0.2, 0.35, 0.05}, |
|
... |
... |
int main(){ |
370 |
385 |
// Create an interior zone. |
// Create an interior zone. |
371 |
386 |
ZoneAdd((Zone){(FGCColor){0.0, 0.2, 0.35, 0.05}, |
ZoneAdd((Zone){(FGCColor){0.0, 0.2, 0.35, 0.05}, |
372 |
387 |
(FGCColor){0.1, 0.1, 0.0, 1.0}, |
(FGCColor){0.1, 0.1, 0.0, 1.0}, |
373 |
|
(FGCColor){0.0, 0.2, 0.35, 0.05}, |
|
374 |
|
(FGCColor){0.0, 0.0, 0.0, 1.0}, -2.0, 2.0, 0.0, 3.0, -2.0, 2.0, |
|
|
388 |
|
(FGCColor){0.1, 0.2, 0.25, 0.05}, |
|
389 |
|
(FGCColor){0.0, 0.0, 0.0, 1.0}, -5.8, 5.8, 0.0, 3.0, -5.8, 5.8, |
375 |
390 |
1, NULL, NULL}); |
1, NULL, NULL}); |
376 |
391 |
|
|
377 |
392 |
PauseGame(false); |
PauseGame(false); |