diff options
author | inmarket <andrewh@inmarket.com.au> | 2014-08-20 01:36:33 +1000 |
---|---|---|
committer | inmarket <andrewh@inmarket.com.au> | 2014-08-20 01:36:33 +1000 |
commit | 3b21507274aa4f98644382903ae529c1fc2c7bd4 (patch) | |
tree | bd977e47129c44adb20f0f72c891fa960c827d73 /3rdparty/tinygl-0.4-ugfx/src | |
parent | 301f134b9034170e6e26aa307e5ede741db1cf70 (diff) | |
download | uGFX-3b21507274aa4f98644382903ae529c1fc2c7bd4.tar.gz uGFX-3b21507274aa4f98644382903ae529c1fc2c7bd4.tar.bz2 uGFX-3b21507274aa4f98644382903ae529c1fc2c7bd4.zip |
GL3D GWIN window + demo
Diffstat (limited to '3rdparty/tinygl-0.4-ugfx/src')
36 files changed, 6875 insertions, 0 deletions
diff --git a/3rdparty/tinygl-0.4-ugfx/src/Makefile b/3rdparty/tinygl-0.4-ugfx/src/Makefile new file mode 100644 index 00000000..829d3bfb --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/Makefile @@ -0,0 +1,43 @@ +include ../config.mk + +OBJS= api.o list.o vertex.o init.o matrix.o texture.o \ + misc.o clear.o light.o clip.o select.o get.o error.o \ + zbuffer.o zline.o zdither.o ztriangle.o \ + zmath.o image_util.o oscontext.o msghandling.o \ + arrays.o specbuf.o memory.o +ifdef TINYGL_USE_GLX +OBJS += glx.o +endif +ifdef TINYGL_USE_NANOX +OBJS += nglx.o +endif + +INCLUDES = -I../include +LIB = libTinyGL.a + +all: $(LIB) + +$(LIB): $(OBJS) + rm -f $(LIB) + ar rcs $(LIB) $(OBJS) + cp $(LIB) ../lib + +clean: + rm -f *~ *.o *.a + +.c.o: + $(CC) $(CFLAGS) $(INCLUDES) -c $*.c + +clip.o: zgl.h zfeatures.h +vertex.o: zgl.h zfeatures.h +light.o: zgl.h zfeatures.h +matrix.o: zgl.h zfeatures.h +list.o: zgl.h opinfo.h zfeatures.h +arrays.c: zgl.h zfeatures.h +specbuf.o: zgl.h zfeatures.h +glx.o: zgl.h zfeatures.h +nglx.o: zgl.h zfeatures.h +zline.o: zgl.h zfeatures.h zline.h + +ztriangle.o: ztriangle.c ztriangle.h zgl.h zfeatures.h + $(CC) $(CFLAGS) -Wno-uninitialized $(INCLUDES) -c $*.c diff --git a/3rdparty/tinygl-0.4-ugfx/src/api.c b/3rdparty/tinygl-0.4-ugfx/src/api.c new file mode 100644 index 00000000..11764a1e --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/api.c @@ -0,0 +1,667 @@ +#include "zgl.h" +#include <stdio.h> +/* glVertex */ + +void glVertex4f(float x,float y,float z,float w) +{ + GLParam p[5]; + + p[0].op=OP_Vertex; + p[1].f=x; + p[2].f=y; + p[3].f=z; + p[4].f=w; + + gl_add_op(p); +} + +void glVertex2f(float x,float y) +{ + glVertex4f(x,y,0,1); +} + +void glVertex3f(float x,float y,float z) +{ + glVertex4f(x,y,z,1); +} + +void glVertex3fv(float *v) +{ + glVertex4f(v[0],v[1],v[2],1); +} + +/* glNormal */ + +void glNormal3f(float x,float y,float z) +{ + GLParam p[4]; + + p[0].op=OP_Normal; + p[1].f=x; + p[2].f=y; + p[3].f=z; + + gl_add_op(p); +} + +void glNormal3fv(float *v) +{ + glNormal3f(v[0],v[1],v[2]); +} + +/* glColor */ + +void glColor4f(float r,float g,float b,float a) +{ + GLParam p[8]; + + p[0].op=OP_Color; + p[1].f=r; + p[2].f=g; + p[3].f=b; + p[4].f=a; + /* direct convertion to integer to go faster if no shading */ + p[5].ui = (unsigned int) (r * (ZB_POINT_RED_MAX - ZB_POINT_RED_MIN) + + ZB_POINT_RED_MIN); + p[6].ui = (unsigned int) (g * (ZB_POINT_GREEN_MAX - ZB_POINT_GREEN_MIN) + + ZB_POINT_GREEN_MIN); + p[7].ui = (unsigned int) (b * (ZB_POINT_BLUE_MAX - ZB_POINT_BLUE_MIN) + + ZB_POINT_BLUE_MIN); + gl_add_op(p); +} + +void glColor4fv(float *v) +{ + GLParam p[8]; + + p[0].op=OP_Color; + p[1].f=v[0]; + p[2].f=v[1]; + p[3].f=v[2]; + p[4].f=v[3]; + /* direct convertion to integer to go faster if no shading */ + p[5].ui = (unsigned int) (v[0] * (ZB_POINT_RED_MAX - ZB_POINT_RED_MIN) + + ZB_POINT_RED_MIN); + p[6].ui = (unsigned int) (v[1] * (ZB_POINT_GREEN_MAX - ZB_POINT_GREEN_MIN) + + ZB_POINT_GREEN_MIN); + p[7].ui = (unsigned int) (v[2] * (ZB_POINT_BLUE_MAX - ZB_POINT_BLUE_MIN) + + ZB_POINT_BLUE_MIN); + gl_add_op(p); +} + +void glColor3f(float x,float y,float z) +{ + glColor4f(x,y,z,1); +} + +void glColor3fv(float *v) +{ + glColor4f(v[0],v[1],v[2],1); +} + + +/* TexCoord */ + +void glTexCoord4f(float s,float t,float r,float q) +{ + GLParam p[5]; + + p[0].op=OP_TexCoord; + p[1].f=s; + p[2].f=t; + p[3].f=r; + p[4].f=q; + + gl_add_op(p); +} + +void glTexCoord2f(float s,float t) +{ + glTexCoord4f(s,t,0,1); +} + +void glTexCoord2fv(float *v) +{ + glTexCoord4f(v[0],v[1],0,1); +} + +void glEdgeFlag(int flag) +{ + GLParam p[2]; + + p[0].op=OP_EdgeFlag; + p[1].i=flag; + + gl_add_op(p); +} + +/* misc */ + +void glShadeModel(int mode) +{ + GLParam p[2]; + + gl_assert(mode == GL_FLAT || mode == GL_SMOOTH); + + p[0].op=OP_ShadeModel; + p[1].i=mode; + + gl_add_op(p); +} + +void glCullFace(int mode) +{ + GLParam p[2]; + + gl_assert(mode == GL_BACK || + mode == GL_FRONT || + mode == GL_FRONT_AND_BACK); + + p[0].op=OP_CullFace; + p[1].i=mode; + + gl_add_op(p); +} + +void glFrontFace(int mode) +{ + GLParam p[2]; + + gl_assert(mode == GL_CCW || mode == GL_CW); + + mode = (mode != GL_CCW); + + p[0].op=OP_FrontFace; + p[1].i=mode; + + gl_add_op(p); +} + +void glPolygonMode(int face,int mode) +{ + GLParam p[3]; + + gl_assert(face == GL_BACK || + face == GL_FRONT || + face == GL_FRONT_AND_BACK); + gl_assert(mode == GL_POINT || mode == GL_LINE || mode==GL_FILL); + + p[0].op=OP_PolygonMode; + p[1].i=face; + p[2].i=mode; + + gl_add_op(p); +} + + +/* glEnable / glDisable */ + +void glEnable(int cap) +{ + GLParam p[3]; + + p[0].op=OP_EnableDisable; + p[1].i=cap; + p[2].i=1; + + gl_add_op(p); +} + +void glDisable(int cap) +{ + GLParam p[3]; + + p[0].op=OP_EnableDisable; + p[1].i=cap; + p[2].i=0; + + gl_add_op(p); +} + +/* glBegin / glEnd */ + +void glBegin(int mode) +{ + GLParam p[2]; + + p[0].op=OP_Begin; + p[1].i=mode; + + gl_add_op(p); +} + +void glEnd(void) +{ + GLParam p[1]; + + p[0].op=OP_End; + + gl_add_op(p); +} + +/* matrix */ + +void glMatrixMode(int mode) +{ + GLParam p[2]; + + p[0].op=OP_MatrixMode; + p[1].i=mode; + + gl_add_op(p); +} + +void glLoadMatrixf(const float *m) +{ + GLParam p[17]; + int i; + + p[0].op=OP_LoadMatrix; + for(i=0;i<16;i++) p[i+1].f=m[i]; + + gl_add_op(p); +} + +void glLoadIdentity(void) +{ + GLParam p[1]; + + p[0].op=OP_LoadIdentity; + + gl_add_op(p); +} + +void glMultMatrixf(const float *m) +{ + GLParam p[17]; + int i; + + p[0].op=OP_MultMatrix; + for(i=0;i<16;i++) p[i+1].f=m[i]; + + gl_add_op(p); +} + +void glPushMatrix(void) +{ + GLParam p[1]; + + p[0].op=OP_PushMatrix; + + gl_add_op(p); +} + +void glPopMatrix(void) +{ + GLParam p[1]; + + p[0].op=OP_PopMatrix; + + gl_add_op(p); +} + +void glRotatef(float angle,float x,float y,float z) +{ + GLParam p[5]; + + p[0].op=OP_Rotate; + p[1].f=angle; + p[2].f=x; + p[3].f=y; + p[4].f=z; + + gl_add_op(p); +} + +void glTranslatef(float x,float y,float z) +{ + GLParam p[4]; + + p[0].op=OP_Translate; + p[1].f=x; + p[2].f=y; + p[3].f=z; + + gl_add_op(p); +} + +void glScalef(float x,float y,float z) +{ + GLParam p[4]; + + p[0].op=OP_Scale; + p[1].f=x; + p[2].f=y; + p[3].f=z; + + gl_add_op(p); +} + + +void glViewport(int x,int y,int width,int height) +{ + GLParam p[5]; + + p[0].op=OP_Viewport; + p[1].i=x; + p[2].i=y; + p[3].i=width; + p[4].i=height; + + gl_add_op(p); +} + +void glFrustum(double left,double right,double bottom,double top, + double xnear,double farv) +{ + GLParam p[7]; + + p[0].op=OP_Frustum; + p[1].f=left; + p[2].f=right; + p[3].f=bottom; + p[4].f=top; + p[5].f=xnear; + p[6].f=farv; + + gl_add_op(p); +} + +/* lightening */ + +void glMaterialfv(int mode,int type,float *v) +{ + GLParam p[7]; + int i,n; + + gl_assert(mode == GL_FRONT || mode == GL_BACK || mode==GL_FRONT_AND_BACK); + + p[0].op=OP_Material; + p[1].i=mode; + p[2].i=type; + n=4; + if (type == GL_SHININESS) n=1; + for(i=0;i<4;i++) p[3+i].f=v[i]; + for(i=n;i<4;i++) p[3+i].f=0; + + gl_add_op(p); +} + +void glMaterialf(int mode,int type,float v) +{ + GLParam p[7]; + int i; + + p[0].op=OP_Material; + p[1].i=mode; + p[2].i=type; + p[3].f=v; + for(i=0;i<3;i++) p[4+i].f=0; + + gl_add_op(p); +} + +void glColorMaterial(int mode,int type) +{ + GLParam p[3]; + + p[0].op=OP_ColorMaterial; + p[1].i=mode; + p[2].i=type; + + gl_add_op(p); +} + +void glLightfv(int light,int type,float *v) +{ + GLParam p[7]; + int i; + + p[0].op=OP_Light; + p[1].i=light; + p[2].i=type; + /* TODO: 3 composants ? */ + for(i=0;i<4;i++) p[3+i].f=v[i]; + + gl_add_op(p); +} + + +void glLightf(int light,int type,float v) +{ + GLParam p[7]; + int i; + + p[0].op=OP_Light; + p[1].i=light; + p[2].i=type; + p[3].f=v; + for(i=0;i<3;i++) p[4+i].f=0; + + gl_add_op(p); +} + +void glLightModeli(int pname,int param) +{ + GLParam p[6]; + int i; + + p[0].op=OP_LightModel; + p[1].i=pname; + p[2].f=(float)param; + for(i=0;i<4;i++) p[3+i].f=0; + + gl_add_op(p); +} + +void glLightModelfv(int pname,float *param) +{ + GLParam p[6]; + int i; + + p[0].op=OP_LightModel; + p[1].i=pname; + for(i=0;i<4;i++) p[2+i].f=param[i]; + + gl_add_op(p); +} + +/* clear */ + +void glClear(int mask) +{ + GLParam p[2]; + + p[0].op=OP_Clear; + p[1].i=mask; + + gl_add_op(p); +} + +void glClearColor(float r,float g,float b,float a) +{ + GLParam p[5]; + + p[0].op=OP_ClearColor; + p[1].f=r; + p[2].f=g; + p[3].f=b; + p[4].f=a; + + gl_add_op(p); +} + +void glClearDepth(double depth) +{ + GLParam p[2]; + + p[0].op=OP_ClearDepth; + p[1].f=depth; + + gl_add_op(p); +} + + +/* textures */ + +void glTexImage2D( int target, int level, int components, + int width, int height, int border, + int format, int type, void *pixels) +{ + GLParam p[10]; + + p[0].op=OP_TexImage2D; + p[1].i=target; + p[2].i=level; + p[3].i=components; + p[4].i=width; + p[5].i=height; + p[6].i=border; + p[7].i=format; + p[8].i=type; + p[9].p=pixels; + + gl_add_op(p); +} + + +void glBindTexture(int target,int texture) +{ + GLParam p[3]; + + p[0].op=OP_BindTexture; + p[1].i=target; + p[2].i=texture; + + gl_add_op(p); +} + +void glTexEnvi(int target,int pname,int param) +{ + GLParam p[8]; + + p[0].op=OP_TexEnv; + p[1].i=target; + p[2].i=pname; + p[3].i=param; + p[4].f=0; + p[5].f=0; + p[6].f=0; + p[7].f=0; + + gl_add_op(p); +} + +void glTexParameteri(int target,int pname,int param) +{ + GLParam p[8]; + + p[0].op=OP_TexParameter; + p[1].i=target; + p[2].i=pname; + p[3].i=param; + p[4].f=0; + p[5].f=0; + p[6].f=0; + p[7].f=0; + + gl_add_op(p); +} + +void glPixelStorei(int pname,int param) +{ + GLParam p[3]; + + p[0].op=OP_PixelStore; + p[1].i=pname; + p[2].i=param; + + gl_add_op(p); +} + +/* selection */ + +void glInitNames(void) +{ + GLParam p[1]; + + p[0].op=OP_InitNames; + + gl_add_op(p); +} + +void glPushName(unsigned int name) +{ + GLParam p[2]; + + p[0].op=OP_PushName; + p[1].i=name; + + gl_add_op(p); +} + +void glPopName(void) +{ + GLParam p[1]; + + p[0].op=OP_PopName; + + gl_add_op(p); +} + +void glLoadName(unsigned int name) +{ + GLParam p[2]; + + p[0].op=OP_LoadName; + p[1].i=name; + + gl_add_op(p); +} + +void +glPolygonOffset(GLfloat factor, GLfloat units) +{ + GLParam p[3]; + p[0].op = OP_PolygonOffset; + p[1].f = factor; + p[2].f = units; + gl_add_op(p); +} + +/* Special Functions */ + +void glCallList(unsigned int list) +{ + GLParam p[2]; + + p[0].op=OP_CallList; + p[1].i=list; + + gl_add_op(p); +} + +void glFlush(void) +{ + /* nothing to do */ +} + +void glHint(int target,int mode) +{ + GLParam p[3]; + + p[0].op=OP_Hint; + p[1].i=target; + p[2].i=mode; + + gl_add_op(p); +} + +/* Non standard functions */ + +void glDebug(int mode) +{ + GLContext *c=gl_get_context(); + c->print_flag=mode; +} + diff --git a/3rdparty/tinygl-0.4-ugfx/src/arrays.c b/3rdparty/tinygl-0.4-ugfx/src/arrays.c new file mode 100644 index 00000000..85b21bed --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/arrays.c @@ -0,0 +1,207 @@ +#include "zgl.h" +#include <stdio.h> + +#define VERTEX_ARRAY 0x0001 +#define COLOR_ARRAY 0x0002 +#define NORMAL_ARRAY 0x0004 +#define TEXCOORD_ARRAY 0x0008 + +void +glopArrayElement(GLContext *c, GLParam *param) +{ + int i; + int states = c->client_states; + int idx = param[1].i; + + if (states & COLOR_ARRAY) { + GLParam p[5]; + int size = c->color_array_size; + i = idx * (size + c->color_array_stride); + p[1].f = c->color_array[i]; + p[2].f = c->color_array[i+1]; + p[3].f = c->color_array[i+2]; + p[4].f = size > 3 ? c->color_array[i+3] : 1.0f; + glopColor(c, p); + } + if (states & NORMAL_ARRAY) { + i = idx * (3 + c->normal_array_stride); + c->current_normal.X = c->normal_array[i]; + c->current_normal.Y = c->normal_array[i+1]; + c->current_normal.Z = c->normal_array[i+2]; + c->current_normal.Z = 0.0f; + } + if (states & TEXCOORD_ARRAY) { + int size = c->texcoord_array_size; + i = idx * (size + c->texcoord_array_stride); + c->current_tex_coord.X = c->texcoord_array[i]; + c->current_tex_coord.Y = c->texcoord_array[i+1]; + c->current_tex_coord.Z = size > 2 ? c->texcoord_array[i+2] : 0.0f; + c->current_tex_coord.W = size > 3 ? c->texcoord_array[i+3] : 1.0f; + } + if (states & VERTEX_ARRAY) { + GLParam p[5]; + int size = c->vertex_array_size; + i = idx * (size + c->vertex_array_stride); + p[1].f = c->vertex_array[i]; + p[2].f = c->vertex_array[i+1]; + p[3].f = size > 2 ? c->vertex_array[i+2] : 0.0f; + p[4].f = size > 3 ? c->vertex_array[i+3] : 1.0f; + glopVertex(c, p); + } +} + +void +glArrayElement(GLint i) +{ + GLParam p[2]; + p[0].op = OP_ArrayElement; + p[1].i = i; + gl_add_op(p); +} + + +void +glopEnableClientState(GLContext *c, GLParam *p) +{ + c->client_states |= p[1].i; +} + +void +glEnableClientState(GLenum array) +{ + GLParam p[2]; + p[0].op = OP_EnableClientState; + + switch(array) { + case GL_VERTEX_ARRAY: + p[1].i = VERTEX_ARRAY; + break; + case GL_NORMAL_ARRAY: + p[1].i = NORMAL_ARRAY; + break; + case GL_COLOR_ARRAY: + p[1].i = COLOR_ARRAY; + break; + case GL_TEXTURE_COORD_ARRAY: + p[1].i = TEXCOORD_ARRAY; + break; + default: + gl_assert(0); + break; + } + gl_add_op(p); +} + +void +glopDisableClientState(GLContext *c, GLParam *p) +{ + c->client_states &= p[1].i; +} + +void +glDisableClientState(GLenum array) +{ + GLParam p[2]; + p[0].op = OP_DisableClientState; + + switch(array) { + case GL_VERTEX_ARRAY: + p[1].i = ~VERTEX_ARRAY; + break; + case GL_NORMAL_ARRAY: + p[1].i = ~NORMAL_ARRAY; + break; + case GL_COLOR_ARRAY: + p[1].i = ~COLOR_ARRAY; + break; + case GL_TEXTURE_COORD_ARRAY: + p[1].i = ~TEXCOORD_ARRAY; + break; + default: + gl_assert(0); + break; + } + gl_add_op(p); +} + +void +glopVertexPointer(GLContext *c, GLParam *p) +{ + c->vertex_array_size = p[1].i; + c->vertex_array_stride = p[2].i; + c->vertex_array = p[3].p; +} + +void +glVertexPointer(GLint size, GLenum type, GLsizei stride, + const GLvoid *pointer) +{ + GLParam p[4]; + gl_assert(type == GL_FLOAT); + p[0].op = OP_VertexPointer; + p[1].i = size; + p[2].i = stride; + p[3].p = (void*)pointer; + gl_add_op(p); +} + +void +glopColorPointer(GLContext *c, GLParam *p) +{ + c->color_array_size = p[1].i; + c->color_array_stride = p[2].i; + c->color_array = p[3].p; +} + +void +glColorPointer(GLint size, GLenum type, GLsizei stride, + const GLvoid *pointer) +{ + GLParam p[4]; + gl_assert(type == GL_FLOAT); + p[0].op = OP_ColorPointer; + p[1].i = size; + p[2].i = stride; + p[3].p = (void*)pointer; + gl_add_op(p); +} + +void +glopNormalPointer(GLContext *c, GLParam *p) +{ + c->normal_array_stride = p[1].i; + c->normal_array = p[2].p; +} + +void +glNormalPointer(GLenum type, GLsizei stride, + const GLvoid *pointer) +{ + GLParam p[3]; + gl_assert(type == GL_FLOAT); + p[0].op = OP_NormalPointer; + p[1].i = stride; + p[2].p = (void*)pointer; + gl_add_op(p); +} + +void +glopTexCoordPointer(GLContext *c, GLParam *p) +{ + c->texcoord_array_size = p[1].i; + c->texcoord_array_stride = p[2].i; + c->texcoord_array = p[3].p; +} + +void +glTexCoordPointer(GLint size, GLenum type, GLsizei stride, + const GLvoid *pointer) +{ + GLParam p[4]; + gl_assert(type == GL_FLOAT); + p[0].op = OP_TexCoordPointer; + p[1].i = size; + p[2].i = stride; + p[3].p = (void*)pointer; + gl_add_op(p); +} diff --git a/3rdparty/tinygl-0.4-ugfx/src/clear.c b/3rdparty/tinygl-0.4-ugfx/src/clear.c new file mode 100644 index 00000000..f5b75585 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/clear.c @@ -0,0 +1,30 @@ +#include "zgl.h" + + +void glopClearColor(GLContext *c,GLParam *p) +{ + c->clear_color.v[0]=p[1].f; + c->clear_color.v[1]=p[2].f; + c->clear_color.v[2]=p[3].f; + c->clear_color.v[3]=p[4].f; +} +void glopClearDepth(GLContext *c,GLParam *p) +{ + c->clear_depth=p[1].f; +} + + +void glopClear(GLContext *c,GLParam *p) +{ + int mask=p[1].i; + int z=0; + int r=(int)(c->clear_color.v[0]*65535); + int g=(int)(c->clear_color.v[1]*65535); + int b=(int)(c->clear_color.v[2]*65535); + + /* TODO : correct value of Z */ + + ZB_clear(c->zb,mask & GL_DEPTH_BUFFER_BIT,z, + mask & GL_COLOR_BUFFER_BIT,r,g,b); +} + diff --git a/3rdparty/tinygl-0.4-ugfx/src/clip.c b/3rdparty/tinygl-0.4-ugfx/src/clip.c new file mode 100644 index 00000000..47481fa3 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/clip.c @@ -0,0 +1,445 @@ +#include "zgl.h" + +/* fill triangle profile */ +/* #define PROFILE */ + +#define CLIP_XMIN (1<<0) +#define CLIP_XMAX (1<<1) +#define CLIP_YMIN (1<<2) +#define CLIP_YMAX (1<<3) +#define CLIP_ZMIN (1<<4) +#define CLIP_ZMAX (1<<5) + +void gl_transform_to_viewport(GLContext *c,GLVertex *v) +{ + float winv; + + /* coordinates */ + winv=1.0/v->pc.W; + v->zp.x= (int) ( v->pc.X * winv * c->viewport.scale.X + + c->viewport.trans.X ); + v->zp.y= (int) ( v->pc.Y * winv * c->viewport.scale.Y + + c->viewport.trans.Y ); + v->zp.z= (int) ( v->pc.Z * winv * c->viewport.scale.Z + + c->viewport.trans.Z ); + /* color */ + if (c->lighting_enabled) { + v->zp.r=(int)(v->color.v[0] * (ZB_POINT_RED_MAX - ZB_POINT_RED_MIN) + + ZB_POINT_RED_MIN); + v->zp.g=(int)(v->color.v[1] * (ZB_POINT_GREEN_MAX - ZB_POINT_GREEN_MIN) + + ZB_POINT_GREEN_MIN); + v->zp.b=(int)(v->color.v[2] * (ZB_POINT_BLUE_MAX - ZB_POINT_BLUE_MIN) + + ZB_POINT_BLUE_MIN); + } else { + /* no need to convert to integer if no lighting : take current color */ + v->zp.r = c->longcurrent_color[0]; + v->zp.g = c->longcurrent_color[1]; + v->zp.b = c->longcurrent_color[2]; + } + + /* texture */ + + if (c->texture_2d_enabled) { + v->zp.s=(int)(v->tex_coord.X * (ZB_POINT_S_MAX - ZB_POINT_S_MIN) + + ZB_POINT_S_MIN); + v->zp.t=(int)(v->tex_coord.Y * (ZB_POINT_T_MAX - ZB_POINT_T_MIN) + + ZB_POINT_T_MIN); + } +} + + +static void gl_add_select1(GLContext *c,int z1,int z2,int z3) +{ + unsigned int min,max; + min=max=z1; + if ((unsigned int)z2<min) min=z2; + if ((unsigned int)z3<min) min=z3; + if ((unsigned int)z2>max) max=z2; + if ((unsigned int)z3>max) max=z3; + + gl_add_select(c,0xffffffff-min,0xffffffff-max); +} + +/* point */ + +void gl_draw_point(GLContext *c,GLVertex *p0) +{ + if (p0->clip_code == 0) { + if (c->render_mode == GL_SELECT) { + gl_add_select(c,p0->zp.z,p0->zp.z); + } else { + ZB_plot(c->zb,&p0->zp); + } + } +} + +/* line */ + +static inline void line_interpolate(GLVertex *q,GLVertex *p0,GLVertex *p1,float t) +{ + q->pc.X=p0->pc.X+(p1->pc.X-p0->pc.X)*t; + q->pc.Y=p0->pc.Y+(p1->pc.Y-p0->pc.Y)*t; + q->pc.Z=p0->pc.Z+(p1->pc.Z-p0->pc.Z)*t; + q->pc.W=p0->pc.W+(p1->pc.W-p0->pc.W)*t; + + q->color.v[0]=p0->color.v[0] + (p1->color.v[0]-p0->color.v[0])*t; + q->color.v[1]=p0->color.v[1] + (p1->color.v[1]-p0->color.v[1])*t; + q->color.v[2]=p0->color.v[2] + (p1->color.v[2]-p0->color.v[2])*t; +} + +/* + * Line Clipping + */ + +/* Line Clipping algorithm from 'Computer Graphics', Principles and + Practice */ +static inline int ClipLine1(float denom,float num,float *tmin,float *tmax) +{ + float t; + + if (denom>0) { + t=num/denom; + if (t>*tmax) return 0; + if (t>*tmin) *tmin=t; + } else if (denom<0) { + t=num/denom; + if (t<*tmin) return 0; + if (t<*tmax) *tmax=t; + } else if (num>0) return 0; + return 1; +} + +void gl_draw_line(GLContext *c,GLVertex *p1,GLVertex *p2) +{ + float dx,dy,dz,dw,x1,y1,z1,w1; + float tmin,tmax; + GLVertex q1,q2; + int cc1,cc2; + + cc1=p1->clip_code; + cc2=p2->clip_code; + + if ( (cc1 | cc2) == 0) { + if (c->render_mode == GL_SELECT) { + gl_add_select1(c,p1->zp.z,p2->zp.z,p2->zp.z); + } else { + if (c->depth_test) + ZB_line_z(c->zb,&p1->zp,&p2->zp); + else + ZB_line(c->zb,&p1->zp,&p2->zp); + } + } else if ( (cc1&cc2) != 0 ) { + return; + } else { + dx=p2->pc.X-p1->pc.X; + dy=p2->pc.Y-p1->pc.Y; + dz=p2->pc.Z-p1->pc.Z; + dw=p2->pc.W-p1->pc.W; + x1=p1->pc.X; + y1=p1->pc.Y; + z1=p1->pc.Z; + w1=p1->pc.W; + + tmin=0; + tmax=1; + if (ClipLine1(dx+dw,-x1-w1,&tmin,&tmax) && + ClipLine1(-dx+dw,x1-w1,&tmin,&tmax) && + ClipLine1(dy+dw,-y1-w1,&tmin,&tmax) && + ClipLine1(-dy+dw,y1-w1,&tmin,&tmax) && + ClipLine1(dz+dw,-z1-w1,&tmin,&tmax) && + ClipLine1(-dz+dw,z1-w1,&tmin,&tmax)) { + + line_interpolate(&q1,p1,p2,tmin); + line_interpolate(&q2,p1,p2,tmax); + gl_transform_to_viewport(c,&q1); + gl_transform_to_viewport(c,&q2); + + if (c->depth_test) + ZB_line_z(c->zb,&q1.zp,&q2.zp); + else + ZB_line(c->zb,&q1.zp,&q2.zp); + } + } +} + + +/* triangle */ + +/* + * Clipping + */ + +/* We clip the segment [a,b] against the 6 planes of the normal volume. + * We compute the point 'c' of intersection and the value of the parameter 't' + * of the intersection if x=a+t(b-a). + */ + +#define clip_func(name,sign,dir,dir1,dir2) \ +static float name(V4 *c,V4 *a,V4 *b) \ +{\ + float t,dX,dY,dZ,dW,den;\ + dX = (b->X - a->X);\ + dY = (b->Y - a->Y);\ + dZ = (b->Z - a->Z);\ + dW = (b->W - a->W);\ + den = -(sign d ## dir) + dW;\ + if (den == 0) t=0;\ + else t = ( sign a->dir - a->W) / den;\ + c->dir1 = a->dir1 + t * d ## dir1;\ + c->dir2 = a->dir2 + t * d ## dir2;\ + c->W = a->W + t * dW;\ + c->dir = sign c->W;\ + return t;\ +} + + +clip_func(clip_xmin,-,X,Y,Z) + +clip_func(clip_xmax,+,X,Y,Z) + +clip_func(clip_ymin,-,Y,X,Z) + +clip_func(clip_ymax,+,Y,X,Z) + +clip_func(clip_zmin,-,Z,X,Y) + +clip_func(clip_zmax,+,Z,X,Y) + + +float (*clip_proc[6])(V4 *,V4 *,V4 *)= { + clip_xmin,clip_xmax, + clip_ymin,clip_ymax, + clip_zmin,clip_zmax +}; + +static inline void updateTmp(GLContext *c, + GLVertex *q,GLVertex *p0,GLVertex *p1,float t) +{ + if (c->current_shade_model == GL_SMOOTH) { + q->color.v[0]=p0->color.v[0] + (p1->color.v[0]-p0->color.v[0])*t; + q->color.v[1]=p0->color.v[1] + (p1->color.v[1]-p0->color.v[1])*t; + q->color.v[2]=p0->color.v[2] + (p1->color.v[2]-p0->color.v[2])*t; + } else { + q->color.v[0]=p0->color.v[0]; + q->color.v[1]=p0->color.v[1]; + q->color.v[2]=p0->color.v[2]; + } + + if (c->texture_2d_enabled) { + q->tex_coord.X=p0->tex_coord.X + (p1->tex_coord.X-p0->tex_coord.X)*t; + q->tex_coord.Y=p0->tex_coord.Y + (p1->tex_coord.Y-p0->tex_coord.Y)*t; + } + + q->clip_code=gl_clipcode(q->pc.X,q->pc.Y,q->pc.Z,q->pc.W); + if (q->clip_code==0) + gl_transform_to_viewport(c,q); +} + +static void gl_draw_triangle_clip(GLContext *c, + GLVertex *p0,GLVertex *p1,GLVertex *p2,int clip_bit); + +void gl_draw_triangle(GLContext *c, + GLVertex *p0,GLVertex *p1,GLVertex *p2) +{ + int co,c_and,cc[3],front; + float norm; + + cc[0]=p0->clip_code; + cc[1]=p1->clip_code; + cc[2]=p2->clip_code; + + co=cc[0] | cc[1] | cc[2]; + + /* we handle the non clipped case here to go faster */ + if (co==0) { + + norm=(float)(p1->zp.x-p0->zp.x)*(float)(p2->zp.y-p0->zp.y)- + (float)(p2->zp.x-p0->zp.x)*(float)(p1->zp.y-p0->zp.y); + + if (norm == 0) return; + + front = norm < 0.0; + front = front ^ c->current_front_face; + + /* back face culling */ + if (c->cull_face_enabled) { + /* most used case first */ + if (c->current_cull_face == GL_BACK) { + if (front == 0) return; + c->draw_triangle_front(c,p0,p1,p2); + } else if (c->current_cull_face == GL_FRONT) { + if (front != 0) return; + c->draw_triangle_back(c,p0,p1,p2); + } else { + return; + } + } else { + /* no culling */ + if (front) { + c->draw_triangle_front(c,p0,p1,p2); + } else { + c->draw_triangle_back(c,p0,p1,p2); + } + } + } else { + c_and=cc[0] & cc[1] & cc[2]; + if (c_and==0) { + gl_draw_triangle_clip(c,p0,p1,p2,0); + } + } +} + +static void gl_draw_triangle_clip(GLContext *c, + GLVertex *p0,GLVertex *p1,GLVertex *p2,int clip_bit) +{ + int co,c_and,co1,cc[3],edge_flag_tmp,clip_mask; + GLVertex tmp1,tmp2,*q[3]; + float tt; + + cc[0]=p0->clip_code; + cc[1]=p1->clip_code; + cc[2]=p2->clip_code; + + co=cc[0] | cc[1] | cc[2]; + if (co == 0) { + gl_draw_triangle(c,p0,p1,p2); + } else { + c_and=cc[0] & cc[1] & cc[2]; + /* the triangle is completely outside */ + if (c_and!=0) return; + + /* find the next direction to clip */ + while (clip_bit < 6 && (co & (1 << clip_bit)) == 0) { + clip_bit++; + } + + /* this test can be true only in case of rounding errors */ + if (clip_bit == 6) { +#if 0 + printf("Error:\n"); + printf("%f %f %f %f\n",p0->pc.X,p0->pc.Y,p0->pc.Z,p0->pc.W); + printf("%f %f %f %f\n",p1->pc.X,p1->pc.Y,p1->pc.Z,p1->pc.W); + printf("%f %f %f %f\n",p2->pc.X,p2->pc.Y,p2->pc.Z,p2->pc.W); +#endif + return; + } + + clip_mask = 1 << clip_bit; + co1=(cc[0] ^ cc[1] ^ cc[2]) & clip_mask; + + if (co1) { + /* one point outside */ + + if (cc[0] & clip_mask) { q[0]=p0; q[1]=p1; q[2]=p2; } + else if (cc[1] & clip_mask) { q[0]=p1; q[1]=p2; q[2]=p0; } + else { q[0]=p2; q[1]=p0; q[2]=p1; } + + tt=clip_proc[clip_bit](&tmp1.pc,&q[0]->pc,&q[1]->pc); + updateTmp(c,&tmp1,q[0],q[1],tt); + + tt=clip_proc[clip_bit](&tmp2.pc,&q[0]->pc,&q[2]->pc); + updateTmp(c,&tmp2,q[0],q[2],tt); + + tmp1.edge_flag=q[0]->edge_flag; + edge_flag_tmp=q[2]->edge_flag; + q[2]->edge_flag=0; + gl_draw_triangle_clip(c,&tmp1,q[1],q[2],clip_bit+1); + + tmp2.edge_flag=1; + tmp1.edge_flag=0; + q[2]->edge_flag=edge_flag_tmp; + gl_draw_triangle_clip(c,&tmp2,&tmp1,q[2],clip_bit+1); + } else { + /* two points outside */ + + if ((cc[0] & clip_mask)==0) { q[0]=p0; q[1]=p1; q[2]=p2; } + else if ((cc[1] & clip_mask)==0) { q[0]=p1; q[1]=p2; q[2]=p0; } + else { q[0]=p2; q[1]=p0; q[2]=p1; } + + tt=clip_proc[clip_bit](&tmp1.pc,&q[0]->pc,&q[1]->pc); + updateTmp(c,&tmp1,q[0],q[1],tt); + + tt=clip_proc[clip_bit](&tmp2.pc,&q[0]->pc,&q[2]->pc); + updateTmp(c,&tmp2,q[0],q[2],tt); + + tmp1.edge_flag=1; + tmp2.edge_flag=q[2]->edge_flag; + gl_draw_triangle_clip(c,q[0],&tmp1,&tmp2,clip_bit+1); + } + } +} + + +void gl_draw_triangle_select(GLContext *c, + GLVertex *p0,GLVertex *p1,GLVertex *p2) +{ + gl_add_select1(c,p0->zp.z,p1->zp.z,p2->zp.z); +} + +#ifdef PROFILE +int count_triangles,count_triangles_textured,count_pixels; +#endif + +void gl_draw_triangle_fill(GLContext *c, + GLVertex *p0,GLVertex *p1,GLVertex *p2) +{ +#ifdef PROFILE + { + int norm; + gl_assert(p0->zp.x >= 0 && p0->zp.x < c->zb->xsize); + gl_assert(p0->zp.y >= 0 && p0->zp.y < c->zb->ysize); + gl_assert(p1->zp.x >= 0 && p1->zp.x < c->zb->xsize); + gl_assert(p1->zp.y >= 0 && p1->zp.y < c->zb->ysize); + gl_assert(p2->zp.x >= 0 && p2->zp.x < c->zb->xsize); + gl_assert(p2->zp.y >= 0 && p2->zp.y < c->zb->ysize); + + norm=(p1->zp.x-p0->zp.x)*(p2->zp.y-p0->zp.y)- + (p2->zp.x-p0->zp.x)*(p1->zp.y-p0->zp.y); + count_pixels+=abs(norm)/2; + count_triangles++; + } +#endif + + if (c->texture_2d_enabled) { +#ifdef PROFILE + count_triangles_textured++; +#endif + ZB_setTexture(c->zb,c->current_texture->images[0].pixmap); + ZB_fillTriangleMappingPerspective(c->zb,&p0->zp,&p1->zp,&p2->zp); + } else if (c->current_shade_model == GL_SMOOTH) { + ZB_fillTriangleSmooth(c->zb,&p0->zp,&p1->zp,&p2->zp); + } else { + ZB_fillTriangleFlat(c->zb,&p0->zp,&p1->zp,&p2->zp); + } +} + +/* Render a clipped triangle in line mode */ + +void gl_draw_triangle_line(GLContext *c, + GLVertex *p0,GLVertex *p1,GLVertex *p2) +{ + if (c->depth_test) { + if (p0->edge_flag) ZB_line_z(c->zb,&p0->zp,&p1->zp); + if (p1->edge_flag) ZB_line_z(c->zb,&p1->zp,&p2->zp); + if (p2->edge_flag) ZB_line_z(c->zb,&p2->zp,&p0->zp); + } else { + if (p0->edge_flag) ZB_line(c->zb,&p0->zp,&p1->zp); + if (p1->edge_flag) ZB_line(c->zb,&p1->zp,&p2->zp); + if (p2->edge_flag) ZB_line(c->zb,&p2->zp,&p0->zp); + } +} + + + +/* Render a clipped triangle in point mode */ +void gl_draw_triangle_point(GLContext *c, + GLVertex *p0,GLVertex *p1,GLVertex *p2) +{ + if (p0->edge_flag) ZB_plot(c->zb,&p0->zp); + if (p1->edge_flag) ZB_plot(c->zb,&p1->zp); + if (p2->edge_flag) ZB_plot(c->zb,&p2->zp); +} + + + + diff --git a/3rdparty/tinygl-0.4-ugfx/src/error.c b/3rdparty/tinygl-0.4-ugfx/src/error.c new file mode 100644 index 00000000..a1c0a6df --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/error.c @@ -0,0 +1,22 @@ +#include <stdarg.h> +#include <assert.h> +#include "zgl.h" + +void gl_fatal_error(char *format, ...) +{ + va_list ap; + + va_start(ap,format); + + fprintf(stderr,"TinyGL: fatal error: "); + vfprintf(stderr,format,ap); + fprintf(stderr,"\n"); + exit(1); + + va_end(ap); +} + +void gl_assert(int test) +{ + assert(test); +} diff --git a/3rdparty/tinygl-0.4-ugfx/src/get.c b/3rdparty/tinygl-0.4-ugfx/src/get.c new file mode 100644 index 00000000..8cd0d787 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/get.c @@ -0,0 +1,74 @@ +#include "zgl.h" + +void glGetIntegerv(int pname,int *params) +{ + GLContext *c=gl_get_context(); + + switch(pname) { + case GL_VIEWPORT: + params[0]=c->viewport.xmin; + params[1]=c->viewport.ymin; + params[2]=c->viewport.xsize; + params[3]=c->viewport.ysize; + break; + case GL_MAX_MODELVIEW_STACK_DEPTH: + *params = MAX_MODELVIEW_STACK_DEPTH; + break; + case GL_MAX_PROJECTION_STACK_DEPTH: + *params = MAX_PROJECTION_STACK_DEPTH; + break; + case GL_MAX_LIGHTS: + *params = MAX_LIGHTS; + break; + case GL_MAX_TEXTURE_SIZE: + *params = 256; /* not completely true, but... */ + break; + case GL_MAX_TEXTURE_STACK_DEPTH: + *params = MAX_TEXTURE_STACK_DEPTH; + break; + default: + gl_fatal_error("glGet: option not implemented"); + break; + } +} + +void glGetFloatv(int pname, float *v) +{ + int i; + int mnr = 0; /* just a trick to return the correct matrix */ + GLContext *c = gl_get_context(); + switch (pname) { + case GL_TEXTURE_MATRIX: + mnr++; + case GL_PROJECTION_MATRIX: + mnr++; + case GL_MODELVIEW_MATRIX: + { + float *p = &c->matrix_stack_ptr[mnr]->m[0][0];; + for (i = 0; i < 4; i++) { + *v++ = p[0]; + *v++ = p[4]; + *v++ = p[8]; + *v++ = p[12]; + p++; + } + } + break; + case GL_LINE_WIDTH: + *v = 1.0f; + break; + case GL_LINE_WIDTH_RANGE: + v[0] = v[1] = 1.0f; + break; + case GL_POINT_SIZE: + *v = 1.0f; + break; + case GL_POINT_SIZE_RANGE: + v[0] = v[1] = 1.0f; + default: +#ifndef NO_CLIBRARY + fprintf(stderr,"warning: unknown pname in glGetFloatv()\n"); +#endif + break; + } +} diff --git a/3rdparty/tinygl-0.4-ugfx/src/glx.c b/3rdparty/tinygl-0.4-ugfx/src/glx.c new file mode 100644 index 00000000..2c018128 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/glx.c @@ -0,0 +1,413 @@ +/* simple glx driver for TinyGL */ +#include <GL/glx.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <X11/extensions/XShm.h> +#include "zgl.h" + +typedef struct { + GLContext *gl_context; + Display *display; + XVisualInfo visual_info; + int xsize,ysize; + XImage *ximage; + GC gc; + Colormap cmap; + Drawable drawable; + int do_convert; /* true if must do convertion to X11 format */ + /* shared memory */ + int shm_use; + XShmSegmentInfo *shm_info; + int CompletionType; +} TinyGLXContext; + +Bool glXQueryExtension( Display *dpy, int *errorb, int *event ) +{ + return True; +} + + +XVisualInfo* glXChooseVisual( Display *dpy, int screen, + int *attribList ) +{ + XVisualInfo vinfo; + int n; + + /* the attribList is ignored : we consider only RGBA rendering (no + direct color) */ + + if (XMatchVisualInfo (dpy, screen, 16, TrueColor, &vinfo)) { + /* 16 bit visual (fastest with TinyGL) */ + } else if (XMatchVisualInfo (dpy, screen, 24, TrueColor, &vinfo)) { + /* 24 bit visual */ + } else if (XMatchVisualInfo (dpy, screen, 32, TrueColor, &vinfo)) { + /* 32 bit visual */ + } else if (XMatchVisualInfo (dpy, screen, 8, PseudoColor, &vinfo)) { + /* 8 bit visual */ + } else { + /* no suitable visual */ + return NULL; + } + + return XGetVisualInfo(dpy,VisualAllMask,&vinfo,&n); +} + + + +GLXContext glXCreateContext( Display *dpy, XVisualInfo *vis, + GLXContext shareList, Bool direct ) +{ + TinyGLXContext *ctx; + + if (shareList != NULL) { + gl_fatal_error("No sharing available in TinyGL"); + } + ctx=gl_malloc(sizeof(TinyGLXContext)); + ctx->gl_context=NULL; + ctx->visual_info=*vis; + return (GLXContext) ctx; +} + + +void glXDestroyContext( Display *dpy, GLXContext ctx1 ) +{ + TinyGLXContext *ctx = (TinyGLXContext *) ctx1; + if (ctx->gl_context != NULL) { + glClose(); + } + gl_free(ctx); +} + + +static int glxXErrorFlag=0; + +static int glxHandleXError(Display *dpy,XErrorEvent *event) +{ + glxXErrorFlag=1; + return 0; +} + +static int bits_per_pixel(Display *dpy, XVisualInfo *visinfo) +{ + XImage *img; + int bpp; + char *data; + + data = gl_malloc(8); + if (data == NULL) + return visinfo->depth; + + img = XCreateImage(dpy, visinfo->visual, visinfo->depth, + ZPixmap, 0, data, 1, 1, 32, 0); + if (img == NULL) { + gl_free(data); + return visinfo->depth; + } + bpp = img->bits_per_pixel; + gl_free(data); + img->data = NULL; + XDestroyImage(img); + return bpp; +} + +static int create_ximage(TinyGLXContext *ctx, + int xsize,int ysize,int depth) +{ + int major,minor; + Bool pixmaps; + unsigned char *framebuffer; + int (*old_handler)(Display *,XErrorEvent *); + + if (XShmQueryVersion(ctx->display,&major,&minor,&pixmaps)) + ctx->shm_use=1; + else + ctx->shm_use=0; + + if (!ctx->shm_use) goto no_shm; + + ctx->shm_info=gl_malloc(sizeof(XShmSegmentInfo)); + ctx->ximage=XShmCreateImage(ctx->display,None,depth,ZPixmap,NULL, + ctx->shm_info,xsize,ysize); + if (ctx->ximage == NULL) { + fprintf(stderr,"XShm: error: XShmCreateImage\n"); + ctx->shm_use=0; + gl_free(ctx->shm_info); + goto no_shm; + } + ctx->shm_info->shmid=shmget(IPC_PRIVATE, + ctx->ysize*ctx->ximage->bytes_per_line, + IPC_CREAT | 0777); + if (ctx->shm_info->shmid < 0) { + fprintf(stderr,"XShm: error: shmget\n"); + no_shm1: + ctx->shm_use=0; + XDestroyImage(ctx->ximage); + goto no_shm; + } + ctx->ximage->data=shmat(ctx->shm_info->shmid,0,0); + if (ctx->ximage->data == (char *) -1) { + fprintf(stderr,"XShm: error: shmat\n"); + no_shm2: + shmctl(ctx->shm_info->shmid,IPC_RMID,0); + goto no_shm1; + } + ctx->shm_info->shmaddr=ctx->ximage->data; + + ctx->shm_info->readOnly=False; + + /* attach & test X errors */ + + glxXErrorFlag=0; + old_handler=XSetErrorHandler(glxHandleXError); + XShmAttach(ctx->display,ctx->shm_info); + XSync(ctx->display, False); + + if (glxXErrorFlag) { + XFlush(ctx->display); + shmdt(ctx->shm_info->shmaddr); + XSetErrorHandler(old_handler); + goto no_shm2; + } + + /* the shared memory will be automatically deleted */ + shmctl(ctx->shm_info->shmid,IPC_RMID,0); + + /* test with a dummy XShmPutImage */ + XShmPutImage(ctx->display,ctx->drawable,ctx->gc, + ctx->ximage,0,0,0,0,1,1, + False); + + XSync(ctx->display, False); + XSetErrorHandler(old_handler); + + if (glxXErrorFlag) { + fprintf(stderr,"XShm: error: XShmPutImage\n"); + XFlush(ctx->display); + shmdt(ctx->shm_info->shmaddr); + goto no_shm2; + } + + ctx->CompletionType=XShmGetEventBase(ctx->display) + ShmCompletion; + /* shared memory is OK !! */ + + return 0; + + no_shm: + ctx->ximage=XCreateImage(ctx->display, None, depth, ZPixmap, 0, + NULL,xsize,ysize, 8, 0); + framebuffer=gl_malloc(ysize * ctx->ximage->bytes_per_line); + ctx->ximage->data = framebuffer; + return 0; +} + +static void free_ximage(TinyGLXContext *ctx) +{ + if (ctx->shm_use) + { + XShmDetach(ctx->display, ctx->shm_info); + XDestroyImage(ctx->ximage); + shmdt(ctx->shm_info->shmaddr); + gl_free(ctx->shm_info); + } else { + gl_free(ctx->ximage->data); + XDestroyImage(ctx->ximage); + } +} + +/* resize the glx viewport : we try to use the xsize and ysize + given. We return the effective size which is guaranted to be smaller */ + +int glX_resize_viewport(GLContext *c,int *xsize_ptr,int *ysize_ptr) +{ + TinyGLXContext *ctx; + int xsize,ysize; + + ctx=(TinyGLXContext *)c->opaque; + + xsize=*xsize_ptr; + ysize=*ysize_ptr; + + /* we ensure that xsize and ysize are multiples of 2 for the zbuffer. + TODO: find a better solution */ + xsize&=~3; + ysize&=~3; + + if (xsize == 0 || ysize == 0) return -1; + + *xsize_ptr=xsize; + *ysize_ptr=ysize; + + if (ctx->ximage != NULL) free_ximage(ctx); + + ctx->xsize=xsize; + ctx->ysize=ysize; + + if (create_ximage(ctx,ctx->xsize,ctx->ysize,ctx->visual_info.depth) != 0) + return -1; + + /* resize the Z buffer */ + if (ctx->do_convert) { + ZB_resize(c->zb,NULL,xsize,ysize); + } else { + ZB_resize(c->zb,ctx->ximage->data,xsize,ysize); + } + return 0; +} + +/* we assume here that drawable is a window */ +Bool glXMakeCurrent( Display *dpy, GLXDrawable drawable, + GLXContext ctx1) +{ + TinyGLXContext *ctx = (TinyGLXContext *) ctx1; + XWindowAttributes attr; + int i,xsize,ysize; + unsigned int palette[ZB_NB_COLORS]; + unsigned char color_indexes[ZB_NB_COLORS]; + ZBuffer *zb; + XColor xcolor; + unsigned long pixel[ZB_NB_COLORS],tmp_plane; + + if (ctx->gl_context == NULL) { + /* create the TinyGL context */ + + ctx->display=dpy; + ctx->drawable=drawable; + + XGetWindowAttributes(ctx->display,drawable,&attr); + + xsize=attr.width; + ysize=attr.height; + + if (attr.depth != ctx->visual_info.depth) return False; + + /* ximage structure */ + ctx->ximage=NULL; + ctx->shm_use=1; /* use shm */ + + if (attr.depth == 8) { + /* get the colormap from the window */ + ctx->cmap = attr.colormap; + + if ( XAllocColorCells(ctx->display,ctx->cmap,True,&tmp_plane,0, + pixel,ZB_NB_COLORS) == 0) { + /* private cmap */ + ctx->cmap = XCreateColormap(ctx->display, drawable, + ctx->visual_info.visual, AllocAll); + XSetWindowColormap(ctx->display, drawable, ctx->cmap); + for(i=0;i<ZB_NB_COLORS;i++) pixel[i]=i; + } + + for(i=0;i<ZB_NB_COLORS;i++) color_indexes[i]=pixel[i]; + + /* Open the Z Buffer - 256 colors */ + zb=ZB_open(xsize,ysize,ZB_MODE_INDEX,ZB_NB_COLORS, + color_indexes,palette,NULL); + if (zb == NULL) { + fprintf(stderr, "Error while initializing Z buffer\n"); + exit(1); + } + + for (i=0; i<ZB_NB_COLORS; i++) { + xcolor.flags = DoRed | DoGreen | DoBlue; + + xcolor.red = (palette[i]>>8) & 0xFF00; + xcolor.green = (palette[i] & 0xFF00); + xcolor.blue = (palette[i] << 8) & 0xFF00; + xcolor.pixel = pixel[i]; + XStoreColor(ctx->display,ctx->cmap,&xcolor); + } + ctx->do_convert = 1; + } else { + int mode,bpp; + /* RGB 16/24/32 */ + bpp = bits_per_pixel(ctx->display,&ctx->visual_info); + switch(bpp) { + case 24: + mode = ZB_MODE_RGB24; + ctx->do_convert = (TGL_FEATURE_RENDER_BITS != 16); + break; + case 32: + mode = ZB_MODE_RGBA; + ctx->do_convert = (TGL_FEATURE_RENDER_BITS != 16); + break; + default: + mode = ZB_MODE_5R6G5B; + ctx->do_convert = (TGL_FEATURE_RENDER_BITS != 16); + break; + } + zb=ZB_open(xsize,ysize,mode,0,NULL,NULL,NULL); + if (zb == NULL) { + fprintf(stderr, "Error while initializing Z buffer\n"); + exit(1); + } + } + + /* create a gc */ + ctx->gc = XCreateGC(ctx->display, drawable, 0, 0); + + /* initialisation of the TinyGL interpreter */ + glInit(zb); + ctx->gl_context=gl_get_context(); + ctx->gl_context->opaque=(void *) ctx; + ctx->gl_context->gl_resize_viewport=glX_resize_viewport; + + /* set the viewport : we force a call to glX_resize_viewport */ + ctx->gl_context->viewport.xsize=-1; + ctx->gl_context->viewport.ysize=-1; + + glViewport(0, 0, xsize, ysize); + } + + return True; +} + +static Bool WaitForShmCompletion(Display *dpy, XEvent *event, char *arg) +{ + TinyGLXContext *ctx=(TinyGLXContext *) arg; + + return (event->type == ctx->CompletionType) && + ( ((XShmCompletionEvent *)event)->drawable == (Window)ctx->drawable); +} + +void glXSwapBuffers( Display *dpy, GLXDrawable drawable ) +{ + GLContext *gl_context; + TinyGLXContext *ctx; + + /* retrieve the current GLXContext */ + gl_context=gl_get_context(); + ctx=(TinyGLXContext *)gl_context->opaque; + + /* for non 16 bits visuals, a conversion is required */ + + + if (ctx->do_convert) { + ZB_copyFrameBuffer(ctx->gl_context->zb, + ctx->ximage->data, + ctx->ximage->bytes_per_line); + + } + + /* draw the ximage */ + if (ctx->shm_use) { + XEvent event; + + XShmPutImage(dpy,drawable,ctx->gc, + ctx->ximage,0,0,0,0,ctx->ximage->width, ctx->ximage->height, + True); + XIfEvent(dpy, &event, WaitForShmCompletion, (char*)ctx); + } else { + XPutImage(dpy, drawable, ctx->gc, + ctx->ximage, 0, 0, 0, 0, ctx->ximage->width, ctx->ximage->height); + } + XFlush(dpy); +} + + +void glXWaitGL( void ) +{ +} + +void glXWaitX( void ) +{ +} diff --git a/3rdparty/tinygl-0.4-ugfx/src/image_util.c b/3rdparty/tinygl-0.4-ugfx/src/image_util.c new file mode 100644 index 00000000..2789a55c --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/image_util.c @@ -0,0 +1,136 @@ +#include "zgl.h" + +/* + * image conversion + */ + +void gl_convertRGB_to_5R6G5B(unsigned short *pixmap,unsigned char *rgb, + int xsize,int ysize) +{ + int i,n; + unsigned char *p; + + p=rgb; + n=xsize*ysize; + for(i=0;i<n;i++) { + pixmap[i]=((p[0]&0xF8)<<8) | ((p[1]&0xFC)<<3) | ((p[2]&0xF8)>>3); + p+=3; + } +} + +void gl_convertRGB_to_8A8R8G8B(unsigned int *pixmap, unsigned char *rgb, + int xsize, int ysize) +{ + int i,n; + unsigned char *p; + + p=rgb; + n=xsize*ysize; + for(i=0;i<n;i++) { + pixmap[i]=(((unsigned int)p[0])<<16) | + (((unsigned int)p[1])<<8) | + (((unsigned int)p[2])); + p+=3; + } +} + +/* + * linear interpolation with xf,yf normalized to 2^16 + */ + +#define INTERP_NORM_BITS 16 +#define INTERP_NORM (1 << INTERP_NORM_BITS) + +static inline int interpolate(int v00,int v01,int v10,int xf,int yf) +{ + return v00+(((v01-v00)*xf + (v10-v00)*yf) >> INTERP_NORM_BITS); +} + + +/* + * TODO: more accurate resampling + */ + +void gl_resizeImage(unsigned char *dest,int xsize_dest,int ysize_dest, + unsigned char *src,int xsize_src,int ysize_src) +{ + unsigned char *pix,*pix_src; + float x1,y1,x1inc,y1inc; + int xi,yi,j,xf,yf,x,y; + + pix=dest; + pix_src=src; + + x1inc=(float) (xsize_src - 1) / (float) (xsize_dest - 1); + y1inc=(float) (ysize_src - 1) / (float) (ysize_dest - 1); + + y1=0; + for(y=0;y<ysize_dest;y++) { + x1=0; + for(x=0;x<xsize_dest;x++) { + xi=(int) x1; + yi=(int) y1; + xf=(int) ((x1 - floor(x1)) * INTERP_NORM); + yf=(int) ((y1 - floor(y1)) * INTERP_NORM); + + if ((xf+yf) <= INTERP_NORM) { + for(j=0;j<3;j++) { + pix[j]=interpolate(pix_src[(yi*xsize_src+xi)*3+j], + pix_src[(yi*xsize_src+xi+1)*3+j], + pix_src[((yi+1)*xsize_src+xi)*3+j], + xf,yf); + } + } else { + xf=INTERP_NORM - xf; + yf=INTERP_NORM - yf; + for(j=0;j<3;j++) { + pix[j]=interpolate(pix_src[((yi+1)*xsize_src+xi+1)*3+j], + pix_src[((yi+1)*xsize_src+xi)*3+j], + pix_src[(yi*xsize_src+xi+1)*3+j], + xf,yf); + } + } + + pix+=3; + x1+=x1inc; + } + y1+=y1inc; + } +} + +#define FRAC_BITS 16 + +/* resizing with no interlating nor nearest pixel */ + +void gl_resizeImageNoInterpolate(unsigned char *dest,int xsize_dest,int ysize_dest, + unsigned char *src,int xsize_src,int ysize_src) +{ + unsigned char *pix,*pix_src,*pix1; + int x1,y1,x1inc,y1inc; + int xi,yi,x,y; + + pix=dest; + pix_src=src; + + x1inc=(int)((float) ((xsize_src)<<FRAC_BITS) / (float) (xsize_dest)); + y1inc=(int)((float) ((ysize_src)<<FRAC_BITS) / (float) (ysize_dest)); + + y1=0; + for(y=0;y<ysize_dest;y++) { + x1=0; + for(x=0;x<xsize_dest;x++) { + xi=x1 >> FRAC_BITS; + yi=y1 >> FRAC_BITS; + pix1=pix_src+(yi*xsize_src+xi)*3; + + pix[0]=pix1[0]; + pix[1]=pix1[1]; + pix[2]=pix1[2]; + + pix+=3; + x1+=x1inc; + } + y1+=y1inc; + } +} + diff --git a/3rdparty/tinygl-0.4-ugfx/src/init.c b/3rdparty/tinygl-0.4-ugfx/src/init.c new file mode 100644 index 00000000..edc7a4c3 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/init.c @@ -0,0 +1,189 @@ +#include "zgl.h" + +GLContext *gl_ctx; + + +void initSharedState(GLContext *c) +{ + GLSharedState *s=&c->shared_state; + s->lists=gl_zalloc(sizeof(GLList *) * MAX_DISPLAY_LISTS); + s->texture_hash_table= + gl_zalloc(sizeof(GLTexture *) * TEXTURE_HASH_TABLE_SIZE); + + alloc_texture(c,0); +} + +void endSharedState(GLContext *c) +{ + GLSharedState *s=&c->shared_state; + int i; + + for(i=0;i<MAX_DISPLAY_LISTS;i++) { + /* TODO */ + } + gl_free(s->lists); + + gl_free(s->texture_hash_table); +} + + +void glInit(void *zbuffer1) +{ + ZBuffer *zbuffer=(ZBuffer *)zbuffer1; + GLContext *c; + GLViewport *v; + int i; + + c=gl_zalloc(sizeof(GLContext)); + gl_ctx=c; + + c->zb=zbuffer; + + /* allocate GLVertex array */ + c->vertex_max = POLYGON_MAX_VERTEX; + c->vertex = gl_malloc(POLYGON_MAX_VERTEX*sizeof(GLVertex)); + + /* viewport */ + v=&c->viewport; + v->xmin=0; + v->ymin=0; + v->xsize=zbuffer->xsize; + v->ysize=zbuffer->ysize; + v->updated=1; + + /* shared state */ + initSharedState(c); + + /* lists */ + + c->exec_flag=1; + c->compile_flag=0; + c->print_flag=0; + + c->in_begin=0; + + /* lights */ + for(i=0;i<MAX_LIGHTS;i++) { + GLLight *l=&c->lights[i]; + l->ambient=gl_V4_New(0,0,0,1); + l->diffuse=gl_V4_New(1,1,1,1); + l->specular=gl_V4_New(1,1,1,1); + l->position=gl_V4_New(0,0,1,0); + l->norm_position=gl_V3_New(0,0,1); + l->spot_direction=gl_V3_New(0,0,-1); + l->norm_spot_direction=gl_V3_New(0,0,-1); + l->spot_exponent=0; + l->spot_cutoff=180; + l->attenuation[0]=1; + l->attenuation[1]=0; + l->attenuation[2]=0; + l->enabled=0; + } + c->first_light=NULL; + c->ambient_light_model=gl_V4_New(0.2,0.2,0.2,1); + c->local_light_model=0; + c->lighting_enabled=0; + c->light_model_two_side = 0; + + /* default materials */ + for(i=0;i<2;i++) { + GLMaterial *m=&c->materials[i]; + m->emission=gl_V4_New(0,0,0,1); + m->ambient=gl_V4_New(0.2,0.2,0.2,1); + m->diffuse=gl_V4_New(0.8,0.8,0.8,1); + m->specular=gl_V4_New(0,0,0,1); + m->shininess=0; + } + c->current_color_material_mode=GL_FRONT_AND_BACK; + c->current_color_material_type=GL_AMBIENT_AND_DIFFUSE; + c->color_material_enabled=0; + + /* textures */ + glInitTextures(c); + + /* default state */ + c->current_color.X=1.0; + c->current_color.Y=1.0; + c->current_color.Z=1.0; + c->current_color.W=1.0; + c->longcurrent_color[0] = 65535; + c->longcurrent_color[1] = 65535; + c->longcurrent_color[2] = 65535; + + c->current_normal.X=1.0; + c->current_normal.Y=0.0; + c->current_normal.Z=0.0; + c->current_normal.W=0.0; + + c->current_edge_flag=1; + + c->current_tex_coord.X=0; + c->current_tex_coord.Y=0; + c->current_tex_coord.Z=0; + c->current_tex_coord.W=1; + + c->polygon_mode_front=GL_FILL; + c->polygon_mode_back=GL_FILL; + + c->current_front_face=0; /* 0 = GL_CCW 1 = GL_CW */ + c->current_cull_face=GL_BACK; + c->current_shade_model=GL_SMOOTH; + c->cull_face_enabled=0; + + /* clear */ + c->clear_color.v[0]=0; + c->clear_color.v[1]=0; + c->clear_color.v[2]=0; + c->clear_color.v[3]=0; + c->clear_depth=0; + + /* selection */ + c->render_mode=GL_RENDER; + c->select_buffer=NULL; + c->name_stack_size=0; + + /* matrix */ + c->matrix_mode=0; + + c->matrix_stack_depth_max[0]=MAX_MODELVIEW_STACK_DEPTH; + c->matrix_stack_depth_max[1]=MAX_PROJECTION_STACK_DEPTH; + c->matrix_stack_depth_max[2]=MAX_TEXTURE_STACK_DEPTH; + + for(i=0;i<3;i++) { + c->matrix_stack[i]=gl_zalloc(c->matrix_stack_depth_max[i] * sizeof(M4)); + c->matrix_stack_ptr[i]=c->matrix_stack[i]; + } + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + c->matrix_model_projection_updated=1; + + /* opengl 1.1 arrays */ + c->client_states = 0; + + /* opengl 1.1 polygon offset */ + c->offset_states = 0; + + /* clear the resize callback function pointer */ + c->gl_resize_viewport = NULL; + + /* specular buffer */ + c->specbuf_first = NULL; + c->specbuf_used_counter = 0; + c->specbuf_num_buffers = 0; + + /* depth test */ + c->depth_test = 0; +} + +void glClose(void) +{ + GLContext *c=gl_get_context(); + endSharedState(c); + gl_free(c); +} diff --git a/3rdparty/tinygl-0.4-ugfx/src/light.c b/3rdparty/tinygl-0.4-ugfx/src/light.c new file mode 100644 index 00000000..a0eeca2d --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/light.c @@ -0,0 +1,306 @@ +#include "zgl.h" +#include "msghandling.h" + +void glopMaterial(GLContext *c,GLParam *p) +{ + int mode=p[1].i; + int type=p[2].i; + float *v=&p[3].f; + int i; + GLMaterial *m; + + if (mode == GL_FRONT_AND_BACK) { + p[1].i=GL_FRONT; + glopMaterial(c,p); + mode=GL_BACK; + } + if (mode == GL_FRONT) m=&c->materials[0]; + else m=&c->materials[1]; + + switch(type) { + case GL_EMISSION: + for(i=0;i<4;i++) + m->emission.v[i]=v[i]; + break; + case GL_AMBIENT: + for(i=0;i<4;i++) + m->ambient.v[i]=v[i]; + break; + case GL_DIFFUSE: + for(i=0;i<4;i++) + m->diffuse.v[i]=v[i]; + break; + case GL_SPECULAR: + for(i=0;i<4;i++) + m->specular.v[i]=v[i]; + break; + case GL_SHININESS: + m->shininess=v[0]; + m->shininess_i = (v[0]/128.0f)*SPECULAR_BUFFER_RESOLUTION; + break; + case GL_AMBIENT_AND_DIFFUSE: + for(i=0;i<4;i++) + m->diffuse.v[i]=v[i]; + for(i=0;i<4;i++) + m->ambient.v[i]=v[i]; + break; + default: + gl_assert(0); + } +} + +void glopColorMaterial(GLContext *c,GLParam *p) +{ + int mode=p[1].i; + int type=p[2].i; + + c->current_color_material_mode=mode; + c->current_color_material_type=type; +} + +void glopLight(GLContext *c,GLParam *p) +{ + int light=p[1].i; + int type=p[2].i; + V4 v; + GLLight *l; + int i; + + gl_assert(light >= GL_LIGHT0 && light < GL_LIGHT0+MAX_LIGHTS ); + + l=&c->lights[light-GL_LIGHT0]; + + for(i=0;i<4;i++) v.v[i]=p[3+i].f; + + switch(type) { + case GL_AMBIENT: + l->ambient=v; + break; + case GL_DIFFUSE: + l->diffuse=v; + break; + case GL_SPECULAR: + l->specular=v; + break; + case GL_POSITION: + { + V4 pos; + gl_M4_MulV4(&pos,c->matrix_stack_ptr[0],&v); + + l->position=pos; + + if (l->position.v[3] == 0) { + l->norm_position.X=pos.X; + l->norm_position.Y=pos.Y; + l->norm_position.Z=pos.Z; + + gl_V3_Norm(&l->norm_position); + } + } + break; + case GL_SPOT_DIRECTION: + for(i=0;i<3;i++) { + l->spot_direction.v[i]=v.v[i]; + l->norm_spot_direction.v[i]=v.v[i]; + } + gl_V3_Norm(&l->norm_spot_direction); + break; + case GL_SPOT_EXPONENT: + l->spot_exponent=v.v[0]; + break; + case GL_SPOT_CUTOFF: + { + float a=v.v[0]; + gl_assert(a == 180 || (a>=0 && a<=90)); + l->spot_cutoff=a; + if (a != 180) l->cos_spot_cutoff=cos(a * M_PI / 180.0); + } + break; + case GL_CONSTANT_ATTENUATION: + l->attenuation[0]=v.v[0]; + break; + case GL_LINEAR_ATTENUATION: + l->attenuation[1]=v.v[0]; + break; + case GL_QUADRATIC_ATTENUATION: + l->attenuation[2]=v.v[0]; + break; + default: + gl_assert(0); + } +} + + +void glopLightModel(GLContext *c,GLParam *p) +{ + int pname=p[1].i; + float *v=&p[2].f; + int i; + + switch(pname) { + case GL_LIGHT_MODEL_AMBIENT: + for(i=0;i<4;i++) + c->ambient_light_model.v[i]=v[i]; + break; + case GL_LIGHT_MODEL_LOCAL_VIEWER: + c->local_light_model=(int)v[0]; + break; + case GL_LIGHT_MODEL_TWO_SIDE: + c->light_model_two_side = (int)v[0]; + break; + default: + tgl_warning("glopLightModel: illegal pname: 0x%x\n", pname); + //gl_assert(0); + break; + } +} + + +static inline float clampf(float a,float min,float max) +{ + if (a<min) return min; + else if (a>max) return max; + else return a; +} + +void gl_enable_disable_light(GLContext *c,int light,int v) +{ + GLLight *l=&c->lights[light]; + if (v && !l->enabled) { + l->enabled=1; + l->next=c->first_light; + c->first_light=l; + l->prev=NULL; + } else if (!v && l->enabled) { + l->enabled=0; + if (l->prev == NULL) c->first_light=l->next; + else l->prev->next=l->next; + if (l->next != NULL) l->next->prev=l->prev; + } +} + +/* non optimized lightening model */ +void gl_shade_vertex(GLContext *c,GLVertex *v) +{ + float R,G,B,A; + GLMaterial *m; + GLLight *l; + V3 n,s,d; + float dist,tmp,att,dot,dot_spot,dot_spec; + int twoside = c->light_model_two_side; + + m=&c->materials[0]; + + n.X=v->normal.X; + n.Y=v->normal.Y; + n.Z=v->normal.Z; + + R=m->emission.v[0]+m->ambient.v[0]*c->ambient_light_model.v[0]; + G=m->emission.v[1]+m->ambient.v[1]*c->ambient_light_model.v[1]; + B=m->emission.v[2]+m->ambient.v[2]*c->ambient_light_model.v[2]; + A=clampf(m->diffuse.v[3],0,1); + + for(l=c->first_light;l!=NULL;l=l->next) { + float lR,lB,lG; + + /* ambient */ + lR=l->ambient.v[0] * m->ambient.v[0]; + lG=l->ambient.v[1] * m->ambient.v[1]; + lB=l->ambient.v[2] * m->ambient.v[2]; + + if (l->position.v[3] == 0) { + /* light at infinity */ + d.X=l->position.v[0]; + d.Y=l->position.v[1]; + d.Z=l->position.v[2]; + att=1; + } else { + /* distance attenuation */ + d.X=l->position.v[0]-v->ec.v[0]; + d.Y=l->position.v[1]-v->ec.v[1]; + d.Z=l->position.v[2]-v->ec.v[2]; + dist=sqrt(d.X*d.X+d.Y*d.Y+d.Z*d.Z); + if (dist>1E-3) { + tmp=1/dist; + d.X*=tmp; + d.Y*=tmp; + d.Z*=tmp; + } + att=1.0f/(l->attenuation[0]+dist*(l->attenuation[1]+ + dist*l->attenuation[2])); + } + dot=d.X*n.X+d.Y*n.Y+d.Z*n.Z; + if (twoside && dot < 0) dot = -dot; + if (dot>0) { + /* diffuse light */ + lR+=dot * l->diffuse.v[0] * m->diffuse.v[0]; + lG+=dot * l->diffuse.v[1] * m->diffuse.v[1]; + lB+=dot * l->diffuse.v[2] * m->diffuse.v[2]; + + /* spot light */ + if (l->spot_cutoff != 180) { + dot_spot=-(d.X*l->norm_spot_direction.v[0]+ + d.Y*l->norm_spot_direction.v[1]+ + d.Z*l->norm_spot_direction.v[2]); + if (twoside && dot_spot < 0) dot_spot = -dot_spot; + if (dot_spot < l->cos_spot_cutoff) { + /* no contribution */ + continue; + } else { + /* TODO: optimize */ + if (l->spot_exponent > 0) { + att=att*pow(dot_spot,l->spot_exponent); + } + } + } + + /* specular light */ + + if (c->local_light_model) { + V3 vcoord; + vcoord.X=v->ec.X; + vcoord.Y=v->ec.Y; + vcoord.Z=v->ec.Z; + gl_V3_Norm(&vcoord); + s.X=d.X-vcoord.X; + s.Y=d.Y-vcoord.X; + s.Z=d.Z-vcoord.X; + } else { + s.X=d.X; + s.Y=d.Y; + s.Z=d.Z+1.0; + } + dot_spec=n.X*s.X+n.Y*s.Y+n.Z*s.Z; + if (twoside && dot_spec < 0) dot_spec = -dot_spec; + if (dot_spec>0) { + GLSpecBuf *specbuf; + int idx; + tmp=sqrt(s.X*s.X+s.Y*s.Y+s.Z*s.Z); + if (tmp > 1E-3) { + dot_spec=dot_spec / tmp; + } + + /* TODO: optimize */ + /* testing specular buffer code */ + /* dot_spec= pow(dot_spec,m->shininess);*/ + specbuf = specbuf_get_buffer(c, m->shininess_i, m->shininess); + idx = (int)(dot_spec*SPECULAR_BUFFER_SIZE); + if (idx > SPECULAR_BUFFER_SIZE) idx = SPECULAR_BUFFER_SIZE; + dot_spec = specbuf->buf[idx]; + lR+=dot_spec * l->specular.v[0] * m->specular.v[0]; + lG+=dot_spec * l->specular.v[1] * m->specular.v[1]; + lB+=dot_spec * l->specular.v[2] * m->specular.v[2]; + } + } + + R+=att * lR; + G+=att * lG; + B+=att * lB; + } + + v->color.v[0]=clampf(R,0,1); + v->color.v[1]=clampf(G,0,1); + v->color.v[2]=clampf(B,0,1); + v->color.v[3]=A; +} + diff --git a/3rdparty/tinygl-0.4-ugfx/src/list.c b/3rdparty/tinygl-0.4-ugfx/src/list.c new file mode 100644 index 00000000..b8d84137 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/list.c @@ -0,0 +1,263 @@ +#include "zgl.h" + +static char *op_table_str[]= +{ +#define ADD_OP(a,b,c) "gl" #a " " #c, + +#include "opinfo.h" +}; + +static void (*op_table_func[])(GLContext *,GLParam *)= +{ +#define ADD_OP(a,b,c) glop ## a , + +#include "opinfo.h" +}; + +static int op_table_size[]= +{ +#define ADD_OP(a,b,c) b + 1 , + +#include "opinfo.h" +}; + + +GLContext *gl_get_context(void) +{ + return gl_ctx; +} + +static GLList *find_list(GLContext *c,unsigned int list) +{ + return c->shared_state.lists[list]; +} + +static void delete_list(GLContext *c,int list) +{ + GLParamBuffer *pb,*pb1; + GLList *l; + + l=find_list(c,list); + gl_assert(l != NULL); + + /* free param buffer */ + pb=l->first_op_buffer; + while (pb!=NULL) { + pb1=pb->next; + gl_free(pb); + pb=pb1; + } + + gl_free(l); + c->shared_state.lists[list]=NULL; +} + +static GLList *alloc_list(GLContext *c,int list) +{ + GLList *l; + GLParamBuffer *ob; + + l=gl_zalloc(sizeof(GLList)); + ob=gl_zalloc(sizeof(GLParamBuffer)); + + ob->next=NULL; + l->first_op_buffer=ob; + + ob->ops[0].op=OP_EndList; + + c->shared_state.lists[list]=l; + return l; +} + + +#ifndef NO_STDIO +void gl_print_op(FILE *f,GLParam *p) +{ + int op; + char *s; + + op=p[0].op; + p++; + s=op_table_str[op]; + while (*s != 0) { + if (*s == '%') { + s++; + switch (*s++) { + case 'f': + fprintf(f,"%g",p[0].f); + break; + default: + fprintf(f,"%d",p[0].i); + break; + } + p++; + } else { + fputc(*s,f); + s++; + } + } + fprintf(f,"\n"); +} +#endif + + +void gl_compile_op(GLContext *c,GLParam *p) +{ + int op,op_size; + GLParamBuffer *ob,*ob1; + int index,i; + + op=p[0].op; + op_size=op_table_size[op]; + index=c->current_op_buffer_index; + ob=c->current_op_buffer; + + /* we should be able to add a NextBuffer opcode */ + if ((index + op_size) > (OP_BUFFER_MAX_SIZE-2)) { + + ob1=gl_zalloc(sizeof(GLParamBuffer)); + ob1->next=NULL; + + ob->next=ob1; + ob->ops[index].op=OP_NextBuffer; + ob->ops[index+1].p=(void *)ob1; + + c->current_op_buffer=ob1; + ob=ob1; + index=0; + } + + for(i=0;i<op_size;i++) { + ob->ops[index]=p[i]; + index++; + } + c->current_op_buffer_index=index; +} + +void gl_add_op(GLParam *p) +{ + GLContext *c=gl_get_context(); + int op; + + op=p[0].op; + if (c->exec_flag) { + op_table_func[op](c,p); + } + if (c->compile_flag) { + gl_compile_op(c,p); + } +#ifndef NO_CLIBRARY + if (c->print_flag) { + gl_print_op(stderr,p); + } +#endif +} + +/* this opcode is never called directly */ +void glopEndList(GLContext *c,GLParam *p) +{ + (void) c; + (void) p; + gl_assert(0); +} + +/* this opcode is never called directly */ +void glopNextBuffer(GLContext *c,GLParam *p) +{ + (void) c; + (void) p; + gl_assert(0); +} + + +void glopCallList(GLContext *c,GLParam *p) +{ + GLList *l; + int list,op; + + list=p[1].ui; + l=find_list(c,list); + if (l == NULL) gl_fatal_error("list %d not defined",list); + p=l->first_op_buffer->ops; + + while (1) { + op=p[0].op; + if (op == OP_EndList) break; + if (op == OP_NextBuffer) { + p=(GLParam *)p[1].p; + } else { + op_table_func[op](c,p); + p+=op_table_size[op]; + } + } +} + + + +void glNewList(unsigned int list,int mode) +{ + GLList *l; + GLContext *c=gl_get_context(); + + gl_assert(mode == GL_COMPILE || mode == GL_COMPILE_AND_EXECUTE); + gl_assert(c->compile_flag == 0); + + l=find_list(c,list); + if (l!=NULL) delete_list(c,list); + l=alloc_list(c,list); + + c->current_op_buffer=l->first_op_buffer; + c->current_op_buffer_index=0; + + c->compile_flag=1; + c->exec_flag=(mode == GL_COMPILE_AND_EXECUTE); +} + +void glEndList(void) +{ + GLContext *c=gl_get_context(); + GLParam p[1]; + + gl_assert(c->compile_flag == 1); + + /* end of list */ + p[0].op=OP_EndList; + gl_compile_op(c,p); + + c->compile_flag=0; + c->exec_flag=1; +} + +int glIsList(unsigned int list) +{ + GLContext *c=gl_get_context(); + GLList *l; + l=find_list(c,list); + return (l != NULL); +} + +unsigned int glGenLists(int range) +{ + GLContext *c=gl_get_context(); + int count,i,list; + GLList **lists; + + lists=c->shared_state.lists; + count=0; + for(i=0;i<MAX_DISPLAY_LISTS;i++) { + if (lists[i]==NULL) { + count++; + if (count == range) { + list=i-range+1; + for(i=0;i<range;i++) { + alloc_list(c,list+i); + } + return list; + } + } else { + count=0; + } + } + return 0; +} + diff --git a/3rdparty/tinygl-0.4-ugfx/src/matrix.c b/3rdparty/tinygl-0.4-ugfx/src/matrix.c new file mode 100644 index 00000000..dfdced7b --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/matrix.c @@ -0,0 +1,247 @@ +#include "zgl.h" + +void gl_print_matrix( const float *m) +{ +#ifndef NO_CLIBRARY + int i; + + for (i=0;i<4;i++) { + fprintf(stderr,"%f %f %f %f\n", m[i], m[4+i], m[8+i], m[12+i] ); + } +#else + (void) m; +#endif +} + +static inline void gl_matrix_update(GLContext *c) +{ + c->matrix_model_projection_updated=(c->matrix_mode<=1); +} + + +void glopMatrixMode(GLContext *c,GLParam *p) +{ + int mode=p[1].i; + switch(mode) { + case GL_MODELVIEW: + c->matrix_mode=0; + break; + case GL_PROJECTION: + c->matrix_mode=1; + break; + case GL_TEXTURE: + c->matrix_mode=2; + break; + default: + gl_assert(0); + } +} + +void glopLoadMatrix(GLContext *c,GLParam *p) +{ + M4 *m; + int i; + + GLParam *q; + + m=c->matrix_stack_ptr[c->matrix_mode]; + q=p+1; + + for(i=0;i<4;i++) { + m->m[0][i]=q[0].f; + m->m[1][i]=q[1].f; + m->m[2][i]=q[2].f; + m->m[3][i]=q[3].f; + q+=4; + } + + gl_matrix_update(c); +} + +void glopLoadIdentity(GLContext *c,GLParam *p) +{ + (void)p; + gl_M4_Id(c->matrix_stack_ptr[c->matrix_mode]); + + gl_matrix_update(c); +} + +void glopMultMatrix(GLContext *c,GLParam *p) +{ + M4 m; + int i; + + GLParam *q; + q=p+1; + + for(i=0;i<4;i++) { + m.m[0][i]=q[0].f; + m.m[1][i]=q[1].f; + m.m[2][i]=q[2].f; + m.m[3][i]=q[3].f; + q+=4; + } + + gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode],&m); + + gl_matrix_update(c); +} + + +void glopPushMatrix(GLContext *c,GLParam *p) +{ + int n=c->matrix_mode; + M4 *m; + (void)p; + + gl_assert( (c->matrix_stack_ptr[n] - c->matrix_stack[n] + 1 ) + < c->matrix_stack_depth_max[n] ); + + m=++c->matrix_stack_ptr[n]; + + gl_M4_Move(&m[0],&m[-1]); + + gl_matrix_update(c); +} + +void glopPopMatrix(GLContext *c,GLParam *p) +{ + int n=c->matrix_mode; + (void)p; + + gl_assert( c->matrix_stack_ptr[n] > c->matrix_stack[n] ); + c->matrix_stack_ptr[n]--; + gl_matrix_update(c); +} + + +void glopRotate(GLContext *c,GLParam *p) +{ + M4 m; + float u[3]; + float angle; + int dir_code; + + angle = p[1].f * M_PI / 180.0; + u[0]=p[2].f; + u[1]=p[3].f; + u[2]=p[4].f; + + /* simple case detection */ + dir_code = ((u[0] != 0)<<2) | ((u[1] != 0)<<1) | (u[2] != 0); + + switch(dir_code) { + case 0: + gl_M4_Id(&m); + break; + case 4: + if (u[0] < 0) angle=-angle; + gl_M4_Rotate(&m,angle,0); + break; + case 2: + if (u[1] < 0) angle=-angle; + gl_M4_Rotate(&m,angle,1); + break; + case 1: + if (u[2] < 0) angle=-angle; + gl_M4_Rotate(&m,angle,2); + break; + default: + { + float cost, sint; + + /* normalize vector */ + float len = u[0]*u[0]+u[1]*u[1]+u[2]*u[2]; + if (len == 0.0f) return; + len = 1.0f / sqrt(len); + u[0] *= len; + u[1] *= len; + u[2] *= len; + + /* store cos and sin values */ + cost=cos(angle); + sint=sin(angle); + + /* fill in the values */ + m.m[3][0]=m.m[3][1]=m.m[3][2]= + m.m[0][3]=m.m[1][3]=m.m[2][3]=0.0f; + m.m[3][3]=1.0f; + + /* do the math */ + m.m[0][0]=u[0]*u[0]+cost*(1-u[0]*u[0]); + m.m[1][0]=u[0]*u[1]*(1-cost)-u[2]*sint; + m.m[2][0]=u[2]*u[0]*(1-cost)+u[1]*sint; + m.m[0][1]=u[0]*u[1]*(1-cost)+u[2]*sint; + m.m[1][1]=u[1]*u[1]+cost*(1-u[1]*u[1]); + m.m[2][1]=u[1]*u[2]*(1-cost)-u[0]*sint; + m.m[0][2]=u[2]*u[0]*(1-cost)-u[1]*sint; + m.m[1][2]=u[1]*u[2]*(1-cost)+u[0]*sint; + m.m[2][2]=u[2]*u[2]+cost*(1-u[2]*u[2]); + } + } + + gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode],&m); + + gl_matrix_update(c); +} + +void glopScale(GLContext *c,GLParam *p) +{ + float *m; + float x=p[1].f,y=p[2].f,z=p[3].f; + + m=&c->matrix_stack_ptr[c->matrix_mode]->m[0][0]; + + m[0] *= x; m[1] *= y; m[2] *= z; + m[4] *= x; m[5] *= y; m[6] *= z; + m[8] *= x; m[9] *= y; m[10] *= z; + m[12] *= x; m[13] *= y; m[14] *= z; + gl_matrix_update(c); +} + +void glopTranslate(GLContext *c,GLParam *p) +{ + float *m; + float x=p[1].f,y=p[2].f,z=p[3].f; + + m=&c->matrix_stack_ptr[c->matrix_mode]->m[0][0]; + + m[3] = m[0] * x + m[1] * y + m[2] * z + m[3]; + m[7] = m[4] * x + m[5] * y + m[6] * z + m[7]; + m[11] = m[8] * x + m[9] * y + m[10] * z + m[11]; + m[15] = m[12] * x + m[13] * y + m[14] * z + m[15]; + + gl_matrix_update(c); +} + + +void glopFrustum(GLContext *c,GLParam *p) +{ + float *r; + M4 m; + float left=p[1].f; + float right=p[2].f; + float bottom=p[3].f; + float top=p[4].f; + float xnear=p[5].f; + float farp=p[6].f; + float x,y,A,B,C,D; + + x = (2.0*xnear) / (right-left); + y = (2.0*xnear) / (top-bottom); + A = (right+left) / (right-left); + B = (top+bottom) / (top-bottom); + C = -(farp+xnear) / ( farp-xnear); + D = -(2.0*farp*xnear) / (farp-xnear); + + r=&m.m[0][0]; + r[0]= x; r[1]=0; r[2]=A; r[3]=0; + r[4]= 0; r[5]=y; r[6]=B; r[7]=0; + r[8]= 0; r[9]=0; r[10]=C; r[11]=D; + r[12]= 0; r[13]=0; r[14]=-1; r[15]=0; + + gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode],&m); + + gl_matrix_update(c); +} + diff --git a/3rdparty/tinygl-0.4-ugfx/src/memory.c b/3rdparty/tinygl-0.4-ugfx/src/memory.c new file mode 100644 index 00000000..e1dc3cbb --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/memory.c @@ -0,0 +1,21 @@ +/* + * Memory allocator for TinyGL + */ +#include "zgl.h" + +/* modify these functions so that they suit your needs */ + +void gl_free(void *p) +{ + free(p); +} + +void *gl_malloc(int size) +{ + return malloc(size); +} + +void *gl_zalloc(int size) +{ + return calloc(1, size); +} diff --git a/3rdparty/tinygl-0.4-ugfx/src/misc.c b/3rdparty/tinygl-0.4-ugfx/src/misc.c new file mode 100644 index 00000000..7dedc75a --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/misc.c @@ -0,0 +1,149 @@ +#include "zgl.h" +#include "msghandling.h" + +void glopViewport(GLContext *c,GLParam *p) +{ + int xsize,ysize,xmin,ymin,xsize_req,ysize_req; + + xmin=p[1].i; + ymin=p[2].i; + xsize=p[3].i; + ysize=p[4].i; + + /* we may need to resize the zbuffer */ + + if (c->viewport.xmin != xmin || + c->viewport.ymin != ymin || + c->viewport.xsize != xsize || + c->viewport.ysize != ysize) { + + xsize_req=xmin+xsize; + ysize_req=ymin+ysize; + + if (c->gl_resize_viewport && + c->gl_resize_viewport(c,&xsize_req,&ysize_req) != 0) { + gl_fatal_error("glViewport: error while resizing display"); + } + + xsize=xsize_req-xmin; + ysize=ysize_req-ymin; + if (xsize <= 0 || ysize <= 0) { + gl_fatal_error("glViewport: size too small"); + } + + tgl_trace("glViewport: %d %d %d %d\n", + xmin, ymin, xsize, ysize); + c->viewport.xmin=xmin; + c->viewport.ymin=ymin; + c->viewport.xsize=xsize; + c->viewport.ysize=ysize; + + c->viewport.updated=1; + } +} + +void glopEnableDisable(GLContext *c,GLParam *p) +{ + int code=p[1].i; + int v=p[2].i; + + switch(code) { + case GL_CULL_FACE: + c->cull_face_enabled=v; + break; + case GL_LIGHTING: + c->lighting_enabled=v; + break; + case GL_COLOR_MATERIAL: + c->color_material_enabled=v; + break; + case GL_TEXTURE_2D: + c->texture_2d_enabled=v; + break; + case GL_NORMALIZE: + c->normalize_enabled=v; + break; + case GL_DEPTH_TEST: + c->depth_test = v; + break; + case GL_POLYGON_OFFSET_FILL: + if (v) c->offset_states |= TGL_OFFSET_FILL; + else c->offset_states &= ~TGL_OFFSET_FILL; + break; + case GL_POLYGON_OFFSET_POINT: + if (v) c->offset_states |= TGL_OFFSET_POINT; + else c->offset_states &= ~TGL_OFFSET_POINT; + break; + case GL_POLYGON_OFFSET_LINE: + if (v) c->offset_states |= TGL_OFFSET_LINE; + else c->offset_states &= ~TGL_OFFSET_LINE; + break; + default: + if (code>=GL_LIGHT0 && code<GL_LIGHT0+MAX_LIGHTS) { + gl_enable_disable_light(c,code - GL_LIGHT0, v); + } else { + /* + fprintf(stderr,"glEnableDisable: 0x%X not supported.\n",code); + */ + } + break; + } +} + +void glopShadeModel(GLContext *c,GLParam *p) +{ + int code=p[1].i; + c->current_shade_model=code; +} + +void glopCullFace(GLContext *c,GLParam *p) +{ + int code=p[1].i; + c->current_cull_face=code; +} + +void glopFrontFace(GLContext *c,GLParam *p) +{ + int code=p[1].i; + c->current_front_face=code; +} + +void glopPolygonMode(GLContext *c,GLParam *p) +{ + int face=p[1].i; + int mode=p[2].i; + + switch(face) { + case GL_BACK: + c->polygon_mode_back=mode; + break; + case GL_FRONT: + c->polygon_mode_front=mode; + break; + case GL_FRONT_AND_BACK: + c->polygon_mode_front=mode; + c->polygon_mode_back=mode; + break; + default: + gl_assert(0); + } +} + +void glopHint(GLContext *c,GLParam *p) +{ + (void)c; + (void)p; +#if 0 + int target=p[1].i; + int mode=p[2].i; + + /* do nothing */ +#endif +} + +void +glopPolygonOffset(GLContext *c, GLParam *p) +{ + c->offset_factor = p[1].f; + c->offset_units = p[2].f; +} diff --git a/3rdparty/tinygl-0.4-ugfx/src/msghandling.c b/3rdparty/tinygl-0.4-ugfx/src/msghandling.c new file mode 100644 index 00000000..c5b10614 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/msghandling.c @@ -0,0 +1,52 @@ +#include <stdarg.h> +#include <stdio.h> + +#define NDEBUG + +#ifdef NDEBUG +#define NO_DEBUG_OUTPUT +#endif + +/* Use this function to output messages when something unexpected + happens (which might be an indication of an error). *Don't* use it + when there's internal errors in the code - these should be handled + by asserts. */ +void +tgl_warning(const char *format, ...) +{ +#ifndef NO_DEBUG_OUTPUT + va_list args; + va_start(args, format); + fprintf(stderr, "*WARNING* "); + vfprintf(stderr, format, args); + va_end(args); +#endif /* !NO_DEBUG_OUTPUT */ +} + +/* This function should be used for debug output only. */ +void +tgl_trace(const char *format, ...) +{ +#ifndef NO_DEBUG_OUTPUT + va_list args; + va_start(args, format); + fprintf(stderr, "*DEBUG* "); + vfprintf(stderr, format, args); + va_end(args); +#endif /* !NO_DEBUG_OUTPUT */ +} + +/* Use this function to output info about things in the code which + should be fixed (missing handling of special cases, important + features not implemented, known bugs/buglets, ...). */ +void +tgl_fixme(const char *format, ...) +{ +#ifndef NO_DEBUG_OUTPUT + va_list args; + va_start(args, format); + fprintf(stderr, "*FIXME* "); + vfprintf(stderr, format, args); + va_end(args); +#endif /* !NO_DEBUG_OUTPUT */ +} diff --git a/3rdparty/tinygl-0.4-ugfx/src/msghandling.h b/3rdparty/tinygl-0.4-ugfx/src/msghandling.h new file mode 100644 index 00000000..ebe4548c --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/msghandling.h @@ -0,0 +1,8 @@ +#ifndef _msghandling_h_ +#define _msghandling_h_ + +extern void tgl_warning(const char *text, ...); +extern void tgl_trace(const char *text, ...); +extern void tgl_fixme(const char *text, ...); + +#endif /* _msghandling_h_ */ diff --git a/3rdparty/tinygl-0.4-ugfx/src/nglx.c b/3rdparty/tinygl-0.4-ugfx/src/nglx.c new file mode 100644 index 00000000..26f356c2 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/nglx.c @@ -0,0 +1,128 @@ +/* simple glx like driver for TinyGL and Nano X */ +#include <GL/gl.h> +#include <GL/nglx.h> +#include <microwin/nano-X.h> +#include "zgl.h" + +typedef struct { + GLContext *gl_context; + int xsize,ysize; + GR_DRAW_ID drawable; + GR_GC_ID gc; + int pixtype; /* pixel type in TinyGL */ +} TinyNGLXContext; + +NGLXContext nglXCreateContext(NGLXContext shareList, int flags) +{ + TinyNGLXContext *ctx; + + if (shareList != NULL) { + gl_fatal_error("No sharing available in TinyGL"); + } + ctx=gl_malloc(sizeof(TinyNGLXContext)); + if (!ctx) + return NULL; + ctx->gl_context=NULL; + return (NGLXContext) ctx; +} + +void glXDestroyContext( NGLXContext ctx1 ) +{ + TinyNGLXContext *ctx = (TinyNGLXContext *) ctx1; + if (ctx->gl_context != NULL) { + glClose(); + } + gl_free(ctx); +} + + +/* resize the glx viewport : we try to use the xsize and ysize + given. We return the effective size which is guaranted to be smaller */ + +static int glX_resize_viewport(GLContext *c,int *xsize_ptr,int *ysize_ptr) +{ + TinyNGLXContext *ctx; + int xsize,ysize; + + ctx=(TinyNGLXContext *)c->opaque; + + xsize=*xsize_ptr; + ysize=*ysize_ptr; + + /* we ensure that xsize and ysize are multiples of 2 for the zbuffer. + TODO: find a better solution */ + xsize&=~3; + ysize&=~3; + + if (xsize == 0 || ysize == 0) return -1; + + *xsize_ptr=xsize; + *ysize_ptr=ysize; + + ctx->xsize=xsize; + ctx->ysize=ysize; + + /* resize the Z buffer */ + ZB_resize(c->zb,NULL,xsize,ysize); + return 0; +} + +/* we assume here that drawable is a window */ +int nglXMakeCurrent( NGLXDrawable drawable, + NGLXContext ctx1) +{ + TinyNGLXContext *ctx = (TinyNGLXContext *) ctx1; + int mode, xsize, ysize; + ZBuffer *zb; + GR_WINDOW_INFO win_info; + + if (ctx->gl_context == NULL) { + /* create the TinyGL context */ + GrGetWindowInfo(drawable, &win_info); + + xsize = win_info.width; + ysize = win_info.height; + + /* currently, we only support 16 bit rendering */ + mode = ZB_MODE_5R6G5B; + zb=ZB_open(xsize,ysize,mode,0,NULL,NULL,NULL); + if (zb == NULL) { + fprintf(stderr, "Error while initializing Z buffer\n"); + exit(1); + } + + ctx->pixtype = MWPF_TRUECOLOR565; + + /* create a gc */ + ctx->gc = GrNewGC(); + + /* initialisation of the TinyGL interpreter */ + glInit(zb); + ctx->gl_context=gl_get_context(); + ctx->gl_context->opaque=(void *) ctx; + ctx->gl_context->gl_resize_viewport=glX_resize_viewport; + + /* set the viewport : we force a call to glX_resize_viewport */ + ctx->gl_context->viewport.xsize=-1; + ctx->gl_context->viewport.ysize=-1; + + glViewport(0, 0, xsize, ysize); + } + + return 1; +} + +void nglXSwapBuffers( NGLXDrawable drawable ) +{ + GLContext *gl_context; + TinyNGLXContext *ctx; + + /* retrieve the current NGLXContext */ + gl_context=gl_get_context(); + ctx=(TinyNGLXContext *)gl_context->opaque; + + GrArea(drawable, ctx->gc, 0, 0, ctx->xsize, + ctx->ysize, ctx->gl_context->zb->pbuf, ctx->pixtype); +} + + diff --git a/3rdparty/tinygl-0.4-ugfx/src/opinfo.h b/3rdparty/tinygl-0.4-ugfx/src/opinfo.h new file mode 100644 index 00000000..e57344e8 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/opinfo.h @@ -0,0 +1,71 @@ + + +ADD_OP(Color,7,"%f %f %f %f %d %d %d") +ADD_OP(TexCoord,4,"%f %f %f %f") +ADD_OP(EdgeFlag,1,"%d") +ADD_OP(Normal,3,"%f %f %f") + +ADD_OP(Begin,1,"%C") +ADD_OP(Vertex,4,"%f %f %f %f") +ADD_OP(End,0,"") + +ADD_OP(EnableDisable,2,"%C %d") + +ADD_OP(MatrixMode,1,"%C") +ADD_OP(LoadMatrix,16,"") +ADD_OP(LoadIdentity,0,"") +ADD_OP(MultMatrix,16,"") +ADD_OP(PushMatrix,0,"") +ADD_OP(PopMatrix,0,"") +ADD_OP(Rotate,4,"%f %f %f %f") +ADD_OP(Translate,3,"%f %f %f") +ADD_OP(Scale,3,"%f %f %f") + +ADD_OP(Viewport,4,"%d %d %d %d") +ADD_OP(Frustum,6,"%f %f %f %f %f %f") + +ADD_OP(Material,6,"%C %C %f %f %f %f") +ADD_OP(ColorMaterial,2,"%C %C") +ADD_OP(Light,6,"%C %C %f %f %f %f") +ADD_OP(LightModel,5,"%C %f %f %f %f") + +ADD_OP(Clear,1,"%d") +ADD_OP(ClearColor,4,"%f %f %f %f") +ADD_OP(ClearDepth,1,"%f") + +ADD_OP(InitNames,0,"") +ADD_OP(PushName,1,"%d") +ADD_OP(PopName,0,"") +ADD_OP(LoadName,1,"%d") + +ADD_OP(TexImage2D,9,"%d %d %d %d %d %d %d %d %d") +ADD_OP(BindTexture,2,"%C %d") +ADD_OP(TexEnv,7,"%C %C %C %f %f %f %f") +ADD_OP(TexParameter,7,"%C %C %C %f %f %f %f") +ADD_OP(PixelStore,2,"%C %C") + +ADD_OP(ShadeModel,1,"%C") +ADD_OP(CullFace,1,"%C") +ADD_OP(FrontFace,1,"%C") +ADD_OP(PolygonMode,2,"%C %C") + +ADD_OP(CallList,1,"%d") +ADD_OP(Hint,2,"%C %C") + +/* special opcodes */ +ADD_OP(EndList,0,"") +ADD_OP(NextBuffer,1,"%p") + +/* opengl 1.1 arrays */ +ADD_OP(ArrayElement, 1, "%d") +ADD_OP(EnableClientState, 1, "%C") +ADD_OP(DisableClientState, 1, "%C") +ADD_OP(VertexPointer, 4, "%d %C %d %p") +ADD_OP(ColorPointer, 4, "%d %C %d %p") +ADD_OP(NormalPointer, 3, "%C %d %p") +ADD_OP(TexCoordPointer, 4, "%d %C %d %p") + +/* opengl 1.1 polygon offset */ +ADD_OP(PolygonOffset, 2, "%f %f") + +#undef ADD_OP diff --git a/3rdparty/tinygl-0.4-ugfx/src/oscontext.c b/3rdparty/tinygl-0.4-ugfx/src/oscontext.c new file mode 100644 index 00000000..f91374d3 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/oscontext.c @@ -0,0 +1,83 @@ +#include <GL/oscontext.h> +#include "zbuffer.h" +#include "zgl.h" +#include <GL/gl.h> +#include <stdlib.h> + +static int buffercnt = 0; + +ostgl_context * +ostgl_create_context(const int xsize, + const int ysize, + const int depth, + void **framebuffers, + const int numbuffers) +{ + ostgl_context *context; + int i; + ZBuffer *zb; + + gl_assert(depth == 16); /* support for other depths must include bpp + convertion */ + gl_assert(numbuffers >= 1); + + context = gl_malloc(sizeof(ostgl_context)); + gl_assert(context); + context->zbs = gl_malloc(sizeof(void*)*numbuffers); + context->framebuffers = gl_malloc(sizeof(void*)*numbuffers); + + gl_assert(context->zbs != NULL && context->framebuffers != NULL); + + for (i = 0; i < numbuffers; i++) { + context->framebuffers[i] = framebuffers[i]; + zb = ZB_open(xsize, ysize, ZB_MODE_5R6G5B, 0, NULL, NULL, framebuffers[i]); + if (zb == NULL) { + fprintf(stderr, "Error while initializing Z buffer\n"); + exit(1); + } + context->zbs[i] = zb; + } + if (++buffercnt == 1) { + glInit(context->zbs[0]); + } + context->xsize = xsize; + context->ysize = ysize; + context->numbuffers = numbuffers; + return context; +} + +void +ostgl_delete_context(ostgl_context *context) +{ + int i; + for (i = 0; i < context->numbuffers; i++) { + ZB_close(context->zbs[i]); + } + gl_free(context->zbs); + gl_free(context->framebuffers); + gl_free(context); + + if (--buffercnt == 0) { + glClose(); + } +} + +void +ostgl_make_current(ostgl_context *oscontext, const int idx) +{ + GLContext *context = gl_get_context(); + gl_assert(idx < oscontext->numbuffers); + context->zb = oscontext->zbs[idx]; +} + +void +ostgl_resize(ostgl_context *context, + const int xsize, + const int ysize, + void **framebuffers) +{ + int i; + for (i = 0; i < context->numbuffers; i++) { + ZB_resize(context->zbs[i], framebuffers[i], xsize, ysize); + } +} diff --git a/3rdparty/tinygl-0.4-ugfx/src/select.c b/3rdparty/tinygl-0.4-ugfx/src/select.c new file mode 100644 index 00000000..46134dbc --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/select.c @@ -0,0 +1,116 @@ +#include "zgl.h" + +int glRenderMode(int mode) +{ + GLContext *c=gl_get_context(); + int result=0; + + switch(c->render_mode) { + case GL_RENDER: + break; + case GL_SELECT: + if (c->select_overflow) { + result=-c->select_hits; + } else { + result=c->select_hits; + } + c->select_overflow=0; + c->select_ptr=c->select_buffer; + c->name_stack_size=0; + break; + default: + gl_assert(0); + } + switch(mode) { + case GL_RENDER: + c->render_mode=GL_RENDER; + break; + case GL_SELECT: + c->render_mode=GL_SELECT; + gl_assert( c->select_buffer != NULL); + c->select_ptr=c->select_buffer; + c->select_hits=0; + c->select_overflow=0; + c->select_hit=NULL; + break; + default: + gl_assert(0); + } + return result; +} + +void glSelectBuffer(int size,unsigned int *buf) +{ + GLContext *c=gl_get_context(); + + gl_assert(c->render_mode != GL_SELECT); + + c->select_buffer=buf; + c->select_size=size; +} + + +void glopInitNames(GLContext *c,GLParam *p) +{ + (void)p; + if (c->render_mode == GL_SELECT) { + c->name_stack_size=0; + c->select_hit=NULL; + } +} + +void glopPushName(GLContext *c,GLParam *p) +{ + if (c->render_mode == GL_SELECT) { + gl_assert(c->name_stack_size<MAX_NAME_STACK_DEPTH); + c->name_stack[c->name_stack_size++]=p[1].i; + c->select_hit=NULL; + } +} + +void glopPopName(GLContext *c,GLParam *p) +{ + (void)p; + if (c->render_mode == GL_SELECT) { + gl_assert(c->name_stack_size>0); + c->name_stack_size--; + c->select_hit=NULL; + } +} + +void glopLoadName(GLContext *c,GLParam *p) +{ + if (c->render_mode == GL_SELECT) { + gl_assert(c->name_stack_size>0); + c->name_stack[c->name_stack_size-1]=p[1].i; + c->select_hit=NULL; + } +} + +void gl_add_select(GLContext *c,unsigned int zmin,unsigned int zmax) +{ + unsigned int *ptr; + int n,i; + + if (!c->select_overflow) { + if (c->select_hit==NULL) { + n=c->name_stack_size; + if ((c->select_ptr-c->select_buffer+3+n) > + c->select_size) { + c->select_overflow=1; + } else { + ptr=c->select_ptr; + c->select_hit=ptr; + *ptr++=c->name_stack_size; + *ptr++=zmin; + *ptr++=zmax; + for(i=0;i<n;i++) *ptr++=c->name_stack[i]; + c->select_ptr=ptr; + c->select_hits++; + } + } else { + if (zmin<c->select_hit[1]) c->select_hit[1]=zmin; + if (zmax>c->select_hit[2]) c->select_hit[2]=zmax; + } + } +} diff --git a/3rdparty/tinygl-0.4-ugfx/src/specbuf.c b/3rdparty/tinygl-0.4-ugfx/src/specbuf.c new file mode 100644 index 00000000..7cbfb057 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/specbuf.c @@ -0,0 +1,52 @@ +#include "zgl.h" +#include "msghandling.h" +#include <math.h> +#include <stdlib.h> + +static void calc_buf(GLSpecBuf *buf, const float shininess) +{ + int i; + float val, inc; + val = 0.0f; + inc = 1.0f/SPECULAR_BUFFER_SIZE; + for (i = 0; i <= SPECULAR_BUFFER_SIZE; i++) { + buf->buf[i] = pow(val, shininess); + val += inc; + } +} + +GLSpecBuf * +specbuf_get_buffer(GLContext *c, const int shininess_i, + const float shininess) +{ + GLSpecBuf *found, *oldest; + found = oldest = c->specbuf_first; + while (found && found->shininess_i != shininess_i) { + if (found->last_used < oldest->last_used) { + oldest = found; + } + found = found->next; + } + if (found) { /* hey, found one! */ + found->last_used = c->specbuf_used_counter++; + return found; + } + if (oldest == NULL || c->specbuf_num_buffers < MAX_SPECULAR_BUFFERS) { + /* create new buffer */ + GLSpecBuf *buf = gl_malloc(sizeof(GLSpecBuf)); + if (!buf) gl_fatal_error("could not allocate specular buffer"); + c->specbuf_num_buffers++; + buf->next = c->specbuf_first; + c->specbuf_first = buf; + buf->last_used = c->specbuf_used_counter++; + buf->shininess_i = shininess_i; + calc_buf(buf, shininess); + return buf; + } + /* overwrite the lru buffer */ + /*tgl_trace("overwriting spec buffer :(\n");*/ + oldest->shininess_i = shininess_i; + oldest->last_used = c->specbuf_used_counter++; + calc_buf(oldest, shininess); + return oldest; +} diff --git a/3rdparty/tinygl-0.4-ugfx/src/specbuf.h b/3rdparty/tinygl-0.4-ugfx/src/specbuf.h new file mode 100644 index 00000000..ae5da3f8 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/specbuf.h @@ -0,0 +1,22 @@ +#ifndef _tgl_specbuf_h_ +#define _tgl_specbuf_h_ + +/* Max # of specular light pow buffers */ +#define MAX_SPECULAR_BUFFERS 8 +/* # of entries in specular buffer */ +#define SPECULAR_BUFFER_SIZE 1024 +/* specular buffer granularity */ +#define SPECULAR_BUFFER_RESOLUTION 1024 + +typedef struct GLSpecBuf { + int shininess_i; + int last_used; + float buf[SPECULAR_BUFFER_SIZE+1]; + struct GLSpecBuf *next; +} GLSpecBuf; + +GLSpecBuf *specbuf_get_buffer(GLContext *c, const int shininess_i, + const float shininess); +void specbuf_cleanup(GLContext *c); /* free all memory used */ + +#endif /* _tgl_specbuf_h_ */
\ No newline at end of file diff --git a/3rdparty/tinygl-0.4-ugfx/src/texture.c b/3rdparty/tinygl-0.4-ugfx/src/texture.c new file mode 100644 index 00000000..abd88bd9 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/texture.c @@ -0,0 +1,232 @@ +/* + * Texture Manager + */ + +#include "zgl.h" + +static GLTexture *find_texture(GLContext *c,int h) +{ + GLTexture *t; + + t=c->shared_state.texture_hash_table[h % TEXTURE_HASH_TABLE_SIZE]; + while (t!=NULL) { + if (t->handle == h) return t; + t=t->next; + } + return NULL; +} + +static void free_texture(GLContext *c,int h) +{ + GLTexture *t,**ht; + GLImage *im; + int i; + + t=find_texture(c,h); + if (t->prev==NULL) { + ht=&c->shared_state.texture_hash_table + [t->handle % TEXTURE_HASH_TABLE_SIZE]; + *ht=t->next; + } else { + t->prev->next=t->next; + } + if (t->next!=NULL) t->next->prev=t->prev; + + for(i=0;i<MAX_TEXTURE_LEVELS;i++) { + im=&t->images[i]; + if (im->pixmap != NULL) gl_free(im->pixmap); + } + + gl_free(t); +} + +GLTexture *alloc_texture(GLContext *c,int h) +{ + GLTexture *t,**ht; + + t=gl_zalloc(sizeof(GLTexture)); + + ht=&c->shared_state.texture_hash_table[h % TEXTURE_HASH_TABLE_SIZE]; + + t->next=*ht; + t->prev=NULL; + if (t->next != NULL) t->next->prev=t; + *ht=t; + + t->handle=h; + + return t; +} + + +void glInitTextures(GLContext *c) +{ + /* textures */ + + c->texture_2d_enabled=0; + c->current_texture=find_texture(c,0); +} + +void glGenTextures(int n, unsigned int *textures) +{ + GLContext *c=gl_get_context(); + int max,i; + GLTexture *t; + + max=0; + for(i=0;i<TEXTURE_HASH_TABLE_SIZE;i++) { + t=c->shared_state.texture_hash_table[i]; + while (t!=NULL) { + if (t->handle>max) max=t->handle; + t=t->next; + } + + } + for(i=0;i<n;i++) { + textures[i]=max+i+1; + } +} + + +void glDeleteTextures(int n, const unsigned int *textures) +{ + GLContext *c=gl_get_context(); + int i; + GLTexture *t; + + for(i=0;i<n;i++) { + t=find_texture(c,textures[i]); + if (t!=NULL && t!=0) { + if (t==c->current_texture) { + glBindTexture(GL_TEXTURE_2D,0); + } + free_texture(c,textures[i]); + } + } +} + + +void glopBindTexture(GLContext *c,GLParam *p) +{ + int target=p[1].i; + int texture=p[2].i; + GLTexture *t; + + gl_assert(target == GL_TEXTURE_2D && texture >= 0); + + t=find_texture(c,texture); + if (t==NULL) { + t=alloc_texture(c,texture); + } + c->current_texture=t; +} + +void glopTexImage2D(GLContext *c,GLParam *p) +{ + int target=p[1].i; + int level=p[2].i; + int components=p[3].i; + int width=p[4].i; + int height=p[5].i; + int border=p[6].i; + int format=p[7].i; + int type=p[8].i; + void *pixels=p[9].p; + GLImage *im; + unsigned char *pixels1; + int do_free; + + if (!(target == GL_TEXTURE_2D && level == 0 && components == 3 && + border == 0 && format == GL_RGB && + type == GL_UNSIGNED_BYTE)) { + gl_fatal_error("glTexImage2D: combinaison of parameters not handled"); + } + + do_free=0; + if (width != 256 || height != 256) { + pixels1 = gl_malloc(256 * 256 * 3); + /* no interpolation is done here to respect the original image aliasing ! */ + gl_resizeImageNoInterpolate(pixels1,256,256,pixels,width,height); + do_free=1; + width=256; + height=256; + } else { + pixels1=pixels; + } + + im=&c->current_texture->images[level]; + im->xsize=width; + im->ysize=height; + if (im->pixmap!=NULL) gl_free(im->pixmap); +#if TGL_FEATURE_RENDER_BITS == 24 + im->pixmap=gl_malloc(width*height*3); + if(im->pixmap) { + memcpy(im->pixmap,pixels1,width*height*3); + } +#elif TGL_FEATURE_RENDER_BITS == 32 + im->pixmap=gl_malloc(width*height*4); + if(im->pixmap) { + gl_convertRGB_to_8A8R8G8B(im->pixmap,pixels1,width,height); + } +#elif TGL_FEATURE_RENDER_BITS == 16 + im->pixmap=gl_malloc(width*height*2); + if(im->pixmap) { + gl_convertRGB_to_5R6G5B(im->pixmap,pixels1,width,height); + } +#else +#error TODO +#endif + if (do_free) gl_free(pixels1); +} + + +/* TODO: not all tests are done */ +void glopTexEnv(GLContext *c,GLParam *p) +{ + int target=p[1].i; + int pname=p[2].i; + int param=p[3].i; + (void)c; + + if (target != GL_TEXTURE_ENV) { + error: + gl_fatal_error("glTexParameter: unsupported option"); + } + + if (pname != GL_TEXTURE_ENV_MODE) goto error; + + if (param != GL_DECAL) goto error; +} + +/* TODO: not all tests are done */ +void glopTexParameter(GLContext *c,GLParam *p) +{ + int target=p[1].i; + int pname=p[2].i; + int param=p[3].i; + (void)c; + + if (target != GL_TEXTURE_2D) { + error: + gl_fatal_error("glTexParameter: unsupported option"); + } + + switch(pname) { + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + if (param != GL_REPEAT) goto error; + break; + } +} + +void glopPixelStore(GLContext *c,GLParam *p) +{ + int pname=p[1].i; + int param=p[2].i; + (void)c; + + if (pname != GL_UNPACK_ALIGNMENT || + param != 1) { + gl_fatal_error("glPixelStore: unsupported option"); + } +} diff --git a/3rdparty/tinygl-0.4-ugfx/src/vertex.c b/3rdparty/tinygl-0.4-ugfx/src/vertex.c new file mode 100644 index 00000000..6532c433 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/vertex.c @@ -0,0 +1,365 @@ +#include "zgl.h" + +void glopNormal(GLContext * c, GLParam * p) +{ + V3 v; + + v.X = p[1].f; + v.Y = p[2].f; + v.Z = p[3].f; + + c->current_normal.X = v.X; + c->current_normal.Y = v.Y; + c->current_normal.Z = v.Z; + c->current_normal.W = 0; +} + +void glopTexCoord(GLContext * c, GLParam * p) +{ + c->current_tex_coord.X = p[1].f; + c->current_tex_coord.Y = p[2].f; + c->current_tex_coord.Z = p[3].f; + c->current_tex_coord.W = p[4].f; +} + +void glopEdgeFlag(GLContext * c, GLParam * p) +{ + c->current_edge_flag = p[1].i; +} + +void glopColor(GLContext * c, GLParam * p) +{ + + c->current_color.X = p[1].f; + c->current_color.Y = p[2].f; + c->current_color.Z = p[3].f; + c->current_color.W = p[4].f; + c->longcurrent_color[0] = p[5].ui; + c->longcurrent_color[1] = p[6].ui; + c->longcurrent_color[2] = p[7].ui; + + if (c->color_material_enabled) { + GLParam q[7]; + q[0].op = OP_Material; + q[1].i = c->current_color_material_mode; + q[2].i = c->current_color_material_type; + q[3].f = p[1].f; + q[4].f = p[2].f; + q[5].f = p[3].f; + q[6].f = p[4].f; + glopMaterial(c, q); + } +} + + +void gl_eval_viewport(GLContext * c) +{ + GLViewport *v; + float zsize = (1 << (ZB_Z_BITS + ZB_POINT_Z_FRAC_BITS)); + + v = &c->viewport; + + v->trans.X = ((v->xsize - 0.5) / 2.0) + v->xmin; + v->trans.Y = ((v->ysize - 0.5) / 2.0) + v->ymin; + v->trans.Z = ((zsize - 0.5) / 2.0) + ((1 << ZB_POINT_Z_FRAC_BITS)) / 2; + + v->scale.X = (v->xsize - 0.5) / 2.0; + v->scale.Y = -(v->ysize - 0.5) / 2.0; + v->scale.Z = -((zsize - 0.5) / 2.0); +} + +void glopBegin(GLContext * c, GLParam * p) +{ + int type; + M4 tmp; + + gl_assert(c->in_begin == 0); + + type = p[1].i; + c->begin_type = type; + c->in_begin = 1; + c->vertex_n = 0; + c->vertex_cnt = 0; + + if (c->matrix_model_projection_updated) { + + if (c->lighting_enabled) { + /* precompute inverse modelview */ + gl_M4_Inv(&tmp, c->matrix_stack_ptr[0]); + gl_M4_Transpose(&c->matrix_model_view_inv, &tmp); + } else { + float *m = &c->matrix_model_projection.m[0][0]; + /* precompute projection matrix */ + gl_M4_Mul(&c->matrix_model_projection, + c->matrix_stack_ptr[1], + c->matrix_stack_ptr[0]); + /* test to accelerate computation */ + c->matrix_model_projection_no_w_transform = 0; + if (m[12] == 0.0 && m[13] == 0.0 && m[14] == 0.0) + c->matrix_model_projection_no_w_transform = 1; + } + + /* test if the texture matrix is not Identity */ + c->apply_texture_matrix = !gl_M4_IsId(c->matrix_stack_ptr[2]); + + c->matrix_model_projection_updated = 0; + } + /* viewport */ + if (c->viewport.updated) { + gl_eval_viewport(c); + c->viewport.updated = 0; + } + /* triangle drawing functions */ + if (c->render_mode == GL_SELECT) { + c->draw_triangle_front = gl_draw_triangle_select; + c->draw_triangle_back = gl_draw_triangle_select; + } else { + switch (c->polygon_mode_front) { + case GL_POINT: + c->draw_triangle_front = gl_draw_triangle_point; + break; + case GL_LINE: + c->draw_triangle_front = gl_draw_triangle_line; + break; + default: + c->draw_triangle_front = gl_draw_triangle_fill; + break; + } + + switch (c->polygon_mode_back) { + case GL_POINT: + c->draw_triangle_back = gl_draw_triangle_point; + break; + case GL_LINE: + c->draw_triangle_back = gl_draw_triangle_line; + break; + default: + c->draw_triangle_back = gl_draw_triangle_fill; + break; + } + } +} + +/* coords, tranformation , clip code and projection */ +/* TODO : handle all cases */ +static inline void gl_vertex_transform(GLContext * c, GLVertex * v) +{ + float *m; + V4 *n; + + if (c->lighting_enabled) { + /* eye coordinates needed for lighting */ + + m = &c->matrix_stack_ptr[0]->m[0][0]; + v->ec.X = (v->coord.X * m[0] + v->coord.Y * m[1] + + v->coord.Z * m[2] + m[3]); + v->ec.Y = (v->coord.X * m[4] + v->coord.Y * m[5] + + v->coord.Z * m[6] + m[7]); + v->ec.Z = (v->coord.X * m[8] + v->coord.Y * m[9] + + v->coord.Z * m[10] + m[11]); + v->ec.W = (v->coord.X * m[12] + v->coord.Y * m[13] + + v->coord.Z * m[14] + m[15]); + + /* projection coordinates */ + m = &c->matrix_stack_ptr[1]->m[0][0]; + v->pc.X = (v->ec.X * m[0] + v->ec.Y * m[1] + + v->ec.Z * m[2] + v->ec.W * m[3]); + v->pc.Y = (v->ec.X * m[4] + v->ec.Y * m[5] + + v->ec.Z * m[6] + v->ec.W * m[7]); + v->pc.Z = (v->ec.X * m[8] + v->ec.Y * m[9] + + v->ec.Z * m[10] + v->ec.W * m[11]); + v->pc.W = (v->ec.X * m[12] + v->ec.Y * m[13] + + v->ec.Z * m[14] + v->ec.W * m[15]); + + m = &c->matrix_model_view_inv.m[0][0]; + n = &c->current_normal; + + v->normal.X = (n->X * m[0] + n->Y * m[1] + n->Z * m[2]); + v->normal.Y = (n->X * m[4] + n->Y * m[5] + n->Z * m[6]); + v->normal.Z = (n->X * m[8] + n->Y * m[9] + n->Z * m[10]); + + if (c->normalize_enabled) { + gl_V3_Norm(&v->normal); + } + } else { + /* no eye coordinates needed, no normal */ + /* NOTE: W = 1 is assumed */ + m = &c->matrix_model_projection.m[0][0]; + + v->pc.X = (v->coord.X * m[0] + v->coord.Y * m[1] + + v->coord.Z * m[2] + m[3]); + v->pc.Y = (v->coord.X * m[4] + v->coord.Y * m[5] + + v->coord.Z * m[6] + m[7]); + v->pc.Z = (v->coord.X * m[8] + v->coord.Y * m[9] + + v->coord.Z * m[10] + m[11]); + if (c->matrix_model_projection_no_w_transform) { + v->pc.W = m[15]; + } else { + v->pc.W = (v->coord.X * m[12] + v->coord.Y * m[13] + + v->coord.Z * m[14] + m[15]); + } + } + + v->clip_code = gl_clipcode(v->pc.X, v->pc.Y, v->pc.Z, v->pc.W); +} + +void glopVertex(GLContext * c, GLParam * p) +{ + GLVertex *v; + int n, i, cnt; + + gl_assert(c->in_begin != 0); + + n = c->vertex_n; + cnt = c->vertex_cnt; + cnt++; + c->vertex_cnt = cnt; + + /* quick fix to avoid crashes on large polygons */ + if (n >= c->vertex_max) { + GLVertex *newarray; + c->vertex_max <<= 1; /* just double size */ + newarray = gl_malloc(sizeof(GLVertex) * c->vertex_max); + if (!newarray) { + gl_fatal_error("unable to allocate GLVertex array.\n"); + } + memcpy(newarray, c->vertex, n * sizeof(GLVertex)); + gl_free(c->vertex); + c->vertex = newarray; + } + /* new vertex entry */ + v = &c->vertex[n]; + n++; + + v->coord.X = p[1].f; + v->coord.Y = p[2].f; + v->coord.Z = p[3].f; + v->coord.W = p[4].f; + + gl_vertex_transform(c, v); + + /* color */ + + if (c->lighting_enabled) { + gl_shade_vertex(c, v); + } else { + v->color = c->current_color; + } + + /* tex coords */ + + if (c->texture_2d_enabled) { + if (c->apply_texture_matrix) { + gl_M4_MulV4(&v->tex_coord, c->matrix_stack_ptr[2], &c->current_tex_coord); + } else { + v->tex_coord = c->current_tex_coord; + } + } + /* precompute the mapping to the viewport */ + if (v->clip_code == 0) + gl_transform_to_viewport(c, v); + + /* edge flag */ + + v->edge_flag = c->current_edge_flag; + + switch (c->begin_type) { + case GL_POINTS: + gl_draw_point(c, &c->vertex[0]); + n = 0; + break; + + case GL_LINES: + if (n == 2) { + gl_draw_line(c, &c->vertex[0], &c->vertex[1]); + n = 0; + } + break; + case GL_LINE_STRIP: + case GL_LINE_LOOP: + if (n == 1) { + c->vertex[2] = c->vertex[0]; + } else if (n == 2) { + gl_draw_line(c, &c->vertex[0], &c->vertex[1]); + c->vertex[0] = c->vertex[1]; + n = 1; + } + break; + + case GL_TRIANGLES: + if (n == 3) { + gl_draw_triangle(c, &c->vertex[0], &c->vertex[1], &c->vertex[2]); + n = 0; + } + break; + case GL_TRIANGLE_STRIP: + if (cnt >= 3) { + if (n == 3) + n = 0; + /* needed to respect triangle orientation */ + switch(cnt & 1) { + case 0: + gl_draw_triangle(c,&c->vertex[2],&c->vertex[1],&c->vertex[0]); + break; + default: + case 1: + gl_draw_triangle(c,&c->vertex[0],&c->vertex[1],&c->vertex[2]); + break; + } + } + break; + case GL_TRIANGLE_FAN: + if (n == 3) { + gl_draw_triangle(c, &c->vertex[0], &c->vertex[1], &c->vertex[2]); + c->vertex[1] = c->vertex[2]; + n = 2; + } + break; + + case GL_QUADS: + if (n == 4) { + c->vertex[2].edge_flag = 0; + gl_draw_triangle(c, &c->vertex[0], &c->vertex[1], &c->vertex[2]); + c->vertex[2].edge_flag = 1; + c->vertex[0].edge_flag = 0; + gl_draw_triangle(c, &c->vertex[0], &c->vertex[2], &c->vertex[3]); + n = 0; + } + break; + + case GL_QUAD_STRIP: + if (n == 4) { + gl_draw_triangle(c, &c->vertex[0], &c->vertex[1], &c->vertex[2]); + gl_draw_triangle(c, &c->vertex[1], &c->vertex[3], &c->vertex[2]); + for (i = 0; i < 2; i++) + c->vertex[i] = c->vertex[i + 2]; + n = 2; + } + break; + case GL_POLYGON: + break; + default: + gl_fatal_error("glBegin: type %x not handled\n", c->begin_type); + } + + c->vertex_n = n; +} + +void glopEnd(GLContext * c, GLParam * param) +{ + (void) param; + gl_assert(c->in_begin == 1); + + if (c->begin_type == GL_LINE_LOOP) { + if (c->vertex_cnt >= 3) { + gl_draw_line(c, &c->vertex[0], &c->vertex[2]); + } + } else if (c->begin_type == GL_POLYGON) { + int i = c->vertex_cnt; + while (i >= 3) { + i--; + gl_draw_triangle(c, &c->vertex[i], &c->vertex[0], &c->vertex[i - 1]); + } + } + c->in_begin = 0; +} diff --git a/3rdparty/tinygl-0.4-ugfx/src/zbuffer.c b/3rdparty/tinygl-0.4-ugfx/src/zbuffer.c new file mode 100644 index 00000000..a62baa04 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/zbuffer.c @@ -0,0 +1,517 @@ +/* + + * Z buffer: 16 bits Z / 16 bits color + * + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "zbuffer.h" + +ZBuffer *ZB_open(int xsize, int ysize, int mode, + int nb_colors, + unsigned char *color_indexes, + int *color_table, + void *frame_buffer) +{ + ZBuffer *zb; + int size; + + zb = gl_malloc(sizeof(ZBuffer)); + if (zb == NULL) + return NULL; + + zb->xsize = xsize; + zb->ysize = ysize; + zb->mode = mode; + zb->linesize = (xsize * PSZB + 3) & ~3; + + switch (mode) { +#ifdef TGL_FEATURE_8_BITS + case ZB_MODE_INDEX: + ZB_initDither(zb, nb_colors, color_indexes, color_table); + break; +#endif +#ifdef TGL_FEATURE_32_BITS + case ZB_MODE_RGBA: +#endif +#ifdef TGL_FEATURE_24_BITS + case ZB_MODE_RGB24: +#endif + case ZB_MODE_5R6G5B: + zb->nb_colors = 0; + break; + default: + goto error; + } + + size = zb->xsize * zb->ysize * sizeof(unsigned short); + + zb->zbuf = gl_malloc(size); + if (zb->zbuf == NULL) + goto error; + + if (frame_buffer == NULL) { + zb->pbuf = gl_malloc(zb->ysize * zb->linesize); + if (zb->pbuf == NULL) { + gl_free(zb->zbuf); + goto error; + } + zb->frame_buffer_allocated = 1; + } else { + zb->frame_buffer_allocated = 0; + zb->pbuf = frame_buffer; + } + + zb->current_texture = NULL; + + return zb; + error: + gl_free(zb); + return NULL; +} + +void ZB_close(ZBuffer * zb) +{ +#ifdef TGL_FEATURE_8_BITS + if (zb->mode == ZB_MODE_INDEX) + ZB_closeDither(zb); +#endif + + if (zb->frame_buffer_allocated) + gl_free(zb->pbuf); + + gl_free(zb->zbuf); + gl_free(zb); +} + +void ZB_resize(ZBuffer * zb, void *frame_buffer, int xsize, int ysize) +{ + int size; + + /* xsize must be a multiple of 4 */ + xsize = xsize & ~3; + + zb->xsize = xsize; + zb->ysize = ysize; + zb->linesize = (xsize * PSZB + 3) & ~3; + + size = zb->xsize * zb->ysize * sizeof(unsigned short); + + gl_free(zb->zbuf); + zb->zbuf = gl_malloc(size); + + if (zb->frame_buffer_allocated) + gl_free(zb->pbuf); + + if (frame_buffer == NULL) { + zb->pbuf = gl_malloc(zb->ysize * zb->linesize); + zb->frame_buffer_allocated = 1; + } else { + zb->pbuf = frame_buffer; + zb->frame_buffer_allocated = 0; + } +} + +static void ZB_copyBuffer(ZBuffer * zb, + void *buf, + int linesize) +{ + unsigned char *p1; + PIXEL *q; + int y, n; + + q = zb->pbuf; + p1 = buf; + n = zb->xsize * PSZB; + for (y = 0; y < zb->ysize; y++) { + memcpy(p1, q, n); + p1 += linesize; + q = (PIXEL *) ((char *) q + zb->linesize); + } +} + +#if TGL_FEATURE_RENDER_BITS == 16 + +/* 32 bpp copy */ + +#ifdef TGL_FEATURE_32_BITS + +#define RGB16_TO_RGB32(p0,p1,v)\ +{\ + unsigned int g,b,gb;\ + g = (v & 0x07E007E0) << 5;\ + b = (v & 0x001F001F) << 3;\ + gb = g | b;\ + p0 = (gb & 0x0000FFFF) | ((v & 0x0000F800) << 8);\ + p1 = (gb >> 16) | ((v & 0xF8000000) >> 8);\ +} + +static void ZB_copyFrameBufferRGB32(ZBuffer * zb, + void *buf, + int linesize) +{ + unsigned short *q; + unsigned int *p, *p1, v, w0, w1; + int y, n; + + q = zb->pbuf; + p1 = (unsigned int *) buf; + + for (y = 0; y < zb->ysize; y++) { + p = p1; + n = zb->xsize >> 2; + do { + v = *(unsigned int *) q; +#if BYTE_ORDER == BIG_ENDIAN + RGB16_TO_RGB32(w1, w0, v); +#else + RGB16_TO_RGB32(w0, w1, v); +#endif + p[0] = w0; + p[1] = w1; + + v = *(unsigned int *) (q + 2); +#if BYTE_ORDER == BIG_ENDIAN + RGB16_TO_RGB32(w1, w0, v); +#else + RGB16_TO_RGB32(w0, w1, v); +#endif + p[2] = w0; + p[3] = w1; + + q += 4; + p += 4; + } while (--n > 0); + + p1 += linesize; + } +} + +#endif + +/* 24 bit packed pixel handling */ + +#ifdef TGL_FEATURE_24_BITS + +/* order: RGBR GBRG BRGB */ + +/* XXX: packed pixel 24 bit support not tested */ +/* XXX: big endian case not optimised */ + +#if BYTE_ORDER == BIG_ENDIAN + +#define RGB16_TO_RGB24(p0,p1,p2,v1,v2)\ +{\ + unsigned int r1,g1,b1,gb1,g2,b2,gb2;\ + v1 = (v1 << 16) | (v1 >> 16);\ + v2 = (v2 << 16) | (v2 >> 16);\ + r1 = (v1 & 0xF800F800);\ + g1 = (v1 & 0x07E007E0) << 5;\ + b1 = (v1 & 0x001F001F) << 3;\ + gb1 = g1 | b1;\ + p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24);\ + g2 = (v2 & 0x07E007E0) << 5;\ + b2 = (v2 & 0x001F001F) << 3;\ + gb2 = g2 | b2;\ + p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff);\ + p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16);\ +} + +#else + +#define RGB16_TO_RGB24(p0,p1,p2,v1,v2)\ +{\ + unsigned int r1,g1,b1,gb1,g2,b2,gb2;\ + r1 = (v1 & 0xF800F800);\ + g1 = (v1 & 0x07E007E0) << 5;\ + b1 = (v1 & 0x001F001F) << 3;\ + gb1 = g1 | b1;\ + p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24);\ + g2 = (v2 & 0x07E007E0) << 5;\ + b2 = (v2 & 0x001F001F) << 3;\ + gb2 = g2 | b2;\ + p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff);\ + p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16);\ +} + +#endif + +static void ZB_copyFrameBufferRGB24(ZBuffer * zb, + void *buf, + int linesize) +{ + unsigned short *q; + unsigned int *p, *p1, w0, w1, w2, v0, v1; + int y, n; + + q = zb->pbuf; + p1 = (unsigned int *) buf; + linesize = linesize * 3; + + for (y = 0; y < zb->ysize; y++) { + p = p1; + n = zb->xsize >> 2; + do { + v0 = *(unsigned int *) q; + v1 = *(unsigned int *) (q + 2); + RGB16_TO_RGB24(w0, w1, w2, v0, v1); + p[0] = w0; + p[1] = w1; + p[2] = w2; + + q += 4; + p += 3; + } while (--n > 0); + + p1 = (unsigned int *)(((char *)p1) + linesize); + } +} + +#endif + +void ZB_copyFrameBuffer(ZBuffer * zb, void *buf, + int linesize) +{ + switch (zb->mode) { +#ifdef TGL_FEATURE_8_BITS + case ZB_MODE_INDEX: + ZB_ditherFrameBuffer(zb, buf, linesize >> 1); + break; +#endif +#ifdef TGL_FEATURE_16_BITS + case ZB_MODE_5R6G5B: + ZB_copyBuffer(zb, buf, linesize); + break; +#endif +#ifdef TGL_FEATURE_32_BITS + case ZB_MODE_RGBA: + ZB_copyFrameBufferRGB32(zb, buf, linesize >> 1); + break; +#endif +#ifdef TGL_FEATURE_24_BITS + case ZB_MODE_RGB24: + ZB_copyFrameBufferRGB24(zb, buf, linesize >> 1); + break; +#endif + default: + gl_assert(0); + } +} + +#endif /* TGL_FEATURE_RENDER_BITS == 16 */ + +#if TGL_FEATURE_RENDER_BITS == 24 + +#define RGB24_TO_RGB16(r, g, b) \ + ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3)) + +/* XXX: not optimized */ +static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb, + void *buf, int linesize) +{ + PIXEL *q; + unsigned short *p, *p1; + int y, n; + + q = zb->pbuf; + p1 = (unsigned short *) buf; + + for (y = 0; y < zb->ysize; y++) { + p = p1; + n = zb->xsize >> 2; + do { + p[0] = RGB24_TO_RGB16(q[0], q[1], q[2]); + p[1] = RGB24_TO_RGB16(q[3], q[4], q[5]); + p[2] = RGB24_TO_RGB16(q[6], q[7], q[8]); + p[3] = RGB24_TO_RGB16(q[9], q[10], q[11]); + q = (PIXEL *)((char *)q + 4 * PSZB); + p += 4; + } while (--n > 0); + p1 = (unsigned short *)((char *)p1 + linesize); + } +} + +void ZB_copyFrameBuffer(ZBuffer * zb, void *buf, + int linesize) +{ + switch (zb->mode) { +#ifdef TGL_FEATURE_16_BITS + case ZB_MODE_5R6G5B: + ZB_copyFrameBuffer5R6G5B(zb, buf, linesize); + break; +#endif +#ifdef TGL_FEATURE_24_BITS + case ZB_MODE_RGB24: + ZB_copyBuffer(zb, buf, linesize); + break; +#endif + default: + gl_assert(0); + } +} + +#endif /* TGL_FEATURE_RENDER_BITS == 24 */ + +#if TGL_FEATURE_RENDER_BITS == 32 + +#define RGB32_TO_RGB16(v) \ + (((v >> 8) & 0xf800) | (((v) >> 5) & 0x07e0) | (((v) & 0xff) >> 3)) + +/* XXX: not optimized */ +static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb, + void *buf, int linesize) +{ + PIXEL *q; + unsigned short *p, *p1; + int y, n; + + q = zb->pbuf; + p1 = (unsigned short *) buf; + + for (y = 0; y < zb->ysize; y++) { + p = p1; + n = zb->xsize >> 2; + do { + p[0] = RGB32_TO_RGB16(q[0]); + p[1] = RGB32_TO_RGB16(q[1]); + p[2] = RGB32_TO_RGB16(q[2]); + p[3] = RGB32_TO_RGB16(q[3]); + q += 4; + p += 4; + } while (--n > 0); + p1 = (unsigned short *)((char *)p1 + linesize); + } +} + +void ZB_copyFrameBuffer(ZBuffer * zb, void *buf, + int linesize) +{ + switch (zb->mode) { +#ifdef TGL_FEATURE_16_BITS + case ZB_MODE_5R6G5B: + ZB_copyFrameBuffer5R6G5B(zb, buf, linesize); + break; +#endif +#ifdef TGL_FEATURE_32_BITS + case ZB_MODE_RGBA: + ZB_copyBuffer(zb, buf, linesize); + break; +#endif + default: + gl_assert(0); + } +} + +#endif /* TGL_FEATURE_RENDER_BITS == 32 */ + + +/* + * adr must be aligned on an 'int' + */ +void memset_s(void *adr, int val, int count) +{ + int i, n, v; + unsigned int *p; + unsigned short *q; + + p = adr; + v = val | (val << 16); + + n = count >> 3; + for (i = 0; i < n; i++) { + p[0] = v; + p[1] = v; + p[2] = v; + p[3] = v; + p += 4; + } + + q = (unsigned short *) p; + n = count & 7; + for (i = 0; i < n; i++) + *q++ = val; +} + +void memset_l(void *adr, int val, int count) +{ + int i, n, v; + unsigned int *p; + + p = adr; + v = val; + n = count >> 2; + for (i = 0; i < n; i++) { + p[0] = v; + p[1] = v; + p[2] = v; + p[3] = v; + p += 4; + } + + n = count & 3; + for (i = 0; i < n; i++) + *p++ = val; +} + +/* count must be a multiple of 4 and >= 4 */ +void memset_RGB24(void *adr,int r, int v, int b,long count) +{ + long i, n; + register long v1,v2,v3,*pt=(long *)(adr); + unsigned char *p,R=(unsigned char)r,V=(unsigned char)v,B=(unsigned char)b; + + p=(unsigned char *)adr; + *p++=R; + *p++=V; + *p++=B; + *p++=R; + *p++=V; + *p++=B; + *p++=R; + *p++=V; + *p++=B; + *p++=R; + *p++=V; + *p++=B; + v1=*pt++; + v2=*pt++; + v3=*pt++; + n = count >> 2; + for(i=1;i<n;i++) { + *pt++=v1; + *pt++=v2; + *pt++=v3; + } +} + +void ZB_clear(ZBuffer * zb, int clear_z, int z, + int clear_color, int r, int g, int b) +{ +#if TGL_FEATURE_RENDER_BITS != 24 + int color; +#endif + int y; + PIXEL *pp; + + if (clear_z) { + memset_s(zb->zbuf, z, zb->xsize * zb->ysize); + } + if (clear_color) { + pp = zb->pbuf; + for (y = 0; y < zb->ysize; y++) { +#if TGL_FEATURE_RENDER_BITS == 15 || TGL_FEATURE_RENDER_BITS == 16 + color = RGB_TO_PIXEL(r, g, b); + memset_s(pp, color, zb->xsize); +#elif TGL_FEATURE_RENDER_BITS == 32 + color = RGB_TO_PIXEL(r, g, b); + memset_l(pp, color, zb->xsize); +#elif TGL_FEATURE_RENDER_BITS == 24 + memset_RGB24(pp,r>>8,g>>8,b>>8,zb->xsize); +#else +#error TODO +#endif + pp = (PIXEL *) ((char *) pp + zb->linesize); + } + } +} diff --git a/3rdparty/tinygl-0.4-ugfx/src/zbuffer.h b/3rdparty/tinygl-0.4-ugfx/src/zbuffer.h new file mode 100644 index 00000000..b73e59fb --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/zbuffer.h @@ -0,0 +1,153 @@ +#ifndef _tgl_zbuffer_h_ +#define _tgl_zbuffer_h_ + +/* + * Z buffer + */ + +#include "zfeatures.h" + +#define ZB_Z_BITS 16 + +#define ZB_POINT_Z_FRAC_BITS 14 + +#define ZB_POINT_S_MIN ( (1<<13) ) +#define ZB_POINT_S_MAX ( (1<<22)-(1<<13) ) +#define ZB_POINT_T_MIN ( (1<<21) ) +#define ZB_POINT_T_MAX ( (1<<30)-(1<<21) ) + +#define ZB_POINT_RED_MIN ( (1<<10) ) +#define ZB_POINT_RED_MAX ( (1<<16)-(1<<10) ) +#define ZB_POINT_GREEN_MIN ( (1<<9) ) +#define ZB_POINT_GREEN_MAX ( (1<<16)-(1<<9) ) +#define ZB_POINT_BLUE_MIN ( (1<<10) ) +#define ZB_POINT_BLUE_MAX ( (1<<16)-(1<<10) ) + +/* display modes */ +#define ZB_MODE_5R6G5B 1 /* true color 16 bits */ +#define ZB_MODE_INDEX 2 /* color index 8 bits */ +#define ZB_MODE_RGBA 3 /* 32 bit rgba mode */ +#define ZB_MODE_RGB24 4 /* 24 bit rgb mode */ +#define ZB_NB_COLORS 225 /* number of colors for 8 bit display */ + +#if TGL_FEATURE_RENDER_BITS == 15 + +#define RGB_TO_PIXEL(r,g,b) \ + ((((r) >> 1) & 0x7c00) | (((g) >> 6) & 0x03e0) | ((b) >> 11)) +typedef unsigned short PIXEL; +/* bytes per pixel */ +#define PSZB 2 +/* bits per pixel = (1 << PSZH) */ +#define PSZSH 4 + +#elif TGL_FEATURE_RENDER_BITS == 16 + +/* 16 bit mode */ +#define RGB_TO_PIXEL(r,g,b) \ + (((r) & 0xF800) | (((g) >> 5) & 0x07E0) | ((b) >> 11)) +typedef unsigned short PIXEL; +#define PSZB 2 +#define PSZSH 4 + +#elif TGL_FEATURE_RENDER_BITS == 24 + +#define RGB_TO_PIXEL(r,g,b) \ + ((((r) << 8) & 0xff0000) | ((g) & 0xff00) | ((b) >> 8)) +typedef unsigned char PIXEL; +#define PSZB 3 +#define PSZSH 5 + +#elif TGL_FEATURE_RENDER_BITS == 32 + +#define RGB_TO_PIXEL(r,g,b) \ + ((((r) << 8) & 0xff0000) | ((g) & 0xff00) | ((b) >> 8)) +typedef unsigned int PIXEL; +#define PSZB 4 +#define PSZSH 5 + +#else + +#error Incorrect number of bits per pixel + +#endif + +typedef struct { + int xsize,ysize; + int linesize; /* line size, in bytes */ + int mode; + + unsigned short *zbuf; + PIXEL *pbuf; + int frame_buffer_allocated; + + int nb_colors; + unsigned char *dctable; + int *ctable; + PIXEL *current_texture; +} ZBuffer; + +typedef struct { + int x,y,z; /* integer coordinates in the zbuffer */ + int s,t; /* coordinates for the mapping */ + int r,g,b; /* color indexes */ + + float sz,tz; /* temporary coordinates for mapping */ +} ZBufferPoint; + +/* zbuffer.c */ + +ZBuffer *ZB_open(int xsize,int ysize,int mode, + int nb_colors, + unsigned char *color_indexes, + int *color_table, + void *frame_buffer); + + +void ZB_close(ZBuffer *zb); + +void ZB_resize(ZBuffer *zb,void *frame_buffer,int xsize,int ysize); +void ZB_clear(ZBuffer *zb,int clear_z,int z, + int clear_color,int r,int g,int b); +/* linesize is in BYTES */ +void ZB_copyFrameBuffer(ZBuffer *zb,void *buf,int linesize); + +/* zdither.c */ + +void ZB_initDither(ZBuffer *zb,int nb_colors, + unsigned char *color_indexes,int *color_table); +void ZB_closeDither(ZBuffer *zb); +void ZB_ditherFrameBuffer(ZBuffer *zb,unsigned char *dest, + int linesize); + +/* zline.c */ + +void ZB_plot(ZBuffer *zb,ZBufferPoint *p); +void ZB_line(ZBuffer *zb,ZBufferPoint *p1,ZBufferPoint *p2); +void ZB_line_z(ZBuffer * zb, ZBufferPoint * p1, ZBufferPoint * p2); + +/* ztriangle.c */ + +void ZB_setTexture(ZBuffer *zb, PIXEL *texture); + +void ZB_fillTriangleFlat(ZBuffer *zb, + ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3); + +void ZB_fillTriangleSmooth(ZBuffer *zb, + ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3); + +void ZB_fillTriangleMapping(ZBuffer *zb, + ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3); + +void ZB_fillTriangleMappingPerspective(ZBuffer *zb, + ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2); + + +typedef void (*ZB_fillTriangleFunc)(ZBuffer *, + ZBufferPoint *,ZBufferPoint *,ZBufferPoint *); + +/* memory.c */ +void gl_free(void *p); +void *gl_malloc(int size); +void *gl_zalloc(int size); + +#endif /* _tgl_zbuffer_h_ */ diff --git a/3rdparty/tinygl-0.4-ugfx/src/zdither.c b/3rdparty/tinygl-0.4-ugfx/src/zdither.c new file mode 100644 index 00000000..cbe917fd --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/zdither.c @@ -0,0 +1,158 @@ +/* + * Highly optimised dithering 16 bits -> 8 bits. + * The formulas were taken in Mesa (Bob Mercier mercier@hollywood.cinenet.net). + */ + +#include <stdlib.h> +#include <stdio.h> +#include "zbuffer.h" +#include <assert.h> + +#if defined(TGL_FEATURE_8_BITS) + +#define _R 5 +#define _G 9 +#define _B 5 +#define _DX 4 +#define _DY 4 +#define _D (_DX*_DY) +#define _MIX(r,g,b) ( ((g)<<6) | ((b)<<3) | (r) ) + +#define DITHER_TABLE_SIZE (1 << 15) + +#define DITHER_INDEX(r,g,b) ((b) + (g) * _B + (r) * (_B * _G)) + +#define MAXC 256 +static int kernel8[_DY*_DX] = { + 0 * MAXC, 8 * MAXC, 2 * MAXC, 10 * MAXC, + 12 * MAXC, 4 * MAXC, 14 * MAXC, 6 * MAXC, + 3 * MAXC, 11 * MAXC, 1 * MAXC, 9 * MAXC, + 15 * MAXC, 7 * MAXC, 13 * MAXC, 5 * MAXC, +}; + +/* we build the color table and the lookup table */ + +void ZB_initDither(ZBuffer *zb,int nb_colors, + unsigned char *color_indexes,int *color_table) +{ + int c,r,g,b,i,index,r1,g1,b1; + + if (nb_colors < (_R * _G * _B)) { + gl_fatal_error("zdither: not enough colors\n"); + } + + for(i=0;i<nb_colors;i++) color_table[i]=0; + + zb->nb_colors=nb_colors; + zb->ctable=gl_malloc(nb_colors * sizeof(int)); + + for (r = 0; r < _R; r++) { + for (g = 0; g < _G; g++) { + for (b = 0; b < _B; b++) { + r1=(r*255) / (_R - 1); + g1=(g*255) / (_G - 1); + b1=(b*255) / (_B - 1); + index=DITHER_INDEX(r,g,b); + c=(r1 << 16) | (g1 << 8) | b1; + zb->ctable[index]=c; + color_table[index]=c; + } + } + } + + zb->dctable=gl_malloc( DITHER_TABLE_SIZE ); + + for(i=0;i<DITHER_TABLE_SIZE;i++) { + r=(i >> 12) & 0x7; + g=(i >> 8) & 0xF; + b=(i >> 3) & 0x7; + index=DITHER_INDEX(r,g,b); + zb->dctable[i]=color_indexes[index]; + } +} + +void ZB_closeDither(ZBuffer *zb) +{ + gl_free(zb->ctable); + gl_free(zb->dctable); +} + +#if 0 +int ZDither_lookupColor(int r,int g,int b) +{ + unsigned char *ctable=zdither_color_table; + return ctable[_MIX(_DITH0(_R, r), _DITH0(_G, g),_DITH0(_B, b))]; +} +#endif + + +#define DITHER_PIXEL2(a) \ +{ \ + register int v,t,r,g,c; \ + v=*(unsigned int *)(pp+(a)); \ + g=(v & 0x07DF07DF) + g_d; \ + r=(((v & 0xF800F800) >> 2) + r_d) & 0x70007000; \ + t=r | g; \ + c=ctable[t & 0xFFFF] | (ctable[t >> 16] << 8); \ + *(unsigned short *)(dest+(a))=c; \ +} + +/* NOTE: all the memory access are 16 bit aligned, so if buf or + linesize are not multiple of 2, it cannot work efficiently (or + hang!) */ + +void ZB_ditherFrameBuffer(ZBuffer *zb,unsigned char *buf, + int linesize) +{ + int xk,yk,x,y,c1,c2; + unsigned char *dest1; + unsigned short *pp1; + int r_d,g_d,b_d; + unsigned char *ctable=zb->dctable; + register unsigned char *dest; + register unsigned short *pp; + + assert( ((long)buf & 1) == 0 && (linesize & 1) == 0); + + for(yk=0;yk<4;yk++) { + for(xk=0;xk<4;xk+=2) { +#if BYTE_ORDER == BIG_ENDIAN + c1=kernel8[yk*4+xk+1]; + c2=kernel8[yk*4+xk]; +#else + c1=kernel8[yk*4+xk]; + c2=kernel8[yk*4+xk+1]; +#endif + r_d=((c1 << 2) & 0xF800) >> 2; + g_d=(c1 >> 4) & 0x07C0; + b_d=(c1 >> 9) & 0x001F; + + r_d|=(((c2 << 2) & 0xF800) >> 2) << 16; + g_d|=((c2 >> 4) & 0x07C0) << 16; + b_d|=((c2 >> 9) & 0x001F) << 16; + g_d=b_d | g_d; + + dest1=buf + (yk * linesize) + xk; + pp1=zb->pbuf + (yk * zb->xsize) + xk; + + for(y=yk;y<zb->ysize;y+=4) { + dest=dest1; + pp=pp1; + for(x=xk;x<zb->xsize;x+=16) { + + DITHER_PIXEL2(0); + DITHER_PIXEL2(1*4); + DITHER_PIXEL2(2*4); + DITHER_PIXEL2(3*4); + + pp+=16; + dest+=16; + } + dest1+=linesize*4; + pp1+=zb->xsize*4; + } + } + } +} + +#endif diff --git a/3rdparty/tinygl-0.4-ugfx/src/zfeatures.h b/3rdparty/tinygl-0.4-ugfx/src/zfeatures.h new file mode 100644 index 00000000..cafe0c20 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/zfeatures.h @@ -0,0 +1,43 @@ +#ifndef _tgl_features_h_ +#define _tgl_features_h_ + +/* It is possible to enable/disable (compile time) features in this + header file. */ + +#define TGL_FEATURE_ARRAYS 1 +#define TGL_FEATURE_DISPLAYLISTS 1 +#define TGL_FEATURE_POLYGON_OFFSET 1 + +/* + * Matrix of internal and external pixel formats supported. 'Y' means + * supported. + * + * External 8 16 24 32 + * Internal + * 15 . . . . + * 16 Y Y Y Y + * 24 . Y Y . + * 32 . Y . Y + * + * + * 15 bpp does not work yet (although it is easy to add it - ask me if + * you need it). + * + * Internal pixel format: see TGL_FEATURE_RENDER_BITS + * External pixel format: see TGL_FEATURE_xxx_BITS + */ + +/* enable various convertion code from internal pixel format (usually + 16 bits per pixel) to any external format */ +#define TGL_FEATURE_16_BITS 1 +#define TGL_FEATURE_8_BITS 1 +#define TGL_FEATURE_24_BITS 1 +#define TGL_FEATURE_32_BITS 1 + + +//#define TGL_FEATURE_RENDER_BITS 15 +#define TGL_FEATURE_RENDER_BITS 16 +//#define TGL_FEATURE_RENDER_BITS 24 +//#define TGL_FEATURE_RENDER_BITS 32 + +#endif /* _tgl_features_h_ */ diff --git a/3rdparty/tinygl-0.4-ugfx/src/zgl.h b/3rdparty/tinygl-0.4-ugfx/src/zgl.h new file mode 100644 index 00000000..f9e0578a --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/zgl.h @@ -0,0 +1,372 @@ +#ifndef _tgl_zgl_h_ +#define _tgl_zgl_h_ + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include <GL/gl.h> +#include "zbuffer.h" +#include "zmath.h" +#include "zfeatures.h" + +#define DEBUG +/* #define NDEBUG */ + +enum { + +#define ADD_OP(a,b,c) OP_ ## a , + +#include "opinfo.h" + +}; + +/* initially # of allocated GLVertexes (will grow when necessary) */ +#define POLYGON_MAX_VERTEX 16 + +/* Max # of specular light pow buffers */ +#define MAX_SPECULAR_BUFFERS 8 +/* # of entries in specular buffer */ +#define SPECULAR_BUFFER_SIZE 1024 +/* specular buffer granularity */ +#define SPECULAR_BUFFER_RESOLUTION 1024 + + +#define MAX_MODELVIEW_STACK_DEPTH 32 +#define MAX_PROJECTION_STACK_DEPTH 8 +#define MAX_TEXTURE_STACK_DEPTH 8 +#define MAX_NAME_STACK_DEPTH 64 +#define MAX_TEXTURE_LEVELS 11 +#define MAX_LIGHTS 16 + +#define VERTEX_HASH_SIZE 1031 + +#define MAX_DISPLAY_LISTS 1024 +#define OP_BUFFER_MAX_SIZE 512 + +#define TGL_OFFSET_FILL 0x1 +#define TGL_OFFSET_LINE 0x2 +#define TGL_OFFSET_POINT 0x4 + +typedef struct GLSpecBuf { + int shininess_i; + int last_used; + float buf[SPECULAR_BUFFER_SIZE+1]; + struct GLSpecBuf *next; +} GLSpecBuf; + +typedef struct GLLight { + V4 ambient; + V4 diffuse; + V4 specular; + V4 position; + V3 spot_direction; + float spot_exponent; + float spot_cutoff; + float attenuation[3]; + /* precomputed values */ + float cos_spot_cutoff; + V3 norm_spot_direction; + V3 norm_position; + /* we use a linked list to know which are the enabled lights */ + int enabled; + struct GLLight *next,*prev; +} GLLight; + +typedef struct GLMaterial { + V4 emission; + V4 ambient; + V4 diffuse; + V4 specular; + float shininess; + + /* computed values */ + int shininess_i; + int do_specular; +} GLMaterial; + + +typedef struct GLViewport { + int xmin,ymin,xsize,ysize; + V3 scale; + V3 trans; + int updated; +} GLViewport; + +typedef union { + int op; + float f; + int i; + unsigned int ui; + void *p; +} GLParam; + +typedef struct GLParamBuffer { + GLParam ops[OP_BUFFER_MAX_SIZE]; + struct GLParamBuffer *next; +} GLParamBuffer; + +typedef struct GLList { + GLParamBuffer *first_op_buffer; + /* TODO: extensions for an hash table or a better allocating scheme */ +} GLList; + +typedef struct GLVertex { + int edge_flag; + V3 normal; + V4 coord; + V4 tex_coord; + V4 color; + + /* computed values */ + V4 ec; /* eye coordinates */ + V4 pc; /* coordinates in the normalized volume */ + int clip_code; /* clip code */ + ZBufferPoint zp; /* integer coordinates for the rasterization */ +} GLVertex; + +typedef struct GLImage { + void *pixmap; + int xsize,ysize; +} GLImage; + +/* textures */ + +#define TEXTURE_HASH_TABLE_SIZE 256 + +typedef struct GLTexture { + GLImage images[MAX_TEXTURE_LEVELS]; + int handle; + struct GLTexture *next,*prev; +} GLTexture; + + +/* shared state */ + +typedef struct GLSharedState { + GLList **lists; + GLTexture **texture_hash_table; +} GLSharedState; + +struct GLContext; + +typedef void (*gl_draw_triangle_func)(struct GLContext *c, + GLVertex *p0,GLVertex *p1,GLVertex *p2); + +/* display context */ + +typedef struct GLContext { + /* Z buffer */ + ZBuffer *zb; + + /* lights */ + GLLight lights[MAX_LIGHTS]; + GLLight *first_light; + V4 ambient_light_model; + int local_light_model; + int lighting_enabled; + int light_model_two_side; + + /* materials */ + GLMaterial materials[2]; + int color_material_enabled; + int current_color_material_mode; + int current_color_material_type; + + /* textures */ + GLTexture *current_texture; + int texture_2d_enabled; + + /* shared state */ + GLSharedState shared_state; + + /* current list */ + GLParamBuffer *current_op_buffer; + int current_op_buffer_index; + int exec_flag,compile_flag,print_flag; + + /* matrix */ + + int matrix_mode; + M4 *matrix_stack[3]; + M4 *matrix_stack_ptr[3]; + int matrix_stack_depth_max[3]; + + M4 matrix_model_view_inv; + M4 matrix_model_projection; + int matrix_model_projection_updated; + int matrix_model_projection_no_w_transform; + int apply_texture_matrix; + + /* viewport */ + GLViewport viewport; + + /* current state */ + int polygon_mode_back; + int polygon_mode_front; + + int current_front_face; + int current_shade_model; + int current_cull_face; + int cull_face_enabled; + int normalize_enabled; + gl_draw_triangle_func draw_triangle_front,draw_triangle_back; + + /* selection */ + int render_mode; + unsigned int *select_buffer; + int select_size; + unsigned int *select_ptr,*select_hit; + int select_overflow; + int select_hits; + + /* names */ + unsigned int name_stack[MAX_NAME_STACK_DEPTH]; + int name_stack_size; + + /* clear */ + float clear_depth; + V4 clear_color; + + /* current vertex state */ + V4 current_color; + unsigned int longcurrent_color[3]; /* precomputed integer color */ + V4 current_normal; + V4 current_tex_coord; + int current_edge_flag; + + /* glBegin / glEnd */ + int in_begin; + int begin_type; + int vertex_n,vertex_cnt; + int vertex_max; + GLVertex *vertex; + + /* opengl 1.1 arrays */ + float *vertex_array; + int vertex_array_size; + int vertex_array_stride; + float *normal_array; + int normal_array_stride; + float *color_array; + int color_array_size; + int color_array_stride; + float *texcoord_array; + int texcoord_array_size; + int texcoord_array_stride; + int client_states; + + /* opengl 1.1 polygon offset */ + float offset_factor; + float offset_units; + int offset_states; + + /* specular buffer. could probably be shared between contexts, + but that wouldn't be 100% thread safe */ + GLSpecBuf *specbuf_first; + int specbuf_used_counter; + int specbuf_num_buffers; + + /* opaque structure for user's use */ + void *opaque; + /* resize viewport function */ + int (*gl_resize_viewport)(struct GLContext *c,int *xsize,int *ysize); + + /* depth test */ + int depth_test; +} GLContext; + +extern GLContext *gl_ctx; + +void gl_add_op(GLParam *p); + +/* clip.c */ +void gl_transform_to_viewport(GLContext *c,GLVertex *v); +void gl_draw_triangle(GLContext *c,GLVertex *p0,GLVertex *p1,GLVertex *p2); +void gl_draw_line(GLContext *c,GLVertex *p0,GLVertex *p1); +void gl_draw_point(GLContext *c,GLVertex *p0); + +void gl_draw_triangle_point(GLContext *c, + GLVertex *p0,GLVertex *p1,GLVertex *p2); +void gl_draw_triangle_line(GLContext *c, + GLVertex *p0,GLVertex *p1,GLVertex *p2); +void gl_draw_triangle_fill(GLContext *c, + GLVertex *p0,GLVertex *p1,GLVertex *p2); +void gl_draw_triangle_select(GLContext *c, + GLVertex *p0,GLVertex *p1,GLVertex *p2); + +/* matrix.c */ +void gl_print_matrix(const float *m); +/* +void glopLoadIdentity(GLContext *c,GLParam *p); +void glopTranslate(GLContext *c,GLParam *p);*/ + +/* light.c */ +void gl_add_select(GLContext *c,unsigned int zmin,unsigned int zmax); +void gl_enable_disable_light(GLContext *c,int light,int v); +void gl_shade_vertex(GLContext *c,GLVertex *v); + +void glInitTextures(GLContext *c); +void glEndTextures(GLContext *c); +GLTexture *alloc_texture(GLContext *c,int h); + +/* image_util.c */ +void gl_convertRGB_to_5R6G5B(unsigned short *pixmap,unsigned char *rgb, + int xsize,int ysize); +void gl_convertRGB_to_8A8R8G8B(unsigned int *pixmap, unsigned char *rgb, + int xsize, int ysize); +void gl_resizeImage(unsigned char *dest,int xsize_dest,int ysize_dest, + unsigned char *src,int xsize_src,int ysize_src); +void gl_resizeImageNoInterpolate(unsigned char *dest,int xsize_dest,int ysize_dest, + unsigned char *src,int xsize_src,int ysize_src); + +GLContext *gl_get_context(void); + +void gl_fatal_error(char *format, ...); +void gl_assert(int test); + + +/* specular buffer "api" */ +GLSpecBuf *specbuf_get_buffer(GLContext *c, const int shininess_i, + const float shininess); + +#ifdef __BEOS__ +void dprintf(const char *, ...); + +#else /* !BEOS */ + +#ifdef DEBUG + +#define dprintf(format, args...) \ + fprintf(stderr,"In '%s': " format "\n",__FUNCTION__, ##args); + +#else + +#define dprintf(format, args...) + +#endif +#endif /* !BEOS */ + +/* glopXXX functions */ + +#define ADD_OP(a,b,c) void glop ## a (GLContext *,GLParam *); +#include "opinfo.h" + +/* this clip epsilon is needed to avoid some rounding errors after + several clipping stages */ + +#define CLIP_EPSILON (1E-5) + +static inline int gl_clipcode(float x,float y,float z,float w1) +{ + float w; + + w=w1 * (1.0 + CLIP_EPSILON); + return (x<-w) | + ((x>w)<<1) | + ((y<-w)<<2) | + ((y>w)<<3) | + ((z<-w)<<4) | + ((z>w)<<5) ; +} + +#endif /* _tgl_zgl_h_ */ diff --git a/3rdparty/tinygl-0.4-ugfx/src/zline.c b/3rdparty/tinygl-0.4-ugfx/src/zline.c new file mode 100644 index 00000000..561064b0 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/zline.c @@ -0,0 +1,84 @@ +#include <stdlib.h> +#include "zbuffer.h" + +#define ZCMP(z,zpix) ((z) >= (zpix)) + +void ZB_plot(ZBuffer * zb, ZBufferPoint * p) +{ + unsigned short *pz; + PIXEL *pp; + int zz; + + pz = zb->zbuf + (p->y * zb->xsize + p->x); + pp = (PIXEL *) ((char *) zb->pbuf + zb->linesize * p->y + p->x * PSZB); + zz = p->z >> ZB_POINT_Z_FRAC_BITS; + if (ZCMP(zz, *pz)) { +#if TGL_FEATURE_RENDER_BITS == 24 + pp[0]=p->r>>8; + pp[1]=p->g>>8; + pp[2]=p->b>>8; +#else + *pp = RGB_TO_PIXEL(p->r, p->g, p->b); +#endif + *pz = zz; + } +} + +#define INTERP_Z +static void ZB_line_flat_z(ZBuffer * zb, ZBufferPoint * p1, ZBufferPoint * p2, + int color) +{ +#include "zline.h" +} + +/* line with color interpolation */ +#define INTERP_Z +#define INTERP_RGB +static void ZB_line_interp_z(ZBuffer * zb, ZBufferPoint * p1, ZBufferPoint * p2) +{ +#include "zline.h" +} + +/* no Z interpolation */ + +static void ZB_line_flat(ZBuffer * zb, ZBufferPoint * p1, ZBufferPoint * p2, + int color) +{ +#include "zline.h" +} + +#define INTERP_RGB +static void ZB_line_interp(ZBuffer * zb, ZBufferPoint * p1, ZBufferPoint * p2) +{ +#include "zline.h" +} + +void ZB_line_z(ZBuffer * zb, ZBufferPoint * p1, ZBufferPoint * p2) +{ + int color1, color2; + + color1 = RGB_TO_PIXEL(p1->r, p1->g, p1->b); + color2 = RGB_TO_PIXEL(p2->r, p2->g, p2->b); + + /* choose if the line should have its color interpolated or not */ + if (color1 == color2) { + ZB_line_flat_z(zb, p1, p2, color1); + } else { + ZB_line_interp_z(zb, p1, p2); + } +} + +void ZB_line(ZBuffer * zb, ZBufferPoint * p1, ZBufferPoint * p2) +{ + int color1, color2; + + color1 = RGB_TO_PIXEL(p1->r, p1->g, p1->b); + color2 = RGB_TO_PIXEL(p2->r, p2->g, p2->b); + + /* choose if the line should have its color interpolated or not */ + if (color1 == color2) { + ZB_line_flat(zb, p1, p2, color1); + } else { + ZB_line_interp(zb, p1, p2); + } +} diff --git a/3rdparty/tinygl-0.4-ugfx/src/zline.h b/3rdparty/tinygl-0.4-ugfx/src/zline.h new file mode 100644 index 00000000..00408b45 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/zline.h @@ -0,0 +1,122 @@ +{ + int n, dx, dy, sx, pp_inc_1, pp_inc_2; + register int a; + register PIXEL *pp; +#if defined(INTERP_RGB) || TGL_FEATURE_RENDER_BITS == 24 + register unsigned int r, g, b; +#endif +#ifdef INTERP_RGB + register unsigned int rinc, ginc, binc; +#endif +#ifdef INTERP_Z + register unsigned short *pz; + int zinc; + register int z, zz; +#endif + + if (p1->y > p2->y || (p1->y == p2->y && p1->x > p2->x)) { + ZBufferPoint *tmp; + tmp = p1; + p1 = p2; + p2 = tmp; + } + sx = zb->xsize; + pp = (PIXEL *) ((char *) zb->pbuf + zb->linesize * p1->y + p1->x * PSZB); +#ifdef INTERP_Z + pz = zb->zbuf + (p1->y * sx + p1->x); + z = p1->z; +#endif + + dx = p2->x - p1->x; + dy = p2->y - p1->y; +#ifdef INTERP_RGB + r = p2->r << 8; + g = p2->g << 8; + b = p2->b << 8; +#elif TGL_FEATURE_RENDER_BITS == 24 + /* for 24 bits, we store the colors in different variables */ + r = p2->r >> 8; + g = p2->g >> 8; + b = p2->b >> 8; +#endif + +#undef RGB +#ifdef INTERP_RGB +#define RGB(x) x +#if TGL_FEATURE_RENDER_BITS == 24 +#define RGBPIXEL pp[0] = r >> 16, pp[1] = g >> 16, pp[2] = b >> 16 +#else +#define RGBPIXEL *pp = RGB_TO_PIXEL(r >> 8,g >> 8,b >> 8) +#endif +#else /* INTERP_RGB */ +#define RGB(x) +#if TGL_FEATURE_RENDER_BITS == 24 +#define RGBPIXEL pp[0] = r, pp[1] = g, pp[2] = b +#else +#define RGBPIXEL *pp = color +#endif +#endif /* INTERP_RGB */ + +#ifdef INTERP_Z +#define ZZ(x) x +#define PUTPIXEL() \ + { \ + zz=z >> ZB_POINT_Z_FRAC_BITS; \ + if (ZCMP(zz,*pz)) { \ + RGBPIXEL; \ + *pz=zz; \ + } \ + } +#else /* INTERP_Z */ +#define ZZ(x) +#define PUTPIXEL() RGBPIXEL +#endif /* INTERP_Z */ + +#define DRAWLINE(dx,dy,inc_1,inc_2) \ + n=dx;\ + ZZ(zinc=(p2->z-p1->z)/n);\ + RGB(rinc=((p2->r-p1->r) << 8)/n;\ + ginc=((p2->g-p1->g) << 8)/n;\ + binc=((p2->b-p1->b) << 8)/n);\ + a=2*dy-dx;\ + dy=2*dy;\ + dx=2*dx-dy;\ + pp_inc_1 = (inc_1) * PSZB;\ + pp_inc_2 = (inc_2) * PSZB;\ + do {\ + PUTPIXEL();\ + ZZ(z+=zinc);\ + RGB(r+=rinc;g+=ginc;b+=binc);\ + if (a>0) { pp=(PIXEL *)((char *)pp + pp_inc_1); ZZ(pz+=(inc_1)); a-=dx; }\ + else { pp=(PIXEL *)((char *)pp + pp_inc_2); ZZ(pz+=(inc_2)); a+=dy; }\ + } while (--n >= 0); + +/* fin macro */ + + if (dx == 0 && dy == 0) { + PUTPIXEL(); + } else if (dx > 0) { + if (dx >= dy) { + DRAWLINE(dx, dy, sx + 1, 1); + } else { + DRAWLINE(dy, dx, sx + 1, sx); + } + } else { + dx = -dx; + if (dx >= dy) { + DRAWLINE(dx, dy, sx - 1, -1); + } else { + DRAWLINE(dy, dx, sx - 1, sx); + } + } +} + +#undef INTERP_Z +#undef INTERP_RGB + +/* internal defines */ +#undef DRAWLINE +#undef PUTPIXEL +#undef ZZ +#undef RGB +#undef RGBPIXEL diff --git a/3rdparty/tinygl-0.4-ugfx/src/zmath.c b/3rdparty/tinygl-0.4-ugfx/src/zmath.c new file mode 100644 index 00000000..8ef48d48 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/zmath.c @@ -0,0 +1,275 @@ +/* Some simple mathematical functions. Don't look for some logic in + the function names :-) */ + +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include "zmath.h" + + +/* ******* Gestion des matrices 4x4 ****** */ + +void gl_M4_Id(M4 *a) +{ + int i,j; + for(i=0;i<4;i++) + for(j=0;j<4;j++) + if (i==j) a->m[i][j]=1.0; else a->m[i][j]=0.0; +} + +int gl_M4_IsId(M4 *a) +{ + int i,j; + for(i=0;i<4;i++) + for(j=0;j<4;j++) { + if (i==j) { + if (a->m[i][j] != 1.0) return 0; + } else if (a->m[i][j] != 0.0) return 0; + } + return 1; +} + +void gl_M4_Mul(M4 *c,M4 *a,M4 *b) +{ + int i,j,k; + float s; + for(i=0;i<4;i++) + for(j=0;j<4;j++) { + s=0.0; + for(k=0;k<4;k++) s+=a->m[i][k]*b->m[k][j]; + c->m[i][j]=s; + } +} + +/* c=c*a */ +void gl_M4_MulLeft(M4 *c,M4 *b) +{ + int i,j,k; + float s; + M4 a; + + /*memcpy(&a, c, 16*sizeof(float)); + */ + a=*c; + + for(i=0;i<4;i++) + for(j=0;j<4;j++) { + s=0.0; + for(k=0;k<4;k++) s+=a.m[i][k]*b->m[k][j]; + c->m[i][j]=s; + } +} + +void gl_M4_Move(M4 *a,M4 *b) +{ + memcpy(a,b,sizeof(M4)); +} + +void gl_MoveV3(V3 *a,V3 *b) +{ + memcpy(a,b,sizeof(V3)); +} + + +void gl_MulM4V3(V3 *a,M4 *b,V3 *c) +{ + a->X=b->m[0][0]*c->X+b->m[0][1]*c->Y+b->m[0][2]*c->Z+b->m[0][3]; + a->Y=b->m[1][0]*c->X+b->m[1][1]*c->Y+b->m[1][2]*c->Z+b->m[1][3]; + a->Z=b->m[2][0]*c->X+b->m[2][1]*c->Y+b->m[2][2]*c->Z+b->m[2][3]; +} + +void gl_MulM3V3(V3 *a,M4 *b,V3 *c) +{ + a->X=b->m[0][0]*c->X+b->m[0][1]*c->Y+b->m[0][2]*c->Z; + a->Y=b->m[1][0]*c->X+b->m[1][1]*c->Y+b->m[1][2]*c->Z; + a->Z=b->m[2][0]*c->X+b->m[2][1]*c->Y+b->m[2][2]*c->Z; +} + +void gl_M4_MulV4(V4 *a,M4 *b,V4 *c) +{ + a->X=b->m[0][0]*c->X+b->m[0][1]*c->Y+b->m[0][2]*c->Z+b->m[0][3]*c->W; + a->Y=b->m[1][0]*c->X+b->m[1][1]*c->Y+b->m[1][2]*c->Z+b->m[1][3]*c->W; + a->Z=b->m[2][0]*c->X+b->m[2][1]*c->Y+b->m[2][2]*c->Z+b->m[2][3]*c->W; + a->W=b->m[3][0]*c->X+b->m[3][1]*c->Y+b->m[3][2]*c->Z+b->m[3][3]*c->W; +} + +/* transposition of a 4x4 matrix */ +void gl_M4_Transpose(M4 *a,M4 *b) +{ + a->m[0][0]=b->m[0][0]; + a->m[0][1]=b->m[1][0]; + a->m[0][2]=b->m[2][0]; + a->m[0][3]=b->m[3][0]; + + a->m[1][0]=b->m[0][1]; + a->m[1][1]=b->m[1][1]; + a->m[1][2]=b->m[2][1]; + a->m[1][3]=b->m[3][1]; + + a->m[2][0]=b->m[0][2]; + a->m[2][1]=b->m[1][2]; + a->m[2][2]=b->m[2][2]; + a->m[2][3]=b->m[3][2]; + + a->m[3][0]=b->m[0][3]; + a->m[3][1]=b->m[1][3]; + a->m[3][2]=b->m[2][3]; + a->m[3][3]=b->m[3][3]; +} + +/* inversion of an orthogonal matrix of type Y=M.X+P */ +void gl_M4_InvOrtho(M4 *a,M4 b) +{ + int i,j; + float s; + for(i=0;i<3;i++) + for(j=0;j<3;j++) a->m[i][j]=b.m[j][i]; + a->m[3][0]=0.0; a->m[3][1]=0.0; a->m[3][2]=0.0; a->m[3][3]=1.0; + for(i=0;i<3;i++) { + s=0; + for(j=0;j<3;j++) s-=b.m[j][i]*b.m[j][3]; + a->m[i][3]=s; + } +} + +/* Inversion of a general nxn matrix. + Note : m is destroyed */ + +int Matrix_Inv(float *r,float *m,int n) +{ + int i,j,k,l; + float max,tmp,t; + + /* identitée dans r */ + for(i=0;i<n*n;i++) r[i]=0; + for(i=0;i<n;i++) r[i*n+i]=1; + + for(j=0;j<n;j++) { + + /* recherche du nombre de plus grand module sur la colonne j */ + max=m[j*n+j]; + k=j; + for(i=j+1;i<n;i++) + if (fabs(m[i*n+j])>fabs(max)) { + k=i; + max=m[i*n+j]; + } + + /* non intersible matrix */ + if (max==0) return 1; + + + /* permutation des lignes j et k */ + if (k!=j) { + for(i=0;i<n;i++) { + tmp=m[j*n+i]; + m[j*n+i]=m[k*n+i]; + m[k*n+i]=tmp; + + tmp=r[j*n+i]; + r[j*n+i]=r[k*n+i]; + r[k*n+i]=tmp; + } + } + + /* multiplication de la ligne j par 1/max */ + max=1/max; + for(i=0;i<n;i++) { + m[j*n+i]*=max; + r[j*n+i]*=max; + } + + + for(l=0;l<n;l++) if (l!=j) { + t=m[l*n+j]; + for(i=0;i<n;i++) { + m[l*n+i]-=m[j*n+i]*t; + r[l*n+i]-=r[j*n+i]*t; + } + } + } + + return 0; +} + + +/* inversion of a 4x4 matrix */ + +void gl_M4_Inv(M4 *a,M4 *b) +{ + M4 tmp; + memcpy(&tmp, b, 16*sizeof(float)); + /*tmp=*b;*/ + Matrix_Inv(&a->m[0][0],&tmp.m[0][0],4); +} + +void gl_M4_Rotate(M4 *a,float t,int u) +{ + float s,c; + int v,w; + if ((v=u+1)>2) v=0; + if ((w=v+1)>2) w=0; + s=sin(t); + c=cos(t); + gl_M4_Id(a); + a->m[v][v]=c; a->m[v][w]=-s; + a->m[w][v]=s; a->m[w][w]=c; +} + + +/* inverse of a 3x3 matrix */ +void gl_M3_Inv(M3 *a,M3 *m) +{ + float det; + + det = m->m[0][0]*m->m[1][1]*m->m[2][2]-m->m[0][0]*m->m[1][2]*m->m[2][1]- + m->m[1][0]*m->m[0][1]*m->m[2][2]+m->m[1][0]*m->m[0][2]*m->m[2][1]+ + m->m[2][0]*m->m[0][1]*m->m[1][2]-m->m[2][0]*m->m[0][2]*m->m[1][1]; + + a->m[0][0] = (m->m[1][1]*m->m[2][2]-m->m[1][2]*m->m[2][1])/det; + a->m[0][1] = -(m->m[0][1]*m->m[2][2]-m->m[0][2]*m->m[2][1])/det; + a->m[0][2] = -(-m->m[0][1]*m->m[1][2]+m->m[0][2]*m->m[1][1])/det; + + a->m[1][0] = -(m->m[1][0]*m->m[2][2]-m->m[1][2]*m->m[2][0])/det; + a->m[1][1] = (m->m[0][0]*m->m[2][2]-m->m[0][2]*m->m[2][0])/det; + a->m[1][2] = -(m->m[0][0]*m->m[1][2]-m->m[0][2]*m->m[1][0])/det; + + a->m[2][0] = (m->m[1][0]*m->m[2][1]-m->m[1][1]*m->m[2][0])/det; + a->m[2][1] = -(m->m[0][0]*m->m[2][1]-m->m[0][1]*m->m[2][0])/det; + a->m[2][2] = (m->m[0][0]*m->m[1][1]-m->m[0][1]*m->m[1][0])/det; +} + + +/* vector arithmetic */ + +int gl_V3_Norm(V3 *a) +{ + float n; + n=sqrt(a->X*a->X+a->Y*a->Y+a->Z*a->Z); + if (n==0) return 1; + a->X/=n; + a->Y/=n; + a->Z/=n; + return 0; +} + +V3 gl_V3_New(float x,float y,float z) +{ + V3 a; + a.X=x; + a.Y=y; + a.Z=z; + return a; +} + +V4 gl_V4_New(float x,float y,float z,float w) +{ + V4 a; + a.X=x; + a.Y=y; + a.Z=z; + a.W=w; + return a; +} + + diff --git a/3rdparty/tinygl-0.4-ugfx/src/zmath.h b/3rdparty/tinygl-0.4-ugfx/src/zmath.h new file mode 100644 index 00000000..325e408e --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/zmath.h @@ -0,0 +1,53 @@ +#ifndef __ZMATH__ +#define __ZMATH__ + +/* Matrix & Vertex */ + +typedef struct { + float m[4][4]; +} M4; + +typedef struct { + float m[3][3]; +} M3; + +typedef struct { + float m[3][4]; +} M34; + + +#define X v[0] +#define Y v[1] +#define Z v[2] +#define W v[3] + +typedef struct { + float v[3]; +} V3; + +typedef struct { + float v[4]; +} V4; + +void gl_M4_Id(M4 *a); +int gl_M4_IsId(M4 *a); +void gl_M4_Move(M4 *a,M4 *b); +void gl_MoveV3(V3 *a,V3 *b); +void gl_MulM4V3(V3 *a,M4 *b,V3 *c); +void gl_MulM3V3(V3 *a,M4 *b,V3 *c); + +void gl_M4_MulV4(V4 * a,M4 *b,V4 * c); +void gl_M4_InvOrtho(M4 *a,M4 b); +void gl_M4_Inv(M4 *a,M4 *b); +void gl_M4_Mul(M4 *c,M4 *a,M4 *b); +void gl_M4_MulLeft(M4 *c,M4 *a); +void gl_M4_Transpose(M4 *a,M4 *b); +void gl_M4_Rotate(M4 *c,float t,int u); +int gl_V3_Norm(V3 *a); + +V3 gl_V3_New(float x,float y,float z); +V4 gl_V4_New(float x,float y,float z,float w); + +int gl_Matrix_Inv(float *r,float *m,int n); + +#endif //__ZMATH__ diff --git a/3rdparty/tinygl-0.4-ugfx/src/ztriangle.c b/3rdparty/tinygl-0.4-ugfx/src/ztriangle.c new file mode 100644 index 00000000..366d75c5 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/ztriangle.c @@ -0,0 +1,394 @@ +#include <stdlib.h> +#include "zbuffer.h" + +#define ZCMP(z,zpix) ((z) >= (zpix)) + +void ZB_fillTriangleFlat(ZBuffer *zb, + ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) +{ +#if TGL_FEATURE_RENDER_BITS == 24 + unsigned char colorR, colorG, colorB; +#else + int color; +#endif + +#define INTERP_Z + +#if TGL_FEATURE_RENDER_BITS == 24 + +#define DRAW_INIT() \ +{ \ + colorR=p2->r>>8; \ + colorG=p2->g>>8; \ + colorB=p2->b>>8; \ +} + +#define PUT_PIXEL(_a) \ +{ \ + zz=z >> ZB_POINT_Z_FRAC_BITS; \ + if (ZCMP(zz,pz[_a])) { \ + pp[3 * _a]=colorR;\ + pp[3 * _a + 1]=colorG;\ + pp[3 * _a + 2]=colorB;\ + pz[_a]=zz; \ + }\ + z+=dzdx; \ +} + +#else + +#define DRAW_INIT() \ +{ \ + color=RGB_TO_PIXEL(p2->r,p2->g,p2->b); \ +} + +#define PUT_PIXEL(_a) \ +{ \ + zz=z >> ZB_POINT_Z_FRAC_BITS; \ + if (ZCMP(zz,pz[_a])) { \ + pp[_a]=color; \ + pz[_a]=zz; \ + } \ + z+=dzdx; \ +} +#endif /* TGL_FEATURE_RENDER_BITS == 24 */ + +#include "ztriangle.h" +} + +/* + * Smooth filled triangle. + * The code below is very tricky :) + */ + +void ZB_fillTriangleSmooth(ZBuffer *zb, + ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) +{ +#if TGL_FEATURE_RENDER_BITS == 16 + int _drgbdx; +#endif + +#define INTERP_Z +#define INTERP_RGB + +#define SAR_RND_TO_ZERO(v,n) (v / (1<<n)) + +#if TGL_FEATURE_RENDER_BITS == 24 + +#define DRAW_INIT() \ +{ \ +} + +#define PUT_PIXEL(_a) \ +{ \ + zz=z >> ZB_POINT_Z_FRAC_BITS; \ + if (ZCMP(zz,pz[_a])) { \ + pp[3 * _a]=or1 >> 8;\ + pp[3 * _a + 1]=og1 >> 8;\ + pp[3 * _a + 2]=ob1 >> 8;\ + pz[_a]=zz; \ + }\ + z+=dzdx; \ + og1+=dgdx; \ + or1+=drdx; \ + ob1+=dbdx; \ +} + +#elif TGL_FEATURE_RENDER_BITS == 16 + +#define DRAW_INIT() \ +{ \ + _drgbdx=(SAR_RND_TO_ZERO(drdx,6) << 22) & 0xFFC00000; \ + _drgbdx|=SAR_RND_TO_ZERO(dgdx,5) & 0x000007FF; \ + _drgbdx|=(SAR_RND_TO_ZERO(dbdx,7) << 12) & 0x001FF000; \ +} + + +#define PUT_PIXEL(_a) \ +{ \ + zz=z >> ZB_POINT_Z_FRAC_BITS; \ + if (ZCMP(zz,pz[_a])) { \ + tmp=rgb & 0xF81F07E0; \ + pp[_a]=tmp | (tmp >> 16); \ + pz[_a]=zz; \ + } \ + z+=dzdx; \ + rgb=(rgb+drgbdx) & ( ~ 0x00200800); \ +} + +#define DRAW_LINE() \ +{ \ + register unsigned short *pz; \ + register PIXEL *pp; \ + register unsigned int tmp,z,zz,rgb,drgbdx; \ + register int n; \ + n=(x2 >> 16) - x1; \ + pp=pp1+x1; \ + pz=pz1+x1; \ + z=z1; \ + rgb=(r1 << 16) & 0xFFC00000; \ + rgb|=(g1 >> 5) & 0x000007FF; \ + rgb|=(b1 << 5) & 0x001FF000; \ + drgbdx=_drgbdx; \ + while (n>=3) { \ + PUT_PIXEL(0); \ + PUT_PIXEL(1); \ + PUT_PIXEL(2); \ + PUT_PIXEL(3); \ + pz+=4; \ + pp+=4; \ + n-=4; \ + } \ + while (n>=0) { \ + PUT_PIXEL(0); \ + pz+=1; \ + pp+=1; \ + n-=1; \ + } \ +} + +#else + +#define DRAW_INIT() \ +{ \ +} + +#define PUT_PIXEL(_a) \ +{ \ + zz=z >> ZB_POINT_Z_FRAC_BITS; \ + if (ZCMP(zz,pz[_a])) { \ + pp[_a] = RGB_TO_PIXEL(or1, og1, ob1);\ + pz[_a]=zz; \ + }\ + z+=dzdx; \ + og1+=dgdx; \ + or1+=drdx; \ + ob1+=dbdx; \ +} + +#endif /* TGL_FEATURE_RENDER_BITS */ + +#include "ztriangle.h" +} + +void ZB_setTexture(ZBuffer *zb,PIXEL *texture) +{ + zb->current_texture=texture; +} + +void ZB_fillTriangleMapping(ZBuffer *zb, + ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) +{ + PIXEL *texture; + +#define INTERP_Z +#define INTERP_ST + +#define DRAW_INIT() \ +{ \ + texture=zb->current_texture; \ +} + +#if TGL_FEATURE_RENDER_BITS == 24 + +#define PUT_PIXEL(_a) \ +{ \ + unsigned char *ptr;\ + zz=z >> ZB_POINT_Z_FRAC_BITS; \ + if (ZCMP(zz,pz[_a])) { \ + ptr = texture + (((t & 0x3FC00000) | s) >> 14) * 3; \ + pp[3 * _a]= ptr[0];\ + pp[3 * _a + 1]= ptr[1];\ + pp[3 * _a + 2]= ptr[2];\ + pz[_a]=zz; \ + } \ + z+=dzdx; \ + s+=dsdx; \ + t+=dtdx; \ +} + +#else + +#define PUT_PIXEL(_a) \ +{ \ + zz=z >> ZB_POINT_Z_FRAC_BITS; \ + if (ZCMP(zz,pz[_a])) { \ + pp[_a]=texture[((t & 0x3FC00000) | s) >> 14]; \ + pz[_a]=zz; \ + } \ + z+=dzdx; \ + s+=dsdx; \ + t+=dtdx; \ +} + +#endif + +#include "ztriangle.h" +} + +/* + * Texture mapping with perspective correction. + * We use the gradient method to make less divisions. + * TODO: pipeline the division + */ +#if 1 + +void ZB_fillTriangleMappingPerspective(ZBuffer *zb, + ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) +{ + PIXEL *texture; + float fdzdx,fndzdx,ndszdx,ndtzdx; + +#define INTERP_Z +#define INTERP_STZ + +#define NB_INTERP 8 + +#define DRAW_INIT() \ +{ \ + texture=zb->current_texture;\ + fdzdx=(float)dzdx;\ + fndzdx=NB_INTERP * fdzdx;\ + ndszdx=NB_INTERP * dszdx;\ + ndtzdx=NB_INTERP * dtzdx;\ +} + + +#if TGL_FEATURE_RENDER_BITS == 24 + +#define PUT_PIXEL(_a) \ +{ \ + unsigned char *ptr;\ + zz=z >> ZB_POINT_Z_FRAC_BITS; \ + if (ZCMP(zz,pz[_a])) { \ + ptr = texture + (((t & 0x3FC00000) | (s & 0x003FC000)) >> 14) * 3;\ + pp[3 * _a]= ptr[0];\ + pp[3 * _a + 1]= ptr[1];\ + pp[3 * _a + 2]= ptr[2];\ + pz[_a]=zz; \ + } \ + z+=dzdx; \ + s+=dsdx; \ + t+=dtdx; \ +} + +#else + +#define PUT_PIXEL(_a) \ +{ \ + zz=z >> ZB_POINT_Z_FRAC_BITS; \ + if (ZCMP(zz,pz[_a])) { \ + pp[_a]=*(PIXEL *)((char *)texture+ \ + (((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH)));\ + pz[_a]=zz; \ + } \ + z+=dzdx; \ + s+=dsdx; \ + t+=dtdx; \ +} + +#endif + +#define DRAW_LINE() \ +{ \ + register unsigned short *pz; \ + register PIXEL *pp; \ + register unsigned int s,t,z,zz; \ + register int n,dsdx,dtdx; \ + float sz,tz,fz,zinv; \ + n=(x2>>16)-x1; \ + fz=(float)z1;\ + zinv=1.0 / fz;\ + pp=(PIXEL *)((char *)pp1 + x1 * PSZB); \ + pz=pz1+x1; \ + z=z1; \ + sz=sz1;\ + tz=tz1;\ + while (n>=(NB_INTERP-1)) { \ + {\ + float ss,tt;\ + ss=(sz * zinv);\ + tt=(tz * zinv);\ + s=(int) ss;\ + t=(int) tt;\ + dsdx= (int)( (dszdx - ss*fdzdx)*zinv );\ + dtdx= (int)( (dtzdx - tt*fdzdx)*zinv );\ + fz+=fndzdx;\ + zinv=1.0 / fz;\ + }\ + PUT_PIXEL(0); \ + PUT_PIXEL(1); \ + PUT_PIXEL(2); \ + PUT_PIXEL(3); \ + PUT_PIXEL(4); \ + PUT_PIXEL(5); \ + PUT_PIXEL(6); \ + PUT_PIXEL(7); \ + pz+=NB_INTERP; \ + pp=(PIXEL *)((char *)pp + NB_INTERP * PSZB);\ + n-=NB_INTERP; \ + sz+=ndszdx;\ + tz+=ndtzdx;\ + } \ + {\ + float ss,tt;\ + ss=(sz * zinv);\ + tt=(tz * zinv);\ + s=(int) ss;\ + t=(int) tt;\ + dsdx= (int)( (dszdx - ss*fdzdx)*zinv );\ + dtdx= (int)( (dtzdx - tt*fdzdx)*zinv );\ + }\ + while (n>=0) { \ + PUT_PIXEL(0); \ + pz+=1; \ + pp=(PIXEL *)((char *)pp + PSZB);\ + n-=1; \ + } \ +} + +#include "ztriangle.h" +} + +#endif + +#if 0 + +/* slow but exact version (only there for reference, incorrect for 24 + bits) */ + +void ZB_fillTriangleMappingPerspective(ZBuffer *zb, + ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) +{ + PIXEL *texture; + +#define INTERP_Z +#define INTERP_STZ + +#define DRAW_INIT() \ +{ \ + texture=zb->current_texture; \ +} + +#define PUT_PIXEL(_a) \ +{ \ + float zinv; \ + int s,t; \ + zz=z >> ZB_POINT_Z_FRAC_BITS; \ + if (ZCMP(zz,pz[_a])) { \ + zinv= 1.0 / (float) z; \ + s= (int) (sz * zinv); \ + t= (int) (tz * zinv); \ + pp[_a]=texture[((t & 0x3FC00000) | s) >> 14]; \ + pz[_a]=zz; \ + } \ + z+=dzdx; \ + sz+=dszdx; \ + tz+=dtzdx; \ +} + +#include "ztriangle.h" +} + + +#endif diff --git a/3rdparty/tinygl-0.4-ugfx/src/ztriangle.h b/3rdparty/tinygl-0.4-ugfx/src/ztriangle.h new file mode 100644 index 00000000..b6142642 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/ztriangle.h @@ -0,0 +1,363 @@ +/* + * We draw a triangle with various interpolations + */ + +{ + ZBufferPoint *t,*pr1,*pr2,*l1,*l2; + float fdx1, fdx2, fdy1, fdy2, fz, d1, d2; + unsigned short *pz1; + PIXEL *pp1; + int part,update_left,update_right; + + int nb_lines,dx1,dy1,tmp,dx2,dy2; + + int error,derror; + int x1,dxdy_min,dxdy_max; +/* warning: x2 is multiplied by 2^16 */ + int x2,dx2dy2; + +#ifdef INTERP_Z + int z1,dzdx,dzdy,dzdl_min,dzdl_max; +#endif +#ifdef INTERP_RGB + int r1,drdx,drdy,drdl_min,drdl_max; + int g1,dgdx,dgdy,dgdl_min,dgdl_max; + int b1,dbdx,dbdy,dbdl_min,dbdl_max; +#endif +#ifdef INTERP_ST + int s1,dsdx,dsdy,dsdl_min,dsdl_max; + int t1,dtdx,dtdy,dtdl_min,dtdl_max; +#endif +#ifdef INTERP_STZ + float sz1,dszdx,dszdy,dszdl_min,dszdl_max; + float tz1,dtzdx,dtzdy,dtzdl_min,dtzdl_max; +#endif + + /* we sort the vertex with increasing y */ + if (p1->y < p0->y) { + t = p0; + p0 = p1; + p1 = t; + } + if (p2->y < p0->y) { + t = p2; + p2 = p1; + p1 = p0; + p0 = t; + } else if (p2->y < p1->y) { + t = p1; + p1 = p2; + p2 = t; + } + + /* we compute dXdx and dXdy for all interpolated values */ + + fdx1 = p1->x - p0->x; + fdy1 = p1->y - p0->y; + + fdx2 = p2->x - p0->x; + fdy2 = p2->y - p0->y; + + fz = fdx1 * fdy2 - fdx2 * fdy1; + if (fz == 0) + return; + fz = 1.0 / fz; + + fdx1 *= fz; + fdy1 *= fz; + fdx2 *= fz; + fdy2 *= fz; + +#ifdef INTERP_Z + d1 = p1->z - p0->z; + d2 = p2->z - p0->z; + dzdx = (int) (fdy2 * d1 - fdy1 * d2); + dzdy = (int) (fdx1 * d2 - fdx2 * d1); +#endif + +#ifdef INTERP_RGB + d1 = p1->r - p0->r; + d2 = p2->r - p0->r; + drdx = (int) (fdy2 * d1 - fdy1 * d2); + drdy = (int) (fdx1 * d2 - fdx2 * d1); + + d1 = p1->g - p0->g; + d2 = p2->g - p0->g; + dgdx = (int) (fdy2 * d1 - fdy1 * d2); + dgdy = (int) (fdx1 * d2 - fdx2 * d1); + + d1 = p1->b - p0->b; + d2 = p2->b - p0->b; + dbdx = (int) (fdy2 * d1 - fdy1 * d2); + dbdy = (int) (fdx1 * d2 - fdx2 * d1); + +#endif + +#ifdef INTERP_ST + d1 = p1->s - p0->s; + d2 = p2->s - p0->s; + dsdx = (int) (fdy2 * d1 - fdy1 * d2); + dsdy = (int) (fdx1 * d2 - fdx2 * d1); + + d1 = p1->t - p0->t; + d2 = p2->t - p0->t; + dtdx = (int) (fdy2 * d1 - fdy1 * d2); + dtdy = (int) (fdx1 * d2 - fdx2 * d1); +#endif + +#ifdef INTERP_STZ + { + float zz; + zz=(float) p0->z; + p0->sz= (float) p0->s * zz; + p0->tz= (float) p0->t * zz; + zz=(float) p1->z; + p1->sz= (float) p1->s * zz; + p1->tz= (float) p1->t * zz; + zz=(float) p2->z; + p2->sz= (float) p2->s * zz; + p2->tz= (float) p2->t * zz; + + d1 = p1->sz - p0->sz; + d2 = p2->sz - p0->sz; + dszdx = (fdy2 * d1 - fdy1 * d2); + dszdy = (fdx1 * d2 - fdx2 * d1); + + d1 = p1->tz - p0->tz; + d2 = p2->tz - p0->tz; + dtzdx = (fdy2 * d1 - fdy1 * d2); + dtzdy = (fdx1 * d2 - fdx2 * d1); + } +#endif + + /* screen coordinates */ + + pp1 = (PIXEL *) ((char *) zb->pbuf + zb->linesize * p0->y); + pz1 = zb->zbuf + p0->y * zb->xsize; + + DRAW_INIT(); + + for(part=0;part<2;part++) { + if (part == 0) { + if (fz > 0) { + update_left=1; + update_right=1; + l1=p0; + l2=p2; + pr1=p0; + pr2=p1; + } else { + update_left=1; + update_right=1; + l1=p0; + l2=p1; + pr1=p0; + pr2=p2; + } + nb_lines = p1->y - p0->y; + } else { + /* second part */ + if (fz > 0) { + update_left=0; + update_right=1; + pr1=p1; + pr2=p2; + } else { + update_left=1; + update_right=0; + l1=p1; + l2=p2; + } + nb_lines = p2->y - p1->y + 1; + } + + /* compute the values for the left edge */ + + if (update_left) { + dy1 = l2->y - l1->y; + dx1 = l2->x - l1->x; + if (dy1 > 0) + tmp = (dx1 << 16) / dy1; + else + tmp = 0; + x1 = l1->x; + error = 0; + derror = tmp & 0x0000ffff; + dxdy_min = tmp >> 16; + dxdy_max = dxdy_min + 1; + +#ifdef INTERP_Z + z1=l1->z; + dzdl_min=(dzdy + dzdx * dxdy_min); + dzdl_max=dzdl_min + dzdx; +#endif +#ifdef INTERP_RGB + r1=l1->r; + drdl_min=(drdy + drdx * dxdy_min); + drdl_max=drdl_min + drdx; + + g1=l1->g; + dgdl_min=(dgdy + dgdx * dxdy_min); + dgdl_max=dgdl_min + dgdx; + + b1=l1->b; + dbdl_min=(dbdy + dbdx * dxdy_min); + dbdl_max=dbdl_min + dbdx; +#endif +#ifdef INTERP_ST + s1=l1->s; + dsdl_min=(dsdy + dsdx * dxdy_min); + dsdl_max=dsdl_min + dsdx; + + t1=l1->t; + dtdl_min=(dtdy + dtdx * dxdy_min); + dtdl_max=dtdl_min + dtdx; +#endif +#ifdef INTERP_STZ + sz1=l1->sz; + dszdl_min=(dszdy + dszdx * dxdy_min); + dszdl_max=dszdl_min + dszdx; + + tz1=l1->tz; + dtzdl_min=(dtzdy + dtzdx * dxdy_min); + dtzdl_max=dtzdl_min + dtzdx; +#endif + } + + /* compute values for the right edge */ + + if (update_right) { + dx2 = (pr2->x - pr1->x); + dy2 = (pr2->y - pr1->y); + if (dy2>0) + dx2dy2 = ( dx2 << 16) / dy2; + else + dx2dy2 = 0; + x2 = pr1->x << 16; + } + + /* we draw all the scan line of the part */ + + while (nb_lines>0) { + nb_lines--; +#ifndef DRAW_LINE + /* generic draw line */ + { + register PIXEL *pp; + register int n; +#ifdef INTERP_Z + register unsigned short *pz; + register unsigned int z,zz; +#endif +#ifdef INTERP_RGB + register unsigned int or1,og1,ob1; +#endif +#ifdef INTERP_ST + register unsigned int s,t; +#endif +#ifdef INTERP_STZ + float sz,tz; +#endif + + n=(x2 >> 16) - x1; + pp=(PIXEL *)((char *)pp1 + x1 * PSZB); +#ifdef INTERP_Z + pz=pz1+x1; + z=z1; +#endif +#ifdef INTERP_RGB + or1 = r1; + og1 = g1; + ob1 = b1; +#endif +#ifdef INTERP_ST + s=s1; + t=t1; +#endif +#ifdef INTERP_STZ + sz=sz1; + tz=tz1; +#endif + while (n>=3) { + PUT_PIXEL(0); + PUT_PIXEL(1); + PUT_PIXEL(2); + PUT_PIXEL(3); +#ifdef INTERP_Z + pz+=4; +#endif + pp=(PIXEL *)((char *)pp + 4 * PSZB); + n-=4; + } + while (n>=0) { + PUT_PIXEL(0); +#ifdef INTERP_Z + pz+=1; +#endif + pp=(PIXEL *)((char *)pp + PSZB); + n-=1; + } + } +#else + DRAW_LINE(); +#endif + + /* left edge */ + error+=derror; + if (error > 0) { + error-=0x10000; + x1+=dxdy_max; +#ifdef INTERP_Z + z1+=dzdl_max; +#endif +#ifdef INTERP_RGB + r1+=drdl_max; + g1+=dgdl_max; + b1+=dbdl_max; +#endif +#ifdef INTERP_ST + s1+=dsdl_max; + t1+=dtdl_max; +#endif +#ifdef INTERP_STZ + sz1+=dszdl_max; + tz1+=dtzdl_max; +#endif + } else { + x1+=dxdy_min; +#ifdef INTERP_Z + z1+=dzdl_min; +#endif +#ifdef INTERP_RGB + r1+=drdl_min; + g1+=dgdl_min; + b1+=dbdl_min; +#endif +#ifdef INTERP_ST + s1+=dsdl_min; + t1+=dtdl_min; +#endif +#ifdef INTERP_STZ + sz1+=dszdl_min; + tz1+=dtzdl_min; +#endif + } + + /* right edge */ + x2+=dx2dy2; + + /* screen coordinates */ + pp1=(PIXEL *)((char *)pp1 + zb->linesize); + pz1+=zb->xsize; + } + } +} + +#undef INTERP_Z +#undef INTERP_RGB +#undef INTERP_ST +#undef INTERP_STZ + +#undef DRAW_INIT +#undef DRAW_LINE +#undef PUT_PIXEL |