Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

M3DE (Micro-3D Engine)

Assembly C C++ DOS

M3DE test scene  M3DE demo scene  M3DE shaded blocks demo

M3DE rendered 3D object  M3DE shaded blocks render  M3DE rendered 3D object

M3DE rendered 3D object  M3DE rendered 3D object  M3DE demo render


A 3D graphics engine for writing mode-13h demos for DOS, with elements written in C++, C, and x86 assembly language back in the 90s. Built on top of the GFX-13 VGA Mode 13h 2D graphics library (v2, C with inline assembly).

📑 Table of Contents

✨ Features

  • Procedural 3D object generation (box, icosphere, geosphere, hemisphere, cylinder, cone, tube, torus, lamina).
  • Per-face flat shading with omnidirectional and spot lighting.
  • Backface culling and painter's algorithm depth sorting.
  • Object, camera, and light transformations.
  • Double-buffered rendering with VGA vertical retrace sync.

🔌 API

// Initialization and cleanup

void InitWorld         ( WORLD  far *world );
void InitObject        ( OBJECT far *object );
void InitFace          ( FACE   far *face );
void InitLight         ( LIGHT  far *light );
void InitCamera        ( CAMERA far *camera );
void InitDepthBuffer   ( WORLD  far *world );

void DestroyFace       ( FACE   far *face );
void DestroyObject     ( OBJECT far *object );
void DestroyWorld      ( WORLD  far *world );

// World construction

void SetNumberObjects  ( int n, WORLD  far *world );
void SetNumberFaces    ( int n, OBJECT far *object );
void SetNumberVertices ( int n, FACE   far *face );
void SetNumberLights   ( int n, WORLD  far *world );
void SetNumberCameras  ( int n, WORLD  far *world );

// Object manipulation

void SetObjectColor        ( int          color,           OBJECT *object );
void SetObjectConstruction ( CONSTRUCTION construction,    OBJECT *object );
void SetObjectShading      ( BOOLEAN      shading_enabled, OBJECT *object );
void FlipNormals           ( OBJECT      *object );

// Object generation

int GenerateBox              ( CALC width, CALC width_grid, CALC height, CALC height_grid, CALC length, CALC length_grid, OBJECT far *object );
int GenerateCone             ( CALC height, CALC radius, int sides, int segments, OBJECT far *object );
int GenerateCylinder         ( CALC height, CALC radius, int sides, int segments, OBJECT far *object );
int GenerateIcosphere        ( CALC radius, int frequency, OBJECT far *object );
int GenerateGeosphere        ( CALC radius, int equatorial_sides, OBJECT far *object );
int GenerateHemisphere       ( CALC radius, int equatorial_sides, OBJECT far *object );
int GenerateTorus            ( CALC inner_radius, CALC outer_radius, int segments, int circle_sides, OBJECT far *object );
int GenerateTube             ( CALC height, CALC inner_radius, CALC outer_radius, int sides, int segments, OBJECT far *object );
int GenerateSquareLamina     ( VECTOR a, VECTOR b, VECTOR c, VECTOR d, int grid1, int grid2, OBJECT far *object );
int GenerateTriangularLamina ( VECTOR a, VECTOR b, VECTOR c, OBJECT far *object );
int GeneratePolygonalLamina  ( CALC radius, int segments, OBJECT far *object );
int GenerateLine             ( VECTOR a, VECTOR b, int segments, OBJECT far *object );
int GeneratePoint            ( VECTOR a, OBJECT far *object );

// Transformation pipeline

VECTOR ObjectTranslation ( VECTOR c, OBJECT object );
VECTOR CameraTranslation ( VECTOR c, WORLD world );
VERTEX ScreenTranslation ( VECTOR c, WORLD world );
CALC   LightTranslation  ( VECTOR n1, VECTOR n2, VECTOR c, OBJECT object, WORLD world );

void TranslateWorld    ( WORLD far *world );
void DisplayWorld      ( WORLD world, unsigned int screen );

// Mathematical utilities

VECTOR GetVector       ( VECTOR a, VECTOR b );
CALC   GetMagnitude    ( VECTOR v );
CALC   GetDistance     ( VECTOR a, VECTOR b );
VECTOR GetNormal       ( VECTOR a, VECTOR b, VECTOR c );
CALC   GetVectorAngle  ( VECTOR u, VECTOR v );
VECTOR GetCenter       ( VECTOR *v, int n );
CALC   GetVisibility   ( VECTOR n1, VECTOR p, WORLD world );

🚀 Usage

#include "GFX13.H"
#include "M3DE.H"

#define VGA 0xA000

int main ( void )
{
    // Set VGA Mode 13h (320x200, 256 colors)

    SetMode13   ();
    SetClipping ( 0, 0, 319, 199 );

    // Create and configure the 3D world

    WORLD world;

    InitWorld ( &world );

    world.first_color  = 0;
    world.color_length = 32;
    world.xr           = 320;
    world.yr           = 200;
    world.xd           = 160;
    world.yd           = 100;
    world.scale        = 100.0;
    world.xa           = 100.0;
    world.ya           = 100.0;

    // Create an icosphere

    SetNumberObjects ( 1, &world );
    OBJECT far *object = &( world.object [ 0 ] );

    GenerateIcosphere     ( 1.0, 3, object );
    SetObjectColor        ( 2, object );
    SetObjectShading      ( TRUE, object );
    SetObjectConstruction ( SOLID, object );

    object->backface_culling_enabled = TRUE;
    object->visible = TRUE;
    object->yd      = 2.0;

    // Add a light and a camera

    SetNumberLights  ( 1, &world );
    InitLight        ( &world.light [ 0 ] );
    world.light [ 0 ].source.x   = -4.0;
    world.light [ 0 ].source.y   = -2.0;
    world.light [ 0 ].source.z   =  4.0;
    world.light [ 0 ].light_type =  OMNI;
    world.light [ 0 ].enabled    =  TRUE;

    SetNumberCameras ( 1, &world );
    InitCamera       ( &world.camera [ 0 ] );
    world.camera [ 0 ].f = 2.0;
    world.active_camera  = 0;

    InitDepthBuffer ( &world );

    // Render

    TranslateWorld ( &world );
    DisplayWorld   ( world, VGA );

    getch       ();
    DestroyWorld ( &world );
    SetTextMode  ( 25 );

    return 0;
}

🔨 Build

Requires DOSBox (or real DOS) with Borland Turbo C++ 3.1 (BCC) on PATH. Run from the test/ directory. Two build scripts are provided, one for each version of GFX-13.

Build with GFX-13 v2 (recommended)

buildv2

Compiles GFX13/v2/gfx13.c (C with inline assembly, -2 for 80186+ instructions), M3DE/m3de.cpp and test/test.cpp (C++ via BCC), all with the large memory model (-ml), then links them into TEST.EXE.

Build with GFX-13 v1

buildv1

Assembles GFX13/v1/gfx13.asm (pure assembly via TASM), compiles M3DE/m3de.cpp and test/test.cpp (C++ via BCC), all with the large memory model (-ml), then links them into TEST.EXE. Requires Borland Turbo Assembler (TASM) on PATH.

Clean

buildv1 clean
buildv2 clean

Removes build artifacts (.OBJ, .EXE, .LOG) from the test/ directory.

🎮 Test Program

The included test program (test.cpp) is an interactive 3D shape gallery that renders each object type with real-time rotation, lighting, and color cycling.

Controls

Key Action
Esc Quit
O Cycle to next object
Shift+O Cycle to previous object
C Cycle object color
+ / - Adjust background brightness
Arrow keys Move object (X / Z axis)
Shift + Up/Down Move object along Y axis (depth)

Objects

# Object
0 Box
1 Icosphere
2 Geosphere
3 Hemisphere
4 Cylinder
5 Cone
6 Tube
7 Torus

📁 Repository Structure

m3de/
├── GFX13/
│   ├── v1/
│   │   ├── gfx13.asm       GFX-13 v1 (pure assembly, TASM) — reference only
│   │   └── gfx13.h         GFX-13 v1 header
│   └── v2/
│       ├── gfx13.c         GFX-13 v2 (C with inline assembly) — used for building
│       └── gfx13.h         GFX-13 v2 header
├── M3DE/
│   ├── m3de.h              M3DE header (3D engine structs and functions)
│   └── m3de.cpp            M3DE implementation
├── test/
│   ├── test.cpp            Interactive 3D shape gallery
│   ├── buildv1.bat         Build script using GFX-13 v1 (TASM + BCC 3.1)
│   ├── buildv2.bat         Build script using GFX-13 v2 (BCC 3.1)
│   └── clean.bat           Clean build artifacts
├── demo/                   Pre-built demo (DEMO1.EXE + assets)
└── images/capture/         DOSBox screenshots

🔬 Technical Details

  • Target: 80186+ real mode, large memory model (far pointers, farmalloc)
  • Resolution: 320x200, 256 colors (VGA Mode 13h)
  • Rendering: Painter's algorithm with per-face depth sorting (qsort)
  • Shading: Per-face flat shading via face-normal-to-light-vector dot product
  • Lighting: Omnidirectional and spot light types
  • Normals: Cross-product surface normals with flip_normal flag for inner faces (tubes, tori)
  • Geometry: Procedural generation — all meshes are computed at runtime, no external model files
  • Double buffering: Off-screen allocmem buffer, copied to VGA on vertical retrace
  • Timer: Sub-tick precision via BIOS tick counter + 8254 PIT channel 0 (frame-rate-independent animation)

📄 License

Released under the MIT License — Copyright © 1991 Rohin Gosling.