diff options
| author | KonAki <konaki@anokonaki.org> | 2026-10-11 21:57:22 +0800 |
|---|---|---|
| committer | KonAki <konaki@anokonaki.org> | 2026-10-11 21:57:22 +0800 |
| commit | 95bd48a7b0556adab5250cae766ee9dd9c6b2cde (patch) | |
| tree | a29b83a4f436d6c58321a44977e4eb6d30f7c8d8 | |
| parent | 42630ebee76996a37f5104e6e11b860f31634dab (diff) | |
konsofren: 3D is opt-in with KONSOFREN_3D, build.sh sets it for 3d, model and sector
| -rw-r--r-- | README.md | 4 | ||||
| -rwxr-xr-x | build.sh | 5 | ||||
| -rw-r--r-- | examples/handmade.c | 1 | ||||
| -rw-r--r-- | kon/kon3d.h | 4 | ||||
| -rw-r--r-- | kon/konmodel.h | 4 | ||||
| -rw-r--r-- | kon/konsector.h | 11 | ||||
| -rw-r--r-- | kon/konsofren.h | 18 | ||||
| -rw-r--r-- | src/engine.c | 55 |
8 files changed, 78 insertions, 24 deletions
@@ -17,7 +17,7 @@ Everything is written in [c99](https://en.wikipedia.org/wiki/C99) and drawn by a The reusable stuff is single-header and lives in [kon](kon). Those are the ones you can drag into any project: - konwinlib: windows and input events -- konsofren: the software renderer, 2D and 3D +- konsofren: the software renderer, 2D always, 3D when you define `KONSOFREN_3D` (the 3d, model and sector modules do it for you) - konmath: vectors, matrices - konfont: text, built-in bitmap font or a ttf - kontime: timing and sleeping @@ -43,6 +43,8 @@ The engine modules are a `.h` and a `.c` pair, they depend on each other a bit, | ui | immediate mode ui | | debug | developer console and asset view | +The 3D part of konsofren (cameras, triangles, meshes, billboards, fog) is only compiled when a module that draws in 3D is picked, so a 2D game does not carry it. Using konsofren.h on its own, define `KONSOFREN_3D` before including it. + ### Supported Platforms: - linux @@ -110,10 +110,9 @@ case " $modules " in *" 3d "*) need tile ;; esac case " $modules " in *" model "*) need assets ;; esac case " $DEFS " in *" -DKON_MODULE_ASSETS "*) need pack ;; esac -# 2D games do not get the 3D renderer, the 3d, model and sector modules turn it on +# the 3D renderer is only compiled when a module that draws in 3D is picked case " $DEFS " in -*" -DKON_MODULE_3D "*|*" -DKON_MODULE_MODEL "*|*" -DKON_MODULE_SECTOR "*) ;; -*) DEFS="$DEFS -DKONSOFREN_NO_3D" ;; +*" -DKON_MODULE_3D "*|*" -DKON_MODULE_MODEL "*|*" -DKON_MODULE_SECTOR "*) DEFS="$DEFS -DKONSOFREN_3D" ;; esac case " $modules " in diff --git a/examples/handmade.c b/examples/handmade.c index f2f6847..61b983e 100644 --- a/examples/handmade.c +++ b/examples/handmade.c @@ -10,6 +10,7 @@ * w and s walk, a and d strafe, left and right turn, escape quits. which picture goes on which texture name is the table in textures[] */ +#define KONSOFREN_3D #define KONWINLIB_IMPLEMENTATION #define KONSOFREN_IMPLEMENTATION #define KONTIME_IMPLEMENTATION diff --git a/kon/kon3d.h b/kon/kon3d.h index 726df26..f45f985 100644 --- a/kon/kon3d.h +++ b/kon/kon3d.h @@ -29,6 +29,10 @@ #include "konprogram.h" #include "kontile.h" +#ifndef KONSOFREN_HAS_3D +#error "this needs the 3D part of konsofren, define KONSOFREN_3D before the first include of konsofren.h (build.sh does it for -m 3d, model and sector)" +#endif + /*** definition ***/ /* a first person body on a tilemap. the world is one unit per tile, y is up, yaw 0 looks up the map (towards row 0) */ diff --git a/kon/konmodel.h b/kon/konmodel.h index 8ce36c8..9120194 100644 --- a/kon/konmodel.h +++ b/kon/konmodel.h @@ -33,6 +33,10 @@ #include "konsofren.h" #include "konassets.h" +#ifndef KONSOFREN_HAS_3D +#error "this needs the 3D part of konsofren, define KONSOFREN_3D before the first include of konsofren.h (build.sh does it for -m 3d, model and sector)" +#endif + /*** definition ***/ #define KON_MODEL_MAX_BONES 128 diff --git a/kon/konsector.h b/kon/konsector.h index c7a71e3..fa65a0e 100644 --- a/kon/konsector.h +++ b/kon/konsector.h @@ -24,7 +24,8 @@ */ /* a map made of rooms: loading, saving, looking things up, building a mesh and drawing it. it needs konsofren.h and konmath.h next to it - * and nothing else, so it is copy and paste like the other single header libs. in exactly one .c file: + * and nothing else, so it is copy and paste like the other single header libs. it turns on the 3D part of konsofren, so include it + * before konsofren.h or define KONSOFREN_3D yourself. in exactly one .c file: * * #define KONSOFREN_IMPLEMENTATION (once, wherever konsofren is) * #define KONSECTOR_IMPLEMENTATION @@ -37,9 +38,17 @@ #include <stddef.h> +#ifndef KONSOFREN_3D +#define KONSOFREN_3D +#endif + #include "konmath.h" #include "konsofren.h" +#ifndef KONSOFREN_HAS_3D +#error "this needs the 3D part of konsofren, define KONSOFREN_3D before the first include of konsofren.h (build.sh does it for -m 3d, model and sector)" +#endif + /*** definition ***/ /* a map is rooms seen from above. every room (sector) is a polygon of vertices with a floor and a ceiling height, and every diff --git a/kon/konsofren.h b/kon/konsofren.h index d7f3570..4e29e56 100644 --- a/kon/konsofren.h +++ b/kon/konsofren.h @@ -26,8 +26,8 @@ #ifndef KONSOFREN_H #define KONSOFREN_H -/* define KONSOFREN_NO_3D (in every file that includes this, and where the implementation is) for a 2D game, the cameras, - triangles, meshes and billboards are left out. 3D is on by default */ +/* the 3D part (cameras, triangles, meshes, billboards, mipmaps, fog) is only there if you ask for it. define KONSOFREN_3D + before this header in every file that includes it, and in the one with the implementation. a 2D game compiles without it */ #include <stdint.h> #include <stdlib.h> @@ -77,7 +77,9 @@ typedef struct kon_display { kon_filter_t filter; } kon_display_t; -#ifndef KONSOFREN_NO_3D +#ifdef KONSOFREN_3D + +#define KONSOFREN_HAS_3D typedef enum kon_projection { KON_PROJECTION_PERSPECTIVE = 0, @@ -152,7 +154,7 @@ typedef struct kon_mesh { int triangleCount; } kon_mesh_t; -#endif /* KONSOFREN_NO_3D */ +#endif /* KONSOFREN_3D */ /*** 2D declarations ***/ @@ -208,7 +210,7 @@ void kon_presentDisplay(kon_display_t *display); /* returns 0 if the window position is on a bar, outside the game image */ int kon_windowToGame(const kon_display_t *display, int windowX, int windowY, int *gameX, int *gameY); -#ifndef KONSOFREN_NO_3D +#ifdef KONSOFREN_3D /*** 3D declarations ***/ @@ -250,7 +252,7 @@ int kon_drawBillboard(kon_framebuffer_t *fb, kon_mat4_t viewProjection, kon_vec3 /* cube from -1 to 1 with every face mapped to the whole texture */ extern const kon_mesh_t kon_cubeMesh; -#endif /* KONSOFREN_NO_3D */ +#endif /* KONSOFREN_3D */ /*** implementation ***/ @@ -996,7 +998,7 @@ int kon_windowToGame(const kon_display_t *display, int windowX, int windowY, int return 1; } -#ifndef KONSOFREN_NO_3D +#ifdef KONSOFREN_3D /*** 3D implementation ***/ @@ -1650,7 +1652,7 @@ int kon_drawBillboard(kon_framebuffer_t *fb, kon_mat4_t viewProjection, kon_vec3 return 1; } -#endif /* KONSOFREN_NO_3D */ +#endif /* KONSOFREN_3D */ #endif /* end of KONSOFREN_IMPLEMENTATION */ #endif diff --git a/src/engine.c b/src/engine.c index 1594032..362e522 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1,11 +1,17 @@ #include "konprogram.h" +/* the starting point for a game. with the 3d module (./build.sh -m 3d) it is a spinning cube, without it a square that bounces around */ + typedef struct demo { +#ifdef KONSOFREN_3D kon_camera_t camera; kon_material_t material; kon_light_t light; - float angle; int ortho; +#else + float x, y, vx, vy; +#endif + float angle; } demo_t; static int init(kon_program_t *program, void *user) @@ -13,23 +19,36 @@ static int init(kon_program_t *program, void *user) demo_t *demo = user; (void)program; +#ifdef KONSOFREN_3D demo->camera = kon_cameraDefault(); demo->camera.position = KON_VEC3(3, 3, 6); demo->material = kon_materialColor(0xFFC8C8FF); demo->light = kon_lightDefault(); +#else + demo->x = 40.0f; + demo->y = 30.0f; + demo->vx = 70.0f; + demo->vy = 50.0f; +#endif return 1; } static int event(kon_program_t *program, const kon_event_t *ev, void *user) { - demo_t *demo = user; - (void)program; - if (ev->type == KON_EVENT_KEY_DOWN && ev->key == KON_KEY_O) { - demo->ortho = !demo->ortho; - demo->camera.projection = demo->ortho ? KON_PROJECTION_ORTHOGRAPHIC : KON_PROJECTION_PERSPECTIVE; - return 1; +#ifdef KONSOFREN_3D + { + demo_t *demo = user; + + if (ev->type == KON_EVENT_KEY_DOWN && ev->key == KON_KEY_O) { + demo->ortho = !demo->ortho; + demo->camera.projection = demo->ortho ? KON_PROJECTION_ORTHOGRAPHIC : KON_PROJECTION_PERSPECTIVE; + return 1; + } } +#else + (void)ev; (void)user; +#endif return 0; } @@ -37,18 +56,32 @@ static void update(kon_program_t *program, double dt, void *user) { demo_t *demo = user; - (void)program; demo->angle += (float)dt; +#ifndef KONSOFREN_3D + demo->x += demo->vx * (float)dt; + demo->y += demo->vy * (float)dt; + if (demo->x < 0.0f || demo->x > (float)program->display->game->width - 24.0f) demo->vx = -demo->vx; + if (demo->y < 0.0f || demo->y > (float)program->display->game->height - 24.0f) demo->vy = -demo->vy; +#else + (void)program; +#endif } static void draw(kon_program_t *program, kon_framebuffer_t *game, void *user) { demo_t *demo = user; - kon_mat4_t model = kon_mat4Rotate(kon_mat4Identity(), KON_VEC3(demo->angle * 0.5f, demo->angle, 0)); - kon_mat4_t viewProjection = kon_cameraViewProjection(&demo->camera, game->width, game->height); (void)program; - kon_drawMesh(game, viewProjection, model, &kon_cubeMesh, &demo->material, &demo->light, KON_RENDER_DEFAULT); +#ifdef KONSOFREN_3D + { + kon_mat4_t model = kon_mat4Rotate(kon_mat4Identity(), KON_VEC3(demo->angle * 0.5f, demo->angle, 0)); + kon_mat4_t viewProjection = kon_cameraViewProjection(&demo->camera, game->width, game->height); + + kon_drawMesh(game, viewProjection, model, &kon_cubeMesh, &demo->material, &demo->light, KON_RENDER_DEFAULT); + } +#else + kon_fillRectangle(game, (int)demo->x, (int)demo->y, 24, 24, 0xFFF2A7C3); +#endif } int main(void) |
