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; }
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 = 1024; /* 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 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"); } }
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; } }
NGLXContext nglXCreateContext(NGLXContext shareList, int flags) { TinyNGLXContext *ctx; if (shareList != NULL) { gl_fatal_error("No sharing available in TinyGL"); } ctx=gl_malloc(sizeof(TinyNGLXContext)); if (!ctx) return NULL; ctx->gl_context=NULL; return (NGLXContext) ctx; }
/* 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 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); return; } 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 ZB_initDither(ZBuffer *zb,int nb_colors, unsigned char *color_indexes,int *color_table) { int c,r,g,b,i,index,r1,g1,b1; if (nb_colors < (_R * _G * _B)) { gl_fatal_error("zdither: not enough colors\n"); } for(i=0;i<nb_colors;i++) color_table[i]=0; zb->nb_colors=nb_colors; zb->ctable=gl_malloc(nb_colors * sizeof(int)); for (r = 0; r < _R; r++) { for (g = 0; g < _G; g++) { for (b = 0; b < _B; b++) { r1=(r*255) / (_R - 1); g1=(g*255) / (_G - 1); b1=(b*255) / (_B - 1); index=DITHER_INDEX(r,g,b); c=(r1 << 16) | (g1 << 8) | b1; zb->ctable[index]=c; color_table[index]=c; } } } zb->dctable=gl_malloc( DITHER_TABLE_SIZE ); for(i=0;i<DITHER_TABLE_SIZE;i++) { r=(i >> 12) & 0x7; g=(i >> 8) & 0xF; b=(i >> 3) & 0x7; index=DITHER_INDEX(r,g,b); zb->dctable[i]=color_indexes[index]; } }
void glopVertex(GLContext * c, GLParam * p) { GLVertex *v; int n, i, cnt; gl_assert(c->in_begin != 0); n = c->vertex_n; cnt = c->vertex_cnt; cnt++; c->vertex_cnt = cnt; /* quick fix to avoid crashes on large polygons */ if (n >= c->vertex_max) { GLVertex *newarray; c->vertex_max <<= 1; /* just double size */ newarray = gl_malloc(sizeof(GLVertex) * c->vertex_max); if (!newarray) { gl_fatal_error("unable to allocate GLVertex array.\n"); } memcpy(newarray, c->vertex, n * sizeof(GLVertex)); gl_free(c->vertex); c->vertex = newarray; } /* new vertex entry */ v = &c->vertex[n]; n++; v->coord.X = p[1].f; v->coord.Y = p[2].f; v->coord.Z = p[3].f; v->coord.W = p[4].f; gl_vertex_transform(c, v); /* color */ if (c->lighting_enabled) { gl_shade_vertex(c, v); } else { v->color = c->current_color; } /* tex coords */ if (c->texture_2d_enabled) { if (c->apply_texture_matrix) { gl_M4_MulV4(&v->tex_coord, c->matrix_stack_ptr[2], &c->current_tex_coord); } else { v->tex_coord = c->current_tex_coord; } } /* precompute the mapping to the viewport */ if (v->clip_code == 0) gl_transform_to_viewport(c, v); /* edge flag */ v->edge_flag = c->current_edge_flag; switch (c->begin_type) { case GL_POINTS: gl_draw_point(c, &c->vertex[0]); n = 0; break; case GL_LINES: if (n == 2) { gl_draw_line(c, &c->vertex[0], &c->vertex[1]); n = 0; } break; case GL_LINE_STRIP: case GL_LINE_LOOP: if (n == 1) { c->vertex[2] = c->vertex[0]; } else if (n == 2) { gl_draw_line(c, &c->vertex[0], &c->vertex[1]); c->vertex[0] = c->vertex[1]; n = 1; } break; case GL_TRIANGLES: if (n == 3) { gl_draw_triangle(c, &c->vertex[0], &c->vertex[1], &c->vertex[2]); n = 0; } break; case GL_TRIANGLE_STRIP: if (cnt >= 3) { if (n == 3) n = 0; /* needed to respect triangle orientation */ switch(cnt & 1) { case 0: gl_draw_triangle(c,&c->vertex[2],&c->vertex[1],&c->vertex[0]); break; default: case 1: gl_draw_triangle(c,&c->vertex[0],&c->vertex[1],&c->vertex[2]); break; } } break; case GL_TRIANGLE_FAN: if (n == 3) { gl_draw_triangle(c, &c->vertex[0], &c->vertex[1], &c->vertex[2]); c->vertex[1] = c->vertex[2]; n = 2; } break; case GL_QUADS: if (n == 4) { c->vertex[2].edge_flag = 0; gl_draw_triangle(c, &c->vertex[0], &c->vertex[1], &c->vertex[2]); c->vertex[2].edge_flag = 1; c->vertex[0].edge_flag = 0; gl_draw_triangle(c, &c->vertex[0], &c->vertex[2], &c->vertex[3]); n = 0; } break; case GL_QUAD_STRIP: if (n == 4) { gl_draw_triangle(c, &c->vertex[0], &c->vertex[1], &c->vertex[2]); gl_draw_triangle(c, &c->vertex[1], &c->vertex[3], &c->vertex[2]); for (i = 0; i < 2; i++) c->vertex[i] = c->vertex[i + 2]; n = 2; } break; case GL_POLYGON: break; default: gl_fatal_error("glBegin: type %x not handled\n", c->begin_type); } c->vertex_n = n; }
void 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; int do_free; int isRGBA = (format == GL_RGBA); #if 0 if (target == GL_TEXTURE_2D && level == 0 && components == 4 && border == 0 && format == GL_RGBA && type == GL_UNSIGNED_BYTE) { 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 == 32 im->pixmap=gl_malloc(width*height*4); if(im->pixmap) { gl_convertRGBA_to_8A8R8G8B(im->pixmap,pixels,width,height); } #elif TGL_FEATURE_RENDER_BITS == 16 im->pixmap=gl_malloc(width*height*2); if(im->pixmap) { gl_convertRGBA_to_5R6G5B(im->pixmap,pixels,width,height); } #else #error 32 or 16 #endif return; } #endif unsigned char *pixels1; if (!(target == GL_TEXTURE_2D && level == 0 && (components == 3 || components == 4) && border == 0 && (format == GL_RGB || format == GL_RGBA ) && type == GL_UNSIGNED_BYTE)) { gl_fatal_error("glTexImage2D: combinaison of parameters not handled"); } do_free=0; if (width != NEWXS || height != NEWYS) { pixels1 = gl_malloc(NEWXS * NEWYS * 3); /* no interpolation is done here to respect the original image aliasing ! */ if(isRGBA) gl_resizeImageNoInterpolate_rgba2rgb(pixels1,NEWXS,NEWYS,pixels,width,height); else gl_resizeImageNoInterpolate(pixels1,NEWXS,NEWYS,pixels,width,height); do_free=1; width=NEWXS; height=NEWYS; } 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); }