#ifndef _tgl_zgl_h_ #define _tgl_zgl_h_ #include #include #include #include #include #include #include "zbuffer.h" #include "zmath.h" #include "zfeatures.h" #define DEBUG /* #define NDEBUG */ enum { #define ADD_OP(a,b,c) OP_ ## a , #include "opinfo.h" }; /* initially # of allocated GLVertexes (will grow when necessary) */ #define POLYGON_MAX_VERTEX 16 /* Max # of specular light pow buffers */ #define MAX_SPECULAR_BUFFERS 8 /* # of entries in specular buffer */ #define SPECULAR_BUFFER_SIZE 1024 /* specular buffer granularity */ #define SPECULAR_BUFFER_RESOLUTION 1024 #define MAX_MODELVIEW_STACK_DEPTH 32 #define MAX_PROJECTION_STACK_DEPTH 8 #define MAX_TEXTURE_STACK_DEPTH 8 #define MAX_NAME_STACK_DEPTH 64 #define MAX_TEXTURE_LEVELS 11 #define MAX_LIGHTS 16 #define VERTEX_HASH_SIZE 1031 #define MAX_DISPLAY_LISTS 1024 #define OP_BUFFER_MAX_SIZE 512 #define TGL_OFFSET_FILL 0x1 #define TGL_OFFSET_LINE 0x2 #define TGL_OFFSET_POINT 0x4 typedef struct GLSpecBuf { int shininess_i; int last_used; float buf[SPECULAR_BUFFER_SIZE+1]; struct GLSpecBuf *next; } GLSpecBuf; typedef struct GLLight { V4 ambient; V4 diffuse; V4 specular; V4 position; V3 spot_direction; float spot_exponent; float spot_cutoff; float attenuation[3]; /* precomputed values */ float cos_spot_cutoff; V3 norm_spot_direction; V3 norm_position; /* we use a linked list to know which are the enabled lights */ int enabled; struct GLLight *next,*prev; } GLLight; typedef struct GLMaterial { V4 emission; V4 ambient; V4 diffuse; V4 specular; float shininess; /* computed values */ int shininess_i; int do_specular; } GLMaterial; typedef struct GLViewport { int xmin,ymin,xsize,ysize; V3 scale; V3 trans; int updated; } GLViewport; typedef union { int op; float f; int i; unsigned int ui; void *p; } GLParam; typedef struct GLParamBuffer { GLParam ops[OP_BUFFER_MAX_SIZE]; struct GLParamBuffer *next; } GLParamBuffer; typedef struct GLList { GLParamBuffer *first_op_buffer; /* TODO: extensions for an hash table or a better allocating scheme */ } GLList; typedef struct GLVertex { int edge_flag; V3 normal; V4 coord; V4 tex_coord; V4 color; /* computed values */ V4 ec; /* eye coordinates */ V4 pc; /* coordinates in the normalized volume */ int clip_code; /* clip code */ ZBufferPoint zp; /* integer coordinates for the rasterization */ } GLVertex; typedef struct GLImage { void *pixmap; int xsize,ysize; } GLImage; /* textures */ #define TEXTURE_HASH_TABLE_SIZE 256 typedef struct GLTexture { GLImage images[MAX_TEXTURE_LEVELS]; int handle; struct GLTexture *next,*prev; } GLTexture; /* shared state */ typedef struct GLSharedState { GLList **lists; GLTexture **texture_hash_table; } GLSharedState; struct GLContext; typedef void (*gl_draw_triangle_func)(struct GLContext *c, GLVertex *p0,GLVertex *p1,GLVertex *p2); /* display context */ typedef struct GLContext { /* Z buffer */ ZBuffer *zb; /* lights */ GLLight lights[MAX_LIGHTS]; GLLight *first_light; V4 ambient_light_model; int local_light_model; int lighting_enabled; int light_model_two_side; /* materials */ GLMaterial materials[2]; int color_material_enabled; int current_color_material_mode; int current_color_material_type; /* textures */ GLTexture *current_texture; int texture_2d_enabled; /* shared state */ GLSharedState shared_state; /* current list */ GLParamBuffer *current_op_buffer; int current_op_buffer_index; int exec_flag,compile_flag,print_flag; /* matrix */ int matrix_mode; M4 *matrix_stack[3]; M4 *matrix_stack_ptr[3]; int matrix_stack_depth_max[3]; M4 matrix_model_view_inv; M4 matrix_model_projection; int matrix_model_projection_updated; int matrix_model_projection_no_w_transform; int apply_texture_matrix; /* viewport */ GLViewport viewport; /* current state */ int polygon_mode_back; int polygon_mode_front; int current_front_face; int current_shade_model; int current_cull_face; int cull_face_enabled; int normalize_enabled; gl_draw_triangle_func draw_triangle_front,draw_triangle_back; /* selection */ int render_mode; unsigned int *select_buffer; int select_size; unsigned int *select_ptr,*select_hit; int select_overflow; int select_hits; /* names */ unsigned int name_stack[MAX_NAME_STACK_DEPTH]; int name_stack_size; /* clear */ float clear_depth; V4 clear_color; /* current vertex state */ V4 current_color; unsigned int longcurrent_color[3]; /* precomputed integer color */ V4 current_normal; V4 current_tex_coord; int current_edge_flag; /* glBegin / glEnd */ int in_begin; int begin_type; int vertex_n,vertex_cnt; int vertex_max; GLVertex *vertex; /* opengl 1.1 arrays */ float *vertex_array; int vertex_array_size; int vertex_array_stride; float *normal_array; int normal_array_stride; float *color_array; int color_array_size; int color_array_stride; float *texcoord_array; int texcoord_array_size; int texcoord_array_stride; int client_states; /* opengl 1.1 polygon offset */ float offset_factor; float offset_units; int offset_states; /* specular buffer. could probably be shared between contexts, but that wouldn't be 100% thread safe */ GLSpecBuf *specbuf_first; int specbuf_used_counter; int specbuf_num_buffers; /* opaque structure for user's use */ void *opaque; /* resize viewport function */ int (*gl_resize_viewport)(struct GLContext *c,int *xsize,int *ysize); /* depth test */ int depth_test; } GLContext; extern GLContext *gl_ctx; void gl_add_op(GLParam *p); /* clip.c */ void gl_transform_to_viewport(GLContext *c,GLVertex *v); void gl_draw_triangle(GLContext *c,GLVertex *p0,GLVertex *p1,GLVertex *p2); void gl_draw_line(GLContext *c,GLVertex *p0,GLVertex *p1); void gl_draw_point(GLContext *c,GLVertex *p0); void gl_draw_triangle_point(GLContext *c, GLVertex *p0,GLVertex *p1,GLVertex *p2); void gl_draw_triangle_line(GLContext *c, GLVertex *p0,GLVertex *p1,GLVertex *p2); void gl_draw_triangle_fill(GLContext *c, GLVertex *p0,GLVertex *p1,GLVertex *p2); void gl_draw_triangle_select(GLContext *c, GLVertex *p0,GLVertex *p1,GLVertex *p2); /* matrix.c */ void gl_print_matrix(const float *m); /* void glopLoadIdentity(GLContext *c,GLParam *p); void glopTranslate(GLContext *c,GLParam *p);*/ /* light.c */ void gl_add_select(GLContext *c,unsigned int zmin,unsigned int zmax); void gl_enable_disable_light(GLContext *c,int light,int v); void gl_shade_vertex(GLContext *c,GLVertex *v); void glInitTextures(GLContext *c); void glEndTextures(GLContext *c); GLTexture *alloc_texture(GLContext *c,int h); /* image_util.c */ void gl_convertRGB_to_5R6G5B(unsigned short *pixmap,unsigned char *rgb, int xsize,int ysize); void gl_convertRGB_to_8A8R8G8B(unsigned int *pixmap, unsigned char *rgb, int xsize, int ysize); void gl_resizeImage(unsigned char *dest,int xsize_dest,int ysize_dest, unsigned char *src,int xsize_src,int ysize_src); void gl_resizeImageNoInterpolate(unsigned char *dest,int xsize_dest,int ysize_dest, unsigned char *src,int xsize_src,int ysize_src); GLContext *gl_get_context(void); void gl_fatal_error(char *format, ...); /* specular buffer "api" */ GLSpecBuf *specbuf_get_buffer(GLContext *c, const int shininess_i, const float shininess); #ifdef __BEOS__ void dprintf(const char *, ...); #else /* !BEOS */ #ifdef DEBUG #define dprintf(format, args...) \ fprintf(stderr,"In '%s': " format "\n",__FUNCTION__, ##args); #else #define dprintf(format, args...) #endif #endif /* !BEOS */ /* glopXXX functions */ #define ADD_OP(a,b,c) void glop ## a (GLContext *,GLParam *); #include "opinfo.h" /* this clip epsilon is needed to avoid some rounding errors after several clipping stages */ #define CLIP_EPSILON (1E-5) static inline int gl_clipcode(float x,float y,float z,float w1) { float w; w=w1 * (1.0 + CLIP_EPSILON); return (x<-w) | ((x>w)<<1) | ((y<-w)<<2) | ((y>w)<<3) | ((z<-w)<<4) | ((z>w)<<5) ; } #endif /* _tgl_zgl_h_ */