List of commits:
Subject Hash Author Date (UTC)
Fix fgcLoadOBJ and update pagoda demo e77a6c778f218f906b73825aaa7d5924b0c4cd0f fluffrabbit 2024-09-18 02:06:07
Work on fgcLoadOBJ some more 3429e9a2b8fef4700ea61eede2974c532b6b4a5d fluffrabbit 2024-09-17 06:56:23
Work on fgcLoadOBJ e1d3eb6f3b0d009a30d1f2931f9d548cc8d14967 fluffrabbit 2024-09-14 06:37:16
Add fgcNormalizeVertices 7d7dfbf70275dc5cd3529e3755a2301ba06cb6fe fluffrabbit 2024-09-10 01:44:33
Draw scene color 12354112add161591f2801600ffc592faddef502 fluffrabbit 2024-07-11 22:18:26
Put framebuffer textures in an array ad44ec442db02cbb194559948d7183580b488cec fluffrabbit 2024-07-11 19:33:58
Initial commit cd1f3278f6f9a79255ba17b3b9eb0c224c8fd091 fluffrabbit 2024-07-10 17:32:30
Commit e77a6c778f218f906b73825aaa7d5924b0c4cd0f - Fix fgcLoadOBJ and update pagoda demo
Author: fluffrabbit
Author date (UTC): 2024-09-18 02:06
Committer name: fluffrabbit
Committer date (UTC): 2024-09-18 02:06
Parent(s): 3429e9a2b8fef4700ea61eede2974c532b6b4a5d
Signer:
Signing key:
Signing status: N
Tree: 0c357b8a7019b469bf7f69f4b731582f2c9ec4f4
File Lines added Lines deleted
include/fgc.h 28 42
src/cfps.c 22 7
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);
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/fluffrabbit/cfps

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

Clone this repository using git:
git clone git://git.rocketgit.com/user/fluffrabbit/cfps

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