int32_t ay = pv[1].y - pv[0].y;
int32_t bx = pv[2].x - pv[0].x;
int32_t by = pv[2].y - pv[0].y;
- int32_t cross_z = ax * (by >> 8) - ay * (bx >> 8);
+ int32_t cross_z = (ax >> 4) * (by >> 4) - (ay >> 4) * (bx >> 4);
int sign = (cross_z >> 31) & 1;
if(!(sign ^ st->frontface)) {
void g3d_end(void);
void g3d_vertex(float x, float y, float z);
void g3d_normal(float x, float y, float z);
-void g3d_color(float r, float g, float b);
-void g3d_color4(float r, float g, float b, float a);
+void g3d_color3b(unsigned char r, unsigned char g, unsigned char b);
+void g3d_color4b(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
+void g3d_color3f(float r, float g, float b);
+void g3d_color4f(float r, float g, float b, float a);
void g3d_texcoord(float u, float v);
#endif /* THREEDGFX_H_ */
#include "music.h"
#include "cfgopt.h"
#include "tinyfps.h"
+#include "util.h"
int fb_width = 320;
int fb_height = 240;
demo_quit();
break;
+ case 127:
+ debug_break();
+ break;
+
case '\n':
case '\r':
dptr = inp;
#include <stdio.h>
+#include <string.h>
#include <math.h>
#include "demo.h"
#include "3dgfx.h"
#include "screen.h"
#include "cfgopt.h"
+#include "polyfill.h"
+#include "imago2.h"
+#include "gfxutil.h"
static int init(void);
static void destroy(void);
static void start(long trans_time);
static void draw(void);
-static void draw_cube(void);
+static void draw_cube(float sz);
static struct screen scr = {
"infcubes",
draw
};
-static float cam_theta, cam_phi;
+static float cam_theta = -29, cam_phi = 35;
static float cam_dist = 5;
+static struct pimage tex_crate;
struct screen *infcubes_screen(void)
{
static int init(void)
{
+ int i, npixels;
+ unsigned char *src;
+ uint16_t *dst;
+
+ if(!(tex_crate.pixels = img_load_pixels("data/crate.jpg", &tex_crate.width,
+ &tex_crate.height, IMG_FMT_RGB24))) {
+ fprintf(stderr, "infcubes: failed to load crate texture\n");
+ return -1;
+ }
+
+ npixels = tex_crate.width * tex_crate.height;
+ src = (unsigned char*)tex_crate.pixels;
+ dst = tex_crate.pixels;
+ for(i=0; i<npixels; i++) {
+ int r = *src++;
+ int g = *src++;
+ int b = *src++;
+ *dst++ = PACK_RGB16(r, g, b);
+ }
return 0;
}
static void destroy(void)
{
+ img_free_pixels(tex_crate.pixels);
}
static void start(long trans_time)
g3d_load_identity();
g3d_perspective(50.0, 1.3333333, 0.5, 100.0);
- g3d_enable(G3D_LIGHTING);
+ g3d_enable(G3D_CULL_FACE);
+ g3d_disable(G3D_LIGHTING);
g3d_enable(G3D_LIGHT0);
+
+ g3d_set_texture(tex_crate.width, tex_crate.height, tex_crate.pixels);
}
static void update(void)
memset(fb_pixels, 0, fb_width * fb_height * 2);
- draw_cube();
+ g3d_polygon_mode(G3D_FLAT);
+ draw_cube(-6);
+
+ g3d_polygon_mode(G3D_TEX);
+ draw_cube(1);
swap_buffers(fb_pixels);
}
-static void draw_cube(void)
+static void draw_cube(float sz)
{
+ float hsz = sz * 0.5f;
g3d_begin(G3D_QUADS);
+ g3d_color3b(255, 0, 0);
g3d_normal(0, 0, 1);
- g3d_vertex(-1, -1, 1);
- g3d_vertex(1, -1, 1);
- g3d_vertex(1, 1, 1);
- g3d_vertex(-1, 1, 1);
+ g3d_texcoord(0, 0); g3d_vertex(-hsz, -hsz, hsz);
+ g3d_texcoord(1, 0); g3d_vertex(hsz, -hsz, hsz);
+ g3d_texcoord(1, 1); g3d_vertex(hsz, hsz, hsz);
+ g3d_texcoord(0, 1); g3d_vertex(-hsz, hsz, hsz);
+ g3d_color3b(0, 255, 0);
g3d_normal(1, 0, 0);
- g3d_vertex(1, -1, 1);
- g3d_vertex(1, -1, -1);
- g3d_vertex(1, 1, -1);
- g3d_vertex(1, 1, 1);
+ g3d_texcoord(0, 0); g3d_vertex(hsz, -hsz, hsz);
+ g3d_texcoord(1, 0); g3d_vertex(hsz, -hsz, -hsz);
+ g3d_texcoord(1, 1); g3d_vertex(hsz, hsz, -hsz);
+ g3d_texcoord(0, 1); g3d_vertex(hsz, hsz, hsz);
+ g3d_color3b(0, 0, 255);
g3d_normal(0, 0, -1);
- g3d_vertex(1, -1, -1);
- g3d_vertex(-1, -1, -1);
- g3d_vertex(-1, 1, -1);
- g3d_vertex(1, 1, -1);
+ g3d_texcoord(0, 0); g3d_vertex(hsz, -hsz, -hsz);
+ g3d_texcoord(1, 0); g3d_vertex(-hsz, -hsz, -hsz);
+ g3d_texcoord(1, 1); g3d_vertex(-hsz, hsz, -hsz);
+ g3d_texcoord(0, 1); g3d_vertex(hsz, hsz, -hsz);
+ g3d_color3b(255, 0, 255);
g3d_normal(-1, 0, 0);
- g3d_vertex(-1, -1, -1);
- g3d_vertex(-1, -1, 1);
- g3d_vertex(-1, 1, 1);
- g3d_vertex(-1, 1, -1);
+ g3d_texcoord(0, 0); g3d_vertex(-hsz, -hsz, -hsz);
+ g3d_texcoord(1, 0); g3d_vertex(-hsz, -hsz, hsz);
+ g3d_texcoord(1, 1); g3d_vertex(-hsz, hsz, hsz);
+ g3d_texcoord(0, 1); g3d_vertex(-hsz, hsz, -hsz);
+ g3d_color3b(255, 255, 0);
g3d_normal(0, 1, 0);
- g3d_vertex(-1, 1, 1);
- g3d_vertex(1, 1, 1);
- g3d_vertex(1, 1, -1);
- g3d_vertex(-1, 1, -1);
+ g3d_texcoord(0, 0); g3d_vertex(-hsz, hsz, hsz);
+ g3d_texcoord(1, 0); g3d_vertex(hsz, hsz, hsz);
+ g3d_texcoord(1, 1); g3d_vertex(hsz, hsz, -hsz);
+ g3d_texcoord(0, 1); g3d_vertex(-hsz, hsz, -hsz);
+ g3d_color3b(0, 255, 255);
g3d_normal(0, -1, 0);
- g3d_vertex(1, -1, 1);
- g3d_vertex(-1, -1, 1);
- g3d_vertex(-1, -1, -1);
- g3d_vertex(1, -1, -1);
+ g3d_texcoord(0, 0); g3d_vertex(hsz, -hsz, hsz);
+ g3d_texcoord(1, 0); g3d_vertex(-hsz, -hsz, hsz);
+ g3d_texcoord(1, 1); g3d_vertex(-hsz, -hsz, -hsz);
+ g3d_texcoord(0, 1); g3d_vertex(hsz, -hsz, -hsz);
g3d_end();
}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "mesh.h"
+#include "3dgfx.h"
+
+int load_mesh(struct g3d_mesh *mesh, const char *fname)
+{
+ return -1; /* TODO */
+}
+
+static struct {
+ struct g3d_vertex *varr;
+ const float *xform;
+} zsort_cls;
+
+static int zsort_cmp(const void *aptr, const void *bptr)
+{
+ const float *m = zsort_cls.xform;
+
+ const struct g3d_vertex *va = (const struct g3d_vertex*)aptr;
+ const struct g3d_vertex *vb = (const struct g3d_vertex*)bptr;
+
+ float za = m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14];
+ float zb = m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14];
+
+ ++va;
+ ++vb;
+
+ za += m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14];
+ zb += m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14];
+
+ return za - zb;
+}
+
+static int zsort_indexed_cmp(const void *aptr, const void *bptr)
+{
+ const int16_t *a = (const int16_t*)aptr;
+ const int16_t *b = (const int16_t*)bptr;
+
+ const float *m = zsort_cls.xform;
+
+ const struct g3d_vertex *va = zsort_cls.varr + a[0];
+ const struct g3d_vertex *vb = zsort_cls.varr + b[0];
+
+ float za = m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14];
+ float zb = m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14];
+
+ va = zsort_cls.varr + a[2];
+ vb = zsort_cls.varr + b[2];
+
+ za += m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14];
+ zb += m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14];
+
+ return za - zb;
+}
+
+
+void zsort_mesh(struct g3d_mesh *m)
+{
+ zsort_cls.varr = m->varr;
+ zsort_cls.xform = g3d_get_matrix(G3D_MODELVIEW, 0);
+
+ if(m->iarr) {
+ int nfaces = m->icount / m->prim;
+ qsort(m->iarr, nfaces, m->prim * sizeof *m->iarr, zsort_indexed_cmp);
+ } else {
+ int nfaces = m->vcount / m->prim;
+ qsort(m->varr, nfaces, m->prim * sizeof *m->varr, zsort_cmp);
+ }
+}
+
+
+void draw_mesh(struct g3d_mesh *mesh)
+{
+ if(mesh->iarr) {
+ g3d_draw_indexed(mesh->prim, mesh->varr, mesh->vcount, mesh->iarr, mesh->icount);
+ } else {
+ g3d_draw(mesh->prim, mesh->varr, mesh->vcount);
+ }
+}
+
+
+#define NORMAL(vp, x, y, z) do { vp->nx = x; vp->ny = y; vp->nz = z; } while(0)
+#define COLOR(vp, cr, cg, cb) do { vp->r = cr; vp->g = cg; vp->b = cb; } while(0)
+#define TEXCOORD(vp, tu, tv) do { vp->u = tu; vp->v = tv; } while(0)
+#define VERTEX(vp, vx, vy, vz) \
+ do { \
+ vp->x = vx; vp->y = vy; vp->z = vz; vp->w = 1.0f; \
+ ++vp; \
+ } while(0)
+
+int gen_cube(struct g3d_mesh *mesh, float sz, int sub)
+{
+ struct g3d_vertex *vptr;
+ float hsz = sz / 2.0;
+
+ mesh->prim = G3D_QUADS;
+ mesh->iarr = 0;
+ mesh->icount = 0;
+
+ mesh->vcount = 24;
+ if(!(mesh->varr = malloc(mesh->vcount * sizeof *mesh->varr))) {
+ return -1;
+ }
+ vptr = mesh->varr;
+
+ /* -Z */
+ NORMAL(vptr, 0, 0, -1);
+ COLOR(vptr, 255, 0, 255);
+ VERTEX(vptr, hsz, -hsz, -hsz);
+ VERTEX(vptr, -hsz, -hsz, -hsz);
+ VERTEX(vptr, -hsz, hsz, -hsz);
+ VERTEX(vptr, hsz, hsz, -hsz);
+ /* -Y */
+ NORMAL(vptr, 0, -1, 0);
+ COLOR(vptr, 0, 255, 255);
+ VERTEX(vptr, -hsz, -hsz, -hsz);
+ VERTEX(vptr, hsz, -hsz, -hsz);
+ VERTEX(vptr, hsz, -hsz, hsz);
+ VERTEX(vptr, -hsz, -hsz, hsz);
+ /* -X */
+ NORMAL(vptr, -1, 0, 0);
+ COLOR(vptr, 255, 255, 0);
+ VERTEX(vptr, -hsz, -hsz, -hsz);
+ VERTEX(vptr, -hsz, -hsz, hsz);
+ VERTEX(vptr, -hsz, hsz, hsz);
+ VERTEX(vptr, -hsz, hsz, -hsz);
+ /* +X */
+ NORMAL(vptr, 1, 0, 0);
+ COLOR(vptr, 255, 0, 0);
+ VERTEX(vptr, hsz, -hsz, hsz);
+ VERTEX(vptr, hsz, -hsz, -hsz);
+ VERTEX(vptr, hsz, hsz, -hsz);
+ VERTEX(vptr, hsz, hsz, hsz);
+ /* +Y */
+ NORMAL(vptr, 0, 1, 0);
+ COLOR(vptr, 0, 255, 0);
+ VERTEX(vptr, -hsz, hsz, hsz);
+ VERTEX(vptr, hsz, hsz, hsz);
+ VERTEX(vptr, hsz, hsz, -hsz);
+ VERTEX(vptr, -hsz, hsz, -hsz);
+ /* +Z */
+ NORMAL(vptr, 0, 0, 1);
+ COLOR(vptr, 0, 0, 255);
+ VERTEX(vptr, -hsz, -hsz, hsz);
+ VERTEX(vptr, hsz, -hsz, hsz);
+ VERTEX(vptr, hsz, hsz, hsz);
+ VERTEX(vptr, -hsz, hsz, hsz);
+
+ return 0;
+}
+
+static void torusvec(float *res, float theta, float phi, float mr, float rr)
+{
+ float rx, ry, rz;
+ theta = -theta;
+
+ rx = -cos(phi) * rr + mr;
+ ry = sin(phi) * rr;
+ rz = 0.0f;
+
+ res[0] = rx * sin(theta) + rz * cos(theta);
+ res[1] = ry;
+ res[2] = -rx * cos(theta) + rz * sin(theta);
+}
+
+int gen_torus(struct g3d_mesh *mesh, float rad, float ringrad, int usub, int vsub)
+{
+ int i, j;
+ int nfaces, uverts, vverts;
+ struct g3d_vertex *vptr;
+ int16_t *iptr;
+
+ mesh->prim = G3D_QUADS;
+
+ if(usub < 4) usub = 4;
+ if(vsub < 2) vsub = 2;
+
+ uverts = usub + 1;
+ vverts = vsub + 1;
+
+ mesh->vcount = uverts * vverts;
+ nfaces = usub * vsub;
+ mesh->icount = nfaces * 4;
+
+ printf("generating torus with %d faces (%d vertices)\n", nfaces, mesh->vcount);
+
+ if(!(mesh->varr = malloc(mesh->vcount * sizeof *mesh->varr))) {
+ return -1;
+ }
+ if(!(mesh->iarr = malloc(mesh->icount * sizeof *mesh->iarr))) {
+ return -1;
+ }
+ vptr = mesh->varr;
+ iptr = mesh->iarr;
+
+ for(i=0; i<uverts; i++) {
+ float u = (float)i / (float)(uverts - 1);
+ float theta = u * 2.0 * M_PI;
+ float rcent[3];
+
+ torusvec(rcent, theta, 0, rad, 0);
+
+ for(j=0; j<vverts; j++) {
+ float v = (float)j / (float)(vverts - 1);
+ float phi = v * 2.0 * M_PI;
+ int chess = (i & 1) == (j & 1);
+
+ torusvec(&vptr->x, theta, phi, rad, ringrad);
+
+ vptr->nx = (vptr->x - rcent[0]) / ringrad;
+ vptr->ny = (vptr->y - rcent[1]) / ringrad;
+ vptr->nz = (vptr->z - rcent[2]) / ringrad;
+ vptr->u = u;
+ vptr->v = v;
+ vptr->r = chess ? 255 : 64;
+ vptr->g = 128;
+ vptr->b = chess ? 64 : 255;
+ ++vptr;
+
+ if(i < usub && j < vsub) {
+ int idx = i * vverts + j;
+ *iptr++ = idx;
+ *iptr++ = idx + 1;
+ *iptr++ = idx + vverts + 1;
+ *iptr++ = idx + vverts;
+ }
+ }
+ }
+ return 0;
+}
+
--- /dev/null
+#ifndef MESH_H_
+#define MESH_H_
+
+struct g3d_mesh {
+ int prim;
+ struct g3d_vertex *varr;
+ int16_t *iarr;
+ int vcount, icount;
+};
+
+int load_mesh(struct g3d_mesh *mesh, const char *fname);
+
+void zsort_mesh(struct g3d_mesh *mesh);
+void draw_mesh(struct g3d_mesh *mesh);
+
+int gen_cube(struct g3d_mesh *mesh, float sz, int sub);
+int gen_torus(struct g3d_mesh *mesh, float rad, float ringrad, int usub, int vsub);
+
+#endif /* MESH_H_ */
#include "gfxutil.h"
#include "util.h"
#include "metasurf.h"
-
-struct mesh {
- int prim;
- struct g3d_vertex *varr;
- int16_t *iarr;
- int vcount, icount;
-};
+#include "mesh.h"
struct metaball {
float energy;
static void destroy(void);
static void start(long trans_time);
static void draw(void);
-static void draw_mesh(struct mesh *mesh);
-static void zsort(struct mesh *m);
static void calc_voxel_field(void);
static float cam_theta, cam_phi = 25;
static float cam_dist = 10;
-static struct mesh mmesh;
+static struct g3d_mesh mmesh;
static struct metasurface *msurf;
static void update(void)
{
- static int prev_mx, prev_my;
- static unsigned int prev_bmask;
+ int i, j;
+ float tsec = time_msec / 1000.0f;
+ static float phase[] = {0.0, M_PI / 3.0, M_PI * 0.8};
+ static float speed[] = {0.8, 1.4, 1.0};
+ static float scale[][3] = {{1, 2, 0.8}, {0.5, 1.6, 0.6}, {1.5, 0.7, 0.5}};
+ static float offset[][3] = {{0, 0, 0}, {0.25, 0, 0}, {-0.2, 0.15, 0.2}};
- if(mouse_bmask) {
- if((mouse_bmask ^ prev_bmask) == 0) {
- int dx = mouse_x - prev_mx;
- int dy = mouse_y - prev_my;
+ mouse_orbit_update(&cam_theta, &cam_phi, &cam_dist);
- if(dx || dy) {
- if(mouse_bmask & 1) {
- cam_theta += dx * 1.0;
- cam_phi += dy * 1.0;
+ for(i=0; i<NUM_MBALLS; i++) {
+ float t = (tsec + phase[i]) * speed[i];
- if(cam_phi < -90) cam_phi = -90;
- if(cam_phi > 90) cam_phi = 90;
- }
- if(mouse_bmask & 4) {
- cam_dist += dy * 0.5;
-
- if(cam_dist < 0) cam_dist = 0;
- }
- }
- }
- }
- prev_mx = mouse_x;
- prev_my = mouse_y;
- prev_bmask = mouse_bmask;
-
- {
- int i, j;
- float tsec = time_msec / 1000.0f;
- static float phase[] = {0.0, M_PI / 3.0, M_PI * 0.8};
- static float speed[] = {0.8, 1.4, 1.0};
- static float scale[][3] = {{1, 2, 0.8}, {0.5, 1.6, 0.6}, {1.5, 0.7, 0.5}};
- static float offset[][3] = {{0, 0, 0}, {0.25, 0, 0}, {-0.2, 0.15, 0.2}};
-
- for(i=0; i<NUM_MBALLS; i++) {
- float t = (tsec + phase[i]) * speed[i];
-
- for(j=0; j<3; j++) {
- float x = sin(t + j * M_PI / 2.0);
- mball[i].pos[j] = offset[i][j] + x * scale[i][j];
- }
+ for(j=0; j<3; j++) {
+ float x = sin(t + j * M_PI / 2.0);
+ mball[i].pos[j] = offset[i][j] + x * scale[i][j];
}
}
g3d_light_pos(0, -10, 10, 20);
- zsort(&mmesh);
+ zsort_mesh(&mmesh);
g3d_mtl_diffuse(0.6, 0.6, 0.6);
swap_buffers(fb_pixels);
}
-static void draw_mesh(struct mesh *mesh)
-{
- if(mesh->iarr) {
- g3d_draw_indexed(mesh->prim, mesh->varr, mesh->vcount, mesh->iarr, mesh->icount);
- } else {
- g3d_draw(mesh->prim, mesh->varr, mesh->vcount);
- }
-}
-
-static struct {
- struct g3d_vertex *varr;
- const float *xform;
-} zsort_cls;
-
-static int zsort_cmp(const void *aptr, const void *bptr)
-{
- const float *m = zsort_cls.xform;
-
- const struct g3d_vertex *va = (const struct g3d_vertex*)aptr;
- const struct g3d_vertex *vb = (const struct g3d_vertex*)bptr;
-
- float za = m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14];
- float zb = m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14];
-
- ++va;
- ++vb;
-
- za += m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14];
- zb += m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14];
-
- return za - zb;
-}
-
-static void zsort(struct mesh *m)
-{
- int nfaces = m->vcount / m->prim;
-
- zsort_cls.varr = m->varr;
- zsort_cls.xform = g3d_get_matrix(G3D_MODELVIEW, 0);
-
- qsort(m->varr, nfaces, m->prim * sizeof *m->varr, zsort_cmp);
-}
-
static void calc_voxel_field(void)
{
int i, j, k, b;
#include "gfxutil.h"
#include "polyfill.h" /* just for struct pimage */
#include "cfgopt.h"
-
-struct mesh {
- int prim;
- struct g3d_vertex *varr;
- int16_t *iarr;
- int vcount, icount;
-};
+#include "mesh.h"
static int init(void);
static void destroy(void);
static void start(long trans_time);
static void draw(void);
-static void draw_mesh(struct mesh *mesh);
-static int gen_cube(struct mesh *mesh, float sz);
-static int gen_torus(struct mesh *mesh, float rad, float ringrad, int usub, int vsub);
-static void zsort(struct mesh *m);
static void draw_lowres_raster(void);
static int gen_texture(struct pimage *img, int xsz, int ysz);
static float cam_theta, cam_phi = 25;
static float cam_dist = 3;
-static struct mesh cube, torus;
+static struct g3d_mesh cube, torus;
static struct pimage tex;
{
int i;
- gen_cube(&cube, 1.0);
+ gen_cube(&cube, 1.0, 0);
gen_torus(&torus, 1.0, 0.25, 24, 12);
/* scale texcoords */
for(i=0; i<torus.vcount; i++) {
static void update(void)
{
- static int prev_mx, prev_my;
- static unsigned int prev_bmask;
-
- if(mouse_bmask) {
- if((mouse_bmask ^ prev_bmask) == 0) {
- int dx = mouse_x - prev_mx;
- int dy = mouse_y - prev_my;
-
- if(dx || dy) {
- if(mouse_bmask & 1) {
- cam_theta += dx * 1.0;
- cam_phi += dy * 1.0;
-
- if(cam_phi < -90) cam_phi = -90;
- if(cam_phi > 90) cam_phi = 90;
- }
- if(mouse_bmask & 4) {
- cam_dist += dy * 0.5;
-
- if(cam_dist < 0) cam_dist = 0;
- }
- }
- }
- }
- prev_mx = mouse_x;
- prev_my = mouse_y;
- prev_bmask = mouse_bmask;
+ mouse_orbit_update(&cam_theta, &cam_phi, &cam_dist);
}
g3d_light_pos(0, -10, 10, 20);
- zsort(&torus);
+ zsort_mesh(&torus);
g3d_mtl_diffuse(0.4, 0.7, 1.0);
g3d_set_texture(tex.width, tex.height, tex.pixels);
swap_buffers(fb_pixels);
}
-static void draw_mesh(struct mesh *mesh)
-{
- if(mesh->iarr) {
- g3d_draw_indexed(mesh->prim, mesh->varr, mesh->vcount, mesh->iarr, mesh->icount);
- } else {
- g3d_draw(mesh->prim, mesh->varr, mesh->vcount);
- }
-}
-
-#define NORMAL(vp, x, y, z) do { vp->nx = x; vp->ny = y; vp->nz = z; } while(0)
-#define COLOR(vp, cr, cg, cb) do { vp->r = cr; vp->g = cg; vp->b = cb; } while(0)
-#define TEXCOORD(vp, tu, tv) do { vp->u = tu; vp->v = tv; } while(0)
-#define VERTEX(vp, vx, vy, vz) \
- do { \
- vp->x = vx; vp->y = vy; vp->z = vz; vp->w = 1.0f; \
- ++vp; \
- } while(0)
-
-static int gen_cube(struct mesh *mesh, float sz)
-{
- struct g3d_vertex *vptr;
- float hsz = sz / 2.0;
-
- mesh->prim = G3D_QUADS;
- mesh->iarr = 0;
- mesh->icount = 0;
-
- mesh->vcount = 24;
- if(!(mesh->varr = malloc(mesh->vcount * sizeof *mesh->varr))) {
- return -1;
- }
- vptr = mesh->varr;
-
- /* -Z */
- NORMAL(vptr, 0, 0, -1);
- COLOR(vptr, 255, 0, 255);
- VERTEX(vptr, hsz, -hsz, -hsz);
- VERTEX(vptr, -hsz, -hsz, -hsz);
- VERTEX(vptr, -hsz, hsz, -hsz);
- VERTEX(vptr, hsz, hsz, -hsz);
- /* -Y */
- NORMAL(vptr, 0, -1, 0);
- COLOR(vptr, 0, 255, 255);
- VERTEX(vptr, -hsz, -hsz, -hsz);
- VERTEX(vptr, hsz, -hsz, -hsz);
- VERTEX(vptr, hsz, -hsz, hsz);
- VERTEX(vptr, -hsz, -hsz, hsz);
- /* -X */
- NORMAL(vptr, -1, 0, 0);
- COLOR(vptr, 255, 255, 0);
- VERTEX(vptr, -hsz, -hsz, -hsz);
- VERTEX(vptr, -hsz, -hsz, hsz);
- VERTEX(vptr, -hsz, hsz, hsz);
- VERTEX(vptr, -hsz, hsz, -hsz);
- /* +X */
- NORMAL(vptr, 1, 0, 0);
- COLOR(vptr, 255, 0, 0);
- VERTEX(vptr, hsz, -hsz, hsz);
- VERTEX(vptr, hsz, -hsz, -hsz);
- VERTEX(vptr, hsz, hsz, -hsz);
- VERTEX(vptr, hsz, hsz, hsz);
- /* +Y */
- NORMAL(vptr, 0, 1, 0);
- COLOR(vptr, 0, 255, 0);
- VERTEX(vptr, -hsz, hsz, hsz);
- VERTEX(vptr, hsz, hsz, hsz);
- VERTEX(vptr, hsz, hsz, -hsz);
- VERTEX(vptr, -hsz, hsz, -hsz);
- /* +Z */
- NORMAL(vptr, 0, 0, 1);
- COLOR(vptr, 0, 0, 255);
- VERTEX(vptr, -hsz, -hsz, hsz);
- VERTEX(vptr, hsz, -hsz, hsz);
- VERTEX(vptr, hsz, hsz, hsz);
- VERTEX(vptr, -hsz, hsz, hsz);
-
- return 0;
-}
-
-static void torusvec(float *res, float theta, float phi, float mr, float rr)
-{
- float rx, ry, rz;
- theta = -theta;
-
- rx = -cos(phi) * rr + mr;
- ry = sin(phi) * rr;
- rz = 0.0f;
-
- res[0] = rx * sin(theta) + rz * cos(theta);
- res[1] = ry;
- res[2] = -rx * cos(theta) + rz * sin(theta);
-}
-
-static int gen_torus(struct mesh *mesh, float rad, float ringrad, int usub, int vsub)
-{
- int i, j;
- int nfaces, uverts, vverts;
- struct g3d_vertex *vptr;
- int16_t *iptr;
-
- mesh->prim = G3D_QUADS;
-
- if(usub < 4) usub = 4;
- if(vsub < 2) vsub = 2;
-
- uverts = usub + 1;
- vverts = vsub + 1;
-
- mesh->vcount = uverts * vverts;
- nfaces = usub * vsub;
- mesh->icount = nfaces * 4;
-
- printf("generating torus with %d faces (%d vertices)\n", nfaces, mesh->vcount);
-
- if(!(mesh->varr = malloc(mesh->vcount * sizeof *mesh->varr))) {
- return -1;
- }
- if(!(mesh->iarr = malloc(mesh->icount * sizeof *mesh->iarr))) {
- return -1;
- }
- vptr = mesh->varr;
- iptr = mesh->iarr;
-
- for(i=0; i<uverts; i++) {
- float u = (float)i / (float)(uverts - 1);
- float theta = u * 2.0 * M_PI;
- float rcent[3];
-
- torusvec(rcent, theta, 0, rad, 0);
-
- for(j=0; j<vverts; j++) {
- float v = (float)j / (float)(vverts - 1);
- float phi = v * 2.0 * M_PI;
- int chess = (i & 1) == (j & 1);
-
- torusvec(&vptr->x, theta, phi, rad, ringrad);
-
- vptr->nx = (vptr->x - rcent[0]) / ringrad;
- vptr->ny = (vptr->y - rcent[1]) / ringrad;
- vptr->nz = (vptr->z - rcent[2]) / ringrad;
- vptr->u = u;
- vptr->v = v;
- vptr->r = chess ? 255 : 64;
- vptr->g = 128;
- vptr->b = chess ? 64 : 255;
- ++vptr;
-
- if(i < usub && j < vsub) {
- int idx = i * vverts + j;
- *iptr++ = idx;
- *iptr++ = idx + 1;
- *iptr++ = idx + vverts + 1;
- *iptr++ = idx + vverts;
- }
- }
- }
- return 0;
-}
-
-
-static struct {
- struct g3d_vertex *varr;
- const float *xform;
-} zsort_cls;
-
-static int zsort_cmp(const void *aptr, const void *bptr)
-{
- const int16_t *a = (const int16_t*)aptr;
- const int16_t *b = (const int16_t*)bptr;
-
- const float *m = zsort_cls.xform;
-
- const struct g3d_vertex *va = zsort_cls.varr + a[0];
- const struct g3d_vertex *vb = zsort_cls.varr + b[0];
-
- float za = m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14];
- float zb = m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14];
-
- va = zsort_cls.varr + a[2];
- vb = zsort_cls.varr + b[2];
-
- za += m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14];
- zb += m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14];
-
- return za - zb;
-}
-
-static void zsort(struct mesh *m)
-{
- int nfaces = m->icount / m->prim;
-
- zsort_cls.varr = m->varr;
- zsort_cls.xform = g3d_get_matrix(G3D_MODELVIEW, 0);
-
- qsort(m->iarr, nfaces, m->prim * sizeof *m->iarr, zsort_cmp);
-}
static void draw_huge_pixel(uint16_t *dest, int dest_width, uint16_t color)
{
"sub eax, [perf_start_count]" \
"mov [perf_interval_count], eax" \
modify [eax ebx ecx edx];
+
+void debug_break(void);
+#pragma aux debug_break = "int 3";
#endif
#ifdef __GNUC__
: "=m"(perf_interval_count) \
: "m"(perf_start_count) \
: "%eax", "%ebx", "%ecx", "%edx")
+
+#define debug_break() \
+ asm volatile ("int $3")
#endif
#ifdef _MSC_VER
mov [perf_interval_count], eax \
} \
} while(0)
+
+#define debug_break() \
+ do { \
+ __asm { int 3 } \
+ } while(0)
#endif
#endif /* UTIL_H_ */