/programs/develop/libraries/TinyGL/src/Makefile |
---|
0,0 → 1,38 |
include ../config.mk |
OBJS= clip.o vertex.o api.o list.o init.o matrix.o texture.o \ |
misc.o clear.o light.o select.o get.o error.o \ |
zbuffer.o zline.o zdither.o ztriangle.o \ |
zmath.o image_util.o msghandling.o \ |
arrays.o specbuf.o glu.o kosgl.o |
INCLUDES = -I$(TINYGL)/include -I$(MENUETDEV)/include |
LIB = libTinyGL.a |
all: $(LIB) |
$(LIB): $(OBJS) |
rm -f $(LIB) |
ar rcs $(LIB) $(OBJS) |
copy /y $@ $(TINYGL)\lib |
del $(LIB) |
clean: |
rm -f *~ *.o *.a $(TINYGL)/$(LIB) |
.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) $(INCLUDES) -c $*.c |
/programs/develop/libraries/TinyGL/src/Tupfile.lua |
---|
0,0 → 1,7 |
if tup.getconfig("NO_GCC") ~= "" then return end |
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../../../.." or tup.getconfig("HELPERDIR") |
tup.include(HELPERDIR .. "/use_gcc.lua") |
tup.include(HELPERDIR .. "/use_menuetlibc.lua") |
INCLUDES = INCLUDES .. " -I../include" |
compile_gcc("*.c") |
tup.rule(OBJS, "kos32-ar rcs %o %f", {"../lib/libTinyGL.a", "../<>"}) |
/programs/develop/libraries/TinyGL/src/api.c |
---|
0,0 → 1,666 |
#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=b; |
p[2].f=g; |
p[3].f=r; |
p[4].f=a; |
/* direct convertion to integer to go faster if no shading */ |
RGBFtoRGBI(r,g,b,p[7].ui,p[6].ui,p[5].ui); |
gl_add_op(p); |
} |
void glColor4fv(float *v) |
{ |
GLParam p[8]; |
p[0].op=OP_Color; |
p[1].f=v[2]; |
p[2].f=v[1]; |
p[3].f=v[0]; |
p[4].f=v[3]; |
/* direct convertion to integer to go faster if no shading */ |
p[5].ui = (unsigned int) (v[2] * (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[0] * (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]; |
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]; |
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]; |
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]; |
assert(face == GL_BACK || |
face == GL_FRONT || |
face == GL_FRONT_AND_BACK); |
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 near,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=near; |
p[6].f=farv; |
gl_add_op(p); |
} |
/* lightening */ |
void glMaterialfv(int mode,int type,float *v) |
{ |
GLParam p[7]; |
int i,n; |
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; |
p[3].f=v[2]; |
p[4].f=v[1]; |
p[5].f=v[0]; |
p[6].f=v[3]; |
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=b; |
p[2].f=g; |
p[3].f=r; |
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; |
} |
/* 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; |
} |
/programs/develop/libraries/TinyGL/src/arrays.c |
---|
0,0 → 1,206 |
#include "zgl.h" |
/*#include <assert.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: |
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: |
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]; |
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]; |
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]; |
assert(type == GL_FLOAT); |
p[0].op = OP_NormalPointer; |
p[1].i = stride; |
p[2].p = (void*)pointer; |
} |
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]; |
assert(type == GL_FLOAT); |
p[0].op = OP_TexCoordPointer; |
p[1].i = size; |
p[2].i = stride; |
p[3].p = (void*)pointer; |
} |
/programs/develop/libraries/TinyGL/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); |
} |
/programs/develop/libraries/TinyGL/src/clip.c |
---|
0,0 → 1,450 |
#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 (z2<min) min=z2; |
if (z3<min) min=z3; |
if (z2>max) max=z2; |
if (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 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)) { |
interpolate(&q1,p1,p2,tmin); |
interpolate(&q2,p1,p2,tmax); |
gl_transform_to_viewport(c,&q1); |
gl_transform_to_viewport(c,&q2); |
RGBFtoRGBI(q1.color.v[0],q1.color.v[1],q1.color.v[2],q1.zp.r,q1.zp.g,q1.zp.b); |
RGBFtoRGBI(q2.color.v[0],q2.color.v[1],q2.color.v[2],q2.zp.r,q2.zp.g,q2.zp.b); |
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); |
RGBFtoRGBI(q->color.v[0],q->color.v[1],q->color.v[2],q->zp.r,q->zp.g,q->zp.b); |
} |
} |
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=0; |
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; |
assert(p0->zp.x >= 0 && p0->zp.x < c->zb->xsize); |
assert(p0->zp.y >= 0 && p0->zp.y < c->zb->ysize); |
assert(p1->zp.x >= 0 && p1->zp.x < c->zb->xsize); |
assert(p1->zp.y >= 0 && p1->zp.y < c->zb->ysize); |
assert(p2->zp.x >= 0 && p2->zp.x < c->zb->xsize); |
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); |
} |
/programs/develop/libraries/TinyGL/src/error.c |
---|
0,0 → 1,16 |
#include <stdarg.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); |
} |
/programs/develop/libraries/TinyGL/src/get.c |
---|
0,0 → 1,72 |
#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: |
fprintf(stderr,"warning: unknown pname in glGetFloatv()\n"); |
break; |
} |
} |
/programs/develop/libraries/TinyGL/src/glu.c |
---|
0,0 → 1,343 |
#include <stdlib.h> |
#include <math.h> |
#include <GL/gl.h> |
#include <GL/glu.h> |
void drawTorus(float rc, int numc, float rt, int numt) |
{ |
int i, j, k; |
double s, t; |
double x, y, z; |
double pi, twopi; |
pi = 3.14159265358979323846; |
twopi = 2 * pi; |
for (i = 0; i < numc; i++) { |
glBegin(GL_QUAD_STRIP); |
for (j = 0; j <= numt; j++) { |
for (k = 1; k >= 0; k--) { |
s = (i + k) % numc + 0.5; |
t = j % numt; |
x = cos(t*twopi/numt) * cos(s*twopi/numc); |
y = sin(t*twopi/numt) * cos(s*twopi/numc); |
z = sin(s*twopi/numc); |
glNormal3f(x, y, z); |
x = (rt + rc * cos(s*twopi/numc)) * cos(t*twopi/numt); |
y = (rt + rc * cos(s*twopi/numc)) * sin(t*twopi/numt); |
z = rc * sin(s*twopi/numc); |
glVertex3f(x, y, z); |
} |
} |
glEnd(); |
} |
} |
static void normal3f( GLfloat x, GLfloat y, GLfloat z ) |
{ |
GLdouble mag; |
mag = sqrt( x*x + y*y + z*z ); |
if (mag>0.00001F) { |
x /= mag; |
y /= mag; |
z /= mag; |
} |
glNormal3f( x, y, z ); |
} |
void gluPerspective( GLdouble fovy, GLdouble aspect, |
GLdouble zNear, GLdouble zFar ) |
{ |
GLdouble xmin, xmax, ymin, ymax; |
ymax = zNear * tan( fovy * M_PI / 360.0 ); |
ymin = -ymax; |
xmin = ymin * aspect; |
xmax = ymax * aspect; |
glFrustum( xmin, xmax, ymin, ymax, zNear, zFar ); |
} |
void |
gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, |
GLdouble centerx, GLdouble centery, GLdouble centerz, |
GLdouble upx, GLdouble upy, GLdouble upz) |
{ |
GLfloat m[16]; |
GLdouble x[3], y[3], z[3]; |
GLdouble mag; |
/* Make rotation matrix */ |
/* Z vector */ |
z[0] = eyex - centerx; |
z[1] = eyey - centery; |
z[2] = eyez - centerz; |
mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]); |
if (mag) { /* mpichler, 19950515 */ |
z[0] /= mag; |
z[1] /= mag; |
z[2] /= mag; |
} |
/* Y vector */ |
y[0] = upx; |
y[1] = upy; |
y[2] = upz; |
/* X vector = Y cross Z */ |
x[0] = y[1] * z[2] - y[2] * z[1]; |
x[1] = -y[0] * z[2] + y[2] * z[0]; |
x[2] = y[0] * z[1] - y[1] * z[0]; |
/* Recompute Y = Z cross X */ |
y[0] = z[1] * x[2] - z[2] * x[1]; |
y[1] = -z[0] * x[2] + z[2] * x[0]; |
y[2] = z[0] * x[1] - z[1] * x[0]; |
/* mpichler, 19950515 */ |
/* cross product gives area of parallelogram, which is < 1.0 for |
* non-perpendicular unit-length vectors; so normalize x, y here |
*/ |
mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); |
if (mag) { |
x[0] /= mag; |
x[1] /= mag; |
x[2] /= mag; |
} |
mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]); |
if (mag) { |
y[0] /= mag; |
y[1] /= mag; |
y[2] /= mag; |
} |
#define M(row,col) m[col*4+row] |
M(0, 0) = x[0]; |
M(0, 1) = x[1]; |
M(0, 2) = x[2]; |
M(0, 3) = 0.0; |
M(1, 0) = y[0]; |
M(1, 1) = y[1]; |
M(1, 2) = y[2]; |
M(1, 3) = 0.0; |
M(2, 0) = z[0]; |
M(2, 1) = z[1]; |
M(2, 2) = z[2]; |
M(2, 3) = 0.0; |
M(3, 0) = 0.0; |
M(3, 1) = 0.0; |
M(3, 2) = 0.0; |
M(3, 3) = 1.0; |
#undef M |
glMultMatrixf(m); |
/* Translate Eye to Origin */ |
glTranslatef(-eyex, -eyey, -eyez); |
} |
GLUquadricObj *gluNewQuadric(void) |
{ |
return NULL; |
} |
void gluQuadricDrawStyle(GLUquadricObj *obj, int style) |
{ |
} |
void gluCylinder( GLUquadricObj *qobj, |
GLdouble baseRadius, GLdouble topRadius, GLdouble height, |
GLint slices, GLint stacks ) |
{ |
GLdouble da, r, dr, dz; |
GLfloat z, nz, nsign; |
GLint i, j; |
GLfloat du = 1.0 / slices; |
GLfloat dv = 1.0 / stacks; |
GLfloat tcx = 0.0, tcy = 0.0; |
nsign = 1.0; |
da = 2.0*M_PI / slices; |
dr = (topRadius-baseRadius) / stacks; |
dz = height / stacks; |
nz = (baseRadius-topRadius) / height; /* Z component of normal vectors */ |
for (i=0;i<slices;i++) { |
GLfloat x1 = -sin(i*da); |
GLfloat y1 = cos(i*da); |
GLfloat x2 = -sin((i+1)*da); |
GLfloat y2 = cos((i+1)*da); |
z = 0.0; |
r = baseRadius; |
tcy = 0.0; |
glBegin( GL_QUAD_STRIP ); |
for (j=0;j<=stacks;j++) { |
if (nsign==1.0) { |
normal3f( x1*nsign, y1*nsign, nz*nsign ); |
glTexCoord2f(tcx, tcy); |
glVertex3f( x1*r, y1*r, z ); |
normal3f( x2*nsign, y2*nsign, nz*nsign ); |
glTexCoord2f(tcx+du, tcy); |
glVertex3f( x2*r, y2*r, z ); |
} |
else { |
normal3f( x2*nsign, y2*nsign, nz*nsign ); |
glTexCoord2f(tcx, tcy); |
glVertex3f( x2*r, y2*r, z ); |
normal3f( x1*nsign, y1*nsign, nz*nsign ); |
glTexCoord2f(tcx+du, tcy); |
glVertex3f( x1*r, y1*r, z ); |
} |
z += dz; |
r += dr; |
tcy += dv; |
} |
glEnd(); |
tcx += du; |
} |
} |
/* Disk (adapted from Mesa) */ |
void gluDisk( GLUquadricObj *qobj, |
GLdouble innerRadius, GLdouble outerRadius, |
GLint slices, GLint loops ) |
{ |
GLdouble a, da; |
GLfloat dr; |
GLfloat r1, r2, dtc; |
GLint s, l; |
GLfloat sa,ca; |
/* Normal vectors */ |
glNormal3f( 0.0, 0.0, +1.0 ); |
da = 2.0*M_PI / slices; |
dr = (outerRadius-innerRadius) / (GLfloat) loops; |
/* texture of a gluDisk is a cut out of the texture unit square */ |
/* x, y in [-outerRadius, +outerRadius]; s, t in [0, 1] (linear mapping) */ |
dtc = 2.0f * outerRadius; |
r1 = innerRadius; |
for (l=0;l<loops;l++) { |
r2 = r1 + dr; |
glBegin( GL_QUAD_STRIP ); |
for (s=0;s<=slices;s++) { |
if (s==slices) a = 0.0; |
else a = s * da; |
sa = sin(a); ca = cos(a); |
glTexCoord2f(0.5+sa*r2/dtc,0.5+ca*r2/dtc); |
glVertex2f( r2*sa, r2*ca ); |
glTexCoord2f(0.5+sa*r1/dtc,0.5+ca*r1/dtc); |
glVertex2f( r1*sa, r1*ca ); |
} |
glEnd(); |
r1 = r2; |
} |
} |
/* |
* Sphere (adapted from Mesa) |
*/ |
void gluSphere(GLUquadricObj *qobj, |
float radius,int slices,int stacks) |
{ |
float rho, drho, theta, dtheta; |
float x, y, z; |
float s, t, ds, dt; |
int i, j, imin, imax; |
int normals; |
float nsign; |
normals=1; |
nsign=1; |
drho = M_PI / (float) stacks; |
dtheta = 2.0 * M_PI / (float) slices; |
/* draw +Z end as a triangle fan */ |
glBegin( GL_TRIANGLE_FAN ); |
glNormal3f( 0.0, 0.0, 1.0 ); |
glTexCoord2f(0.5,0.0); |
glVertex3f( 0.0, 0.0, nsign * radius ); |
for (j=0;j<=slices;j++) { |
theta = (j==slices) ? 0.0 : j * dtheta; |
x = -sin(theta) * sin(drho); |
y = cos(theta) * sin(drho); |
z = nsign * cos(drho); |
if (normals) glNormal3f( x*nsign, y*nsign, z*nsign ); |
glVertex3f( x*radius, y*radius, z*radius ); |
} |
glEnd(); |
ds = 1.0 / slices; |
dt = 1.0 / stacks; |
t = 1.0; /* because loop now runs from 0 */ |
if (1) { |
imin = 0; |
imax = stacks; |
} |
else { |
imin = 1; |
imax = stacks-1; |
} |
/* draw intermediate stacks as quad strips */ |
for (i=imin;i<imax;i++) { |
rho = i * drho; |
glBegin( GL_QUAD_STRIP ); |
s = 0.0; |
for (j=0;j<=slices;j++) { |
theta = (j==slices) ? 0.0 : j * dtheta; |
x = -sin(theta) * sin(rho); |
y = cos(theta) * sin(rho); |
z = nsign * cos(rho); |
if (normals) glNormal3f( x*nsign, y*nsign, z*nsign ); |
glTexCoord2f(s,1-t); |
glVertex3f( x*radius, y*radius, z*radius ); |
x = -sin(theta) * sin(rho+drho); |
y = cos(theta) * sin(rho+drho); |
z = nsign * cos(rho+drho); |
if (normals) glNormal3f( x*nsign, y*nsign, z*nsign ); |
glTexCoord2f(s,1-(t-dt)); |
s += ds; |
glVertex3f( x*radius, y*radius, z*radius ); |
} |
glEnd(); |
t -= dt; |
} |
/* draw -Z end as a triangle fan */ |
glBegin( GL_TRIANGLE_FAN ); |
glNormal3f( 0.0, 0.0, -1.0 ); |
glTexCoord2f(0.5,1.0); |
glVertex3f( 0.0, 0.0, -radius*nsign ); |
rho = M_PI - drho; |
s = 1.0; |
t = dt; |
for (j=slices;j>=0;j--) { |
theta = (j==slices) ? 0.0 : j * dtheta; |
x = -sin(theta) * sin(rho); |
y = cos(theta) * sin(rho); |
z = nsign * cos(rho); |
if (normals) glNormal3f( x*nsign, y*nsign, z*nsign ); |
glTexCoord2f(s,1-t); |
s -= ds; |
glVertex3f( x*radius, y*radius, z*radius ); |
} |
glEnd(); |
} |
/programs/develop/libraries/TinyGL/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; |
} |
} |
/programs/develop/libraries/TinyGL/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); |
} |
/programs/develop/libraries/TinyGL/src/kosgl.c |
---|
0,0 → 1,127 |
/* simple gl like driver for TinyGL and KolibriOS - porting iadn */ |
#include <GL/gl.h> |
#include "kosgl.h" |
#include "zgl.h" |
typedef struct { |
GLContext *gl_context; |
int xsize,ysize; |
int dx,dy; |
int x,y; |
} TinyGLContext; |
KOSGLContext kosglCreateContext(KOSGLContext shareList, int flags) |
{ |
TinyGLContext *ctx; |
if (shareList != NULL) { |
gl_fatal_error("No sharing available in TinyGL"); |
} |
ctx=gl_malloc(sizeof(TinyGLContext)); |
if (!ctx) |
return NULL; |
ctx->gl_context=NULL; |
return (KOSGLContext) ctx; |
} |
void kosglDestroyContext( KOSGLContext ctx1 ) |
{ |
TinyGLContext *ctx = (TinyGLContext *) 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 gl_resize_viewport(GLContext *c,int *xsize_ptr,int *ysize_ptr) |
{ |
TinyGLContext *ctx; |
int xsize,ysize; |
ctx=(TinyGLContext *)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-1; |
*ysize_ptr=ysize-1; |
ctx->dx = xsize; |
ctx->dy = 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 kosglMakeCurrent( int win_x0, int win_y0,int win_x, int win_y, KOSGLContext ctx1) |
{ |
TinyGLContext *ctx = (TinyGLContext *) ctx1; |
int mode; |
ZBuffer *zb; |
if (ctx->gl_context == NULL) { |
/* create the TinyGL context */ |
ctx->x = win_x0; |
ctx->y = win_y0; |
ctx->dx = win_x; |
ctx->dy = win_y; |
/* currently, we only support 16 bit rendering */ |
mode = ZB_MODE_RGB24; |
zb=ZB_open(win_x,win_y,mode,0,NULL,NULL,NULL); |
if (zb == NULL) { |
fprintf(stderr, "Error while initializing Z buffer\n"); |
exit(1); |
} |
/* 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=gl_resize_viewport; |
/* set the viewport : we force a call to gl_resize_viewport */ |
ctx->gl_context->viewport.xsize=-1; |
ctx->gl_context->viewport.ysize=-1; |
glViewport(0, 0, win_x, win_y); |
} |
return 1; |
} |
void kosglSwapBuffers( ) |
{ |
GLContext *gl_context; |
TinyGLContext *ctx; |
/* retrieve the current TinyGLContext */ |
gl_context=gl_get_context(); |
ctx=(TinyGLContext *)gl_context->opaque; |
__asm__ __volatile__("int $0x40"::"a"(7), |
"b"((char *)gl_context->zb->pbuf), |
"c"((ctx->dx<<16)|ctx->dy), |
"d"((ctx->x<<16)|ctx->y)); |
} |
/programs/develop/libraries/TinyGL/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: |
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; |
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]; |
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: |
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); |
//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; |
} |
/programs/develop/libraries/TinyGL/src/list.c |
---|
0,0 → 1,251 |
#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" |
}; |
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); |
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; |
} |
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"); |
} |
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); |
} |
if (c->print_flag) { |
gl_print_op(stderr,p); |
} |
} |
/* this opcode is never called directly */ |
void glopEndList(GLContext *c,GLParam *p) |
{ |
assert(0); |
} |
/* this opcode is never called directly */ |
void glopNextBuffer(GLContext *c,GLParam *p) |
{ |
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(); |
assert(mode == GL_COMPILE || mode == GL_COMPILE_AND_EXECUTE); |
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]; |
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; |
} |
/programs/develop/libraries/TinyGL/src/matrix.c |
---|
0,0 → 1,241 |
#include "zgl.h" |
void gl_print_matrix( const float *m) |
{ |
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] ); |
} |
} |
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: |
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) |
{ |
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; |
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; |
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 near=p[5].f; |
float farp=p[6].f; |
float x,y,A,B,C,D; |
x = (2.0*near) / (right-left); |
y = (2.0*near) / (top-bottom); |
A = (right+left) / (right-left); |
B = (top+bottom) / (top-bottom); |
C = -(farp+near) / ( farp-near); |
D = -(2.0*farp*near) / (farp-near); |
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); |
} |
/programs/develop/libraries/TinyGL/src/misc.c |
---|
0,0 → 1,147 |
#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: |
assert(0); |
} |
} |
void glopHint(GLContext *c,GLParam *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; |
} |
/programs/develop/libraries/TinyGL/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 */ |
} |
/programs/develop/libraries/TinyGL/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_ */ |
/programs/develop/libraries/TinyGL/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 |
/programs/develop/libraries/TinyGL/src/select.c |
---|
0,0 → 1,114 |
#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: |
assert(0); |
} |
switch(mode) { |
case GL_RENDER: |
c->render_mode=GL_RENDER; |
break; |
case GL_SELECT: |
c->render_mode=GL_SELECT; |
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: |
assert(0); |
} |
return result; |
} |
void glSelectBuffer(int size,unsigned int *buf) |
{ |
GLContext *c=gl_get_context(); |
assert(c->render_mode != GL_SELECT); |
c->select_buffer=buf; |
c->select_size=size; |
} |
void glopInitNames(GLContext *c,GLParam *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) { |
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) |
{ |
if (c->render_mode == GL_SELECT) { |
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) { |
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; |
} |
} |
} |
/programs/develop/libraries/TinyGL/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; |
} |
/programs/develop/libraries/TinyGL/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_ */ |
/programs/develop/libraries/TinyGL/src/texture.c |
---|
0,0 → 1,229 |
/* |
* 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; |
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; |
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; |
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; |
if (pname != GL_UNPACK_ALIGNMENT || |
param != 1) { |
gl_fatal_error("glPixelStore: unsupported option"); |
} |
} |
/programs/develop/libraries/TinyGL/src/vertex.c |
---|
0,0 → 1,364 |
#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; |
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; |
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) |
{ |
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; |
} |
/programs/develop/libraries/TinyGL/src/zbuffer.c |
---|
0,0 → 1,509 |
/* |
* Z buffer: 16 bits Z / 16 bits color |
* |
*/ |
#include <stdlib.h> |
#include <stdio.h> |
/*#include <assert.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; |
zb->frame_buffer_allocated = 0; |
zb->pbuf = NULL; |
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+1) * (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); |
(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: |
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: |
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: |
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); |
} |
} |
} |
/programs/develop/libraries/TinyGL/src/zbuffer.h |
---|
0,0 → 1,169 |
#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 allocator for TinyGL |
*/ |
/* modify these functions so that they suit your needs */ |
static inline void gl_free(void *p) |
{ |
free(p); |
} |
static inline void *gl_malloc(int size) |
{ |
return malloc(size); |
} |
static inline void *gl_zalloc(int size) |
{ |
return calloc(1, size); |
} |
#endif /* _tgl_zbuffer_h_ */ |
/programs/develop/libraries/TinyGL/src/zdither.c |
---|
0,0 → 1,159 |
/* |
* 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)) { |
fprintf(stderr,"zdither: not enough colors\n"); |
exit(1); |
} |
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 |
/programs/develop/libraries/TinyGL/src/zfeatures.h |
---|
0,0 → 1,54 |
#ifndef _tgl_features_h_ |
#define _tgl_features_h_ |
#define NDEBUG |
/*for menuetlibc*/ |
#ifdef NDEBUG |
/* |
* If not debugging, assert does nothing. |
*/ |
#define assert(x) ((void)0) |
#else /* debugging enabled */ |
#include <assert.h> |
#endif |
/* 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_ */ |
/programs/develop/libraries/TinyGL/src/zgl.h |
---|
0,0 → 1,392 |
#ifndef _tgl_zgl_h_ |
#define _tgl_zgl_h_ |
#include <stdlib.h> |
#include <stdio.h> |
#include <math.h> |
/*#include <assert.h>*/ |
#include <GL/gl.h> |
#include "zbuffer.h" |
#include "zmath.h" |
#include "zfeatures.h" |
#define fputc(...) /*nothing*/ |
#define fprintf(...) /*nothing*/ |
#define vfprintf(...) /*nothing*/ |
#undef stderr |
#define stderr ((FILE*)-1) |
/*#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); |
static inline GLContext *gl_get_context(void) |
{ |
return gl_ctx; |
}; |
void gl_fatal_error(char *format, ...); |
/* 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) ; |
} |
#define RGBFtoRGBI(rf,gf,bf,ri,gi,bi) \ |
{\ |
ri = (unsigned int) (rf * (ZB_POINT_RED_MAX - ZB_POINT_RED_MIN) + \ |
ZB_POINT_RED_MIN); \ |
gi = (unsigned int) (gf * (ZB_POINT_GREEN_MAX - ZB_POINT_GREEN_MIN) + \ |
ZB_POINT_GREEN_MIN); \ |
bi = (unsigned int) (bf * (ZB_POINT_BLUE_MAX - ZB_POINT_BLUE_MIN) + \ |
ZB_POINT_BLUE_MIN);\ |
} |
#endif /* _tgl_zgl_h_ */ |
/programs/develop/libraries/TinyGL/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); |
} |
} |
/programs/develop/libraries/TinyGL/src/zline.h |
---|
0,0 → 1,121 |
{ |
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 = p1->r << 8; |
g = p1->g << 8; |
b = p1->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 |
#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 |
/programs/develop/libraries/TinyGL/src/zmath.c |
---|
0,0 → 1,274 |
/* 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)); |
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; |
} |
/programs/develop/libraries/TinyGL/src/zmath.h |
---|
0,0 → 1,56 |
#ifndef __ZMATH__ |
#define __ZMATH__ |
/*for menuetlibc*/ |
#define pow powf |
/* 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__*/ |
/programs/develop/libraries/TinyGL/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 |
/programs/develop/libraries/TinyGL/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 |