diff options
Diffstat (limited to 'opengl/system/pdp_texture.c')
-rw-r--r-- | opengl/system/pdp_texture.c | 541 |
1 files changed, 0 insertions, 541 deletions
diff --git a/opengl/system/pdp_texture.c b/opengl/system/pdp_texture.c deleted file mode 100644 index 46e1c7a..0000000 --- a/opengl/system/pdp_texture.c +++ /dev/null @@ -1,541 +0,0 @@ -/* - * OpenGL Extension Module for pdp - texture packet implementation - * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -/* this modules implemtents the opengl texture packet - it contains only portable opengl code */ - -#include <stdio.h> -#include <GL/gl.h> -#include <GL/glu.h> -#include "pdp_opengl.h" -#include "pdp_texture.h" -#include "pdp_dpd_command.h" - - -static t_pdp_class *texture_class; - -static t_pdp_dpd_commandfactory _tex_cf; - -typedef struct _texture_command -{ - t_pdp_dpd_command base; - int p_src; - int p_dst; -} t_texture_command; - - -/* all symbols are C-style */ -#ifdef __cplusplus -extern "C" -{ -#endif - - - -/* returns a pointer to the packet subheader given the pdp header */ -static t_texture *_pdp_tex_info(t_pdp *x) -{ - return (t_texture *)&(x->info.raw); -} - - -/* create a pow of 2 texture dimension, ge than 8 */ -static int _round_to_pow_2(int n){ - int r = 8; - while (n > r) r <<= 1; - return r; -} - -t_pdp_symbol *_pdp_get_tex_description_from_params(GLsizei width, GLsizei height, GLint format) -{ - char description[1024]; - char *c = description; - - c += sprintf(c, "texture"); - switch(format){ - case GL_LUMINANCE: c += sprintf(c, "/grey"); break; - case GL_RGB: c += sprintf(c, "/rgb"); break; - case GL_RGBA: c += sprintf(c, "/rgba"); break; - default: - c += sprintf(c, "/unknown"); goto exit; - } - c += sprintf(c, "/%dx%d", width, height); - - exit: - return pdp_gensym(description); -} - -t_pdp_symbol *_pdp_tex_get_description(t_pdp *header) -{ - t_texture *texture = _pdp_tex_info(header); - int encoding; - - if (!header) return pdp_gensym("invalid"); - else if (!header->desc){ - if (header->type == PDP_TEXTURE){ - /* if description is not defined, try to construct it */ - return _pdp_get_tex_description_from_params(texture->width, texture->height, texture->format); - } - else return pdp_gensym("unknown"); - } - else return header->desc; -} - - -static int _pdp_packet_texture_old_or_dummy(u32 width, u32 height, s32 format); -static void _pdp_packet_gentexture(int packet); - -static void texture_command_convert_bitmap_to_texture(t_texture_command *c) -{ - t_texture *t = (t_texture *)pdp_packet_subheader(c->p_dst); - - /* make sure packet contains a texture, since it is created with _pdp_packet_reuse_texture */ - _pdp_packet_gentexture(c->p_dst); - - /* flip source image before uploading */ - pdp_packet_bitmap_flip_top_bottom(c->p_src); - - /* fill texture */ - pdp_packet_texture_make_current(c->p_dst); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, t->sub_width, t->sub_height, - t->format, GL_UNSIGNED_BYTE, (char *)pdp_packet_data(c->p_src)); - - /* decrease refcount */ - pdp_packet_mark_unused(c->p_src); - pdp_packet_mark_unused(c->p_dst); - - //post("conversion done"); - pdp_dpd_command_suicide(c); -} - - -/* converters to standard pdp types */ -int _pdp_packet_texture_convert_image_to_texture(int packet, t_pdp_symbol *dest_template) -{ - int p_temp, p; - - //post ("converting to bitmap"); - p_temp = pdp_packet_convert_rw(packet, pdp_gensym("bitmap/*/*")); - if (p_temp == -1) return -1; - - //post ("converting to texture"); - p = pdp_packet_convert_rw(p_temp, pdp_gensym("texture/*/*")); - pdp_packet_mark_unused(p_temp); - return p; -} - - - -/* converters to standard pdp types */ -int _pdp_packet_texture_convert_bitmap_to_texture(int packet, t_pdp_symbol *dest_template) -{ - t_pdp *header = pdp_packet_header(packet); - void *data = pdp_packet_data (packet); - int new_p; - u32 w; - u32 h; - t_texture_command *c; - - if (!pdp_packet_bitmap_isvalid(packet)) return -1; - - w = header->info.image.width; - h = header->info.image.height; - - switch (header->info.image.encoding){ - case PDP_BITMAP_GREY: - /* create greyscale texture */ - new_p = _pdp_packet_texture_old_or_dummy(w,h, GL_LUMINANCE); - break; - case PDP_BITMAP_RGB: - /* create rgb texture */ - new_p = _pdp_packet_texture_old_or_dummy(w,h, GL_RGB); - break; - case PDP_BITMAP_RGBA: - /* create greyscale texture */ - new_p = _pdp_packet_texture_old_or_dummy(w,h, GL_RGBA); - break; - default: - new_p = -1; - break; - } - - if (new_p != -1){ - - /* remark: this is a hack. a texture has to be created - when a rendering context is active. this means it has - to be created in the correct thread. therefore a dpd - command is added to the 3dp queue. this seems to work, - but without a dropping mechanism, this can overload the - queue. the real solution would be to add a converter - object to a 3dp chain, or to accept image or bitmap - packets in 3dp objects */ - - - /* dispatch command */ - c = (t_texture_command *)pdp_dpd_commandfactory_get_new_command(&_tex_cf); - c->p_src = pdp_packet_copy_rw(packet); - c->p_dst = pdp_packet_copy_ro(new_p); - pdp_procqueue_add(pdp_opengl_get_queue(), c, texture_command_convert_bitmap_to_texture, 0, 0); - } - return new_p; - -} - - - -int _pdp_packet_texture_convert_texture_to_bitmap(int packet, t_pdp_symbol *dest_template0) -{ - post("_pdp_packet_texture_convert_texture_to_bitmap not implemented."); - return -1; -} - - -t_texture *pdp_packet_texture_info(int packet) -{ - t_pdp *header = pdp_packet_header(packet); - if (pdp_packet_texture_isvalid(packet)) return _pdp_tex_info(header); - else return 0; -} - -/* check if valid texture packet. all other methods assume packet is valid */ -int pdp_packet_texture_isvalid(int packet) -{ - t_pdp *header; - if (!(header = pdp_packet_header(packet))) return 0; - if (PDP_TEXTURE != header->type) return 0; - return glIsTexture(_pdp_tex_info(header)->tex_obj); -} - - - -static void _tex_init_obj(t_texture *t) -{ - //u8 *dummydata; - //int i; - - glBindTexture(GL_TEXTURE_2D, t->tex_obj); - glTexImage2D(GL_TEXTURE_2D, 0, t->format, t->width, t->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - - /* debug - dummydata = (u8 *)malloc(t->width*t->height*4); - for (i=0; i<t->width*t->height*4; i++){dummydata[i] = random(); } - glTexImage2D(GL_TEXTURE_2D, 0, t->format, t->width, t->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dummydata); - free(dummydata); - */ - -} - - -static void _pdp_tex_copy(t_pdp *dst, t_pdp *src); -static void _pdp_tex_clone(t_pdp *dst, t_pdp *src); -static void _pdp_tex_reinit(t_pdp *dst); -static void _pdp_tex_cleanup(t_pdp *dst); - -static void _pdp_tex_init_methods(t_pdp *h) -{ - h->theclass = texture_class; -} - -static void _pdp_tex_reinit(t_pdp *dst) -{ - /* this does nothing. texture is assumed to be in a valid state */ -} -static void _pdp_tex_clone(t_pdp *dst, t_pdp *src) -{ - t_texture *dst_t = _pdp_tex_info(dst); - t_texture *src_t = _pdp_tex_info(src); - - //post("WARNING: _pdp_tex_clone: should not be called from outside 3d thread"); - - /* determine if destination texture is valid */ - if (glIsTexture(dst_t->tex_obj)){ - /* check format */ - if ((dst_t->width >= src_t->width) - && (dst_t->height >= src_t->height) - && (dst_t->format == src_t->format)){ - dst_t->sub_width = src_t->sub_width; - dst_t->sub_height = src_t->sub_height; - return; - } - } - /* not initialized, so we need to create a new one */ - else { - glGenTextures(1, (GLuint*)&dst_t->tex_obj); - } - - /* setup header */ - dst_t->width = src_t->width; - dst_t->height = src_t->height; - dst_t->format = src_t->format; - dst_t->sub_width = src_t->sub_width; - dst_t->sub_height = src_t->sub_height; - - /* setup packet methods */ - _pdp_tex_init_methods(dst); - - /* init description */ - dst->desc = _pdp_tex_get_description(dst); - -} -static void _pdp_tex_copy(t_pdp *dst, t_pdp *src) -{ - /* texture copying is inefficient. for the tex extensions there is no analogy - for "efficient in-place processing" - this means the pdp_packet_register_rw() call should be avoided - this inconsistency should be tucked away in a texture base class */ - - /* todo: use texture combining extensions for this */ - - post("WARNING: fanout is not yet implemented correctly for texture packets"); - - /* not implemented yet, just a call to the clone method */ - _pdp_tex_clone(dst, src); -} - -static void _pdp_tex_cleanup(t_pdp *dst) -{ - t_texture *t = _pdp_tex_info(dst); - glDeleteTextures(1, (GLuint*)&t->tex_obj); - t->tex_obj = -1; /* is this value guaranteed to be invalid? */ -} - - -/* texture constructors */ - -/* reuse a texture, or create a "dummy" == packet with everything except a valid texture object */ -static int _pdp_packet_texture_old_or_dummy(u32 width, u32 height, s32 format) -{ - int p = -1; - t_pdp *h; - t_texture *t; - - int p2_w = _round_to_pow_2(width); - int p2_h = _round_to_pow_2(height); - - - /* try to reuse a texture packet or get a new one */ - p = pdp_packet_reuse(_pdp_get_tex_description_from_params(p2_w, p2_h, format)); - if (-1 == p) p = pdp_packet_brandnew(PDP_TEXTURE, 0); - if (-1 == p) return -1; - - h = pdp_packet_header(p); - t = _pdp_tex_info(h); - - /* check if alloc succeded */ - if (!h) return -1; - - /* check if tex is already initialized */ - if (pdp_packet_texture_isvalid(p)){ - /* check format */ - if ((t->width >= width) && (t->height >= height) && (t->format == format)){ - //post("pdp_packet_new_tex: reused"); - t->sub_width = width; - t->sub_height = height; - return p; - } - post("ERROR: pdp_packet_new_texture: pdp_packet_reuse returned wrong type"); - } - - /* determine the texture dims * setup rest of data struct */ - t->width = 64; - t->height = 64; - while (t->width < width) t->width <<= 1; - while (t->height < height) t->height <<= 1; - - t->format = format; - t->sub_width = width; - t->sub_height = height; - - _pdp_tex_init_methods(h); - - - /* init the texture */ - //_tex_init_obj(t); - - /* init description */ - h->desc = _pdp_tex_get_description(h); - - - return p; -} - -/* don't call this method on a non-texture object! */ -static void _pdp_packet_gentexture(int p) -{ - t_texture *t; - if (!pdp_packet_texture_isvalid(p)){ - /* not initialized, so we need to create a new one */ - // post("generating texture"); - t = (t_texture *)pdp_packet_subheader(p); - - /* create the texture object */ - glGenTextures(1, (GLuint *)&t->tex_obj); - - /* init the texture */ - _tex_init_obj(t); - - } -} - -int pdp_packet_new_texture(u32 width, u32 height, s32 format) -{ - t_texture *t; - int p = _pdp_packet_texture_old_or_dummy(width, height, format); - - //post("WARNING: pdp_packet_new_texture: this method should not be called outside the 3dp thread"); - - if (p == -1) return -1; - _pdp_packet_gentexture(p); - return p; -} - - -/* high level texture packet operators */ - -/* make a texture the current texture context */ -void pdp_packet_texture_make_current(int packet) -{ - t_texture *t = pdp_packet_texture_info(packet); - if (!t) return; - glBindTexture(GL_TEXTURE_2D, t->tex_obj); -} - -void pdp_packet_texture_make_current_enable(int packet) -{ - glEnable(GL_TEXTURE_2D); - pdp_packet_texture_make_current(packet); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); -} - -float pdp_packet_texture_fracx(int packet) -{ - t_texture *t = pdp_packet_texture_info(packet); - if (!t) return 0.0; - return (float)t->sub_width/t->width; -} - -float pdp_packet_texture_fracy(int packet) -{ - t_texture *t = pdp_packet_texture_info(packet); - if (!t) return 0.0; - return (float)t->sub_height/t->height; -} - -u32 pdp_packet_texture_total_width(int packet) -{ - t_texture *t = pdp_packet_texture_info(packet); - if (!t) return 0; - return t->width; - -} -u32 pdp_packet_texture_total_height(int packet) -{ - t_texture *t = pdp_packet_texture_info(packet); - if (!t) return 0; - return t->height; - -} - -u32 pdp_packet_texture_sub_width(int packet) -{ - t_texture *t = pdp_packet_texture_info(packet); - if (!t) return 0; - return t->sub_width; - -} -u32 pdp_packet_texture_sub_height(int packet) -{ - t_texture *t = pdp_packet_texture_info(packet); - if (!t) return 0; - return t->sub_height; -} - -float pdp_packet_texture_sub_aspect(int packet) -{ - t_texture *t = pdp_packet_texture_info(packet); - if (!t) return 0; - return (float)t->sub_width/t->sub_height; -} - -/* setup for 2d operation from texture dimensions */ -void pdp_packet_texture_setup_2d_context(int p) -{ - u32 w; - u32 h; - float asp; - if (!pdp_packet_texture_isvalid(p)) return; - w = pdp_packet_texture_sub_width(p); - h = pdp_packet_texture_sub_height(p); - asp = pdp_packet_texture_sub_aspect(p); - - /* set the viewport to the size of the sub texture */ - glViewport(0, 0, w, h); - - /* set orthogonal projection, with a relative frame size of (2asp x 2) */ - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0.0, 2*asp, 0, 2); - - /* set the center of view */ - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslatef(asp, 1, 0); - glScalef(1,-1,1); -} - -void pdp_texture_setup(void) -{ - t_pdp_conversion_program *program; - - /* setup packet class */ - texture_class = pdp_class_new(pdp_gensym("texture/*/*"), 0); - texture_class->cleanup = _pdp_tex_cleanup; - texture_class->reinit = _pdp_tex_reinit; - texture_class->clone = _pdp_tex_clone; - texture_class->copy = _pdp_tex_copy; - - /* init command list */ - pdp_dpd_commandfactory_init(&_tex_cf, sizeof(t_texture_command)); - - - - /* setup programs */ - program = pdp_conversion_program_new(_pdp_packet_texture_convert_bitmap_to_texture, 0); - pdp_type_register_conversion(pdp_gensym("bitmap/*/*"), pdp_gensym("texture/*/*"), program); - - /* this is a hack to use until the type conversion system has a proper search algo */ - program = pdp_conversion_program_new(_pdp_packet_texture_convert_image_to_texture, 0); - pdp_type_register_conversion(pdp_gensym("image/*/*"), pdp_gensym("texture/*/*"), program); - - - program = pdp_conversion_program_new(_pdp_packet_texture_convert_texture_to_bitmap, 0); - pdp_type_register_conversion(pdp_gensym("texture/*/*"), pdp_gensym("bitmap/*/*"), program); - -} - -/* all symbols are C-style */ -#ifdef __cplusplus -} -#endif |