diff options
Diffstat (limited to 'opengl/modules')
-rw-r--r-- | opengl/modules/Makefile | 10 | ||||
-rw-r--r-- | opengl/modules/README | 3 | ||||
-rw-r--r-- | opengl/modules/pdp_3d_color.c | 167 | ||||
-rw-r--r-- | opengl/modules/pdp_3d_context.c | 163 | ||||
-rw-r--r-- | opengl/modules/pdp_3d_dlist.c | 183 | ||||
-rw-r--r-- | opengl/modules/pdp_3d_draw.c | 500 | ||||
-rw-r--r-- | opengl/modules/pdp_3d_drawmesh.c | 340 | ||||
-rw-r--r-- | opengl/modules/pdp_3d_for.c | 106 | ||||
-rw-r--r-- | opengl/modules/pdp_3d_light.c | 155 | ||||
-rw-r--r-- | opengl/modules/pdp_3d_push.c | 181 | ||||
-rw-r--r-- | opengl/modules/pdp_3d_snap.c | 216 | ||||
-rw-r--r-- | opengl/modules/pdp_3d_state.c | 135 | ||||
-rw-r--r-- | opengl/modules/pdp_3d_subcontext.c | 116 | ||||
-rw-r--r-- | opengl/modules/pdp_3d_view.c | 231 | ||||
-rw-r--r-- | opengl/modules/pdp_3d_windowcontext.c | 232 |
15 files changed, 2738 insertions, 0 deletions
diff --git a/opengl/modules/Makefile b/opengl/modules/Makefile new file mode 100644 index 0000000..a11fa1d --- /dev/null +++ b/opengl/modules/Makefile @@ -0,0 +1,10 @@ +include ../Makefile.config + +all: pdp_3d_windowcontext.o pdp_3d_draw.o pdp_3d_view.o \ + pdp_3d_push.o pdp_3d_light.o pdp_3d_dlist.o pdp_3d_color.o \ + pdp_3d_snap.o pdp_3d_drawmesh.o pdp_3d_for.o pdp_3d_state.o \ + pdp_3d_subcontext.o + +clean: + rm -rf *~ *.o + diff --git a/opengl/modules/README b/opengl/modules/README new file mode 100644 index 0000000..613661e --- /dev/null +++ b/opengl/modules/README @@ -0,0 +1,3 @@ + +This directory contains opengl modules for the pdp_opengl library. + diff --git a/opengl/modules/pdp_3d_color.c b/opengl/modules/pdp_3d_color.c new file mode 100644 index 0000000..b237e9a --- /dev/null +++ b/opengl/modules/pdp_3d_color.c @@ -0,0 +1,167 @@ +/* + * Pure Data Packet module. + * 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. + * + */ + + +#include <GL/gl.h> +#include "pdp_3dp_base.h" +#include "pdp_opengl.h" + + +typedef struct _color_command +{ + t_pdp_dpd_command x_base; + int x_context; + float x_newcolor[4]; + float x_oldcolor[4]; +} t_color_command; + +typedef struct _pdp_3d_color +{ + t_pdp_3dp_base x_base; + t_pdp_dpd_commandfactory x_cfact; + + float x_red; + float x_green; + float x_blue; + float x_alpha; + +} t_pdp_3d_color; + + + +/* COMMAND METHODS */ +static void pdp_3d_color_process_right(t_color_command *x) +{ + int p = x->x_context; + if (pdp_packet_3Dcontext_isvalid(p)){ + pdp_packet_3Dcontext_set_rendering_context(p); + + /* save old color*/ + glGetFloatv(GL_CURRENT_COLOR, x->x_oldcolor); + + /* set new color */ + glColor4fv(x->x_newcolor); + } + +} + +static void pdp_3d_color_process_left(t_color_command *x) +{ + int p = x->x_context; + if (pdp_packet_3Dcontext_isvalid(p)){ + pdp_packet_3Dcontext_set_rendering_context(p); + + /* restore old color */ + glColor4fv(x->x_oldcolor); + //glColor4f(1,1,1,1); + } + /* kill self */ + pdp_dpd_command_suicide(x); +} + + +/* PD OBJECT METHODS */ +static void *pdp_3d_color_get_new_command(t_pdp_3d_color *x) +{ + t_color_command *c = (t_color_command *)pdp_dpd_commandfactory_get_new_command(&x->x_cfact); + c->x_newcolor[0] = x->x_red; + c->x_newcolor[1] = x->x_green; + c->x_newcolor[2] = x->x_blue; + c->x_newcolor[3] = x->x_alpha; + c->x_context = pdp_3dp_base_get_context_packet(x); + return (void *)c; +} + + +static void pdp_3d_color_set_r(t_pdp_3d_color *x, t_floatarg f) {x->x_red = f;} +static void pdp_3d_color_set_g(t_pdp_3d_color *x, t_floatarg f) {x->x_green = f;} +static void pdp_3d_color_set_b(t_pdp_3d_color *x, t_floatarg f) {x->x_blue = f;} +static void pdp_3d_color_set_a(t_pdp_3d_color *x, t_floatarg f) {x->x_alpha = f;} + + +t_class *pdp_3d_color_class; + + +void pdp_3d_color_free(t_pdp_3d_color *x) +{ + pdp_3dp_base_free(x); +} + +void *pdp_3d_color_new(t_floatarg r, t_floatarg g, t_floatarg b, t_floatarg a) +{ + t_pdp_3d_color *x = (t_pdp_3d_color *)pd_new(pdp_3d_color_class); + + /* super init */ + pdp_3dp_base_init(x); + + + /* input */ + pdp_base_add_gen_inlet(x, gensym("float"), gensym("r")); + pdp_base_add_gen_inlet(x, gensym("float"), gensym("g")); + pdp_base_add_gen_inlet(x, gensym("float"), gensym("b")); + pdp_base_add_gen_inlet(x, gensym("float"), gensym("a")); + + /* output */ + pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_color_process_left, 0); + pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_color_process_right, 0); + + x->x_red = r; + x->x_green = g; + x->x_blue = b; + x->x_alpha = a; + + /* init factory */ + pdp_dpd_commandfactory_init(&x->x_cfact, sizeof(t_color_command)); + + /* register command factory method */ + pdp_dpd_base_register_command_factory_method(x, (t_pdp_newmethod)pdp_3d_color_get_new_command); + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_3d_color_setup(void) +{ + + + pdp_3d_color_class = class_new(gensym("3dp_color"), (t_newmethod)pdp_3d_color_new, + (t_method)pdp_3d_color_free, sizeof(t_pdp_3d_color), 0, + A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_NULL); + + + pdp_3dp_base_setup(pdp_3d_color_class); + + class_addmethod(pdp_3d_color_class, (t_method)pdp_3d_color_set_r, gensym("r"), A_FLOAT, A_NULL); + class_addmethod(pdp_3d_color_class, (t_method)pdp_3d_color_set_g, gensym("g"), A_FLOAT, A_NULL); + class_addmethod(pdp_3d_color_class, (t_method)pdp_3d_color_set_b, gensym("b"), A_FLOAT, A_NULL); + class_addmethod(pdp_3d_color_class, (t_method)pdp_3d_color_set_a, gensym("a"), A_FLOAT, A_NULL); + + +} + +#ifdef __cplusplus +} +#endif diff --git a/opengl/modules/pdp_3d_context.c b/opengl/modules/pdp_3d_context.c new file mode 100644 index 0000000..9e9c08f --- /dev/null +++ b/opengl/modules/pdp_3d_context.c @@ -0,0 +1,163 @@ +/* + * Pure Data Packet module. + * 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. + * + */ + + + +#include "pdp.h" +#include "pdp_base.h" +#include "pdp_opengl.h" + + +typedef struct pdp_3d_context_struct +{ + t_pdp_base x_base; + + t_outlet *x_outlet0; + + int x_packet0; + + t_symbol *x_type; + + unsigned int x_width; + unsigned int x_height; + + void *x_constant; + +} t_pdp_3d_context; + + + + + +static void pdp_3d_context_preproc(t_pdp_3d_context *x) +{ + int p; + int i; + + /* create new packet */ + p = pdp_packet_new_pbuf(x->x_width, x->x_height, 0); + x->x_packet0 = p; + + if (-1 == p) return; + + pdp_pbuf_set_rendering_context(p); + pdp_pbuf_setup_3d_context(p); + + /* clear buffer */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + glEnable(GL_AUTO_NORMAL); + glEnable(GL_NORMALIZE); + glShadeModel(GL_SMOOTH); + + + /* disable everything that is enabled in other modules */ + glDisable(GL_LIGHTING); + for (i=0; i<8; i++) glDisable(GL_LIGHT0 + i); + glDisable(GL_COLOR_MATERIAL); + + +} + +static void pdp_3d_context_process(t_pdp_3d_context *x) +{ +} + +static void pdp_3d_context_postproc(t_pdp_3d_context *x) +{ + pdp_pass_if_valid(x->x_outlet0, &x->x_packet0); +} + +static void pdp_3d_context_bang(t_pdp_3d_context *x) +{ + pdp_base_bang(x); +} + +static void pdp_3d_context_dim(t_pdp_3d_context *x, t_floatarg w, t_floatarg h) +{ + x->x_width = pdp_imageproc_legalwidth((int)w); + x->x_height = pdp_imageproc_legalheight((int)h); + //post("dims %d %d", x->x_width, x->x_height); +} + + +static void pdp_3d_context_free(t_pdp_3d_context *x) +{ + pdp_base_free(x); + pdp_packet_mark_unused(x->x_packet0); + +} + +t_class *pdp_3d_context_class; + + + +void *pdp_3d_context_new(void) +{ + int i; + t_pdp_3d_context *x = (t_pdp_3d_context *)pd_new(pdp_3d_context_class); + + /* super init */ + pdp_base_init(x); + + /* in/out*/ + x->x_outlet0 = pdp_base_add_pdp_outlet(x); + + /* base callbacks */ + pdp_base_disable_active_inlet(x); + pdp_base_set_process_method(x, (t_pdp_method)pdp_3d_context_process); + pdp_base_set_preproc_method(x, (t_pdp_method)pdp_3d_context_preproc); + pdp_base_set_postproc_method(x, (t_pdp_method)pdp_3d_context_postproc); + + /* data init */ + x->x_packet0 = -1; + pdp_3d_context_dim(x, 320, 240); + + + return (void *)x; +} + + + +#ifdef __cplusplus +extern "C" +{ +#endif + + + +void pdp_3d_context_setup(void) +{ + + + pdp_3d_context_class = class_new(gensym("pdp_3d_context"), (t_newmethod)pdp_3d_context_new, + (t_method)pdp_3d_context_free, sizeof(t_pdp_3d_context), 0, A_NULL); + class_addcreator((t_newmethod)pdp_3d_context_new, gensym("3dp_context"), A_NULL); + + pdp_base_setup(pdp_3d_context_class); + + class_addmethod(pdp_3d_context_class, (t_method)pdp_3d_context_dim, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(pdp_3d_context_class, (t_method)pdp_3d_context_bang, gensym("bang"), A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/opengl/modules/pdp_3d_dlist.c b/opengl/modules/pdp_3d_dlist.c new file mode 100644 index 0000000..9f087e0 --- /dev/null +++ b/opengl/modules/pdp_3d_dlist.c @@ -0,0 +1,183 @@ +/* + * Pure Data Packet module. + * 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. + * + */ + + +#include <GL/gl.h> + +#include "pdp_opengl.h" +#include "pdp_3dp_base.h" + +/* gl display list compilation & execution */ + +typedef struct pdp_3d_dlist_struct +{ + t_pdp_3dp_base x_base; + + GLuint x_dlist; + int x_compile; + +} t_pdp_3d_dlist; + + + +static void pdp_3d_dlist_complete_notify(t_pdp_3d_dlist *x) +{ + /* disable the second outlet */ + pdp_3dp_base_enable_outlet(x, 0, 0); +} + +static void pdp_3d_dlist_compile(t_pdp_3d_dlist *x) +{ + //x->x_compile = 1; + /* enable the second outlet */ + pdp_3dp_base_enable_outlet(x, 0, 1); +} + +static void pdp_3d_dlist_process_start(t_pdp_3d_dlist *x) +{ + int p = pdp_3dp_base_get_context_packet(x); + if (-1 != p){ + + /* check if pbuf */ + if (pdp_packet_3Dcontext_isvalid(p)){ + + /* set context */ + //pdp_pbuf_set_rendering_context(p); + + /* display list needs to be created in the correct context + if we don't have one yet, create it */ + if (!x->x_dlist) x->x_dlist = glGenLists(1); + + + + /* start the list */ /* $$$TODO: error checking for recursion */ + x->x_compile = 1; + glNewList(x->x_dlist, GL_COMPILE_AND_EXECUTE); + //glNewList(x->x_dlist, GL_COMPILE); + + //post("compiling"); + + + } + } +} + +static void pdp_3d_dlist_process_cleanup(t_pdp_3d_dlist *x) +{ + int p = pdp_3dp_base_get_context_packet(x); + if (-1 != p){ + + /* check if pbuf */ + if (pdp_packet_3Dcontext_isvalid(p)){ + + /* end list if we're compiling */ + if (x->x_compile){ + + /* end the list */ + glEndList(); + + /* use the list next time */ + x->x_compile = 0; + + //post("ending compile"); + + } + + /* or execute the old one */ + else { + if (x->x_dlist) { + //post("calling dlist %d", x->x_dlist); + glCallList(x->x_dlist); + } + + } + + + } + } +} + + + + +t_class *pdp_3d_dlist_class; + + + +void pdp_3d_dlist_free(t_pdp_3d_dlist *x) +{ + pdp_3dp_base_free(x); + if (x->x_dlist) glDeleteLists(x->x_dlist, 1); +} + +void *pdp_3d_dlist_new(t_symbol *s) +{ + t_pdp_3d_dlist *x = (t_pdp_3d_dlist *)pd_new(pdp_3d_dlist_class); + + /* super init */ + pdp_3dp_base_init(x); + + + /* io & callbacks */ + pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_dlist_process_start, 0); + pdp_3dp_base_add_cleanup(x, (t_pdp_method)pdp_3d_dlist_process_cleanup, 0); + pdp_3dp_base_register_complete_notify(x, (t_pdp_method)pdp_3d_dlist_complete_notify); + + /* disable the second outlet */ + pdp_3dp_base_enable_outlet(x, 1, 0); + + + /* create dlist */ + x->x_dlist = 0; + x->x_compile = 0; + + /* compile the first packet */ + pdp_3d_dlist_compile(x); + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_3d_dlist_setup(void) +{ + + + pdp_3d_dlist_class = class_new(gensym("pdp_3d_dlist"), (t_newmethod)pdp_3d_dlist_new, + (t_method)pdp_3d_dlist_free, sizeof(t_pdp_3d_dlist), 0, A_DEFSYMBOL, A_NULL); + + class_addcreator((t_newmethod)pdp_3d_dlist_new, gensym("3dp_dlist"), A_DEFSYMBOL, A_NULL); + + pdp_3dp_base_setup(pdp_3d_dlist_class); + + class_addmethod(pdp_3d_dlist_class, (t_method)pdp_3d_dlist_compile, gensym("compile"), A_NULL); + + + +} + +#ifdef __cplusplus +} +#endif diff --git a/opengl/modules/pdp_3d_draw.c b/opengl/modules/pdp_3d_draw.c new file mode 100644 index 0000000..39434cb --- /dev/null +++ b/opengl/modules/pdp_3d_draw.c @@ -0,0 +1,500 @@ +/* + * Pure Data Packet module. + * 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. + * + */ + + +//#include "GL/gl.h" +#include <GL/glut.h> +#include <math.h> + +#include "pdp_opengl.h" +#include "pdp_3dp_base.h" + +typedef struct _drawcommand +{ + t_pdp_dpd_command x_head; + int x_context_packet; + int x_texture_packet; + float x_p0; + float x_p1; + float x_p2; + float x_p3; + t_pdp_method x_method; + GLUquadric* x_quadric; + int x_have_texture; /* is there a valid texture ? */ + +} t_drawcommand; + + +typedef struct _pdp_3d_draw +{ + t_pdp_3dp_base x_base; + t_pdp_dpd_commandfactory x_clist; + + int x_inlets; + float x_p0; + float x_p1; + float x_p2; + float x_p3; + + t_pdp_method x_method; + + int x_tex_in; /* the number of texture inlets */ + GLUquadric* x_quadric; +} t_pdp_3d_draw; + + +void pdp_3d_draw_delete_texture(t_pdp_3d_draw *x) +{ + pdp_base_move_packet(x, 1); +} + +/* return a new command object */ +void *pdp_3d_draw_get_command_object(t_pdp_3d_draw *x) +{ + t_drawcommand *c = (t_drawcommand *)pdp_dpd_commandfactory_get_new_command(&x->x_clist); + c->x_p0 = x->x_p0; + c->x_p1 = x->x_p1; + c->x_p2 = x->x_p2; + c->x_p3 = x->x_p3; + c->x_context_packet = pdp_3dp_base_get_context_packet(x); + c->x_texture_packet = pdp_packet_copy_ro(pdp_base_get_packet(x, 1)); + + c->x_quadric = x->x_quadric; /* $$$TODO: this assumes quadric doesn't change */ + + c->x_method = x->x_method; + //post("o: %x, vc %x, n %d, u %d", x, c, x->x_clist.nb_commands, c->x_head.used); + return c; +} + +/* object drawing methods */ + +static void draw_clear(t_drawcommand *x) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + +} + +static void draw_square(t_drawcommand *x) +{ + float f = x->x_p0 * 0.5f; + float z = x->x_p1 * 0.5f; + /* draw a square */ + glBegin(GL_QUADS); + glNormal3f(0.0f, 0.0f, 1.0f); + glTexCoord2f(1, 0); + glVertex3f(f,-f, z); + glTexCoord2f(1, 1); + glVertex3f(f, f, z); + glTexCoord2f(0, 1); + glVertex3f(-f, f, z); + glTexCoord2f(0, 0); + glVertex3f(-f,-f, z); + glEnd(); +} + +static void draw_wsquare(t_drawcommand *x) +{ + float f = x->x_p0; + float z = x->x_p1; + /* draw a square */ + glBegin(GL_LINE_LOOP); + glVertex3f(f,-f, z); + glVertex3f(f, f, z); + glVertex3f(-f, f, z); + glVertex3f(-f,-f, z); + glEnd(); +} + +static void draw_triangle(t_drawcommand *x) +{ + float f = x->x_p0 * 0.5f; + float f2 = f * 0.5f; + float f3 = f * (sqrt(3.0f) / 2.0f); + float z = x->x_p1 * 0.5f; + /* draw a triangle */ + glBegin(GL_TRIANGLES); + glNormal3f(0.0f, 0.0f, 1.0f); + + glTexCoord2f(0.5f, 1.0f); + glVertex3f(0, f, z); + + glTexCoord2f(0.5f * (1.0f - sqrt(3.0f)/2.0f), 0.25f); + glVertex3f(-f3, -f2, z); + + glTexCoord2f(0.5f * (1.0f + sqrt(3.0f)/2.0f), 0.25f); + glVertex3f(f3, -f2, z); + glEnd(); +} + +static void draw_wtriangle(t_drawcommand *x) +{ + float f = x->x_p0 * 0.5f; + float f2 = f * 0.5f; + float f3 = f * (sqrt(3.0f) / 2.0f); + float z = x->x_p1 * 0.5f; + + /* draw a wire triangle */ + glBegin(GL_LINE_LOOP); + glNormal3f(0.0f, 0.0f, 1.0f); + glVertex3f(0, f, z); + glVertex3f(-f3, -f2, z); + glVertex3f(f3, -f2, z); + glEnd(); +} + + +static void draw_wcube(t_drawcommand *x) +{ + glutWireCube(x->x_p0); +} + +static void draw_cube(t_drawcommand *x) +{ + x->x_p1 = x->x_p0; // set square z coord; + + //glutSolidCube(x->x_p0); + + //glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + draw_square(x); + glRotatef(90, 0,1,0); + draw_square(x); + glRotatef(90, 0,1,0); + draw_square(x); + glRotatef(90, 0,1,0); + draw_square(x); + glPopMatrix(); + + glPushMatrix(); + glRotatef(90, 1, 0, 0); + draw_square(x); + glRotatef(180, 1, 0, 0); + draw_square(x); + glPopMatrix(); + +} + +static void draw_wtorus(t_drawcommand *x) +{ + float ri = x->x_p0; + float ro = x->x_p1; + int n = (int)x->x_p2; + int m = (int)x->x_p3; + + if (n < 1) n = 20; + if (m < 1) m = n; + + glutWireTorus(ri, ro, n, m); + +} + +static void draw_torus(t_drawcommand *x) +{ + float ri = x->x_p0; + float ro = x->x_p1; + int n = (int)x->x_p2; + int m = (int)x->x_p3; + + if (n < 1) n = 20; + if (m < 1) m = n; + + glutSolidTorus(ri, ro, n, m); + +} + +static void draw_cone(t_drawcommand *x) +{ + float base = x->x_p0; + float height = x->x_p1; + int n = (int)x->x_p2; + int m = (int)x->x_p3; + + if (n < 1) n = 20; + if (m < 1) m = n; + + glutSolidCone(base, height, n, m); + +} + +static void draw_wcone(t_drawcommand *x) +{ + float base = x->x_p0; + float height = x->x_p1; + int n = (int)x->x_p2; + int m = (int)x->x_p3; + + if (n < 1) n = 20; + if (m < 1) m = n; + + glutWireCone(base, height, n, m); + +} + +static void draw_wteapot(t_drawcommand *x) +{ + float f = x->x_p0; + glutWireTeapot(f); + +} + +static void draw_teapot(t_drawcommand *x) +{ + float f = x->x_p0; + glutSolidTeapot(f); + +} + +static void draw_wsphere(t_drawcommand *x) +{ + float f = x->x_p0; + int n = (int)x->x_p1; + int m = (int)x->x_p2; + + if (n < 1) n = 20; + if (m < 1) m = n; + + glutWireSphere(f, n, m); + +} + +static void draw_sphere(t_drawcommand *x) +{ + float f = x->x_p0; + int n = (int)x->x_p1; + int m = (int)x->x_p2; + + if (n < 1) n = 20; + if (m < 1) m = n; + + gluSphere(x->x_quadric, f, n, m); + + //glutSolidSphere(f, n, m); + +} + +static void draw_dodeca(t_drawcommand *x){glutSolidDodecahedron();} +static void draw_octa(t_drawcommand *x) {glutSolidOctahedron();} +static void draw_tetra(t_drawcommand *x) {glutSolidTetrahedron();} +static void draw_icosa(t_drawcommand *x) {glutSolidIcosahedron();} + +static void draw_wdodeca(t_drawcommand *x){glutWireDodecahedron();} +static void draw_wocta(t_drawcommand *x) {glutWireOctahedron();} +static void draw_wtetra(t_drawcommand *x) {glutWireTetrahedron();} +static void draw_wicosa(t_drawcommand *x) {glutWireIcosahedron();} + + + + + + +/* the actual (registered) draw method */ +/* when this is finished, the drawcommand object should commit suicide */ + +static void draw_process(t_drawcommand *x) +{ + int p = x->x_context_packet; + int pt = x->x_texture_packet; + float fx=1; + float fy=1; + x->x_have_texture = pdp_packet_texture_isvalid(pt); + + //post("pdp_3d_draw: context = %d, texture = %d", p, pt); + + /* check if it's a valid buffer we can draw in */ + if (pdp_packet_3Dcontext_isvalid(p)){ + + + /* setup rendering context */ + pdp_packet_3Dcontext_set_rendering_context(p); + + /* enable texture */ + if (x->x_have_texture){ + fx = pdp_packet_texture_fracx(pt); + fy = pdp_packet_texture_fracy(pt); + glEnable(GL_TEXTURE_2D); + pdp_packet_texture_make_current(pt); + 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); + + /* scale texture matrix to reflect subtexture's coords */ + glMatrixMode(GL_TEXTURE); + //glLoadIdentity(); + glPushMatrix(); + glScalef(fx, fy, 1); + glMatrixMode(GL_MODELVIEW); + + gluQuadricTexture(x->x_quadric, 1); + } + + /* call the generating method */ + if (x->x_method) (*x->x_method)(x); + + /* disable texture */ + if (x->x_have_texture){ + glMatrixMode(GL_TEXTURE); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glDisable(GL_TEXTURE_2D); + gluQuadricTexture(x->x_quadric, 0); + } + + } + + /* you know the drill: command done, sword in belly. */ + pdp_packet_mark_unused(x->x_texture_packet); + pdp_dpd_command_suicide(x); + +} + +static void pdp_3d_draw_p0(t_pdp_3d_draw *x, t_floatarg f){x->x_p0 = f;} +static void pdp_3d_draw_p1(t_pdp_3d_draw *x, t_floatarg f){x->x_p1 = f;} +static void pdp_3d_draw_p2(t_pdp_3d_draw *x, t_floatarg f){x->x_p2 = f;} +static void pdp_3d_draw_p3(t_pdp_3d_draw *x, t_floatarg f){x->x_p3 = f;} + + +t_class *pdp_3d_draw_class; + + + +void pdp_3d_draw_free(t_pdp_3d_draw *x) +{ + pdp_3dp_base_free(x); + gluDeleteQuadric(x->x_quadric); + pdp_dpd_commandfactory_free(&x->x_clist); +} + +void pdp_3d_draw_object(t_pdp_3d_draw *x, t_symbol *s) +{ + /* find out if it is a buffer operation */ + if (s == gensym("clear")) {x->x_method = (t_pdp_method)draw_clear; x->x_inlets = 0;} + + /* if not, find out which object we need to draw */ + else if (s == gensym("triangle")) {x->x_method = (t_pdp_method)draw_triangle; x->x_inlets = 1;} + else if (s == gensym("wtriangle")) {x->x_method = (t_pdp_method)draw_wtriangle; x->x_inlets = 1;} + else if (s == gensym("square")) {x->x_method = (t_pdp_method)draw_square; x->x_inlets = 1;} + else if (s == gensym("wsquare")) {x->x_method = (t_pdp_method)draw_wsquare; x->x_inlets = 1;} + else if (s == gensym("cube")) {x->x_method = (t_pdp_method)draw_cube; x->x_inlets = 1;} + else if (s == gensym("wcube")) {x->x_method = (t_pdp_method)draw_wcube; x->x_inlets = 1;} + else if (s == gensym("sphere")) {x->x_method = (t_pdp_method)draw_sphere; x->x_inlets = 3;} + else if (s == gensym("wsphere")) {x->x_method = (t_pdp_method)draw_wsphere; x->x_inlets = 3;} + else if (s == gensym("torus")) {x->x_method = (t_pdp_method)draw_torus; x->x_inlets = 4;} + else if (s == gensym("wtorus")) {x->x_method = (t_pdp_method)draw_wtorus; x->x_inlets = 4;} + else if (s == gensym("cone")) {x->x_method = (t_pdp_method)draw_cone; x->x_inlets = 4;} + else if (s == gensym("wcone")) {x->x_method = (t_pdp_method)draw_wcone; x->x_inlets = 4;} + else if (s == gensym("teapot")) {x->x_method = (t_pdp_method)draw_teapot; x->x_inlets = 1;} + else if (s == gensym("wteapot")) {x->x_method = (t_pdp_method)draw_wteapot; x->x_inlets = 1;} + + else if (s == gensym("dodeca")) {x->x_method = (t_pdp_method)draw_dodeca; x->x_inlets = 0;} + else if (s == gensym("icosa")) {x->x_method = (t_pdp_method)draw_icosa; x->x_inlets = 0;} + else if (s == gensym("octa")) {x->x_method = (t_pdp_method)draw_octa; x->x_inlets = 0;} + else if (s == gensym("tetra")) {x->x_method = (t_pdp_method)draw_tetra; x->x_inlets = 0;} + else if (s == gensym("wdodeca")) {x->x_method = (t_pdp_method)draw_wdodeca; x->x_inlets = 0;} + else if (s == gensym("wicosa")) {x->x_method = (t_pdp_method)draw_wicosa; x->x_inlets = 0;} + else if (s == gensym("wocta")) {x->x_method = (t_pdp_method)draw_wocta; x->x_inlets = 0;} + else if (s == gensym("wtetra")) {x->x_method = (t_pdp_method)draw_wtetra; x->x_inlets = 0;} + + else { + post("pdp_3d_draw: object %s not found", s->s_name); + x->x_method = 0; + x->x_inlets = 0; + } + + // the number of texture inlets + x->x_tex_in = 1; +} + + +void *pdp_3d_draw_new(t_symbol *s, t_floatarg p0, t_floatarg p1, t_floatarg p2, t_floatarg p3) +{ + t_pdp_3d_draw *x = (t_pdp_3d_draw *)pd_new(pdp_3d_draw_class); + char param[] = "p0"; + int i; + + /* super init */ + pdp_3dp_base_init(x); + + x->x_p0 = p0; + x->x_p1 = p1; + x->x_p2 = p2; + x->x_p3 = p3; + + /* set the object & number of inlets */ + pdp_3d_draw_object(x, s); + + /* create texture inlets */ + for(i=0; i<x->x_tex_in; i++){ + pdp_base_add_pdp_inlet(x); + } + + /* create additional inlets */ + for(i=0; i<x->x_inlets; i++){ + pdp_base_add_gen_inlet(x, gensym("float"), gensym(param)); + param[1]++; + } + + /* create dpd outlet */ + pdp_3dp_base_add_outlet(x, (t_pdp_method)draw_process, 0); + + /* setup quadric */ + x->x_quadric = gluNewQuadric(); + + /* init command list */ + pdp_dpd_commandfactory_init(&x->x_clist, sizeof(t_drawcommand)); + + /* register command factory method */ + pdp_dpd_base_register_command_factory_method(x, (t_pdp_newmethod)pdp_3d_draw_get_command_object); + + + + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_3d_draw_setup(void) +{ + + + pdp_3d_draw_class = class_new(gensym("3dp_draw"), (t_newmethod)pdp_3d_draw_new, + (t_method)pdp_3d_draw_free, sizeof(t_pdp_3d_draw), 0, A_SYMBOL, + A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_NULL); + pdp_3dp_base_setup(pdp_3d_draw_class); + + class_addmethod(pdp_3d_draw_class, (t_method)pdp_3d_draw_p0, gensym("p0"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_3d_draw_class, (t_method)pdp_3d_draw_p1, gensym("p1"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_3d_draw_class, (t_method)pdp_3d_draw_p2, gensym("p2"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_3d_draw_class, (t_method)pdp_3d_draw_p3, gensym("p3"), A_DEFFLOAT, A_NULL); + + class_addmethod(pdp_3d_draw_class, (t_method)pdp_3d_draw_delete_texture, gensym("delete_texture"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/opengl/modules/pdp_3d_drawmesh.c b/opengl/modules/pdp_3d_drawmesh.c new file mode 100644 index 0000000..cd2c973 --- /dev/null +++ b/opengl/modules/pdp_3d_drawmesh.c @@ -0,0 +1,340 @@ +/* + * Pure Data Packet module. + * 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. + * + */ + +/* a very naive approach to triangular meshes */ + + +// $$TODO: some serious memory corruption in this file our the list implementation + + +#include "GL/gl.h" +#include <math.h> +//#include <GL/glut.h> + +#include "pdp_opengl.h" +#include "pdp_3dp_base.h" +#include "pdp_mesh.h" + + +/* PD OBJECT */ + +typedef struct _pdp_3d_drawmesh +{ + t_pdp_3dp_base x_base; + t_pdp_dpd_commandfactory x_clist; + + t_mesh *x_mesh; + int x_wireframe; + int x_flatshading; + +} t_pdp_3d_drawmesh; + + +/* MESHCOMMAND OBJECT */ + +typedef struct _meshcommand +{ + t_pdp_dpd_command x_head; + int x_context_packet; + int x_texture_packet; + t_pdp_3d_drawmesh *x_mother; + t_pdp_method x_method; + + int x_wireframe; + int x_flatshading; + float x_step; + float x_d0; + float x_r0; + int x_normal_type; + +} t_meshcommand; + + +/* MESHCOMMAND METHODS */ + +/* draw the mesh */ +static void meshcommand_draw(t_meshcommand *x) +{ + int i = 0; + t_pdp_atom *it; + t_pdp_list *tl = x->x_mother->x_mesh->triangles; + t_triangle *t; + GLenum mode = (x->x_wireframe) ? GL_LINE_LOOP : GL_TRIANGLES; + + //glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); + + glLineWidth(5); + + glBegin(mode); + + if (x->x_flatshading){ + PDP_POINTER_IN(tl, it, t){ + glNormal3fv(t->n); + for (i=0; i<3; i++){ + glVertex3fv(t->v[i]->c); + } + } + } + else{ + PDP_POINTER_IN(tl, it, t){ + for (i=0; i<3; i++){ + glNormal3fv(t->v[i]->n); + glVertex3fv(t->v[i]->c); + } + } + } + glEnd(); +} + +static void meshcommand_relax(t_meshcommand *x) +{ + mesh_relax(x->x_mother->x_mesh, x->x_step, x->x_d0, x->x_r0); +} + + +/* the main subcommand dispatcher */ +static void meshcommand_execute(t_meshcommand *x) +{ + int p = x->x_context_packet; + + /* check if it's a valid buffer we can draw in */ + if (pdp_packet_3Dcontext_isvalid(p)){ + + + /* setup rendering context */ + pdp_packet_3Dcontext_set_rendering_context(p); + + /* call the command method */ + if (x->x_method) (x->x_method)(x); + + } + + /* you know the drill: command done, sword in belly. */ + pdp_dpd_command_suicide(x); +} + +static void meshcommand_split_all_four(t_meshcommand *x) +{ + mesh_split_all_four(x->x_mother->x_mesh); +} +static void meshcommand_split_all_three(t_meshcommand *x){ + mesh_split_all_three(x->x_mother->x_mesh); +} +static void meshcommand_split_random_three(t_meshcommand *x){ + mesh_split_random_three(x->x_mother->x_mesh); +} + + +static void meshcommand_reset(t_meshcommand *x) +{ + mesh_free(x->x_mother->x_mesh); + x->x_mother->x_mesh = mesh_new_tetra(); +} + +static void meshcommand_debug(t_meshcommand *x) +{ + mesh_debug(x->x_mother->x_mesh); +} + +static void meshcommand_calculate_normals(t_meshcommand *x) +{ + x->x_mother->x_mesh->normal_type = x->x_normal_type; + mesh_calculate_normals(x->x_mother->x_mesh); +} + + + + +/* PD OBJECT METHODS */ + + +/* return a new command object */ +void *pdp_3d_drawmesh_get_command_object(t_pdp_3d_drawmesh *x) +{ + t_meshcommand *c = (t_meshcommand *)pdp_dpd_commandfactory_get_new_command(&x->x_clist); + c->x_context_packet = pdp_3dp_base_get_context_packet(x); + c->x_mother = x; + c->x_method = (t_pdp_method)meshcommand_draw; //default command is draw + c->x_wireframe = x->x_wireframe; + c->x_flatshading = x->x_flatshading; + + return c; +} + +/* schedule a command */ +static void pdp_3d_drawmesh_queue_command(t_pdp_3d_drawmesh *x, t_meshcommand *c) +{ + pdp_3dp_base_queue_command(x, c, (t_pdp_method)meshcommand_execute, 0, 0); +} + +static void pdp_3d_drawmesh_queue_simple_command(t_pdp_3d_drawmesh *x, t_pdp_method method) +{ + t_meshcommand *c = (t_meshcommand *)pdp_3d_drawmesh_get_command_object(x); + c->x_method = method; + pdp_3dp_base_queue_command(x, c, (t_pdp_method)meshcommand_execute, 0, 0); +} + +//NOTE: only the meshcommands are entitled to use the mesh (thread issues) +//therefore all mesh manipulations must be queued as a command + + +static void pdp_3d_drawmesh_debug(t_pdp_3d_drawmesh *x) +{ + pdp_3d_drawmesh_queue_simple_command(x, (t_pdp_method)meshcommand_debug); +} + +static void pdp_3d_drawmesh_relax(t_pdp_3d_drawmesh *x, t_floatarg step, + t_floatarg d0, t_floatarg r0) +{ + t_meshcommand *c = (t_meshcommand *)pdp_3d_drawmesh_get_command_object(x); + c->x_step = step; + c->x_d0 = d0; + c->x_r0 = r0; + c->x_method = (t_pdp_method)meshcommand_relax; + pdp_3d_drawmesh_queue_command(x, c); + +} + +void pdp_3d_drawmesh_normal(t_pdp_3d_drawmesh *x, t_symbol *s) +{ + t_meshcommand *c = (t_meshcommand *)pdp_3d_drawmesh_get_command_object(x); + if (gensym("sphere") == s) c->x_normal_type = MESH_NORMAL_SPHERE; + else if (gensym("prism") == s) c->x_normal_type = MESH_NORMAL_PRISM; + else if (gensym("random") == s) c->x_normal_type = MESH_NORMAL_RANDOM; + else if (gensym("average") == s) c->x_normal_type = MESH_NORMAL_AVERAGE; + c->x_method = (t_pdp_method)meshcommand_calculate_normals; + pdp_3d_drawmesh_queue_command(x, c); + +} + +/* this is used by the standard drawing routine, so doesn't need to be scheduled */ +void pdp_3d_drawmesh_wireframe(t_pdp_3d_drawmesh *x, t_float f) +{ + x->x_wireframe = (f != 0.0f); +} + +void pdp_3d_drawmesh_flatshading(t_pdp_3d_drawmesh *x, t_float f) +{ + x->x_flatshading = (f != 0.0f); +} + + +static void pdp_3d_drawmesh_split_all_four(t_pdp_3d_drawmesh *x) +{ + pdp_3d_drawmesh_queue_simple_command(x, (t_pdp_method)meshcommand_split_all_four); +} + +static void pdp_3d_drawmesh_split_all_three(t_pdp_3d_drawmesh *x) +{ + pdp_3d_drawmesh_queue_simple_command(x, (t_pdp_method)meshcommand_split_all_three); +} + +static void pdp_3d_drawmesh_split_random_three(t_pdp_3d_drawmesh *x) +{ + pdp_3d_drawmesh_queue_simple_command(x, (t_pdp_method)meshcommand_split_random_three); +} + + +static void pdp_3d_drawmesh_reset(t_pdp_3d_drawmesh *x) +{ + pdp_3d_drawmesh_queue_simple_command(x, (t_pdp_method)meshcommand_reset); + +} + + + + + + + + + + +t_class *pdp_3d_drawmesh_class; + + +void pdp_3d_drawmesh_free(t_pdp_3d_drawmesh *x) +{ + /* queue needs to finish before mesh is deleted */ + pdp_3dp_base_queue_wait(x); + mesh_free(x->x_mesh); + + pdp_3dp_base_free(x); + pdp_dpd_commandfactory_free(&x->x_clist); +} + +void *pdp_3d_drawmesh_new(t_symbol *s, t_floatarg p0, t_floatarg p1, t_floatarg p2, t_floatarg p3) +{ + t_pdp_3d_drawmesh *x = (t_pdp_3d_drawmesh *)pd_new(pdp_3d_drawmesh_class); + + /* super init */ + pdp_3dp_base_init(x); + + /* create dpd outlet */ + pdp_3dp_base_add_outlet(x, (t_pdp_method)meshcommand_execute, 0); + + /* init command list */ + pdp_dpd_commandfactory_init(&x->x_clist, sizeof(t_meshcommand)); + + /* register command factory method */ + pdp_dpd_base_register_command_factory_method(x, (t_pdp_newmethod)pdp_3d_drawmesh_get_command_object); + + + /* initialize triangular mesh with a simply connected manifold */ + x->x_mesh = mesh_new_tetra(); + + x->x_wireframe = 0; + x->x_flatshading = 0; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_3d_drawmesh_setup(void) +{ + + pdp_3d_drawmesh_class = class_new(gensym("3dp_drawmesh"), (t_newmethod)pdp_3d_drawmesh_new, + (t_method)pdp_3d_drawmesh_free, sizeof(t_pdp_3d_drawmesh), 0, A_DEFSYMBOL, + A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_NULL); + pdp_3dp_base_setup(pdp_3d_drawmesh_class); + + + class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_split_random_three, gensym("split3random"), A_NULL); + class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_split_all_three, gensym("split3"), A_NULL); + class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_split_all_four, gensym("split4"), A_NULL); + class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_reset, gensym("reset"), A_NULL); + class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_normal, gensym("normal"), A_SYMBOL, A_NULL); + class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_relax, gensym("springrelax"), + A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_debug, gensym("info"), A_NULL); + class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_wireframe, gensym("wireframe"), A_FLOAT, A_NULL); + class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_flatshading, gensym("flatshading"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/opengl/modules/pdp_3d_for.c b/opengl/modules/pdp_3d_for.c new file mode 100644 index 0000000..54b0a71 --- /dev/null +++ b/opengl/modules/pdp_3d_for.c @@ -0,0 +1,106 @@ +/* + * Pure Data Packet module. + * 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. + * + */ + +/* a for loop for 3dp packets + this can later be adapted to a for loop for dpd packets. */ + +#include "pdp_opengl.h" +#include "pdp_internals.h" + + +typedef struct pdp_3d_for_struct +{ + t_object x_obj; + + t_int x_count; + + t_outlet *x_outlet_dpd; + t_outlet *x_outlet_float; + +} t_pdp_3d_for; + + + +static void pdp_3d_for_input_0(t_pdp_3d_for *x, t_symbol *s, t_floatarg f) +{ + int i; + + /* trigger on "accumulate" */ + + if (s == gensym("accumulate")){ + for (i=0; i<x->x_count; i++){ + outlet_float(x->x_outlet_float, (float)i); + outlet_dpd(x->x_outlet_dpd, (int)f); + } + } +} + +static void pdp_3d_for_count(t_pdp_3d_for *x, t_floatarg f) +{ + int count = (int)f; + if (count >= 0) x->x_count = count; +} + + +static void pdp_3d_for_free(t_pdp_3d_for *x) +{ +} + +t_class *pdp_3d_for_class; + + + +void *pdp_3d_for_new(t_floatarg f) +{ + int count = (int)f; + + t_pdp_3d_for *x = (t_pdp_3d_for *)pd_new(pdp_3d_for_class); + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("count")); + + x->x_outlet_dpd = outlet_new(&x->x_obj, &s_anything); + x->x_outlet_float = outlet_new(&x->x_obj, &s_float); + x->x_count = (count > 0) ? count : 1; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_3d_for_setup(void) +{ + + + pdp_3d_for_class = class_new(gensym("3dp_for"), (t_newmethod)pdp_3d_for_new, + (t_method)pdp_3d_for_free, sizeof(t_pdp_3d_for), 0, A_DEFFLOAT, A_NULL); + + class_addmethod(pdp_3d_for_class, (t_method)pdp_3d_for_input_0, gensym("dpd"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_3d_for_class, (t_method)pdp_3d_for_count, gensym("count"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/opengl/modules/pdp_3d_light.c b/opengl/modules/pdp_3d_light.c new file mode 100644 index 0000000..b0b4a92 --- /dev/null +++ b/opengl/modules/pdp_3d_light.c @@ -0,0 +1,155 @@ +/* + * Pure Data Packet module. + * 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. + * + */ + + +#include <GL/gl.h> +#include "pdp_opengl.h" +#include "pdp_3dp_base.h" + +typedef struct pdp_3d_light_struct +{ + t_pdp_3dp_base x_base; + + //float x_centerx; + //float x_centery; + //float x_centerz; + int x_index; + +} t_pdp_3d_light; + + + +static void pdp_3d_light_process(t_pdp_3d_light *x) +{ + int p = pdp_3dp_base_get_context_packet(x); + int i; + GLfloat ambient[] = {.7,.7,.7,1}; + GLfloat diffuse[] = {.6,.6,.6,1}; + GLfloat specular[] = {1, 1, 1, 1}; + GLfloat shininess[] = {50}; + GLfloat position[] = {0,0,1,1}; + GLfloat intensity[] = {1,1,1,0}; + + int light = GL_LIGHT0 + x->x_index; + + /* check if it's a valid buffer we can draw in */ + if (pdp_packet_3Dcontext_isvalid(p)){ + + position[0] = 0; //x->x_centerx; + position[1] = 0; //x->x_centery; + position[2] = 0; //x->x_centerz; + + /* set rendering context */ + //pdp_packet_3Dcontext_set_rendering_context(p); + + /* setup lighting */ + + glEnable(GL_LIGHTING); + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + //glMaterialfv(GL_FRONT, GL_AMBIENT, ambient); + glMaterialfv(GL_FRONT, GL_SPECULAR, specular); + glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse); + glMaterialfv(GL_FRONT, GL_SHININESS, shininess); + glLightfv(light, GL_POSITION, position); + //glLightfv(light, GL_DIFFUSE, intensity); + glEnable(light); + + + /* ALPHA HACK */ + //glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); + //glEnable(GL_BLEND); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE); + //glEnable(GL_ALPHA_TEST); + //glAlphaFunc(GL_GREATER, 0.f); + + } + +} + + + +//static void pdp_3d_light_centerx(t_pdp_3d_light *x, t_floatarg f){x->x_centerx = f;} +//static void pdp_3d_light_centery(t_pdp_3d_light *x, t_floatarg f){x->x_centery = f;} +//static void pdp_3d_light_centerz(t_pdp_3d_light *x, t_floatarg f){x->x_centerz = f;} + + +t_class *pdp_3d_light_class; + + + +void pdp_3d_light_free(t_pdp_3d_light *x) +{ + pdp_3dp_base_free(x); +} + +void *pdp_3d_light_new(t_floatarg fi, t_floatarg cx, t_floatarg cy, t_floatarg cz) +{ + t_pdp_3d_light *x = (t_pdp_3d_light *)pd_new(pdp_3d_light_class); + + /* super init */ + pdp_3dp_base_init(x); + + if (fi < 0) fi = 0; + + x->x_index = (int)fi; + //x->x_centerx = cx; + //x->x_centery = cy; + //x->x_centerz = cz; + + /* io */ + //pdp_base_add_gen_inlet(x, gensym("float"), gensym("centerx")); + //pdp_base_add_gen_inlet(x, gensym("float"), gensym("centery")); + //pdp_base_add_gen_inlet(x, gensym("float"), gensym("centerz")); + + /* add dpd outlet */ + pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_light_process, 0); + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_3d_light_setup(void) +{ + + + pdp_3d_light_class = class_new(gensym("3dp_light"), (t_newmethod)pdp_3d_light_new, + (t_method)pdp_3d_light_free, sizeof(t_pdp_3d_light), 0, + A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_NULL); + + pdp_3dp_base_setup(pdp_3d_light_class); + + //class_addmethod(pdp_3d_light_class, (t_method)pdp_3d_light_centerx, gensym("centerx"), A_DEFFLOAT, A_NULL); + //class_addmethod(pdp_3d_light_class, (t_method)pdp_3d_light_centery, gensym("centery"), A_DEFFLOAT, A_NULL); + //class_addmethod(pdp_3d_light_class, (t_method)pdp_3d_light_centerz, gensym("centerz"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/opengl/modules/pdp_3d_push.c b/opengl/modules/pdp_3d_push.c new file mode 100644 index 0000000..d5a45fb --- /dev/null +++ b/opengl/modules/pdp_3d_push.c @@ -0,0 +1,181 @@ +/* + * Pure Data Packet module. + * 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. + * + */ + + + +#include <GL/gl.h> +#include "pdp_opengl.h" +#include "pdp_3dp_base.h" + +typedef struct pdp_3d_push_struct +{ + t_pdp_3dp_base x_base; + GLenum x_matrix; + int x_change_mode; + +} t_pdp_3d_push; + + + +static void pdp_3d_push_process_right(t_pdp_3d_push *x) +{ + int p = pdp_3dp_base_get_context_packet(x); + if (-1 != p){ + + /* push one of the matrices */ + glMatrixMode(x->x_matrix); + glPushMatrix(); + + /* set default matrix to modelview */ + if (!x->x_change_mode) glMatrixMode(GL_MODELVIEW); + + } +} +static void pdp_3d_push_process_left(t_pdp_3d_push *x) +{ + int p = pdp_3dp_base_get_context_packet(x); + if (-1 != p){ + + /* restore the saved matrix */ + glMatrixMode(x->x_matrix); + glPopMatrix(); + + /* set default matrix back to modelview */ + glMatrixMode(GL_MODELVIEW); + + } + +} + + +static void pdp_3d_mode_process_right(t_pdp_3d_push *x) +{ + int p = pdp_3dp_base_get_context_packet(x); + if (-1 != p){ + + /* change matrix mode */ + glMatrixMode(x->x_matrix); + + } +} + +static void pdp_3d_mode_process_left(t_pdp_3d_push *x) +{ + int p = pdp_3dp_base_get_context_packet(x); + if (-1 != p){ + + /* restore default matrix to modelview */ + glMatrixMode(GL_MODELVIEW); + + } +} + + +static void pdp_3d_push_setmatrix(t_pdp_3d_push *x, t_symbol *s) +{ + GLenum m; + + /* find out which matrix to push */ + if (s == gensym("projection")) m = GL_PROJECTION; + else if (s == gensym("modelview")) m = GL_MODELVIEW; + else if (s == gensym("texture")) m = GL_TEXTURE; + else if (s == gensym("color")) m = GL_COLOR; + + /* default is modelview */ + else m = GL_MODELVIEW; + + x->x_matrix = m; +} + + +t_class *pdp_3d_push_class; + + + +void pdp_3d_push_free(t_pdp_3d_push *x) +{ + pdp_3dp_base_free(x); +} + +void *pdp_3d_push_mode_new(t_symbol *s) +{ + t_pdp_3d_push *x = (t_pdp_3d_push *)pd_new(pdp_3d_push_class); + + /* super init */ + pdp_3dp_base_init(x); + + /* setup which matrix we are talking about */ + pdp_3d_push_setmatrix(x, s); + + x->x_change_mode = 0; + + return (void *)x; +} + +void *pdp_3d_push_new(t_symbol *s, t_floatarg f) +{ + t_pdp_3d_push *x = (t_pdp_3d_push *)pdp_3d_push_mode_new(s); + + /* create dpd outlets */ + pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_push_process_left, 0); + pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_push_process_right, 0); + + x->x_change_mode = (f != 0.0f); + + return (void *)x; +} + + +void *pdp_3d_mode_new(t_symbol *s) +{ + t_pdp_3d_push *x = (t_pdp_3d_push *)pdp_3d_push_mode_new(s); + + /* create dpd outlets */ + pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_mode_process_left, 0); + pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_mode_process_right, 0); + + + return (void *)x; +} + + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_3d_push_setup(void) +{ + + + pdp_3d_push_class = class_new(gensym("3dp_push"), (t_newmethod)pdp_3d_push_new, + (t_method)pdp_3d_push_free, sizeof(t_pdp_3d_push), 0, A_DEFSYMBOL, A_NULL); + + class_addcreator((t_newmethod)pdp_3d_mode_new, gensym("3dp_mode"), A_DEFSYMBOL, A_NULL); + + pdp_3dp_base_setup(pdp_3d_push_class); + +} + +#ifdef __cplusplus +} +#endif diff --git a/opengl/modules/pdp_3d_snap.c b/opengl/modules/pdp_3d_snap.c new file mode 100644 index 0000000..2ee6d39 --- /dev/null +++ b/opengl/modules/pdp_3d_snap.c @@ -0,0 +1,216 @@ +/* + * Pure Data Packet module. + * 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. + * + */ + + +#include <GL/gl.h> +#include "pdp.h" +#include "pdp_3dp_base.h" +#include "pdp_opengl.h" + +typedef struct _pdp_3d_snap +{ + t_pdp_3dp_base x_base; + t_pdp_dpd_commandfactory x_cfact; + t_outlet *x_result_outlet; + t_pdp_symbol *x_dest_template; + int x_is_texture; + u32 x_width; + u32 x_height; + int x_auto_snap; + int x_pending_snap; + +} t_pdp_3d_snap; + + +typedef struct _snap_command +{ + t_pdp_dpd_command x_base; + t_pdp_3d_snap *x_mother; + int x_context_packet; + int x_result_packet; + int x_active; +} t_snap_command; + + + + +/* COMAND METHODS */ + +static void snap_texture_process(t_snap_command *x) +{ + int pt = -1; + int p = x->x_context_packet; + int i; + u32 w,h; + + if (x->x_active && pdp_packet_3Dcontext_isvalid(p)){ + + /* get dest texture sub dims */ + w = (x->x_mother->x_width) ? x->x_mother->x_width : pdp_packet_3Dcontext_subwidth(p); + h = (x->x_mother->x_height) ? x->x_mother->x_height : pdp_packet_3Dcontext_subheight(p); + + /* texture is a special case */ + if (x->x_mother->x_is_texture){ + + /* create a new texture packet */ + pt = pdp_packet_new_texture(w,h,GL_RGB); + if (-1 != pt) { + + /* set rendering context */ + pdp_packet_3Dcontext_set_rendering_context(p); + + /* copy pbuf to new texture */ + pdp_packet_texture_make_current(pt); + //glReadBuffer(GL_FRONT); //this is for weird feedback stuff.. + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, w, h); + + x->x_result_packet = pt; + } + } + + /* other type: snap to bitmap first, then convert */ + else{ + + //nvidia driver 4191 bug workaround (w -> multiple of 4) + w &= -4; + + pt = pdp_packet_3Dcontext_snap_to_bitmap(p, w, h); + //pt = pdp_packet_new_bitmap_rgb(w, h); + //pdp_packet_print_debug(pt); + x->x_result_packet = pdp_packet_convert_ro(pt, x->x_mother->x_dest_template); + pdp_packet_mark_unused(pt); + } + } +} + +static void snap_callback(t_snap_command *x) +{ + /* send packet to outlet */ + pdp_packet_pass_if_valid(x->x_mother->x_result_outlet, &x->x_result_packet); + pdp_dpd_command_suicide(x); +} + + +/* PD OBJECT METHODS */ + + +static void pdp_3d_snap_snap(t_pdp_3d_snap *x) +{ + x->x_pending_snap = 1; +} + +static void pdp_3d_snap_autosnap(t_pdp_3d_snap *x, t_floatarg f) +{ + if (f){ + x->x_auto_snap = 1; + x->x_pending_snap = 1; + } + else{ + x->x_auto_snap = 0; + x->x_pending_snap = 0; + } +} + +static void *pdp_3d_snap_get_new_command(t_pdp_3d_snap *x) +{ + t_snap_command *c = (t_snap_command *)pdp_dpd_commandfactory_get_new_command(&x->x_cfact); + c->x_mother = x; + c->x_context_packet = pdp_3dp_base_get_context_packet(x); + c->x_result_packet = -1; + c->x_active = x->x_pending_snap; + if (!x->x_auto_snap) x->x_pending_snap = 0; + return (void *)c; +} + + +t_class *pdp_3d_snap_class; + + + +void pdp_3d_snap_free(t_pdp_3d_snap *x) +{ + //pdp_dpd_base_queue_wait(x); + pdp_3dp_base_free(x); +} + +void *pdp_3d_snap_new(t_symbol *s, t_floatarg w, t_floatarg h) +{ + t_pdp_3d_snap *x = (t_pdp_3d_snap *)pd_new(pdp_3d_snap_class); + + /* super init */ + pdp_3dp_base_init(x); + + /* get destination template */ + x->x_dest_template = (s == gensym("")) ? pdp_gensym("texture/*/*") : pdp_gensym(s->s_name); + x->x_is_texture = pdp_type_description_match(x->x_dest_template, pdp_gensym("texture/*/*")); + w = (w < 0) ? 0 : w; + h = (h < 0) ? 0 : h; + x->x_width = w; + x->x_height = h; + + x->x_auto_snap = 1; + x->x_pending_snap = 1; + + /* issue warning */ + if (!x->x_is_texture && !(x->x_width && x->x_height)){ + //post("WARNING: 3dp_snap: target is not a texture and dimensions are not set."); + //post("WARNING: using default image size 320x240."); + //x->x_width = 320; + //x->x_height = 240; + } + + /* create outlets */ + pdp_3dp_base_add_outlet(x, (t_pdp_method)snap_texture_process, (t_pdp_method)snap_callback); + x->x_result_outlet = outlet_new((t_object *)x, &s_anything); + + /* init command list */ + pdp_dpd_commandfactory_init(&x->x_cfact, sizeof(t_snap_command)); + + /* register command factory method */ + pdp_dpd_base_register_command_factory_method(x, (t_pdp_newmethod)pdp_3d_snap_get_new_command); + + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_3d_snap_setup(void) +{ + + + pdp_3d_snap_class = class_new(gensym("3dp_snap"), (t_newmethod)pdp_3d_snap_new, + (t_method)pdp_3d_snap_free, sizeof(t_pdp_3d_snap), 0, A_DEFSYMBOL, A_DEFFLOAT, A_DEFFLOAT, A_NULL); + + pdp_3dp_base_setup(pdp_3d_snap_class); + + class_addmethod(pdp_3d_snap_class, (t_method)pdp_3d_snap_snap, gensym("bang"), A_NULL); + class_addmethod(pdp_3d_snap_class, (t_method)pdp_3d_snap_autosnap, gensym("autosnap"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/opengl/modules/pdp_3d_state.c b/opengl/modules/pdp_3d_state.c new file mode 100644 index 0000000..d34ff94 --- /dev/null +++ b/opengl/modules/pdp_3d_state.c @@ -0,0 +1,135 @@ +/* + * Pure Data Packet module. + * 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. + * + */ + + +/* change binary opengl state variables. all defaults (flag = 0) should be set + in the render context init. + + right outlet has the thing enabled (or disabled, depending on toggle) + left outlet has the thing disabled (better: it should push it) + + simple version: does not permit reentry (yet) */ + + +#include <GL/gl.h> +#include "pdp_opengl.h" +#include "pdp_3dp_base.h" + +typedef struct pdp_3d_state_struct +{ + t_pdp_3dp_base x_base; + GLboolean x_flag; + GLboolean x_prev_flag; + GLenum x_thing; + void (*x_setup)(void); + +} t_pdp_3d_state; + + +static void _setflag(GLenum thing, GLboolean flag) +{ + if (flag) glEnable(thing); + else glDisable(thing); +} + +static void pdp_3d_state_process_right(t_pdp_3d_state *x) +{ + int p; + if (-1 != (p = pdp_3dp_base_get_context_packet(x))){ + /* store previous flag */ + pdp_packet_3Dcontext_set_rendering_context(p); + glGetBooleanv(x->x_thing, &x->x_prev_flag); + _setflag(x->x_thing, x->x_flag); + if (x->x_setup) x->x_setup(); + } +} + +static void pdp_3d_state_process_left(t_pdp_3d_state *x) +{ + int p; + /* allways run left method (reset) */ + if (-1 != (p = pdp_3dp_base_get_context_packet(x))){ + pdp_packet_3Dcontext_set_rendering_context(p); + _setflag(x->x_thing, x->x_prev_flag); + } +} + +static void pdp_3d_state_flag(t_pdp_3d_state *x, t_floatarg f) +{ + x->x_flag = (f == 0.0f) ? GL_FALSE : GL_TRUE; +} + +static void _blend(void) {glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);} +static void _blend_add(void) {glBlendFunc(GL_SRC_ALPHA, GL_ONE);} + +t_class *pdp_3d_state_class; +void pdp_3d_state_free(t_pdp_3d_state *x){pdp_3dp_base_free(x);} +void *pdp_3d_state_new(t_symbol *s, t_floatarg f) +{ + t_pdp_3d_state *x = (t_pdp_3d_state *)pd_new(pdp_3d_state_class); + + /* super init */ + pdp_3dp_base_init(x); + pdp_3d_state_flag(x,f); + + if (s == gensym("blend_mix")) {x->x_setup = _blend; x->x_thing = GL_BLEND;} + else if (s == gensym("blend_add")) {x->x_setup = _blend_add; x->x_thing = GL_BLEND;} + else if (s == gensym("depth_test")) {x->x_setup = 0; x->x_thing = GL_DEPTH_TEST;} + + /* unkown command: do nothing */ + else { + post ("3dp_state: unknown flag %s", s->s_name); + pd_free((void *)x); + return 0; + } + + /* create additional inlet */ + pdp_base_add_gen_inlet(x, gensym("float"), gensym("flag")); + + /* create dpd outlets */ + pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_state_process_left, 0); + pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_state_process_right, 0); + + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_3d_state_setup(void) +{ + + + pdp_3d_state_class = class_new(gensym("3dp_toggle"), (t_newmethod)pdp_3d_state_new, + (t_method)pdp_3d_state_free, sizeof(t_pdp_3d_state), 0, A_SYMBOL, A_DEFFLOAT, A_NULL); + + pdp_3dp_base_setup(pdp_3d_state_class); + class_addmethod(pdp_3d_state_class, (t_method)pdp_3d_state_flag, gensym("flag"), A_FLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/opengl/modules/pdp_3d_subcontext.c b/opengl/modules/pdp_3d_subcontext.c new file mode 100644 index 0000000..11017e2 --- /dev/null +++ b/opengl/modules/pdp_3d_subcontext.c @@ -0,0 +1,116 @@ +/* + * Pure Data Packet module. + * 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. + * + */ + + + +#include <GL/gl.h> +#include "pdp_opengl.h" +#include "pdp_3dp_base.h" + +typedef struct pdp_3d_subcontext_struct +{ + t_pdp_3dp_base x_base; + int x_width; + int x_height; + +} t_pdp_3d_subcontext; + + + +static void pdp_3d_subcontext_process_right(t_pdp_3d_subcontext *x) +{ + int p = pdp_3dp_base_get_context_packet(x); + if (-1 != p){ + + /* set subdims */ + pdp_packet_3Dcontext_set_subwidth(p, x->x_width); + pdp_packet_3Dcontext_set_subheight(p, x->x_height); + + /* reinit everything */ + pdp_packet_3Dcontext_set_rendering_context(p); + pdp_packet_3Dcontext_setup_3d_context(p); + + } +} +static void pdp_3d_subcontext_process_left(t_pdp_3d_subcontext *x) +{ + int p = pdp_3dp_base_get_context_packet(x); + if (-1 != p){ + + /* restore subdims */ + pdp_packet_3Dcontext_set_subwidth(p, pdp_packet_3Dcontext_width(p)); + pdp_packet_3Dcontext_set_subheight(p, pdp_packet_3Dcontext_height(p)); + + /* re-init everything */ + pdp_packet_3Dcontext_set_rendering_context(p); + pdp_packet_3Dcontext_setup_3d_context(p); + + } + +} + +t_class *pdp_3d_subcontext_class; + + + +void pdp_3d_subcontext_free(t_pdp_3d_subcontext *x) +{ + pdp_3dp_base_free(x); +} + +void *pdp_3d_subcontext_new(t_floatarg w, t_floatarg h) +{ + t_pdp_3d_subcontext *x = (t_pdp_3d_subcontext *)pd_new(pdp_3d_subcontext_class); + + /* super init */ + pdp_3dp_base_init(x); + + + /* create dpd outlets */ + pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_subcontext_process_left, 0); + pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_subcontext_process_right, 0); + + x->x_width = (w < 0) ? 64 : w; + x->x_height = (h < 0) ? 64 : h; + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_3d_subcontext_setup(void) +{ + + + pdp_3d_subcontext_class = class_new(gensym("3dp_subcontext"), (t_newmethod)pdp_3d_subcontext_new, + (t_method)pdp_3d_subcontext_free, sizeof(t_pdp_3d_subcontext), 0, A_FLOAT, A_FLOAT, A_NULL); + + pdp_3dp_base_setup(pdp_3d_subcontext_class); + +} + +#ifdef __cplusplus +} +#endif diff --git a/opengl/modules/pdp_3d_view.c b/opengl/modules/pdp_3d_view.c new file mode 100644 index 0000000..2317703 --- /dev/null +++ b/opengl/modules/pdp_3d_view.c @@ -0,0 +1,231 @@ +/* + * Pure Data Packet module. + * 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. + * + */ + + + +#include <GL/gl.h> +#include "pdp_opengl.h" +#include "pdp_3dp_base.h" + + + +/* PD OBJECT */ +typedef struct _pdp_3d_view +{ + t_pdp_3dp_base x_base; + t_pdp_dpd_commandfactory x_clist; + + float x_p0; + float x_p1; + float x_p2; + float x_p3; + t_pdp_method x_method; + + + int x_inlets; +} t_pdp_3d_view; + + +/* COMMAND OBJECT */ +typedef struct _viewcommand +{ + t_pdp_dpd_command x_head; // viewcommand base + t_pdp_3d_view *x_x; // command owner + int x_context_packet; + float x_p0; + float x_p1; + float x_p2; + float x_p3; + +} t_viewcommand; + + + + +/* COMMAND OBJECT METHODS */ + +/* rotate about the negative z axis */ +static void view_rot2d(t_viewcommand *x) {glRotatef(x->x_p0, 0, 0, -1);} + +/* rotate about the positive x,y,z axis */ +static void view_rotx(t_viewcommand *x) {glRotatef(x->x_p0, 1, 0, 0);} +static void view_roty(t_viewcommand *x) {glRotatef(x->x_p0, 0, 1, 0);} +static void view_rotz(t_viewcommand *x) {glRotatef(x->x_p0, 0, 0, 1);} +static void view_rota(t_viewcommand *x) {glRotatef(x->x_p3, x->x_p0, x->x_p1, x->x_p2);} + +/* translate along an axis */ +static void view_transx(t_viewcommand *x) {glTranslatef(x->x_p0, 0, 0);} +static void view_transy(t_viewcommand *x) {glTranslatef(0, x->x_p0, 0);} +static void view_transz(t_viewcommand *x) {glTranslatef(0, 0, x->x_p0);} +static void view_transxyz(t_viewcommand *x) {glTranslatef(x->x_p0, x->x_p1, x->x_p2);} + +/* rotate about the positive x,y,z axis */ +static void view_scalex(t_viewcommand *x) {glScalef(x->x_p0, 1, 1);} +static void view_scaley(t_viewcommand *x) {glScalef(1, x->x_p0, 1);} +static void view_scalez(t_viewcommand *x) {glScalef(1, 1, x->x_p0);} +static void view_scale(t_viewcommand *x) {glScalef(x->x_p0, x->x_p0, x->x_p0);} + +/* specials */ +static void view_reset_3d(t_viewcommand *x) {pdp_packet_3Dcontext_setup_3d_context(x->x_context_packet);} +static void view_scale_aspect(t_viewcommand *x) {glScalef(pdp_packet_3Dcontext_subaspect(x->x_context_packet),1,1);} + + +/* process command */ +static void view_process(t_viewcommand *x) +{ + int p = x->x_context_packet; + + /* check if it's a valid context buffer we can draw in */ + if (pdp_packet_3Dcontext_isvalid(p)){ + + /* setup rendering context */ + pdp_packet_3Dcontext_set_rendering_context(p); + + /* call the generating method */ + if (x->x_x->x_method) (*x->x_x->x_method)(x); + } + + /* suicide */ + pdp_dpd_command_suicide(x); +} + + + +/* command object factory method */ +void *pdp_3d_view_get_command_object(t_pdp_3d_view *x) +{ + t_viewcommand *c = (t_viewcommand *)pdp_dpd_commandfactory_get_new_command(&x->x_clist); + c->x_p0 = x->x_p0; + c->x_p1 = x->x_p1; + c->x_p2 = x->x_p2; + c->x_p3 = x->x_p3; + c->x_context_packet = pdp_3dp_base_get_context_packet(x); + c->x_x = x; + + return c; +} + + + +/* PD OBJECT METHODS */ + +static void pdp_3d_view_p0(t_pdp_3d_view *x, t_floatarg f){x->x_p0 = f;} +static void pdp_3d_view_p1(t_pdp_3d_view *x, t_floatarg f){x->x_p1 = f;} +static void pdp_3d_view_p2(t_pdp_3d_view *x, t_floatarg f){x->x_p2 = f;} +static void pdp_3d_view_p3(t_pdp_3d_view *x, t_floatarg f){x->x_p3 = f;} + + +t_class *pdp_3d_view_class; + + + +void pdp_3d_view_free(t_pdp_3d_view *x) +{ + pdp_dpd_commandfactory_free(&x->x_clist); + pdp_3dp_base_free(x); +} + +void *pdp_3d_view_new(t_symbol *s, t_floatarg p0, t_floatarg p1, t_floatarg p2, t_floatarg p3) +{ + t_pdp_3d_view *x = (t_pdp_3d_view *)pd_new(pdp_3d_view_class); + char param[] = "p0"; + int i; + + /* super init */ + pdp_3dp_base_init(x); + + x->x_p0 = p0; + x->x_p1 = p1; + x->x_p2 = p2; + x->x_p3 = p3; + + /* find out which transform we need to apply */ + if (s == gensym("rot2d")) {x->x_method = (t_pdp_method)view_rot2d; x->x_inlets = 1;} + + else if (s == gensym("rotx")) {x->x_method = (t_pdp_method)view_rotx; x->x_inlets = 1;} + else if (s == gensym("roty")) {x->x_method = (t_pdp_method)view_roty; x->x_inlets = 1;} + else if (s == gensym("rotz")) {x->x_method = (t_pdp_method)view_rotz; x->x_inlets = 1;} + else if (s == gensym("rota")) {x->x_method = (t_pdp_method)view_rota; x->x_inlets = 4;} + + else if (s == gensym("transx")) {x->x_method = (t_pdp_method)view_transx; x->x_inlets = 1;} + else if (s == gensym("transy")) {x->x_method = (t_pdp_method)view_transy; x->x_inlets = 1;} + else if (s == gensym("transz")) {x->x_method = (t_pdp_method)view_transz; x->x_inlets = 1;} + else if (s == gensym("transxyz")) {x->x_method = (t_pdp_method)view_transxyz; x->x_inlets = 3;} + + else if (s == gensym("scalex")) {x->x_method = (t_pdp_method)view_scalex; x->x_inlets = 1;} + else if (s == gensym("scaley")) {x->x_method = (t_pdp_method)view_scaley; x->x_inlets = 1;} + else if (s == gensym("scalez")) {x->x_method = (t_pdp_method)view_scalez; x->x_inlets = 1;} + else if (s == gensym("scale")) {x->x_method = (t_pdp_method)view_scale; x->x_inlets = 1;} + + else if (s == gensym("scale_aspect")) {x->x_method = (t_pdp_method)view_scale_aspect; x->x_inlets = 0;} + else if (s == gensym("reset")) {x->x_method = (t_pdp_method)view_reset_3d; x->x_inlets = 0;} + + else { + post("pdp_view: view transformation %s not found", s->s_name); + x->x_method = 0; + x->x_inlets = 0; + } + + /* create additional inlets */ + for(i=0; i<x->x_inlets; i++){ + pdp_base_add_gen_inlet(x, gensym("float"), gensym(param)); + param[1]++; + } + + /* create dpd outlet */ + pdp_3dp_base_add_outlet(x, (t_pdp_method)view_process, 0); + + /* init command factory */ + pdp_dpd_commandfactory_init(&x->x_clist, sizeof(t_viewcommand)); + + /* register command factory method */ + pdp_dpd_base_register_command_factory_method(x, (t_pdp_newmethod)pdp_3d_view_get_command_object); + + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_3d_view_setup(void) +{ + + + pdp_3d_view_class = class_new(gensym("3dp_view"), (t_newmethod)pdp_3d_view_new, + (t_method)pdp_3d_view_free, sizeof(t_pdp_3d_view), 0, A_SYMBOL, + A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT, A_NULL); + + pdp_3dp_base_setup(pdp_3d_view_class); + + class_addmethod(pdp_3d_view_class, (t_method)pdp_3d_view_p0, gensym("p0"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_3d_view_class, (t_method)pdp_3d_view_p1, gensym("p1"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_3d_view_class, (t_method)pdp_3d_view_p2, gensym("p2"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_3d_view_class, (t_method)pdp_3d_view_p3, gensym("p3"), A_DEFFLOAT, A_NULL); + +} + +#ifdef __cplusplus +} +#endif diff --git a/opengl/modules/pdp_3d_windowcontext.c b/opengl/modules/pdp_3d_windowcontext.c new file mode 100644 index 0000000..4e7aa93 --- /dev/null +++ b/opengl/modules/pdp_3d_windowcontext.c @@ -0,0 +1,232 @@ +/* + * Pure Data Packet module. + * 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. + * + */ + + +#include <GL/gl.h> +#include "pdp_opengl.h" +#include "pdp_3dp_base.h" + +typedef struct pdp_3d_windowcontext_struct +{ + t_pdp_3dp_base x_base; + int x_width; + int x_height; + t_outlet *x_eventout; + int x_finish_queue_id[2]; + int x_finish_queue_id_current; + +} t_pdp_3d_windowcontext; + + +static void pdp_3d_windowcontext_sendfinish(t_pdp_3d_windowcontext *x) +{ + PDP_ASSERT(x); + PDP_ASSERT(x->x_eventout); + outlet_symbol(x->x_eventout, gensym("done")); +} + +/* outlet methods */ + +/* called before the context is propagated */ +static void pdp_3d_windowcontext_clearbuffer(t_pdp_3d_windowcontext *x) +{ + int p = pdp_3dp_base_get_context_packet(x); + //post("setting up render buffer"); + + // for multipass rendering + //pdp_packet_3Dcontext_set_subwidth(p, 320); + //pdp_packet_3Dcontext_set_subheight(p, 240); + + pdp_packet_3Dcontext_set_rendering_context(p); + pdp_packet_3Dcontext_setup_3d_context(p); + + /* clear buffer */ + //glScissor(0,0, + // pdp_packet_3Dcontext_subwidth(p), + // pdp_packet_3Dcontext_subheight(p)); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + +} + +/* called after context is propagated */ +static void pdp_3d_windowcontext_swapbuffer(t_pdp_3d_windowcontext *x) +{ + int p = pdp_3dp_base_get_context_packet(x); + //post("displaying render buffer"); + //pdp_packet_3Dcontext_set_rendering_context(p); + pdp_packet_3Dcontext_win_swapbuffers(p); + //pdp_packet_3Dcontext_unset_rendering_context(p); +} + +void pdp_3d_windowcontext_resize(t_pdp_3d_windowcontext *x, t_floatarg width, t_floatarg height) +{ + int w = (int)width; + int h = (int)height; + int p = pdp_3dp_base_get_context_packet(x); + if ((w>0) && (h>0)){ + pdp_packet_3Dcontext_win_resize(p, w, h); + x->x_width = w; + x->x_height = h; + } +} + +void pdp_3d_windowcontext_open(t_pdp_3d_windowcontext *x) +{ + int p = pdp_3dp_base_get_context_packet(x); + if (-1 == p){ + p = pdp_packet_new_3Dcontext_win(); + pdp_3d_windowcontext_resize(x, x->x_width, x->x_height); + pdp_3dp_base_set_context_packet(x, p); + } + +} +void pdp_3d_windowcontext_close(t_pdp_3d_windowcontext *x) +{ + t_pdp_procqueue *q = pdp_3dp_base_get_queue(x); + + /* flush all pending tasks in the queue */ + //post("preflush"); + pdp_procqueue_flush(q); + //post("postflush"); + + /* now it is safe to delete the context packet */ + pdp_packet_delete(pdp_3dp_base_move_context_packet(x)); + + //post("deleted"); +} + +void pdp_3d_windowcontext_cursor(t_pdp_3d_windowcontext *x, t_floatarg f) +{ + int p = pdp_3dp_base_get_context_packet(x); + bool toggle = (f != 0.0f); + pdp_packet_3Dcontext_win_cursor(p, toggle); +} + + + +static void pdp_3d_windowcontext_bang(t_pdp_3d_windowcontext *x) +{ + int p; + int cur = x->x_finish_queue_id_current; + t_pdp_list *eventlist; + + /* check if at least recent processing chain is done (two chains busy = max pipeline depth) */ + if (-1 != x->x_finish_queue_id[cur]){ + //post("pdp_3d_windowcontext_bang: bang ignored (previous rendering not finished)"); + return; + } + + /* create a window context if needed */ + pdp_3d_windowcontext_open(x); + + /* get events and send to outlet */ + p = pdp_3dp_base_get_context_packet(x); + eventlist = pdp_packet_3Dcontext_win_get_eventlist(p); + if (eventlist){ + t_pdp_atom *a; + for (a=eventlist->first; a; a=a->next){ + outlet_pdp_list(x->x_eventout, a->w.w_list); + } + pdp_tree_free(eventlist); + } + + /* bang base */ + pdp_3dp_base_bang(x); + + /* add a dummy process to the queue for synchro */ + pdp_procqueue_add(pdp_3dp_base_get_queue(x), x, 0, 0, &x->x_finish_queue_id[cur]); + x->x_finish_queue_id_current = !cur; + + + +} + + +static void pdp_3d_windowcontext_free(t_pdp_3d_windowcontext *x) +{ + pdp_3d_windowcontext_close(x); + pdp_3dp_base_free(x); + +} + +t_class *pdp_3d_windowcontext_class; + + +void *pdp_3d_windowcontext_new(void) +{ + /* allocate */ + t_pdp_3d_windowcontext *x = (t_pdp_3d_windowcontext *)pd_new(pdp_3d_windowcontext_class); + + x->x_width = 320; + x->x_height = 240; + x->x_finish_queue_id[0] = -1; + x->x_finish_queue_id[1] = -1; + x->x_finish_queue_id_current =0; + + /* init super: this is mandatory */ + pdp_3dp_base_init(x); + pdp_3dp_base_disable_active_inlet(x); + + /* set the dpd processing methods & outlets */ + pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_windowcontext_clearbuffer, 0); + pdp_3dp_base_add_cleanup(x, (t_pdp_method)pdp_3d_windowcontext_swapbuffer, (t_pdp_method)pdp_3d_windowcontext_sendfinish); + + /* add event outlet */ + x->x_eventout = outlet_new((t_object *)x, &s_anything); + + + return (void *)x; +} + + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_3d_windowcontext_setup(void) +{ + /* create a standard pd class */ + pdp_3d_windowcontext_class = class_new(gensym("3dp_windowcontext"), (t_newmethod)pdp_3d_windowcontext_new, + (t_method)pdp_3d_windowcontext_free, sizeof(t_pdp_3d_windowcontext), 0, A_NULL); + + /* inherit pdp base class methods */ + pdp_3dp_base_setup(pdp_3d_windowcontext_class); + + /* register methods */ + class_addbang(pdp_3d_windowcontext_class, pdp_3d_windowcontext_bang); + + class_addmethod(pdp_3d_windowcontext_class, (t_method)pdp_3d_windowcontext_open, gensym("open"), A_NULL); + class_addmethod(pdp_3d_windowcontext_class, (t_method)pdp_3d_windowcontext_close, gensym("close"), A_NULL); + class_addmethod(pdp_3d_windowcontext_class, (t_method)pdp_3d_windowcontext_resize, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(pdp_3d_windowcontext_class, (t_method)pdp_3d_windowcontext_resize, gensym("size"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(pdp_3d_windowcontext_class, (t_method)pdp_3d_windowcontext_cursor, gensym("cursor"), A_FLOAT, A_NULL); + +} + + + +#ifdef __cplusplus +} +#endif |