# HG changeset patch # User John Tsiombikas # Date 1321863369 -7200 # Node ID 0e781cc431780fea4380e22236e4603126232986 # Parent 8c9a63a902d5422920f7c5d742d8b14ebb9a313d adding textures diff -r 8c9a63a902d5 -r 0e781cc43178 Makefile --- a/Makefile Mon Nov 21 10:15:37 2011 +0200 +++ b/Makefile Mon Nov 21 10:16:09 2011 +0200 @@ -1,6 +1,6 @@ obj = src/test.o \ src/mingl.o src/mglrast.o src/mglgen.o \ - src/palman.o \ + src/texture.o src/palman.o \ dosemu/dosemu.o dep = $(obj:.o=.d) bin = test diff -r 8c9a63a902d5 -r 0e781cc43178 Makefile.bcc --- a/Makefile.bcc Mon Nov 21 10:15:37 2011 +0200 +++ b/Makefile.bcc Mon Nov 21 10:16:09 2011 +0200 @@ -2,7 +2,7 @@ obj = src\test.obj src\vga.obj src\timer.obj src\mouse.obj \ src\mingl.obj src\mglrast.obj src\mglgen.obj \ - src\palman.obj + src\texture.obj src\palman.obj bin = dos3d.exe CC = bcc diff -r 8c9a63a902d5 -r 0e781cc43178 src/mglgen.c --- a/src/mglgen.c Mon Nov 21 10:15:37 2011 +0200 +++ b/src/mglgen.c Mon Nov 21 10:16:09 2011 +0200 @@ -27,40 +27,40 @@ mgl_begin(MGL_QUADS); /* front */ mgl_normal(0, 0, 1); - mgl_vertex3f(-hsz, hsz, hsz); - mgl_vertex3f(-hsz, -hsz, hsz); - mgl_vertex3f(hsz, -hsz, hsz); - mgl_vertex3f(hsz, hsz, hsz); + mgl_texcoord2f(0, 1); mgl_vertex3f(-hsz, hsz, hsz); + mgl_texcoord2f(0, 0); mgl_vertex3f(-hsz, -hsz, hsz); + mgl_texcoord2f(1, 0); mgl_vertex3f(hsz, -hsz, hsz); + mgl_texcoord2f(1, 1); mgl_vertex3f(hsz, hsz, hsz); /* back */ mgl_normal(0, 0, -1); - mgl_vertex3f(hsz, hsz, -hsz); - mgl_vertex3f(hsz, -hsz, -hsz); - mgl_vertex3f(-hsz, -hsz, -hsz); - mgl_vertex3f(-hsz, hsz, -hsz); + mgl_texcoord2f(0, 1); mgl_vertex3f(hsz, hsz, -hsz); + mgl_texcoord2f(0, 0); mgl_vertex3f(hsz, -hsz, -hsz); + mgl_texcoord2f(1, 0); mgl_vertex3f(-hsz, -hsz, -hsz); + mgl_texcoord2f(1, 1); mgl_vertex3f(-hsz, hsz, -hsz); /* right */ mgl_normal(1, 0, 0); - mgl_vertex3f(hsz, hsz, hsz); - mgl_vertex3f(hsz, -hsz, hsz); - mgl_vertex3f(hsz, -hsz, -hsz); - mgl_vertex3f(hsz, hsz, -hsz); + mgl_texcoord2f(0, 1); mgl_vertex3f(hsz, hsz, hsz); + mgl_texcoord2f(0, 0); mgl_vertex3f(hsz, -hsz, hsz); + mgl_texcoord2f(1, 0); mgl_vertex3f(hsz, -hsz, -hsz); + mgl_texcoord2f(1, 1); mgl_vertex3f(hsz, hsz, -hsz); /* left */ mgl_normal(-1, 0, 0); - mgl_vertex3f(-hsz, hsz, -hsz); - mgl_vertex3f(-hsz, -hsz, -hsz); - mgl_vertex3f(-hsz, -hsz, hsz); - mgl_vertex3f(-hsz, hsz, hsz); + mgl_texcoord2f(0, 1); mgl_vertex3f(-hsz, hsz, -hsz); + mgl_texcoord2f(0, 0); mgl_vertex3f(-hsz, -hsz, -hsz); + mgl_texcoord2f(1, 0); mgl_vertex3f(-hsz, -hsz, hsz); + mgl_texcoord2f(1, 1); mgl_vertex3f(-hsz, hsz, hsz); /* top */ mgl_normal(0, 1, 0); - mgl_vertex3f(-hsz, hsz, -hsz); - mgl_vertex3f(-hsz, hsz, hsz); - mgl_vertex3f(hsz, hsz, hsz); - mgl_vertex3f(hsz, hsz, -hsz); + mgl_texcoord2f(0, 1); mgl_vertex3f(-hsz, hsz, -hsz); + mgl_texcoord2f(0, 0); mgl_vertex3f(-hsz, hsz, hsz); + mgl_texcoord2f(1, 0); mgl_vertex3f(hsz, hsz, hsz); + mgl_texcoord2f(1, 1); mgl_vertex3f(hsz, hsz, -hsz); /* bottom */ mgl_normal(0, -1, 0); - mgl_vertex3f(hsz, -hsz, -hsz); - mgl_vertex3f(hsz, -hsz, hsz); - mgl_vertex3f(-hsz, -hsz, hsz); - mgl_vertex3f(-hsz, -hsz, -hsz); + mgl_texcoord2f(0, 1); mgl_vertex3f(hsz, -hsz, -hsz); + mgl_texcoord2f(0, 0); mgl_vertex3f(hsz, -hsz, hsz); + mgl_texcoord2f(1, 0); mgl_vertex3f(-hsz, -hsz, hsz); + mgl_texcoord2f(1, 1); mgl_vertex3f(-hsz, -hsz, -hsz); mgl_end(); } diff -r 8c9a63a902d5 -r 0e781cc43178 src/mglimpl.h --- a/src/mglimpl.h Mon Nov 21 10:15:37 2011 +0200 +++ b/src/mglimpl.h Mon Nov 21 10:16:09 2011 +0200 @@ -45,6 +45,13 @@ int cidx; }; +struct texture { + int width, height; + int xshift, yshift; + unsigned int xmask, ymask; + unsigned char *pixels; +}; + struct state { unsigned int flags; int ord, frontface, cullface; @@ -57,6 +64,8 @@ int col_range; /* color interpolation range */ vec3_t ldir[MAX_LIGHTS]; float lint[MAX_LIGHTS]; + + struct texture tex; }; struct framebuffer { @@ -65,6 +74,7 @@ unsigned short **zbuf; /* zbuffer broken in 64k tiles */ }; + int mgl_rast_init(struct state *state, struct framebuffer *fbuf); void mgl_rast_cleanup(void); void mgl_rast_prepare(void); diff -r 8c9a63a902d5 -r 0e781cc43178 src/mglrast.c --- a/src/mglrast.c Mon Nov 21 10:15:37 2011 +0200 +++ b/src/mglrast.c Mon Nov 21 10:16:09 2011 +0200 @@ -32,6 +32,7 @@ #define SCAN_LINE scan_line_flat #undef INTERP_DEPTH #undef INTERP_ENERGY +#undef INTERP_TEX #include "scantmpl.h" #undef SCAN_EDGE #undef SCAN_LINE @@ -40,6 +41,7 @@ #define SCAN_LINE scan_line_z #define INTERP_DEPTH #undef INTERP_ENERGY +#undef INTERP_TEX #include "scantmpl.h" #undef SCAN_EDGE #undef SCAN_LINE @@ -48,6 +50,7 @@ #define SCAN_LINE scan_line_e #undef INTERP_DEPTH #define INTERP_ENERGY +#undef INTERP_TEX #include "scantmpl.h" #undef SCAN_EDGE #undef SCAN_LINE @@ -56,10 +59,48 @@ #define SCAN_LINE scan_line_ze #define INTERP_DEPTH #define INTERP_ENERGY +#undef INTERP_TEX #include "scantmpl.h" #undef SCAN_EDGE #undef SCAN_LINE +#define SCAN_EDGE scan_edge_t +#define SCAN_LINE scan_line_t +#undef INTERP_DEPTH +#undef INTERP_ENERGY +#define INTERP_TEX +#include "scantmpl.h" +#undef SCAN_EDGE +#undef SCAN_LINE + +#define SCAN_EDGE scan_edge_zt +#define SCAN_LINE scan_line_zt +#define INTERP_DEPTH +#undef INTERP_ENERGY +#define INTERP_TEX +#include "scantmpl.h" +#undef SCAN_EDGE +#undef SCAN_LINE + +#define SCAN_EDGE scan_edge_et +#define SCAN_LINE scan_line_et +#undef INTERP_DEPTH +#define INTERP_ENERGY +#define INTERP_TEX +#include "scantmpl.h" +#undef SCAN_EDGE +#undef SCAN_LINE + +#define SCAN_EDGE scan_edge_zet +#define SCAN_LINE scan_line_zet +#define INTERP_DEPTH +#define INTERP_ENERGY +#define INTERP_TEX +#include "scantmpl.h" +#undef SCAN_EDGE +#undef SCAN_LINE + + static void (*scan_edge)(struct vertex*, struct vertex*); static void (*scan_line)(int, unsigned char*); @@ -91,19 +132,32 @@ void mgl_rast_prepare(void) { static void (*sedge[])(struct vertex*, struct vertex*) = { - scan_edge_flat, /* 00 */ - scan_edge_z, /* 01 */ - scan_edge_e, /* 10 */ - scan_edge_ze /* 11 */ + /* tez */ + scan_edge_flat, /* 000 */ + scan_edge_z, /* 001 */ + scan_edge_e, /* 010 */ + scan_edge_ze, /* 011 */ + scan_edge_t, /* 100 */ + scan_edge_zt, /* 101 */ + scan_edge_et, /* 110 */ + scan_edge_zet /* 111 */ }; static void (*sline[])(int, unsigned char*) = { - scan_line_flat, /* 00 */ - scan_line_z, /* 01 */ - scan_line_e, /* 10 */ - scan_line_ze /* 11 */ + /* tez */ + scan_line_flat, /* 000 */ + scan_line_z, /* 001 */ + scan_line_e, /* 010 */ + scan_line_ze, /* 011 */ + scan_line_t, /* 100 */ + scan_line_zt, /* 101 */ + scan_line_et, /* 110 */ + scan_line_zet /* 111 */ }; int bits = 0; + if((st->flags & MGL_TEXTURE_2D) && st->tex.pixels) { + bits |= 4; + } if(st->flags & MGL_SMOOTH) { bits |= 2; } diff -r 8c9a63a902d5 -r 0e781cc43178 src/mingl.c --- a/src/mingl.c Mon Nov 21 10:15:37 2011 +0200 +++ b/src/mingl.c Mon Nov 21 10:16:09 2011 +0200 @@ -23,11 +23,13 @@ #include "mingl.h" #include "mglimpl.h" + #define DOT(a, b) ((a).x * (b).x + (a).y * (b).y + (a).z * (b).z) static void transform(vec4_t *res, vec4_t *v, float *mat); static void transform3(vec3_t *res, vec3_t *v, float *mat); static void vertex_proc(struct vertex *vert); +static int calc_shiftmask(int val, int *shiftp, unsigned int *maskp); static struct state st; static struct framebuffer fb; @@ -106,6 +108,11 @@ st.flags &= ~bit; } +int mgl_isenabled(unsigned int bit) +{ + return (st.flags & bit) != 0; +} + void mgl_front_face(int ff) { st.frontface = ff; @@ -464,3 +471,30 @@ float x = nr * tan(vfov_rad / 2.0); mgl_frustum(-aspect * x, aspect * x, -x, x, nr, fr); } + +void mgl_teximage(int width, int height, unsigned char *pixels) +{ + st.tex.width = width; + st.tex.height = height; + st.tex.pixels = pixels; + + if(calc_shiftmask(width, &st.tex.xshift, &st.tex.xmask) == -1 || + calc_shiftmask(height, &st.tex.yshift, &st.tex.ymask) == -1) { + st.tex.pixels = 0; + } +} + +#define MAX_SHIFT 12 +static int calc_shiftmask(int val, int *shiftp, unsigned int *maskp) +{ + int i; + + for(i=0; i> i) == 1) { + *shiftp = i; + *maskp = ~(0xffff << i); + return 0; + } + } + return -1; +} diff -r 8c9a63a902d5 -r 0e781cc43178 src/mingl.h --- a/src/mingl.h Mon Nov 21 10:15:37 2011 +0200 +++ b/src/mingl.h Mon Nov 21 10:16:09 2011 +0200 @@ -23,6 +23,7 @@ #define MGL_DEPTH_TEST 2 #define MGL_SMOOTH 4 #define MGL_LIGHTING 8 +#define MGL_TEXTURE_2D 16 /* primitives */ #define MGL_POINTS 1 @@ -50,6 +51,7 @@ void mgl_enable(unsigned int bit); void mgl_disable(unsigned int bit); +int mgl_isenabled(unsigned int bit); void mgl_front_face(int ff); void mgl_cull_face(int cf); @@ -86,6 +88,8 @@ void mgl_frustum(float left, float right, float bottom, float top, float nr, float fr); void mgl_perspective(float vfov, float aspect, float nr, float fr); +void mgl_teximage(int width, int height, unsigned char *pixels); + void mgl_cube(float sz); void mgl_sphere(float rad, int usub, int vsub); void mgl_sphere_part(float rad, int usub, int vsub, float umax, float vmax); diff -r 8c9a63a902d5 -r 0e781cc43178 src/scantmpl.h --- a/src/scantmpl.h Mon Nov 21 10:15:37 2011 +0200 +++ b/src/scantmpl.h Mon Nov 21 10:16:09 2011 +0200 @@ -25,7 +25,10 @@ #ifdef INTERP_ENERGY float e, de, dfde; #endif - float x, y; +#ifdef INTERP_TEX + float u, v, du, dv, dfdu, dfdv; +#endif + float x; struct vertex *edge; dy = v1->pos.y - v0->pos.y; @@ -37,7 +40,6 @@ dfdx = dx / dy; #ifdef INTERP_DEPTH - assert(fb->zbuf); dz = v1->pos.z - v0->pos.z; dfdz = dz / dy; #endif @@ -45,6 +47,12 @@ de = v1->energy - v0->energy; dfde = de / dy; #endif +#ifdef INTERP_TEX + du = v1->tc.x - v0->tc.x; + dv = v1->tc.y - v0->tc.y; + dfdu = du / dy; + dfdv = dv / dy; +#endif if(dy < 0.0) { struct vertex *tmp = v0; @@ -65,6 +73,10 @@ #ifdef INTERP_ENERGY e = v0->energy; #endif +#ifdef INTERP_TEX + u = v0->tc.x; + v = v0->tc.y; +#endif for(i=start; ienergy; #endif + +#ifdef INTERP_TEX + edge[i].tc.x = u; + edge[i].tc.y = v; + u += dfdu; + v += dfdv; +#endif } } static void SCAN_LINE(int y, unsigned char *sline) { - int i, x0, x1, len, tmp, cidx; -#if defined(INTERP_DEPTH) || defined(INTERP_ENERGY) + int x0, x1, len, tmp, cidx; +#if defined(INTERP_DEPTH) || defined(INTERP_ENERGY) || defined(INTERP_TEX) + int i; float x, dx; #endif #ifdef INTERP_DEPTH @@ -96,6 +116,10 @@ #ifdef INTERP_ENERGY float e, de, dfde; #endif +#ifdef INTERP_TEX + int tx, ty; + float u, v, du, dv, dfdu, dfdv; +#endif struct vertex *left, *right; x0 = (int)ROUND(vleft[y].pos.x); @@ -124,7 +148,7 @@ assert(len >= 0); cidx = left[y].cidx; -#if !defined(INTERP_DEPTH) && !defined(INTERP_ENERGY) +#if !defined(INTERP_DEPTH) && !defined(INTERP_ENERGY) && !defined(INTERP_TEX) /* no interpolation at all, just memset the whole scanline */ memset(sline + x0, cidx + left[y].energy * st->col_range, len); #else @@ -146,13 +170,36 @@ de = right[y].energy - e; dfde = de / dx; #endif +#ifdef INTERP_TEX + u = left[y].tc.x; + v = left[y].tc.y; + du = right[y].tc.x - u; + dv = right[y].tc.y - v; + dfdu = du / dx; + dfdv = dv / dx; +#endif for(i=0; itex.width) & st->tex.xmask; + ty = (int)(v * st->tex.height) & st->tex.ymask; + c = st->tex.pixels[(ty << st->tex.xshift) + tx]; + + u += dfdu; + v += dfdv; +#endif #ifdef INTERP_ENERGY - cidx = left[y].cidx + e * st->col_range; + c += e * st->col_range; e += dfde; +#else + c += left[y].energy * st->col_range; #endif - sline[x0 + i] = cidx; + sline[x0 + i] = c; } #endif /* flat */ } diff -r 8c9a63a902d5 -r 0e781cc43178 src/test.c --- a/src/test.c Mon Nov 21 10:15:37 2011 +0200 +++ b/src/test.c Mon Nov 21 10:16:09 2011 +0200 @@ -25,6 +25,7 @@ #include "timer.h" #include "mouse.h" #include "palman.h" +#include "texture.h" static int init(void); static void shutdown(void); @@ -39,6 +40,8 @@ static unsigned char *fbuf; +static struct texture *tex; + static int white_base, red_base, green_base, blue_base; static int grad_range; @@ -145,6 +148,12 @@ mgl_load_identity(); mgl_perspective(45.0, 320.0 / 200.0, 0.5, 100.0); + if(!(tex = tex_gen_checker(64, 64, 3, 3, red_base, blue_base))) { + fprintf(stderr, "failed to generate texture\n"); + return -1; + } + mgl_teximage(tex->width, tex->height, tex->pixels); + return 0; } @@ -245,6 +254,22 @@ case 27: return 0; + case 's': + if(mgl_isenabled(MGL_SMOOTH)) { + mgl_disable(MGL_SMOOTH); + } else { + mgl_enable(MGL_SMOOTH); + } + break; + + case 't': + if(mgl_isenabled(MGL_TEXTURE_2D)) { + mgl_disable(MGL_TEXTURE_2D); + } else { + mgl_enable(MGL_TEXTURE_2D); + } + break; + case ' ': auto_rotate = !auto_rotate; break; diff -r 8c9a63a902d5 -r 0e781cc43178 src/texture.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/texture.c Mon Nov 21 10:16:09 2011 +0200 @@ -0,0 +1,52 @@ +/* +256-color 3D graphics hack for real-mode DOS. +Copyright (C) 2011 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include +#include "texture.h" +#include "palman.h" + +struct texture *tex_load(const char *fname) +{ + return 0; /* TODO */ +} + +struct texture *tex_gen_checker(int xsz, int ysz, int ush, int vsh, int c1, int c2) +{ + int i, j; + struct texture *tex; + unsigned char *pptr; + + if(!(tex = malloc(sizeof *tex))) { + return 0; + } + if(!(tex->pixels = malloc(xsz * ysz))) { + free(tex); + return 0; + } + tex->width = xsz; + tex->height = ysz; + + pptr = tex->pixels; + for(i=0; i> vsh) & 1) == ((j >> ush) & 1) ? c1 : c2; + *pptr++ = c; + } + } + return tex; +} diff -r 8c9a63a902d5 -r 0e781cc43178 src/texture.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/texture.h Mon Nov 21 10:16:09 2011 +0200 @@ -0,0 +1,30 @@ +/* +256-color 3D graphics hack for real-mode DOS. +Copyright (C) 2011 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef TEXTURE_H_ +#define TEXTURE_H_ + +struct texture { + int width, height; + unsigned char *pixels; +}; + +struct texture *tex_load(const char *fname); + +struct texture *tex_gen_checker(int xsz, int ysz, int usub, int vsub, int c1, int c2); + +#endif /* TEXTURE_H_ */