Basic 3D graphics for the MBED application-shield on-board LCD (initial/incomplete).

Dependents:   co657_lcdplay

gfx3d.h

Committer:
co657_frmb
Date:
2015-11-29
Revision:
9:db4ec6f7d8b2
Parent:
8:55ee7af49f47

File content as of revision 9:db4ec6f7d8b2:

/*
 *  gfx3d.h -- basic 3D graphics
 *  Copyright (C) 2015 Fred Barnes, University of Kent <frmb@kent.ac.uk>
 */


#ifndef __GFX3D_H
#define __GFX3D_H

#include "C12832.h"
#include "g3d_sintab.h"

/* NOTE: this assumes an ARM Cortex-M4 ish FPU, but might work elsewhere */

/* some basic types */

/** g3d_p3_t 3D single-precision point */
typedef struct {
    float x, y, z;
} g3d_p3_t;

/** g3d_2p3_t 2D integer point with original Z scaled */
typedef struct {
    int16_t x, y;
    int16_t z;
    int16_t dummy;      /* fill out to 64 bits */
} __attribute__ ((packed)) g3d_2p3_t;

#define G3D_MAX_POLY_POINTS (3)

/** g3d_poly_t 2D integer triangular polygon, original Z scaled */
typedef struct {
    g3d_2p3_t pts[G3D_MAX_POLY_POINTS];
    uint16_t tx_pts[G3D_MAX_POLY_POINTS];               /* texture co-ords are 0xYYXX */
    int32_t norm;                   /** face normal */
    uint8_t *txptr;                 /** texture pointer (null if unset) */
} g3d_poly_t;

/** g3d_edgebuf_t polygon edge-buffer */
typedef struct {
    uint8_t start[64];
    uint8_t end[64];
    uint16_t zstart[64];
    uint16_t zend[64];
    uint16_t xoff, s_end;
} g3d_edgebuf_t;

/** g3d_polyscan_t polygon scan-line type */
typedef struct {
    uint8_t scans[32][2];           /* pairs of X-start X-end for each line of the display */
    int32_t zscan[32][2];           /* similar, but with Z-depth information */
    int scan_s, scan_e;             /* scan start and end indices */
    int32_t norm;                   /* calculated normal for the polygon (back-face cull) */
} g3d_polyscan_t;

/** angle_t Type for angle (0-255 in unsigned char) */
typedef uint8_t angle_t;            /* working in a coarsely grained world: circle is 256 degrees */

/** g3d_cubepnts A set of 8 points representing a cube */
static const g3d_p3_t g3d_cubepnts[] = {{-1.0, -1.0, -1.0}, {1.0, -1.0, -1.0}, {1.0, 1.0, -1.0}, {-1.0, 1.0, -1.0},
                                        {-1.0, -1.0, 1.0}, {1.0, -1.0, 1.0}, {1.0, 1.0, 1.0}, {-1.0, 1.0, 1.0}};

/** g3d_xyfacepnts A set of 4 points representing a square in X-Y */
static const g3d_p3_t g3d_xyfacepnts[] = {{-1.0, -1.0, 0.0}, {1.0, -1.0, 0.0}, {1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0}};

/* some constants that describe the render target layout -- for the 128x32 LCD */
#define G3D_X2_SHIFT    (64)
#define G3D_Y2_SHIFT    (16)

#define G3D_ZBADD       (32.0f)
#define G3D_ZBSCALE     (256.0f)

#define G3D_Z_DEPTH_MIN (6.0f)
#define G3D_Z_DEPTH_MAX (64.0f)
#define G3D_X_SCALE_MIN (32.0f)
#define G3D_X_SCALE_MAX (512.0f)
#define G3D_Y_SCALE_MIN (32.0f)
#define G3D_Y_SCALE_MAX (512.f)

#define G3D_Z_DEPTH     (12.0f)
#define G3D_X_SCALE     (120.0f)
#define G3D_Y_SCALE     (80.0f)

extern "C" void gfx3d_set_z_depth (const float zd);

extern "C" void gfx3d_rotate_demo (const g3d_p3_t *src, g3d_p3_t *dst, const int npnts, const angle_t a);
extern "C" void gfx3d_rotate_x (const g3d_p3_t *src, g3d_p3_t *dst, const int npnts, const angle_t a);
extern "C" void gfx3d_rotate_y (const g3d_p3_t *src, g3d_p3_t *dst, const int npnts, const angle_t a);
extern "C" void gfx3d_rotate_z (const g3d_p3_t *src, g3d_p3_t *dst, const int npnts, const angle_t a);
extern "C" void gfx3d_scale (const g3d_p3_t *src, g3d_p3_t *dst, const int npnts, const g3d_p3_t scl);
extern "C" void gfx3d_translate (const g3d_p3_t *src, g3d_p3_t *dst, const int npnts, const g3d_p3_t tx);
extern "C" void gfx3d_project (const g3d_p3_t *src, g3d_2p3_t *dst, const int npnts);
extern "C" void gfx3d_cubify_points (const g3d_2p3_t *src, g3d_poly_t *dst, int *npoly, const int backfaces, const uint8_t **txptrs);
extern "C" void gfx3d_squarify_points (const g3d_2p3_t *src, g3d_poly_t *dst, int *npoly, const int backfaces);

extern "C" void gfx3d_clear_zb (void);
extern "C" void gfx3d_sort_poly (g3d_poly_t *p);

extern "C" void gfx3d_wirepoly (const g3d_poly_t *src, C12832 &lcd);
extern "C" void gfx3d_wirepoly_z (const g3d_poly_t *src, C12832 &lcd);

extern "C" void gfx3d_edgebuf_z (const g3d_poly_t *src, g3d_edgebuf_t *dst);
extern "C" void gfx3d_wireedge (const g3d_edgebuf_t *edge, C12832 &lcd);

extern "C" void gfx3d_polytxmap (const g3d_poly_t *src, C12832 &lcd);
extern "C" void gfx3d_polynormmap (const g3d_poly_t *src, C12832 &lcd);


#if 0
extern "C" void gfx3d_polyscan (const g3d_poly_t *src, g3d_polyscan_t *dst);
#endif

extern "C" void gfx3d_wirecube (const g3d_2p3_t *src, C12832 &lcd);

/* some hacky font stuff */
extern "C" int gfx3d_font04b_char_dpw (const char ch);
extern "C" void gfx3d_font04b_tx_putchar (uint8_t *txbuf, const int txwidth, int *xptr, const int y, const char ch, const bool inv);
extern "C" void gfx3d_font04b_tx_putstr (uint8_t *txbuf, const int txwidth, int *xptr, const int y, const char *str, const bool inv);
extern "C" void gfx3d_font04b_tx_putstrn (uint8_t *txbuf, const int txwidth, int *xptr, const int y, const char *str, const int slen, const bool inv);

static inline uint8_t g3d_texture_bit (const uint8_t *tx, int x, int y)
{
    return (tx[(x << 2) | (y >> 3)] & (0x01 << (y & 0x07)));
}


#endif  /* !__GFX3D_H */