ugfx/3rdparty/tinygl-0.4-ugfx/src/texture.c

233 lines
4.5 KiB
C

/*
* Texture Manager
*/
#include "zgl.h"
static GLTexture *find_texture(GLContext *c,int h)
{
GLTexture *t;
t=c->shared_state.texture_hash_table[h % TEXTURE_HASH_TABLE_SIZE];
while (t!=NULL) {
if (t->handle == h) return t;
t=t->next;
}
return NULL;
}
static void free_texture(GLContext *c,int h)
{
GLTexture *t,**ht;
GLImage *im;
int i;
t=find_texture(c,h);
if (t->prev==NULL) {
ht=&c->shared_state.texture_hash_table
[t->handle % TEXTURE_HASH_TABLE_SIZE];
*ht=t->next;
} else {
t->prev->next=t->next;
}
if (t->next!=NULL) t->next->prev=t->prev;
for(i=0;i<MAX_TEXTURE_LEVELS;i++) {
im=&t->images[i];
if (im->pixmap != NULL) gl_free(im->pixmap);
}
gl_free(t);
}
GLTexture *alloc_texture(GLContext *c,int h)
{
GLTexture *t,**ht;
t=gl_zalloc(sizeof(GLTexture));
ht=&c->shared_state.texture_hash_table[h % TEXTURE_HASH_TABLE_SIZE];
t->next=*ht;
t->prev=NULL;
if (t->next != NULL) t->next->prev=t;
*ht=t;
t->handle=h;
return t;
}
void glInitTextures(GLContext *c)
{
/* textures */
c->texture_2d_enabled=0;
c->current_texture=find_texture(c,0);
}
void glGenTextures(int n, unsigned int *textures)
{
GLContext *c=gl_get_context();
int max,i;
GLTexture *t;
max=0;
for(i=0;i<TEXTURE_HASH_TABLE_SIZE;i++) {
t=c->shared_state.texture_hash_table[i];
while (t!=NULL) {
if (t->handle>max) max=t->handle;
t=t->next;
}
}
for(i=0;i<n;i++) {
textures[i]=max+i+1;
}
}
void glDeleteTextures(int n, const unsigned int *textures)
{
GLContext *c=gl_get_context();
int i;
GLTexture *t;
for(i=0;i<n;i++) {
t=find_texture(c,textures[i]);
if (t!=NULL && t!=0) {
if (t==c->current_texture) {
glBindTexture(GL_TEXTURE_2D,0);
}
free_texture(c,textures[i]);
}
}
}
void glopBindTexture(GLContext *c,GLParam *p)
{
int target=p[1].i;
int texture=p[2].i;
GLTexture *t;
gl_assert(target == GL_TEXTURE_2D && texture >= 0);
t=find_texture(c,texture);
if (t==NULL) {
t=alloc_texture(c,texture);
}
c->current_texture=t;
}
void glopTexImage2D(GLContext *c,GLParam *p)
{
int target=p[1].i;
int level=p[2].i;
int components=p[3].i;
int width=p[4].i;
int height=p[5].i;
int border=p[6].i;
int format=p[7].i;
int type=p[8].i;
void *pixels=p[9].p;
GLImage *im;
unsigned char *pixels1;
int do_free;
if (!(target == GL_TEXTURE_2D && level == 0 && components == 3 &&
border == 0 && format == GL_RGB &&
type == GL_UNSIGNED_BYTE)) {
gl_fatal_error("glTexImage2D: combinaison of parameters not handled");
}
do_free=0;
if (width != 256 || height != 256) {
pixels1 = gl_malloc(256 * 256 * 3);
/* no interpolation is done here to respect the original image aliasing ! */
gl_resizeImageNoInterpolate(pixels1,256,256,pixels,width,height);
do_free=1;
width=256;
height=256;
} else {
pixels1=pixels;
}
im=&c->current_texture->images[level];
im->xsize=width;
im->ysize=height;
if (im->pixmap!=NULL) gl_free(im->pixmap);
#if TGL_FEATURE_RENDER_BITS == 24
im->pixmap=gl_malloc(width*height*3);
if(im->pixmap) {
memcpy(im->pixmap,pixels1,width*height*3);
}
#elif TGL_FEATURE_RENDER_BITS == 32
im->pixmap=gl_malloc(width*height*4);
if(im->pixmap) {
gl_convertRGB_to_8A8R8G8B(im->pixmap,pixels1,width,height);
}
#elif TGL_FEATURE_RENDER_BITS == 16
im->pixmap=gl_malloc(width*height*2);
if(im->pixmap) {
gl_convertRGB_to_5R6G5B(im->pixmap,pixels1,width,height);
}
#else
#error TODO
#endif
if (do_free) gl_free(pixels1);
}
/* TODO: not all tests are done */
void glopTexEnv(GLContext *c,GLParam *p)
{
int target=p[1].i;
int pname=p[2].i;
int param=p[3].i;
(void)c;
if (target != GL_TEXTURE_ENV) {
error:
gl_fatal_error("glTexParameter: unsupported option");
}
if (pname != GL_TEXTURE_ENV_MODE) goto error;
if (param != GL_DECAL) goto error;
}
/* TODO: not all tests are done */
void glopTexParameter(GLContext *c,GLParam *p)
{
int target=p[1].i;
int pname=p[2].i;
int param=p[3].i;
(void)c;
if (target != GL_TEXTURE_2D) {
error:
gl_fatal_error("glTexParameter: unsupported option");
}
switch(pname) {
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
if (param != GL_REPEAT) goto error;
break;
}
}
void glopPixelStore(GLContext *c,GLParam *p)
{
int pname=p[1].i;
int param=p[2].i;
(void)c;
if (pname != GL_UNPACK_ALIGNMENT ||
param != 1) {
gl_fatal_error("glPixelStore: unsupported option");
}
}