diff options
author | Hans-Christoph Steiner <eighthave@users.sourceforge.net> | 2005-12-16 01:05:40 +0000 |
---|---|---|
committer | Hans-Christoph Steiner <eighthave@users.sourceforge.net> | 2005-12-16 01:05:40 +0000 |
commit | b694c274836ac8b04d644711ac324eac2e9ab83e (patch) | |
tree | 36b6a5c17f7e1f414f80697210c2ed3e8005035b /opengl | |
parent | e28a07fba67af0af818dda6afa4cf67c09700816 (diff) |
checking in pdp 0.12.4 from http://zwizwa.fartit.com/pd/pdp/pdp-0.12.4.tar.gz
svn path=/trunk/externals/pdp/; revision=4232
Diffstat (limited to 'opengl')
65 files changed, 8030 insertions, 0 deletions
diff --git a/opengl/Makefile b/opengl/Makefile new file mode 100644 index 0000000..d62358e --- /dev/null +++ b/opengl/Makefile @@ -0,0 +1,27 @@ +include Makefile.config + +all: $(TARGET) + +linux: pdp_opengl.pd_linux + +darwin: pdp_opengl.pd_darwin + +subdirs: + make -C system + make -C modules + make -C include + +clean: + make -C system clean + make -C modules clean + make -C include clean + rm -f pdp_opengl.pd_linux + rm -f *~ + +pdp_opengl.pd_linux: subdirs + rm -f pdp_opengl.pd_linux + $(CC) -export_dynamic -shared -o pdp_opengl.pd_linux modules/*.o system/*.o $(LDFLAGS) -g + +pdp_opengl.pd_darwin: subdirs + rm -f pdp_opengl.pd_linux + $(CC) -o pdp_opengl.pd_pd_darwin modules/*.o system/*.o $(LDFLAGS) -g -bundle -bundle_loader $(PD_EXECUTABLE) diff --git a/opengl/Makefile.config b/opengl/Makefile.config new file mode 100644 index 0000000..4e59a4c --- /dev/null +++ b/opengl/Makefile.config @@ -0,0 +1,25 @@ +PD_DIR = /home/tom/pd/distro/pd/src +PDP_DIR = /home/tom/pd/packet/include +PDP_OGL_DIR = /home/tom/pd/packet/opengl/include + + + +CFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer -ffast-math \ + -Wall -W -Wstrict-prototypes -Werror \ + -Wno-unused -Wno-parentheses -Wno-switch -g + +CPPFLAGS = -I$(PD_DIR) -I$(PDP_DIR) -I$(PDP_OGL_DIR) -I/usr/X11R6/include +LDFLAGS = -lGL -lglut + +TARGET=linux + +#uncomment these for darwin: +#TARGET=darwin +#CPPFLAGS+=-I/sw/include +#PD_EXECUTABLE=/usr/local/bin/pd +#LDFLAGS = -lGL -lGLU -lglut -lX11 -L/sw/lib -L/usr/X11R6/lib + + + +.c.o: + $(CC) $(CFLAGS) $(CPPFLAGS) -o $*.o -c $*.c diff --git a/opengl/README b/opengl/README new file mode 100644 index 0000000..2e06708 --- /dev/null +++ b/opengl/README @@ -0,0 +1,248 @@ +pdp_opengl (3dp): opengl extensions for pdp +warning: this is still experimental and incomplete + +this library extends pdp with texture and render context packets, +to use some of the power of current video hardware. + +it is very much like gem (sort of a redesign, filled with my own +idiosyncrasies). gem, like it is now, is not very suited for interaction +with pdp image processing because of its hardcoded window centric rendering, +so i thought i'd write some gem like stuff on top of pdp myself. (3dp right +now only supports window centric rendering itself, but adding pbuffer +or pixmap rendering is easy enough, though it requires a rather new glx +library) + +so, 3dp is an experimental gem clone with tight pdp integration. unless +you like experiments, use gem, since it is better supported, has more +features and runs on linux, windows and mac osx. + +requires glx (opengl on x window). + +building: + +edit Makefile.config to reflect your system and run make. the library is +pdp_opengl.pd_linux + +some of the examples use the abstractions in opengl/abstractions. best to +add this to your pd path. + + +there are some fatal X bugs floating around, so be careful with resizing +windows and closing patches. there are a lot of other, non-fatal bugs +or badly implemented features. if you have remarks, just let me know. + + +i'll move to autoconf once i no longer consider it experimental. + + +TIPS & TRICKS + + +* the 3dp_windowcontext creates a window to draw in. the window packet +will be be output to the left outlet when a bang is received. control +flow for context is right to left, this means if a 3dp object has 2 +context outlets, the rightmost will be propagated before the leftmost. +there is no fanout. all operations are accumulative, including the +geometric transformations. if you need to branch use a 3dp_push object. + + +* geometric transformations can be done using the 3dp_view object. +the first argument is the kind of transformation: scale, scalex, +scaley, scalez, rotx, roty, rotz, rota, transx, transy, transz, +transxyz. + +repectively this scales the object, the x, y, z axis, rotates +around the x, y, z axis, rotates around an arbitrary axis, translates +in the x, y, z directions and translates along a vector. the initial +parameters can be specified as creation arguments, i.e.: + +[3dp_view rota 1 1 1 90] rotates by 90 degrees around axis (1,1,1). + + +* some simple objects can be drawn using the pdp_draw object. the +first argument is the object: square, cube, sphere, torus, cone, +teapot, dodeca, icosa, octa, tetra. prepending the names with a w +draws the wireframe version. (i.e. wcube is a wireframe cube). the +first inlet of the object is a texture inlet. not all objects support +this, but cube, square and sphere do. other inlets set some parameters +like size, nb of segments for sphere, etc.. they can be specified +by creation arguments too. + + +* saving a (matrix) state can be accomplished by the 3dp_push object. +the default matrix is the modelview matrix. it works as follows: both +the right and the left outlet propagate the same matrix state as the +input. so in short you can use 3dp_push to split your rendering tree +into parallel branches. the matrix types that can be pushed are: +modelview, texture, color, projection. + +* setting a current matrix can be done using the 3dp_mode object. +i.e. [3dp_mode texture] will map all geometric transforms to the +texture matrix, for texture coordinate animation. the left outlet +restores the current matrix back to the modelview matrix. + +* it is possible to send a render context trough a drawing/view +transforming object multiple times. the easy way is to use 3dp_for, +but other ways are legal too. this can be done to draw different +versions of the same object. have a look at example01 how this can +be done. + +it is also possible to send multiple render contexts trought the same +rendering tree (i.e. multiple windows). if you use different viewing +transformations on the top of the rendering chain, you can view a scene +trough different angles. + + +* light sources can be introduces using 3dp_light. they can be moved +with oridinary 3dp_view objects. + + +* 3dp_color changes the current color. right outlet is new color, +left outlet is the previous color. + +* 3dp_toggle toggles a boolean opengl switch. enabled now are: +depth_test, blend_add, blend_mix. more to come later. + + + +* couping 3dp and pdp can be done using 3dp_snap and pdp_convert. +the correct way to do it is to put 3dp_snap in a rendering +chain and give it arguments like this: + +[3dp_snap image/*/* 320 240] + +if you specify the subtype to be image/multi/*, the packet +will not be colour space converted: it will stay rgb. +if you want to make a snapshot to store as a high quality +png image, snap to bitmap/rgb/* and store it in pdp_reg to save. +to convert an image back to a texture, use + +[pdp_convert texture/*/*] + +if you snap to a texture (which is the default) +the dimensions don't need to be specified. a texture will be +allocated that can contain the entire screen. this is because +texture coordinates are relative and data is always interpolated. + +snapping only works correctly when the window is not covered +by other windows. + + +* textures can have any dimensions, but only those which have +dimensions that are integral powers of two will be tiled correctly. +i.e. by using pdp_mode to change to texture mode and doing some +coordinate transforms using pdp_view (see example06: this +uses a tilable animated cellular automata texture) + + +* multipass rendering is supported trough the objects +3dp_subcontext, "3dp_draw clear" and "3dp_view reset". the idea +is as follows: before rendering the final scene, you use +(a part of) the drawing buffer to render some things and store +them in a texture to be used in your final drawing pass. have +a look at examples 11, 12 and 13. in theory you could build a +"texture processing" framework on top of 3dp, by using the window +buffer as an accumulator and using textures as auxilary registers, +and drawing your final texture result using i.e. +3dp_display_texture. while this can be much faster than ordinary +pdp image processing, it also requires you to do more bookkeping +yourself, since you can only use a "serial" approach because +you can't modify textures directly, only trough the use of the +render buffer. + + +* 3dp has it's own thread, which is enabled by default. you +can enable/disable this by sending a "3dthread 0/1" message +to pdp_control. in most cases there's no reason to disable +the thread processing, except when you are doing a lot of +pdp<->3dp conversions. in that case the delay introduced by +the thread processing might become problematic. (the same +goes for pdp btw. feedback and threads don't mix too well). +it's a tradeoff. thread processing gives priority to the audio, +so you can obtain low latency, and you don't have to care +about locking up pd by doing too much processing. (instead +frames will be dropped). the drawback is of course that video +timing becomes unpredictable because it is governed by the system +scheduler. so sometimes it can be useful to disable threads +and increase the audio latency, so you can have snappy audio +and video at the same time. getting this to work well usually +requires some experimenting. + + +* if you have an nvidia card, you can set the environment +variable __GL_SYNC_TO_VBLANK to 1 to prevent tearing, until +3dp has default support for it. i.e.: + +export __GL_SYNC_TO_VBLANK=1 + + + +enjoy, + +tom + + + + +--- +some political ranting: gem vs. pdp/3dp + +first a disclaimer. i'm not into dissing people. i respect and appreciate +all the work that has gone into gem, but at the same time i'm not too happy +with what gem has become. not so much the functionality, but the way it is +built. the original design as a 3d processing extension is not flexible enough +to incorporate what's in there now and what could be added in the future.. + +instead of complaining about it, i decided to be pragmatic and write something +from scratch. i think, sometimes this has to be done. for me writing pdp/3dp +has been an extremely interesting learning experience. i think i understand +the trade-offs better now, and i know now it's not too easy to get it all +to work. maybe these remarks can be useful... + +opengl is not a pure dataflow language. it operates on a global machine +state next to the obvious drawing buffer that is passed around. +representing opengl code with a graphic tree view has some advantages, +though it has a different "feel" than normal pd patches. the fact that +opengl transforms object coordinates to screen coordinates, and not vice +versa, gives graphicly represented opengl code an "upside down" feel. + +one of the things i don't like about gem is that it has both the opengl +"upside down drawing and coordinate transformation tree" and the pix +"data flow image processing tree" in the same network, which i find +counterintuitive. it is too monolytic to be truly flexible. in pdp/3dp +i try to separate the two explicitly: dataflow where possible (image +processing), and serial context based processing where needed (opengl). + +another disadvantage of gem is its window centric context. by building +3dp around explicit context passing, with explicit context creation objects, +i try to avoid this. an advantage of this is the possibility to send +multiple contexts trough a rendering tree, i.e. to have 2 different views +of the same scene. + +pdp has implicit fanout for all packets. i think that is its great +strength. it enables you to use any kind of media packet like you would +use floats. it is very intuitive. however, 3d rendering does not fit +this shoe. at least not when you just wrap opengl in the most straightforward +way. 3dp is a test case for pdp's "accumulation packets", which is a formal +abstraction of a context. pdp processors are nothing more than serial programs +working on a context, so in fact it's nothing special. in fact, i'm still +in doubt if it is useful besides being able to support opengl.. + +so, the idea was to improve upon gem a bit, from different angles. i did +not succeed in my primary goal: making 3dp more intuitive than gem. it seems +this is only possible if you limit some of the flexibility. just wrapping +opengl keeps a lot of flexibility, but get's infected with the opengl +paradigm. by separating pdp (image processing) and 3dp (drawing and geometry +processing) as much as possible i think i've solved some intuition problems, +but 3dp itself is still basicly gem, with imho a better overall design, +but due to its more low level approach, maybe harder to understand. it seems +to me that knowing how opengl works is rather necessary to use 3dp. the same +is true for gem. + +one last philo remark: to me it seems the biggest drawback of gem's design is +the processor centric aproach: the only objects are processors, the data is +implicit and seemingly global. in pdp/3dp processors and objects are 2 separate +entities. i tried to unify them in one object model, but to me it seems the two +should really be treated as different complementary entities, to stay close to +the dataflow paradigm which makes pd such an intuitive tool. + diff --git a/opengl/TODO b/opengl/TODO new file mode 100644 index 0000000..58996fc --- /dev/null +++ b/opengl/TODO @@ -0,0 +1,124 @@ +bugs: WARNING: there are still quite a few fatal bugs lurking around. + +* segfault when combining 3dp_windowcontext and pdp_xv. probably a mistake +in the teture<->image conversion or window event handling. +* 3dp is not robust against running out of video card resources. if you +manage to crash it please consider sending a bug report. +* 3dp_dlist triggered a segfault in pdp_mutex(un?)lock. can't reproduce. +this also happens on some other occasions where a post() statement is involved: +crash in pdp_mutex_lock, called by putc() -> happens in pdp too when calling post from +thread (like in pdp_netsend/receive) +* pd hangs on save? what happens during save?? -> 0.35 prob? 0.36 seems to work fine. +* segfaults when deleting 3dp objects. very unpredictable. + + + + +todo: + +* fix flow control for texture conversion +* finish mesh object + + +general: + +* prevent display list recursion: add some state data to the context packet to solve this. + +redesign: +* unify pbuf & window contexts (postponed pbufs because of subcontexts) +* cube mapping +* bubble object (model + wave equation) +* finish 3dp light + +performance: +* why is texture upload so slow? and is there a way to work around it? +* (why) is context switching slow? and how to introduce the render context differently. (direct to window?) + + + +DESIGN NOTES + +3dp is basicly my idea of gem on top of pdp. it is a simple layer around opengl. +3dp_* render and transform objects accept a reference to a rendering context and pass this along. + +3dp_* objects DO NOT SUPPORT FANOUT. they do support fanin. multiple contexts can be sent to an object, which +will result in drawing in (or other manipulations of) the respective contexts. + +texture packets can be used to pass bitmap data around. 3dp_tdraw accepts a texture on its +second inlet. 3dp_snap dumps the current state of the buffer into a texture packet. + +object classes: + +-drawing objects + +[3dp_draw cube] [3dp_draw sphere] .. + +-manipulation objects + +[3dp_view rot2d] + +-opengl stack objects + +[3dp_push color view texture] + +3dp vs pdp design: + +a context packet is an accumulation packet, and the order of operations on it (serial) is important. it has +elements from a readonly packet (only one instance is passed around) and from a rw packet (it is legal to change it's +state and pass it on). + +opengl in dataflow formulation seems to be read bottom to top. i first thought +this was a big drawback of gem, but now that i finally understand how opengl works i think it is +ok. it suddenly dawned on me, usually the number of eyes is much smaller than the number of objects +in a scene, so it is much more straghtforward to start at the eye instead of the objects. since a +simple serial stack mechanism can be used. + +so opengl is really serial, while pd "looks" parallel, but is serial too. i still think this +is a good thing, since it keeps things simple, but for some reason the "upside down & serial" +thing about opengl in pd is rather strange.. + +once you get used to it, and think about rendering a set as a tree rooted at the "context source" +like is done in gem,it seems to work out.. + +i think i'm going to stick to the depth first backtracking a tree serial rendering +way of looking at it. since i don't see a way of making this more intuitive without complicating +it too much. so no legal fanout of a context packet. + +------------------ + +accumulation packets (buckets) & backtracking + +buckets add support for "context based" single threaded programs. it +basicly allows you to construct data processors represented as a control +flow tree. i.e. function calls can be represented by branches in a tree, +with each branch rooted at an object's outlet, executed from right to +left. a "context packet" (or accumulation packet or bucket) is passed +along and acted upon. + +* fanout is illegal for bucket processors (at least, if they are non +cummutative, as is usually the case). this is not explicitly prohibited, +since it is hard to check in pd and it allows some hacks. the reason for +this is obvious: if you do not know which branch of a tree is executed +first, results are undefined. + +* a new communication protocol needs to be introduced, incompatible +with the existing 3 phase protocol: + +(1) register_ro +(2) register_rw +(3) process + +the new dpd (bucket / accumulation packet) protocol is 2 phase: +(1) inspect +(2) accumulate + +(1) is only present to give priority to bucket inspectors over +accumulators (processors) + +an accumulation packet will be owned by its creator all the time. +accumulation processors do not increase the reference count. only ro +inspectors will. + +note: it is legal for a packet to have a broken register_rw (missing +copy constructor, i.e. if a copy is too expensive or impossible. this +must be set in the pdp packet header flags by the packet constructor) diff --git a/opengl/abstractions/3dp_basicscene.pd b/opengl/abstractions/3dp_basicscene.pd new file mode 100644 index 0000000..af79d51 --- /dev/null +++ b/opengl/abstractions/3dp_basicscene.pd @@ -0,0 +1,27 @@ +#N canvas 500 522 450 300 10; +#X obj 54 72 metro 40; +#X obj 54 140 3dp_push; +#X floatatom 375 162 5 0 0 0 - - -; +#X text 19 12 a basic 3d scene with a light source and mouse view rotation +; +#X obj 54 218 outlet; +#X obj 54 46 inlet; +#X floatatom 340 129 5 0 0 0 - - -; +#X floatatom 115 49 5 0 0 0 - - -; +#X obj 254 216 3dp_light 0; +#X obj 254 158 3dp_view roty; +#X obj 254 192 3dp_view transz 10; +#X obj 54 169 3dp_mouserotate; +#X obj 54 111 3dp_windowcontext; +#X connect 0 0 12 0; +#X connect 1 0 11 0; +#X connect 1 1 9 0; +#X connect 2 0 10 1; +#X connect 5 0 0 0; +#X connect 6 0 9 1; +#X connect 7 0 0 1; +#X connect 9 0 10 0; +#X connect 10 0 8 0; +#X connect 11 0 4 0; +#X connect 12 0 1 0; +#X connect 12 1 11 1; diff --git a/opengl/abstractions/3dp_blend.pd b/opengl/abstractions/3dp_blend.pd new file mode 100644 index 0000000..e7768d7 --- /dev/null +++ b/opengl/abstractions/3dp_blend.pd @@ -0,0 +1,13 @@ +#N canvas 554 145 570 225 10; +#X obj 25 124 3dp_toggle depth_test 0; +#X obj 181 159 3dp_toggle blend_add 1; +#X obj 25 90 inlet; +#X obj 330 199 outlet; +#X text 38 11 use this object for quick and dirty blending effects. +it has the depth test disabled and accumulated blending enabled.; +#X text 128 60 NOTE: proper transparency is quite hard to do \, because +it requires manual depth sorting. there is no real support for this +in 3dp yet.; +#X connect 0 1 1 0; +#X connect 1 1 3 0; +#X connect 2 0 0 0; diff --git a/opengl/abstractions/3dp_display_texture.pd b/opengl/abstractions/3dp_display_texture.pd new file mode 100644 index 0000000..63e602b --- /dev/null +++ b/opengl/abstractions/3dp_display_texture.pd @@ -0,0 +1,31 @@ +#N canvas 277 275 874 339 10; +#X obj 244 246 3dp_view scale_aspect; +#X obj 37 131 inlet; +#X obj 222 130 inlet; +#X obj 351 131 inlet; +#X text 27 107 context inlet; +#X text 198 106 texture inlet; +#X text 328 106 scaling inlet; +#X text 406 244 <- scale the square to the window aspect ratio; +#X obj 37 269 outlet; +#X text 40 16 this abstraction can be used for texture display. i.e. +if you use a subcontext at a fixed resolution to create a texture \, +this abstraction stretches the texture to the full size of the window +.; +#X obj 244 274 3dp_draw square 8; +#X obj 244 220 3dp_view scale 1; +#X text 405 219 <- extra scaling (i.e. to clip off garbage boundaries) +; +#X obj 37 162 3dp_toggle depth_test 0; +#X text 404 164 <- disable depth test so the draw will overwrite; +#X obj 193 190 3dp_push; +#X text 405 193 <- save modelview; +#X text 27 295 context outlet; +#X connect 0 0 10 0; +#X connect 1 0 13 0; +#X connect 2 0 10 1; +#X connect 3 0 11 1; +#X connect 11 0 0 0; +#X connect 13 0 8 0; +#X connect 13 1 15 0; +#X connect 15 1 11 0; diff --git a/opengl/abstractions/3dp_fixedsizewindowcontext.pd b/opengl/abstractions/3dp_fixedsizewindowcontext.pd new file mode 100644 index 0000000..5dd5180 --- /dev/null +++ b/opengl/abstractions/3dp_fixedsizewindowcontext.pd @@ -0,0 +1,31 @@ +#N canvas 634 346 592 397 10; +#X obj 27 64 inlet; +#X obj 27 105 3dp_windowcontext; +#X obj 27 138 3dp_subcontext \$1 \$2; +#X obj 220 211 outlet; +#X obj 370 211 outlet; +#X text 350 236 event outlet; +#X obj 162 267 3dp_snap; +#X obj 27 318 3dp_display_texture; +#X text 150 23 a fixed size (window size independent) rendering context +that can be used as 3dp_windowcontext replacement.; +#X text 151 56 creation arguments are the context dimensions.; +#X text 175 87 NOTE: the general subcontext rule applies: if the actual +window size is small than the subcontext \, or is covered by other +windows \, the results might not be what you expect.; +#X text 176 236 context outlet (1); +#X text 241 266 <- when the render chain connected to (1) is done; +#X text 261 281 it will be snapped to texture; +#X text 241 316 <- this texture will then be drawn to cover; +#X text 263 332 the entire window size; +#X obj 162 177 pdp_t p p; +#X obj 184 300 inlet; +#X connect 0 0 1 0; +#X connect 1 0 2 0; +#X connect 1 1 4 0; +#X connect 2 0 7 0; +#X connect 2 1 16 0; +#X connect 6 1 7 1; +#X connect 16 0 6 0; +#X connect 16 1 3 0; +#X connect 17 0 7 2; diff --git a/opengl/abstractions/3dp_mouserotate.pd b/opengl/abstractions/3dp_mouserotate.pd new file mode 100644 index 0000000..b81e27e --- /dev/null +++ b/opengl/abstractions/3dp_mouserotate.pd @@ -0,0 +1,37 @@ +#N canvas 534 483 533 399 10; +#X obj 27 19 inlet; +#X obj 27 363 outlet; +#X obj 70 152 - 0.5; +#X obj 135 151 - 0.5; +#X obj 82 214 *; +#X obj 135 212 *; +#X obj 135 186 t f f; +#X obj 82 184 t f f; +#X obj 82 243 +; +#X obj 113 271 sqrt; +#X obj 92 19 inlet; +#X obj 113 298 * 360; +#X obj 27 329 3dp_view rota; +#X text 216 138 convert mouse coordinates to axis and angle; +#X obj 70 118 unpack 0 0; +#X obj 92 49 route drag1 press1; +#X connect 0 0 12 0; +#X connect 2 0 7 0; +#X connect 2 0 12 2; +#X connect 3 0 6 0; +#X connect 3 0 12 1; +#X connect 4 0 8 0; +#X connect 5 0 8 1; +#X connect 6 0 5 0; +#X connect 6 1 5 1; +#X connect 7 0 4 0; +#X connect 7 1 4 1; +#X connect 8 0 9 0; +#X connect 9 0 11 0; +#X connect 10 0 15 0; +#X connect 11 0 12 4; +#X connect 12 0 1 0; +#X connect 14 0 2 0; +#X connect 14 1 3 0; +#X connect 15 0 14 0; +#X connect 15 1 14 0; diff --git a/opengl/abstractions/3dp_screenshot.pd b/opengl/abstractions/3dp_screenshot.pd new file mode 100644 index 0000000..9cbe07f --- /dev/null +++ b/opengl/abstractions/3dp_screenshot.pd @@ -0,0 +1,21 @@ +#N canvas 550 41 714 494 10; +#X obj 193 284 pdp_reg; +#X obj 193 203 pdp_t b p; +#X obj 193 233 symbol \$1; +#X msg 193 257 save_png \$1; +#X obj 195 110 loadbang; +#X msg 195 135 autosnap 0; +#X obj 51 111 inlet; +#X obj 51 176 3dp_snap bitmap/rgb/*; +#X obj 51 285 outlet; +#X text 41 22 make a screenshot of a 3dp context. creation argument +is filename. send a bang to take a snapshot.; +#X connect 1 0 2 0; +#X connect 1 1 0 1; +#X connect 2 0 3 0; +#X connect 3 0 0 0; +#X connect 4 0 5 0; +#X connect 5 0 7 0; +#X connect 6 0 7 0; +#X connect 7 0 8 0; +#X connect 7 1 1 0; diff --git a/opengl/abstractions/elbat.pd b/opengl/abstractions/elbat.pd new file mode 100644 index 0000000..211da15 --- /dev/null +++ b/opengl/abstractions/elbat.pd @@ -0,0 +1,41 @@ +#N canvas 431 78 581 572 10; +#X obj 23 63 inlet; +#X obj 168 211 outlet; +#X obj 168 150 tabread \$0-vec; +#X msg 15 210 \; \$1 const 0; +#X msg 15 159 bang; +#X obj 15 183 symbol \$0-vec; +#X obj 119 373 until; +#X msg 118 270 bang; +#X obj 155 414 f 0; +#X obj 191 414 + 1; +#X msg 163 338 0; +#X obj 119 318 t b b; +#X obj 156 519 tabwrite \$0-vec; +#X obj 155 443 t b f; +#X obj 154 478 randomnormal; +#X obj 119 348 f \$1; +#X obj 23 86 route reset normal; +#X text 168 274 fill table with normal distributed random variables +; +#X text 19 16 a tabread-like abstraction (with internal table); +#X obj 320 108 table \$0-vec \$1; +#X connect 0 0 16 0; +#X connect 2 0 1 0; +#X connect 4 0 5 0; +#X connect 5 0 3 0; +#X connect 6 0 8 0; +#X connect 7 0 11 0; +#X connect 8 0 9 0; +#X connect 8 0 13 0; +#X connect 9 0 8 1; +#X connect 10 0 8 1; +#X connect 11 0 15 0; +#X connect 11 1 10 0; +#X connect 13 0 14 0; +#X connect 13 1 12 1; +#X connect 14 0 12 0; +#X connect 15 0 6 0; +#X connect 16 0 4 0; +#X connect 16 1 7 0; +#X connect 16 2 2 0; diff --git a/opengl/abstractions/randomnormal.pd b/opengl/abstractions/randomnormal.pd new file mode 100644 index 0000000..bf1d4fa --- /dev/null +++ b/opengl/abstractions/randomnormal.pd @@ -0,0 +1,39 @@ +#N canvas 614 389 451 505 10; +#X obj 48 58 inlet; +#X obj 48 88 t b b; +#X obj 173 167 * 6.28; +#X obj 129 221 cos; +#X obj 173 222 sin; +#X obj 173 143 / 1e+06; +#X obj 173 121 random 1e+06; +#X obj 48 220 * -2; +#X obj 48 170 / 1e+06; +#X obj 48 125 random 1e+06; +#X obj 48 148 + 1; +#X obj 48 194 log; +#X obj 48 327 *; +#X obj 108 328 *; +#X obj 48 292 t f f; +#X obj 48 365 outlet; +#X obj 108 365 outlet; +#X text 35 10 normal gausian random number generator (box-muller); +#X obj 48 253 sqrt; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 1 1 6 0; +#X connect 2 0 4 0; +#X connect 2 0 3 0; +#X connect 3 0 12 1; +#X connect 4 0 13 1; +#X connect 5 0 2 0; +#X connect 6 0 5 0; +#X connect 7 0 18 0; +#X connect 8 0 11 0; +#X connect 9 0 10 0; +#X connect 10 0 8 0; +#X connect 11 0 7 0; +#X connect 12 0 15 0; +#X connect 13 0 16 0; +#X connect 14 0 12 0; +#X connect 14 1 13 0; +#X connect 18 0 14 0; diff --git a/opengl/abstractions/randomwalk2D.pd b/opengl/abstractions/randomwalk2D.pd new file mode 100644 index 0000000..58cf2df --- /dev/null +++ b/opengl/abstractions/randomwalk2D.pd @@ -0,0 +1,51 @@ +#N canvas 502 172 600 400 10; +#X obj 228 221 tabread \$0-x; +#X obj 334 213 tabread \$0-y; +#X obj 228 310 tabwrite \$0-x; +#X obj 350 330 tabwrite \$0-y; +#X obj 244 259 cos; +#X obj 350 266 sin; +#X obj 351 241 * 0.0628; +#X obj 351 185 random 100; +#X obj 228 284 +; +#X obj 334 291 +; +#X obj 228 144 t f b f; +#X msg 53 237 \; \$1 const 0; +#X obj 20 199 symbol \$0-x; +#X obj 108 199 symbol \$0-y; +#X msg 88 173 bang; +#X obj 228 172 t f f; +#X obj 214 337 outlet; +#X obj 334 354 outlet; +#X obj 156 82 inlet; +#X obj 156 106 route reset; +#X obj 351 82 table \$0-x \$1; +#X obj 351 116 table \$0-y \$1; +#X text 37 20 a 2D unit step random walk abstraction for use with 3dp_for +; +#X text 335 45 creation argument = nb of vectors; +#X text 64 44 inlet = vector to update; +#X connect 0 0 8 0; +#X connect 1 0 9 0; +#X connect 4 0 8 1; +#X connect 5 0 9 1; +#X connect 6 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 6 0; +#X connect 8 0 2 0; +#X connect 8 0 16 0; +#X connect 9 0 3 0; +#X connect 9 0 17 0; +#X connect 10 0 15 0; +#X connect 10 1 7 0; +#X connect 10 2 3 1; +#X connect 10 2 2 1; +#X connect 12 0 11 0; +#X connect 13 0 11 0; +#X connect 14 0 12 0; +#X connect 14 0 13 0; +#X connect 15 0 0 0; +#X connect 15 1 1 0; +#X connect 18 0 19 0; +#X connect 19 0 14 0; +#X connect 19 1 10 0; diff --git a/opengl/abstractions/smoothupdate.pd b/opengl/abstractions/smoothupdate.pd new file mode 100644 index 0000000..19df278 --- /dev/null +++ b/opengl/abstractions/smoothupdate.pd @@ -0,0 +1,49 @@ +#N canvas 112 570 450 387 10; +#X obj 225 64 inlet; +#X text 195 40 element to update; +#X obj 23 63 inlet; +#X text 39 39 new value; +#X obj 55 302 outlet; +#X obj 331 173 table \$0-vec; +#X obj 168 121 f 0; +#X obj 168 150 tabread \$0-vec; +#X text 350 41 smooth step; +#X obj 354 65 inlet; +#X obj 354 90 moses 0; +#X obj 366 116 moses 1; +#X msg 331 114 0; +#X msg 410 140 1; +#X obj 135 182 -; +#X obj 57 114 t f b; +#X obj 332 144 f; +#X obj 135 246 +; +#X obj 146 282 tabwrite \$0-vec; +#X obj 23 86 route reset; +#X msg 15 210 \; \$1 const 0; +#X msg 15 159 bang; +#X obj 15 183 symbol \$0-vec; +#X obj 136 215 * 0.1; +#X connect 0 0 6 1; +#X connect 2 0 19 0; +#X connect 6 0 7 0; +#X connect 6 0 18 1; +#X connect 7 0 14 1; +#X connect 7 0 17 1; +#X connect 9 0 10 0; +#X connect 10 0 12 0; +#X connect 10 1 11 0; +#X connect 11 0 16 0; +#X connect 11 1 13 0; +#X connect 12 0 16 0; +#X connect 13 0 16 0; +#X connect 14 0 23 0; +#X connect 15 0 14 0; +#X connect 15 1 6 0; +#X connect 16 0 23 1; +#X connect 17 0 4 0; +#X connect 17 0 18 0; +#X connect 19 0 21 0; +#X connect 19 1 15 0; +#X connect 21 0 22 0; +#X connect 22 0 20 0; +#X connect 23 0 17 0; diff --git a/opengl/doc/examples/arm.pd b/opengl/doc/examples/arm.pd new file mode 100644 index 0000000..36a8f48 --- /dev/null +++ b/opengl/doc/examples/arm.pd @@ -0,0 +1,40 @@ +#N canvas 475 534 572 380 10; +#X obj 43 10 inlet; +#X obj 43 227 outlet; +#X obj 43 141 3dp_push; +#X obj 208 200 3dp_view transx 0.5; +#X obj 43 113 3dp_view rotz; +#X obj 260 11 inlet; +#X obj 208 174 3dp_view scalex \$1; +#X obj 43 186 3dp_view transx \$1; +#X obj 260 275 r texture; +#X obj 43 83 3dp_view roty; +#X obj 129 61 r roty; +#X obj 329 91 r scale; +#X obj 43 37 3dp_draw cube 1; +#X obj 143 11 r cubesize; +#X obj 208 334 3dp_draw torus 0.25 0.5 6; +#X obj 208 256 spigot; +#X obj 245 232 r drawtorus; +#X obj 276 307 r torusr1; +#X obj 353 307 r torusr2; +#X text 375 27 draw one arm segment; +#X connect 0 0 12 0; +#X connect 2 0 7 0; +#X connect 2 1 6 0; +#X connect 3 0 15 0; +#X connect 4 0 2 0; +#X connect 5 0 4 1; +#X connect 6 0 3 0; +#X connect 7 0 1 0; +#X connect 8 0 14 1; +#X connect 9 0 4 0; +#X connect 10 0 9 1; +#X connect 11 0 6 1; +#X connect 11 0 7 1; +#X connect 12 0 9 0; +#X connect 13 0 12 2; +#X connect 15 0 14 0; +#X connect 16 0 15 1; +#X connect 17 0 14 2; +#X connect 18 0 14 3; diff --git a/opengl/doc/examples/example01.pd b/opengl/doc/examples/example01.pd new file mode 100644 index 0000000..969ee17 --- /dev/null +++ b/opengl/doc/examples/example01.pd @@ -0,0 +1,257 @@ +#N canvas 426 142 799 779 10; +#X floatatom 126 37 5 0 0 0 - - -; +#X obj 56 20 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X msg 83 19 stop; +#X floatatom 360 431 5 0 0 0 - - -; +#X obj 59 103 3dp_push; +#X floatatom 672 189 5 0 0 0 - - -; +#X obj 546 244 3dp_view transx 3; +#X obj 546 270 3dp_light; +#X obj 612 97 f; +#X floatatom 641 98 5 0 0 0 - - -; +#X floatatom 669 370 5 0 0 0 - - -; +#X obj 182 491 arm 3; +#X obj 182 514 arm 3; +#X obj 182 537 arm 3; +#X obj 182 467 arm 3; +#X floatatom 360 455 5 0 0 0 - - -; +#X floatatom 359 478 5 0 0 0 - - -; +#X floatatom 358 501 5 0 0 0 - - -; +#X floatatom 358 524 5 0 0 0 - - -; +#X obj 182 584 arm 3; +#X obj 182 607 arm 3; +#X obj 182 630 arm 3; +#X obj 182 560 arm 3; +#X floatatom 358 548 5 0 0 0 - - -; +#X floatatom 358 571 5 0 0 0 - - -; +#X floatatom 358 594 5 0 0 0 - - -; +#X obj 59 224 3dp_view roty; +#X obj 284 449 * 1; +#X obj 284 589 * -1; +#X obj 182 653 arm 3; +#X floatatom 358 617 5 0 0 0 - - -; +#X obj 284 635 * -1.5; +#X obj 663 686 s roty; +#X floatatom 615 611 5 0 0 0 - - -; +#X floatatom 671 585 5 0 0 0 - - -; +#X obj 673 616 s scale; +#X floatatom 359 388 5 0 0 0 - - -; +#X obj 284 473 * -1.01; +#X obj 284 496 * 0.99; +#X obj 284 519 * -1.01; +#X obj 284 542 * 2.1; +#X obj 284 566 * -1.7; +#X obj 182 425 3dp_draw cube 1.4; +#X obj 182 809 3dp_draw cube 1.4; +#X msg 597 536 4; +#X obj 59 151 3dp_view transz -3; +#X obj 546 216 3dp_view roty 54; +#X obj 669 392 s cubesize; +#X msg 360 345 3.15; +#X msg 126 17 20; +#X obj 284 612 * 0.11; +#X floatatom 672 220 5 0 0 0 - - -; +#X msg 612 72 0; +#X obj 342 311 * 1; +#X obj 59 201 3dp_view rotx; +#X floatatom 164 187 5 0 0 0 - - -; +#X floatatom 358 641 5 0 0 0 - - -; +#X obj 182 700 arm 3; +#X obj 182 724 arm 3; +#X obj 182 748 arm 3; +#X obj 182 677 arm 3; +#X floatatom 359 664 5 0 0 0 - - -; +#X floatatom 359 688 5 0 0 0 - - -; +#X floatatom 360 712 5 0 0 0 - - -; +#X obj 284 706 * -1; +#X obj 182 771 arm 3; +#X floatatom 360 735 5 0 0 0 - - -; +#X obj 283 753 * -1.5; +#X obj 284 659 * 2.1; +#X obj 284 682 * -1.7; +#X obj 283 730 * 0.11; +#X obj 9 334 3dp_push; +#X obj 182 399 3dp_view transz; +#X floatatom 282 369 5 0 0 0 - - -; +#X obj 131 371 3dp_view transz; +#X obj 231 338 * -1; +#X msg 282 341 2; +#X obj 564 401 s drawtorus; +#X obj 564 374 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 +1; +#X obj 674 496 s torusr1; +#X floatatom 672 473 5 0 0 0 - - -; +#X floatatom 667 419 5 0 0 0 - - -; +#X obj 669 442 s torusr2; +#X msg 564 349 1; +#X obj 597 645 *; +#X obj 59 126 3dp_push; +#X obj 9 364 3dp_push; +#X obj 9 437 3dp_view rotx; +#X floatatom 96 416 5 0 0 0 - - -; +#X obj 9 471 3dp_draw sphere 30 40; +#X obj 9 593 3dp_snap; +#X obj 473 487 / 1000; +#X floatatom 473 461 5 0 0 0 - - -; +#X obj 430 8 loadbang; +#X obj 430 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 59 77 3dp_windowcontext; +#X obj 59 274 3dp_push; +#X obj 110 303 pdp_t p b; +#X obj 9 307 pdp_t p b; +#X msg 349 252 400; +#X msg 311 252 -400; +#X obj 342 287 +; +#X msg 473 434 3; +#X text 544 189 light source; +#X obj 59 248 3dp_view scale 0.4; +#X obj 640 157 s counter; +#X obj 245 169 r counter; +#X text 694 98 speed; +#X obj 59 54 metro 20; +#X obj 238 207 * 0.05; +#X obj 9 570 spigot; +#X obj 76 546 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 612 122 + 1; +#X text 28 521 texture feedback; +#X text 486 751 "no-bots in no-sphere"; +#X text 459 768 a double dance of 13 segments; +#X text 549 734 ---; +#X text 549 787 ---; +#X obj 59 176 3dp_mouserotate; +#X connect 0 0 108 1; +#X connect 1 0 108 0; +#X connect 2 0 108 0; +#X connect 3 0 27 1; +#X connect 4 0 85 0; +#X connect 4 1 46 0; +#X connect 5 0 46 1; +#X connect 6 0 7 0; +#X connect 8 0 112 0; +#X connect 9 0 112 1; +#X connect 10 0 47 0; +#X connect 11 0 12 0; +#X connect 12 0 13 0; +#X connect 13 0 22 0; +#X connect 14 0 11 0; +#X connect 15 0 37 1; +#X connect 16 0 38 1; +#X connect 17 0 39 1; +#X connect 18 0 40 1; +#X connect 19 0 20 0; +#X connect 20 0 21 0; +#X connect 21 0 29 0; +#X connect 22 0 19 0; +#X connect 23 0 41 1; +#X connect 24 0 28 1; +#X connect 25 0 50 1; +#X connect 26 0 104 0; +#X connect 27 0 37 0; +#X connect 27 0 14 1; +#X connect 28 0 50 0; +#X connect 28 0 20 1; +#X connect 29 0 60 0; +#X connect 30 0 31 1; +#X connect 31 0 29 1; +#X connect 31 0 68 0; +#X connect 33 0 84 1; +#X connect 34 0 35 0; +#X connect 36 0 42 2; +#X connect 36 0 43 2; +#X connect 37 0 38 0; +#X connect 37 0 11 1; +#X connect 38 0 39 0; +#X connect 38 0 12 1; +#X connect 39 0 40 0; +#X connect 39 0 13 1; +#X connect 40 0 41 0; +#X connect 40 0 22 1; +#X connect 41 0 28 0; +#X connect 41 0 19 1; +#X connect 42 0 14 0; +#X connect 44 0 34 0; +#X connect 45 0 118 0; +#X connect 46 0 6 0; +#X connect 48 0 36 0; +#X connect 48 0 102 0; +#X connect 48 0 76 0; +#X connect 48 0 83 0; +#X connect 49 0 0 0; +#X connect 50 0 31 0; +#X connect 50 0 21 1; +#X connect 51 0 6 1; +#X connect 52 0 8 0; +#X connect 53 0 27 0; +#X connect 54 0 26 0; +#X connect 55 0 54 1; +#X connect 56 0 68 1; +#X connect 57 0 58 0; +#X connect 58 0 59 0; +#X connect 59 0 65 0; +#X connect 60 0 57 0; +#X connect 61 0 69 1; +#X connect 62 0 64 1; +#X connect 63 0 70 1; +#X connect 64 0 70 0; +#X connect 64 0 58 1; +#X connect 65 0 43 0; +#X connect 66 0 67 1; +#X connect 67 0 65 1; +#X connect 68 0 69 0; +#X connect 68 0 60 1; +#X connect 69 0 64 0; +#X connect 69 0 57 1; +#X connect 70 0 67 0; +#X connect 70 0 59 1; +#X connect 71 0 86 0; +#X connect 71 1 74 0; +#X connect 72 0 42 0; +#X connect 73 0 72 1; +#X connect 73 0 75 0; +#X connect 74 0 42 0; +#X connect 75 0 74 1; +#X connect 76 0 73 0; +#X connect 78 0 77 0; +#X connect 80 0 79 0; +#X connect 81 0 82 0; +#X connect 83 0 78 0; +#X connect 84 0 32 0; +#X connect 85 0 45 0; +#X connect 86 0 87 0; +#X connect 87 0 89 0; +#X connect 88 0 87 1; +#X connect 89 0 110 0; +#X connect 90 1 89 1; +#X connect 91 0 33 0; +#X connect 92 0 91 0; +#X connect 93 0 94 0; +#X connect 94 0 1 0; +#X connect 94 0 48 0; +#X connect 95 0 4 0; +#X connect 95 1 118 1; +#X connect 96 0 98 0; +#X connect 96 1 97 0; +#X connect 97 0 72 0; +#X connect 97 1 100 0; +#X connect 98 0 71 0; +#X connect 98 1 99 0; +#X connect 99 0 101 0; +#X connect 100 0 101 0; +#X connect 101 0 53 0; +#X connect 102 0 92 0; +#X connect 102 0 44 0; +#X connect 104 0 96 0; +#X connect 106 0 109 0; +#X connect 108 0 95 0; +#X connect 108 0 8 0; +#X connect 109 0 26 1; +#X connect 110 0 90 0; +#X connect 111 0 110 1; +#X connect 112 0 8 1; +#X connect 112 0 84 0; +#X connect 112 0 101 1; +#X connect 112 0 105 0; +#X connect 118 0 54 0; diff --git a/opengl/doc/examples/example02.pd b/opengl/doc/examples/example02.pd new file mode 100644 index 0000000..d5023d9 --- /dev/null +++ b/opengl/doc/examples/example02.pd @@ -0,0 +1,46 @@ +#N canvas 696 306 480 535 10; +#X obj 102 73 3dp_windowcontext; +#X obj 102 36 metro 20; +#X obj 102 122 3dp_push; +#X obj 102 11 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 56 40 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X msg 253 32 cursor \$1; +#X obj 253 12 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X obj 102 209 3dp_mouserotate; +#X obj 153 322 3dp_draw cube 1; +#X obj 265 139 3dp_view transxyz -4 3 4; +#X obj 102 270 3dp_push; +#X obj 102 348 3dp_push; +#X obj 102 425 3dp_push; +#X obj 153 296 3dp_view transx 2; +#X obj 153 374 3dp_view transy 2; +#X obj 153 451 3dp_view transz 2; +#X obj 153 400 3dp_draw cube 1; +#X obj 153 477 3dp_draw cube 1; +#X obj 102 506 3dp_draw dodeca 1; +#X text 25 231 use the mouse to rotate the model (but not the light +source since it is rendered before the rotation is applied.); +#X obj 265 161 3dp_light; +#X connect 0 0 2 0; +#X connect 0 1 7 1; +#X connect 1 0 0 0; +#X connect 2 0 7 0; +#X connect 2 1 9 0; +#X connect 3 0 1 0; +#X connect 4 0 0 0; +#X connect 5 0 0 0; +#X connect 6 0 5 0; +#X connect 7 0 10 0; +#X connect 9 0 20 0; +#X connect 10 0 11 0; +#X connect 10 1 13 0; +#X connect 11 0 12 0; +#X connect 11 1 14 0; +#X connect 12 0 18 0; +#X connect 12 1 15 0; +#X connect 13 0 8 0; +#X connect 14 0 16 0; +#X connect 15 0 17 0; diff --git a/opengl/doc/examples/example03.pd b/opengl/doc/examples/example03.pd new file mode 100644 index 0000000..48d714b --- /dev/null +++ b/opengl/doc/examples/example03.pd @@ -0,0 +1,65 @@ +#N canvas 382 102 480 535 10; +#X obj 102 73 3dp_windowcontext; +#X obj 102 36 metro 20; +#X obj 102 139 3dp_push; +#X obj 261 185 3dp_light; +#X obj 102 11 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 56 40 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X msg 253 32 cursor \$1; +#X obj 253 12 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 102 209 3dp_mouserotate; +#X obj 261 163 3dp_view transxyz -4 3 4; +#X obj 102 427 arm 3; +#X obj 371 230 loadbang; +#X obj 102 333 pdp_t p p p p; +#X obj 102 304 pdp_t p p p p; +#X floatatom 199 386 5 0 0; +#X obj 318 378 s roty; +#X floatatom 318 327 5 0 0; +#X obj 371 378 s drawtorus; +#X obj 371 355 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 +1; +#X obj 102 256 pdp_t p b; +#X obj 212 273 f 0; +#X obj 302 352 *; +#X obj 183 409 *; +#X obj 212 307 + 0.1; +#X obj 102 105 3dp_view transz -5; +#X text 41 471 it is possible to send the rendercontext to the same +rendering/transforming chain multiple times. (in other words: 3dp objects +do not support fanout \, but they do support fanin.); +#X connect 0 0 24 0; +#X connect 0 1 8 1; +#X connect 1 0 0 0; +#X connect 2 0 8 0; +#X connect 2 1 9 0; +#X connect 4 0 1 0; +#X connect 5 0 0 0; +#X connect 6 0 0 0; +#X connect 7 0 6 0; +#X connect 8 0 19 0; +#X connect 9 0 3 0; +#X connect 11 0 18 0; +#X connect 12 0 10 0; +#X connect 12 1 10 0; +#X connect 12 2 10 0; +#X connect 12 3 10 0; +#X connect 13 0 12 0; +#X connect 13 1 12 0; +#X connect 13 2 12 0; +#X connect 13 3 12 0; +#X connect 14 0 22 1; +#X connect 16 0 21 1; +#X connect 18 0 17 0; +#X connect 19 0 13 0; +#X connect 19 1 20 0; +#X connect 20 0 23 0; +#X connect 21 0 15 0; +#X connect 22 0 10 1; +#X connect 23 0 20 1; +#X connect 23 0 22 0; +#X connect 23 0 21 0; +#X connect 24 0 2 0; diff --git a/opengl/doc/examples/example04.pd b/opengl/doc/examples/example04.pd new file mode 100644 index 0000000..5d22270 --- /dev/null +++ b/opengl/doc/examples/example04.pd @@ -0,0 +1,25 @@ +#N canvas 288 311 566 284 10; +#X obj 54 156 3dp_windowcontext; +#X obj 54 43 metro 40; +#X obj 54 19 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X obj 54 76 t b b; +#X obj 134 120 pdp_convert texture/*/*; +#X obj 54 183 3dp_mouserotate; +#X floatatom 180 202 5 0 0 0 - - -; +#X msg 134 68 open /dev/video1; +#X obj 54 227 3dp_draw sphere 5; +#X text 132 18 convert pdp image packets to textures and map them on +a sphere; +#X obj 134 93 pdp_v4l; +#X connect 0 0 5 0; +#X connect 0 1 5 1; +#X connect 1 0 3 0; +#X connect 2 0 1 0; +#X connect 3 0 0 0; +#X connect 3 1 10 0; +#X connect 4 0 8 1; +#X connect 5 0 8 0; +#X connect 6 0 8 2; +#X connect 7 0 10 0; +#X connect 10 0 4 0; diff --git a/opengl/doc/examples/example05.pd b/opengl/doc/examples/example05.pd new file mode 100644 index 0000000..7996355 --- /dev/null +++ b/opengl/doc/examples/example05.pd @@ -0,0 +1,41 @@ +#N canvas 352 162 732 325 10; +#X obj 54 43 metro 40; +#X obj 54 19 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 314 120 pdp_convert texture/*/*; +#X floatatom 343 212 5 0 0; +#X obj 286 247 3dp_draw sphere 5; +#X obj 314 95 pdp_plasma; +#X obj 408 48 loadbang; +#X msg 408 70 dim 512 256; +#X obj 314 65 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 181 144 3dp_windowcontext; +#X obj 181 203 3dp_view roty; +#X floatatom 267 176 5 0 0; +#X obj 31 144 3dp_windowcontext; +#X obj 31 203 3dp_view roty; +#X floatatom 117 176 5 0 0; +#X obj 286 278 3dp_draw cube 2; +#X obj 336 164 pdp_del 3; +#X text 414 164 <- textures can be stored in a delay line; +#X text 133 9 convert pdp image packets to textures and map them on +a sphere and cube. create 2 independent viewing windows.; +#X connect 0 0 9 0; +#X connect 0 0 12 0; +#X connect 1 0 0 0; +#X connect 2 0 4 1; +#X connect 2 0 16 0; +#X connect 3 0 4 2; +#X connect 4 0 15 0; +#X connect 5 0 2 0; +#X connect 6 0 7 0; +#X connect 7 0 5 0; +#X connect 8 0 5 0; +#X connect 9 0 10 0; +#X connect 10 0 4 0; +#X connect 11 0 10 1; +#X connect 12 0 13 0; +#X connect 13 0 4 0; +#X connect 14 0 13 1; +#X connect 16 0 15 1; diff --git a/opengl/doc/examples/example06.pd b/opengl/doc/examples/example06.pd new file mode 100644 index 0000000..8d8595a --- /dev/null +++ b/opengl/doc/examples/example06.pd @@ -0,0 +1,85 @@ +#N canvas 516 361 634 497 10; +#X obj 23 119 metro 40; +#X obj 23 89 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 360 397 pdp_convert texture/*/*; +#X obj 23 387 3dp_mouserotate; +#X obj 155 255 3dp_light 0; +#X obj 23 193 3dp_push; +#X floatatom 269 198 5 0 0; +#X obj 23 161 3dp_windowcontext; +#X obj 360 299 pdp_convert image/grey/*; +#X obj 360 184 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X msg 478 163 random; +#X msg 479 186 rule gameoflife; +#X msg 478 114 rule fire; +#X obj 360 270 pdp_ca; +#X obj 360 371 pdp_motion_phase; +#X floatatom 479 343 5 0 0; +#X obj 478 88 loadbang; +#X msg 479 322 0.33; +#X obj 328 473 3dp_draw sphere 2.6; +#X floatatom 463 434 5 0 0; +#X obj 155 227 3dp_view transz 5; +#X floatatom 480 237 5 0 0; +#X msg 517 322 1; +#X obj 360 347 pdp_gain; +#X floatatom 411 323 5 0 0; +#X msg 478 139 dim 256 128; +#X obj 179 393 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 328 419 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 +1; +#X obj 23 416 3dp_toggle depth_test 0; +#X obj 179 445 3dp_toggle blend_add 1; +#X msg 480 213 1; +#X obj 23 316 3dp_mode texture; +#X floatatom 281 310 5 0 0; +#X obj 156 339 3dp_view scale 1; +#X floatatom 280 340 5 0 0; +#X obj 156 366 3dp_view rotz; +#X text 141 197 move light source; +#X text 143 294 transform texture coords; +#X text 31 12 blending with depth test disabled using 3dp_toggle object. +together with a cellular automata texture (you need pdp_scaf for this) +and texture coordinate transformation.; +#X connect 0 0 7 0; +#X connect 0 0 9 0; +#X connect 1 0 0 0; +#X connect 2 0 18 1; +#X connect 3 0 28 0; +#X connect 5 0 31 0; +#X connect 5 1 20 0; +#X connect 6 0 20 1; +#X connect 7 0 5 0; +#X connect 7 1 3 1; +#X connect 8 0 23 0; +#X connect 9 0 13 0; +#X connect 10 0 13 0; +#X connect 11 0 13 0; +#X connect 12 0 13 0; +#X connect 12 0 25 0; +#X connect 13 0 8 0; +#X connect 14 0 2 0; +#X connect 15 0 14 1; +#X connect 16 0 12 0; +#X connect 17 0 15 0; +#X connect 19 0 18 2; +#X connect 20 0 4 0; +#X connect 21 0 13 2; +#X connect 22 0 15 0; +#X connect 23 0 14 0; +#X connect 24 0 23 1; +#X connect 25 0 13 0; +#X connect 25 0 10 0; +#X connect 26 0 28 1; +#X connect 27 0 29 1; +#X connect 28 1 29 0; +#X connect 29 1 18 0; +#X connect 30 0 21 0; +#X connect 31 0 3 0; +#X connect 31 1 33 0; +#X connect 32 0 33 1; +#X connect 33 0 35 0; +#X connect 34 0 35 1; diff --git a/opengl/doc/examples/example07.pd b/opengl/doc/examples/example07.pd new file mode 100644 index 0000000..cd3618c --- /dev/null +++ b/opengl/doc/examples/example07.pd @@ -0,0 +1,25 @@ +#N canvas 400 454 637 428 10; +#X obj 18 131 3dp_windowcontext; +#X obj 18 159 3dp_push; +#X obj 201 70 metro 40; +#X obj 201 42 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 201 99 pdp_v4l; +#X obj 201 131 pdp_convert texture/*/*; +#X floatatom 258 265 5 0 0; +#X obj 18 218 3dp_view scalex 1.33333; +#X obj 18 187 3dp_mouserotate; +#X text 15 10 using a square scaled by an aspect ratio to construct +an an alternative pdp_glx; +#X obj 144 290 3dp_draw square 8; +#X connect 0 0 1 0; +#X connect 0 1 8 1; +#X connect 1 0 8 0; +#X connect 2 0 0 0; +#X connect 2 0 4 0; +#X connect 3 0 2 0; +#X connect 4 0 5 0; +#X connect 5 0 10 1; +#X connect 6 0 10 2; +#X connect 7 0 10 0; +#X connect 8 0 7 0; diff --git a/opengl/doc/examples/example08.pd b/opengl/doc/examples/example08.pd new file mode 100644 index 0000000..a5f7e9d --- /dev/null +++ b/opengl/doc/examples/example08.pd @@ -0,0 +1,94 @@ +#N canvas 96 78 756 667 10; +#X obj 18 131 3dp_windowcontext; +#X obj 18 159 3dp_push; +#X obj 327 80 metro 40; +#X obj 327 52 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 327 224 pdp_v4l; +#X obj 431 463 pdp_convert texture/*/*; +#X floatatom 488 554 5 0 0; +#X obj 18 215 3dp_view scalex 1.33333; +#X obj 18 189 3dp_mouserotate; +#X floatatom 83 308 5 0 0; +#X msg 83 287 10; +#X obj 69 428 3dp_view rotx; +#X obj 69 475 3dp_view roty; +#X obj 69 523 3dp_view rotz; +#X obj 155 398 random 360; +#X obj 155 453 random 360; +#X obj 155 500 random 360; +#X obj 155 371 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 18 366 3dp_push; +#X text 132 305 nb of squares; +#X floatatom 220 369 5 0 0; +#X obj 431 309 pdp_plasma; +#X obj 431 256 loadbang; +#X obj 327 192 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 397 279 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X msg 417 55 200; +#X floatatom 510 364 5 0 0; +#X msg 378 55 40; +#X obj 327 126 spigot; +#X obj 385 106 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 +1; +#X obj 431 395 pdp_gain 0.3; +#X obj 18 333 3dp_for 10; +#X text 21 12 another example of accumulated blending combined with +a 3dp_for object to render multiple randomly rotated squares.; +#X msg 386 186 open /dev/video1; +#X obj 18 246 3dp_blend; +#X text 411 106 switch between video textures and stills; +#X msg 386 160 open /dev/video0; +#X text 87 246 <-- click for more info; +#X msg 431 281 dim 64 64 \, bang; +#X obj 548 228 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 548 256 metro 2000; +#X obj 374 583 3dp_draw square 8; +#X connect 0 0 1 0; +#X connect 0 1 8 1; +#X connect 1 0 8 0; +#X connect 2 0 0 0; +#X connect 2 0 28 0; +#X connect 3 0 2 0; +#X connect 4 0 30 0; +#X connect 5 0 41 1; +#X connect 6 0 41 2; +#X connect 7 0 34 0; +#X connect 8 0 7 0; +#X connect 9 0 31 1; +#X connect 10 0 9 0; +#X connect 11 0 12 0; +#X connect 12 0 13 0; +#X connect 13 0 41 0; +#X connect 14 0 11 1; +#X connect 15 0 12 1; +#X connect 16 0 13 1; +#X connect 17 0 14 0; +#X connect 17 0 15 0; +#X connect 17 0 16 0; +#X connect 18 1 11 0; +#X connect 20 0 14 1; +#X connect 20 0 15 1; +#X connect 20 0 16 1; +#X connect 21 0 30 0; +#X connect 22 0 38 0; +#X connect 23 0 4 0; +#X connect 24 0 21 0; +#X connect 25 0 2 1; +#X connect 26 0 30 1; +#X connect 27 0 2 1; +#X connect 28 0 23 0; +#X connect 29 0 28 1; +#X connect 30 0 5 0; +#X connect 31 0 18 0; +#X connect 31 1 17 0; +#X connect 33 0 4 0; +#X connect 34 0 31 0; +#X connect 36 0 4 0; +#X connect 38 0 21 0; +#X connect 39 0 40 0; +#X connect 40 0 21 0; diff --git a/opengl/doc/examples/example09.pd b/opengl/doc/examples/example09.pd new file mode 100644 index 0000000..3333d3a --- /dev/null +++ b/opengl/doc/examples/example09.pd @@ -0,0 +1,90 @@ +#N canvas 96 78 756 667 10; +#X obj 18 111 3dp_windowcontext; +#X obj 18 139 3dp_push; +#X obj 18 169 3dp_mouserotate; +#X floatatom 141 370 5 0 0; +#X msg 141 349 10; +#X obj 127 490 3dp_view rotx; +#X obj 127 537 3dp_view roty; +#X obj 127 585 3dp_view rotz; +#X obj 213 460 random 360; +#X obj 213 515 random 360; +#X obj 213 562 random 360; +#X obj 213 433 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 76 428 3dp_push; +#X floatatom 278 431 5 0 0; +#X obj 76 395 3dp_for 10; +#X obj 18 226 3dp_blend; +#X text 87 226 <-- click for more info; +#X obj 18 365 3dp_color; +#X floatatom 32 311 5 0 0; +#X floatatom 78 311 5 0 0; +#X floatatom 123 311 5 0 0; +#X floatatom 167 311 5 0 0; +#X obj 415 193 3dp_view transz 5; +#X obj 415 217 3dp_light; +#X obj 18 78 metro 40; +#X obj 18 50 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X floatatom 529 166 5 0 0; +#X obj 32 252 vsl 15 50 0 1 0 1 empty empty empty 0 -8 0 8 -262144 +-1 -1 2200 1; +#X obj 78 251 vsl 15 50 0 1 0 1 empty empty empty 0 -8 0 8 -262144 +-1 -1 2100 1; +#X obj 123 251 vsl 15 50 0 1 0 1 empty empty empty 0 -8 0 8 -262144 +-1 -1 3800 1; +#X obj 169 250 vsl 15 50 0 1 0 1 empty empty empty 0 -8 0 8 -262144 +-1 -1 1100 1; +#X text 209 275 in this blending mode \, alpha is interpreted as a +color gain; +#X floatatom 515 137 5 0 0; +#X floatatom 144 178 5 0 0; +#X obj 127 633 3dp_draw tetra 4; +#X text 14 13 similar to as example08.; +#X obj 415 168 3dp_view roty 5; +#X obj 18 199 3dp_view scale 4; +#X msg 278 406 18; +#X msg 515 112 75; +#X connect 0 0 1 0; +#X connect 0 1 2 1; +#X connect 1 0 2 0; +#X connect 1 1 36 0; +#X connect 2 0 37 0; +#X connect 3 0 14 1; +#X connect 4 0 3 0; +#X connect 5 0 6 0; +#X connect 6 0 7 0; +#X connect 7 0 34 0; +#X connect 8 0 5 1; +#X connect 9 0 6 1; +#X connect 10 0 7 1; +#X connect 11 0 8 0; +#X connect 11 0 9 0; +#X connect 11 0 10 0; +#X connect 12 1 5 0; +#X connect 13 0 8 1; +#X connect 13 0 9 1; +#X connect 13 0 10 1; +#X connect 14 0 12 0; +#X connect 14 1 11 0; +#X connect 15 0 17 0; +#X connect 17 1 14 0; +#X connect 18 0 17 1; +#X connect 19 0 17 2; +#X connect 20 0 17 3; +#X connect 21 0 17 4; +#X connect 22 0 23 0; +#X connect 24 0 0 0; +#X connect 25 0 24 0; +#X connect 26 0 22 1; +#X connect 27 0 18 0; +#X connect 28 0 19 0; +#X connect 29 0 20 0; +#X connect 30 0 21 0; +#X connect 32 0 36 1; +#X connect 33 0 37 1; +#X connect 36 0 22 0; +#X connect 37 0 15 0; +#X connect 38 0 13 0; +#X connect 39 0 32 0; diff --git a/opengl/doc/examples/example10.pd b/opengl/doc/examples/example10.pd new file mode 100644 index 0000000..2216fb3 --- /dev/null +++ b/opengl/doc/examples/example10.pd @@ -0,0 +1,39 @@ +#N canvas 592 340 647 499 10; +#X obj 231 344 pdp_xv; +#X obj 54 72 metro 40; +#X obj 54 47 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 54 140 3dp_push; +#X obj 248 158 3dp_view transz 5; +#X floatatom 362 126 5 0 0; +#X obj 248 182 3dp_light 0; +#X obj 54 169 3dp_mouserotate; +#X obj 54 111 3dp_windowcontext; +#X obj 231 311 pdp_blur; +#X obj 285 291 hsl 128 15 0 1 0 1 empty empty empty -2 -6 0 8 -262144 +-1 -1 8100 1; +#X text 104 7 connect 3dp and basic pdp image processing with 3dp_snap +; +#X text 105 26 3dp_snap defaults to texture packets \, but you can +specify the desired type as a creation argument; +#X obj 107 377 pdp_convert texture/*/*; +#X obj 54 412 3dp_draw cube 10; +#X text 247 233 <- specify packet type and capture area; +#X obj 54 200 3dp_draw cube 2; +#X obj 54 234 3dp_snap image/*/* 320 240; +#X connect 1 0 8 0; +#X connect 2 0 1 0; +#X connect 3 0 7 0; +#X connect 3 1 4 0; +#X connect 4 0 6 0; +#X connect 5 0 4 1; +#X connect 7 0 16 0; +#X connect 8 0 3 0; +#X connect 8 1 7 1; +#X connect 9 0 13 0; +#X connect 9 0 0 0; +#X connect 10 0 9 1; +#X connect 13 0 14 1; +#X connect 16 0 17 0; +#X connect 17 0 14 0; +#X connect 17 1 9 0; diff --git a/opengl/doc/examples/example11.pd b/opengl/doc/examples/example11.pd new file mode 100644 index 0000000..c902408 --- /dev/null +++ b/opengl/doc/examples/example11.pd @@ -0,0 +1,77 @@ +#N canvas 542 122 669 675 10; +#X obj 23 70 metro 40; +#X obj 23 40 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 23 517 3dp_mouserotate; +#X obj 171 520 3dp_light 0; +#X obj 23 444 3dp_push; +#X obj 171 492 3dp_view transz 5; +#X obj 23 112 3dp_windowcontext; +#X obj 205 311 3dp_snap; +#X obj 205 213 3dp_draw clear; +#X obj 23 406 3dp_draw clear; +#X obj 60 347 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 23 157 3dp_subcontext 64 64; +#X obj 23 380 spigot; +#X text 384 210 <- clear it; +#X text 380 309 <- snap to texture; +#X obj 205 261 3dp_view rota 1 1 0; +#X floatatom 333 236 5 0 0; +#X text 69 10 multipass rendering to texture using a subcontext (subwindow) +; +#X text 381 285 <- draw a wireframe sphere; +#X text 383 235 <- rotate around (1 \, 1 \, 0); +#X text 135 406 <- clear the window; +#X obj 205 286 3dp_draw wsphere 3 10 10; +#X obj 323 429 3dp_draw clear; +#X obj 323 405 3dp_view reset; +#X obj 323 507 3dp_draw wdodeca; +#X obj 323 532 3dp_snap; +#X obj 22 613 3dp_draw cube 10; +#X obj 360 348 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 +1; +#X obj 323 381 spigot; +#X text 381 346 <- enable/disable second pass; +#X text 87 345 <- enable/disable third pass; +#X text 443 404 <- reset context; +#X text 442 427 <- clear context; +#X text 442 507 <- draw wire dodecahedron; +#X text 441 532 <- snap to texture; +#X obj 323 483 3dp_view rota 1 1 0; +#X floatatom 451 458 5 0 0; +#X text 501 457 <- rotate around (1 \, 1 \, 0); +#X obj 23 562 3dp_draw cube 2; +#X text 204 142 NOTE: the part you use as a subcontext must be visible +for the texture snap to work.; +#X text 203 91 use the lower left 64x64 part of the window as a subcontext +(right outlet) the left outlet is a new full window context reset to +default.; +#X connect 0 0 6 0; +#X connect 1 0 0 0; +#X connect 2 0 38 0; +#X connect 4 0 2 0; +#X connect 4 1 5 0; +#X connect 5 0 3 0; +#X connect 6 0 11 0; +#X connect 6 1 2 1; +#X connect 7 0 28 0; +#X connect 7 1 38 1; +#X connect 8 0 15 0; +#X connect 9 0 4 0; +#X connect 10 0 12 1; +#X connect 11 0 12 0; +#X connect 11 1 8 0; +#X connect 12 0 9 0; +#X connect 15 0 21 0; +#X connect 16 0 15 4; +#X connect 21 0 7 0; +#X connect 22 0 35 0; +#X connect 23 0 22 0; +#X connect 24 0 25 0; +#X connect 25 1 26 1; +#X connect 27 0 28 1; +#X connect 28 0 23 0; +#X connect 35 0 24 0; +#X connect 36 0 35 4; +#X connect 38 0 26 0; diff --git a/opengl/doc/examples/example12.pd b/opengl/doc/examples/example12.pd new file mode 100644 index 0000000..14f8afd --- /dev/null +++ b/opengl/doc/examples/example12.pd @@ -0,0 +1,90 @@ +#N canvas 529 191 669 751 10; +#X obj 55 68 metro 40; +#X obj 55 38 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 55 515 3dp_mouserotate; +#X obj 184 514 3dp_light 0; +#X obj 55 442 3dp_push; +#X obj 184 486 3dp_view transz 5; +#X obj 55 110 3dp_windowcontext; +#X obj 343 481 3dp_snap; +#X obj 55 404 3dp_draw clear; +#X obj 436 272 3dp_light 0; +#X obj 436 244 3dp_view transxyz 5 5 0; +#X obj 285 226 3dp_push; +#X obj 343 449 3dp_draw sphere 7 10 10; +#X text 69 10 another multipass rendering example; +#X obj 55 576 3dp_draw cube 7; +#X obj 55 155 3dp_subcontext 256 256; +#X obj 285 260 3dp_mouserotate; +#X obj 343 413 3dp_draw icosa 1; +#X obj 285 342 3dp_color; +#X obj 343 387 3dp_view scale 1; +#X floatatom 450 358 5 0 0; +#N canvas 0 0 291 420 coord_to_color 0; +#X obj 97 85 route drag; +#X obj 97 147 *; +#X obj 134 146 *; +#X obj 97 174 +; +#X obj 97 281 sqrt; +#X obj 97 225 - 1; +#X obj 97 249 * -1; +#X obj 97 114 unpack 0 0; +#X obj 98 45 inlet; +#X obj 53 337 outlet; +#X obj 181 332 outlet; +#X obj 116 336 outlet; +#X connect 0 0 7 0; +#X connect 1 0 3 0; +#X connect 2 0 3 1; +#X connect 3 0 5 0; +#X connect 4 0 11 0; +#X connect 5 0 6 0; +#X connect 6 0 4 0; +#X connect 7 0 1 1; +#X connect 7 0 1 0; +#X connect 7 0 9 0; +#X connect 7 1 2 1; +#X connect 7 1 2 0; +#X connect 7 1 10 0; +#X connect 8 0 0 0; +#X restore 304 305 pd coord_to_color; +#X obj 453 337 hsl 128 15 1 3 0 1 empty empty empty -2 -6 0 8 -262144 +-1 -1 7900 1; +#X obj 285 196 3dp_draw clear; +#X obj 92 622 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 55 662 3dp_screenshot /tmp/screenshot.png; +#X msg 227 71 dim 1023 768; +#X connect 0 0 6 0; +#X connect 1 0 0 0; +#X connect 2 0 14 0; +#X connect 4 0 2 0; +#X connect 4 1 5 0; +#X connect 5 0 3 0; +#X connect 6 0 15 0; +#X connect 6 1 2 1; +#X connect 6 1 21 0; +#X connect 6 1 16 1; +#X connect 7 1 12 1; +#X connect 7 1 14 1; +#X connect 8 0 4 0; +#X connect 10 0 9 0; +#X connect 11 0 16 0; +#X connect 11 1 10 0; +#X connect 12 0 7 0; +#X connect 14 0 25 0; +#X connect 15 0 8 0; +#X connect 15 1 23 0; +#X connect 16 0 18 0; +#X connect 17 0 12 0; +#X connect 18 1 19 0; +#X connect 19 0 17 0; +#X connect 20 0 19 1; +#X connect 21 0 18 1; +#X connect 21 1 18 2; +#X connect 21 2 18 3; +#X connect 22 0 20 0; +#X connect 23 0 11 0; +#X connect 24 0 25 0; +#X connect 26 0 6 0; diff --git a/opengl/doc/examples/example13.pd b/opengl/doc/examples/example13.pd new file mode 100644 index 0000000..a8c5f75 --- /dev/null +++ b/opengl/doc/examples/example13.pd @@ -0,0 +1,81 @@ +#N canvas 478 168 669 751 10; +#X obj 55 68 metro 40; +#X obj 55 38 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 55 110 3dp_windowcontext; +#X obj 262 479 3dp_snap; +#X obj 355 270 3dp_light 0; +#X obj 355 242 3dp_view transxyz 5 5 0; +#X obj 204 224 3dp_push; +#X obj 262 447 3dp_draw sphere 7 10 10; +#X obj 204 258 3dp_mouserotate; +#X obj 262 411 3dp_draw icosa 1; +#X obj 204 340 3dp_color; +#X obj 262 385 3dp_view scale 1; +#X floatatom 369 356 5 0 0; +#N canvas 0 0 291 420 coord_to_color 0; +#X obj 97 85 route drag; +#X obj 97 147 *; +#X obj 134 146 *; +#X obj 97 174 +; +#X obj 97 281 sqrt; +#X obj 97 225 - 1; +#X obj 97 249 * -1; +#X obj 97 114 unpack 0 0; +#X obj 98 45 inlet; +#X obj 53 337 outlet; +#X obj 181 332 outlet; +#X obj 116 336 outlet; +#X connect 0 0 7 0; +#X connect 1 0 3 0; +#X connect 2 0 3 1; +#X connect 3 0 5 0; +#X connect 4 0 11 0; +#X connect 5 0 6 0; +#X connect 6 0 4 0; +#X connect 7 0 1 1; +#X connect 7 0 1 0; +#X connect 7 0 9 0; +#X connect 7 1 2 1; +#X connect 7 1 2 0; +#X connect 7 1 10 0; +#X connect 8 0 0 0; +#X restore 223 303 pd coord_to_color; +#X obj 372 335 hsl 128 15 1 3 0 1 empty empty empty -2 -6 0 8 -262144 +-1 -1 7900 1; +#X obj 204 194 3dp_draw clear; +#X text 209 658 <- stretch the texture to cover the entire window (click +for info); +#X text 119 13 fixed resolution processing (independent of the display +window size) using multipass rendering; +#X floatatom 210 631 5 0 0; +#X obj 55 658 3dp_display_texture; +#X text 338 480 <- snap the result to a texture; +#X text 228 154 <- create a subcontext to do some drawing; +#X text 402 76 see also; +#X obj 405 97 3dp_fixedsizewindowcontext 64 64; +#X obj 55 155 3dp_subcontext 320 240; +#X connect 0 0 2 0; +#X connect 1 0 0 0; +#X connect 2 0 24 0; +#X connect 2 1 13 0; +#X connect 2 1 8 1; +#X connect 3 1 7 1; +#X connect 3 1 19 1; +#X connect 5 0 4 0; +#X connect 6 0 8 0; +#X connect 6 1 5 0; +#X connect 7 0 3 0; +#X connect 8 0 10 0; +#X connect 9 0 7 0; +#X connect 10 1 11 0; +#X connect 11 0 9 0; +#X connect 12 0 11 1; +#X connect 13 0 10 1; +#X connect 13 1 10 2; +#X connect 13 2 10 3; +#X connect 14 0 12 0; +#X connect 15 0 6 0; +#X connect 18 0 19 2; +#X connect 24 0 19 0; +#X connect 24 1 15 0; diff --git a/opengl/doc/examples/example14.pd b/opengl/doc/examples/example14.pd new file mode 100644 index 0000000..fa0cabb --- /dev/null +++ b/opengl/doc/examples/example14.pd @@ -0,0 +1,66 @@ +#N canvas 586 145 669 674 10; +#X obj 67 71 3dp_windowcontext; +#X obj 67 46 metro 40; +#X obj 67 23 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X obj 67 155 3dp_blend; +#X obj 176 423 3dp_view transxyz; +#X msg 226 296 reset; +#X obj 197 374 *; +#X obj 304 375 *; +#X floatatom 320 347 5 0 0; +#X obj 274 154 vsl 15 30 0 1 0 1 empty empty empty 0 -8 0 8 -262144 +-1 -1 700 1; +#X obj 316 154 vsl 15 30 0 1 0 1 empty empty empty 0 -8 0 8 -262144 +-1 -1 1100 1; +#X obj 295 154 vsl 15 30 0 1 0 1 empty empty empty 0 -8 0 8 -262144 +-1 -1 1200 1; +#X obj 337 154 vsl 15 30 0 1 0 1 empty empty empty 0 -8 0 8 -262144 +-1 -1 400 1; +#X obj 125 253 3dp_push; +#X obj 67 95 3dp_mouserotate; +#X obj 67 124 3dp_view scale 1; +#X floatatom 206 99 5 0 0; +#X obj 209 79 hsl 128 15 0.2 5 1 1 empty empty empty -2 -6 0 8 -262144 +-1 -1 7000 1; +#X obj 323 326 hsl 128 15 0.1 2 1 1 empty empty empty -2 -6 0 8 -262144 +-1 -1 2100 1; +#X obj 67 187 3dp_color; +#X obj 226 223 route press3; +#X text 329 223 <- right click mouse to reset; +#X text 211 253 <- remove 3dp_push object to accumulate the translations +; +#X obj 197 326 randomwalk2D 100; +#X obj 125 224 3dp_for 100; +#X text 287 130 R G B I; +#X obj 176 460 3dp_draw cube 1; +#X text 227 13 using 3dp_for and the randomwalk2D abstraction to create +random walking blended cubes.; +#X connect 0 0 14 0; +#X connect 0 1 14 1; +#X connect 0 1 20 0; +#X connect 1 0 0 0; +#X connect 2 0 1 0; +#X connect 3 0 19 0; +#X connect 4 0 26 0; +#X connect 5 0 23 0; +#X connect 6 0 4 1; +#X connect 7 0 4 2; +#X connect 8 0 7 1; +#X connect 8 0 6 1; +#X connect 9 0 19 1; +#X connect 10 0 19 3; +#X connect 11 0 19 2; +#X connect 12 0 19 4; +#X connect 13 1 4 0; +#X connect 14 0 15 0; +#X connect 15 0 3 0; +#X connect 16 0 15 1; +#X connect 17 0 16 0; +#X connect 18 0 8 0; +#X connect 19 1 24 0; +#X connect 20 0 5 0; +#X connect 23 0 6 0; +#X connect 23 1 7 0; +#X connect 24 0 13 0; +#X connect 24 1 23 0; diff --git a/opengl/doc/examples/example15.pd b/opengl/doc/examples/example15.pd new file mode 100644 index 0000000..281c91a --- /dev/null +++ b/opengl/doc/examples/example15.pd @@ -0,0 +1,126 @@ +#N canvas 269 234 933 697 10; +#X obj 67 46 metro 40; +#X obj 67 23 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 67 224 3dp_blend; +#X obj 176 673 3dp_view transxyz; +#X msg 260 342 reset; +#X obj 197 497 *; +#X obj 304 498 *; +#X obj 272 218 vsl 15 30 0 1 0 1 empty empty empty 0 -8 0 8 -262144 +-1 -1 1000 1; +#X obj 314 218 vsl 15 30 0 1 0 1 empty empty empty 0 -8 0 8 -262144 +-1 -1 0 1; +#X obj 293 218 vsl 15 30 0 1 0 1 empty empty empty 0 -8 0 8 -262144 +-1 -1 100 1; +#X obj 335 218 vsl 15 30 0 1 0 1 empty empty empty 0 -8 0 8 -262144 +-1 -1 200 1; +#X obj 125 304 3dp_push; +#X obj 67 119 3dp_mouserotate; +#X obj 67 176 3dp_view scale 1; +#X floatatom 241 145 5 0 0 0 - - -; +#X obj 244 125 hsl 128 15 0.2 5 1 1 empty empty empty -2 -6 0 8 -262144 +-1 -1 3800 1; +#X obj 523 456 hsl 128 15 0.01 2 1 1 empty empty empty -2 -6 0 8 -262144 +-1 -1 7900 1; +#X obj 67 251 3dp_color; +#X obj 402 231 route press3; +#X text 211 304 <- remove 3dp_push object to accumulate the translations +; +#X obj 197 392 randomwalk2D 100; +#X obj 125 275 3dp_for 100; +#X text 285 185 R G B I; +#X obj 197 533 smoothupdate 100; +#X obj 304 567 smoothupdate 100; +#X obj 524 490 hsl 128 15 0.01 1 1 1 empty empty empty -2 -6 0 8 -262144 +-1 -1 1300 1; +#X obj 67 93 3dp_push; +#X obj 476 111 3dp_view transz 5; +#X obj 476 171 3dp_light; +#X obj 219 351 s i; +#X obj 250 511 r i; +#X obj 357 543 r i; +#X obj 419 716 smoothupdate 100; +#X obj 472 692 r i; +#X obj 197 325 t f f b; +#X obj 419 639 random 100; +#X obj 419 662 - 50; +#X obj 529 675 hsl 128 15 0.01 1 1 1 empty empty empty -2 -6 0 8 -262144 +-1 -1 600 1; +#X obj 419 688 / 10; +#X msg 418 424 reset; +#X obj 148 201 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 67 200 pdp_route; +#X obj 176 765 3dp_draw torus 1 2 5 5; +#X obj 176 709 pdp_route; +#X obj 265 711 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 194 741 3dp_draw cube 2; +#X text 315 344 <- reset random walk; +#X text 532 554 <- reset smoothed points to origin; +#X text 227 13 like example14 but with coordinate smoothing and lighting +; +#X text 505 246 <- route mouse buttons; +#X obj 481 265 route press2; +#X text 666 453 <- walk radius; +#X text 667 488 <- walk smoothing; +#X obj 67 70 3dp_fixedsizewindowcontext 320 240; +#X floatatom 199 250 5 0 0 0 - - -; +#X connect 0 0 53 0; +#X connect 1 0 0 0; +#X connect 2 0 17 0; +#X connect 3 0 43 0; +#X connect 4 0 20 0; +#X connect 5 0 23 0; +#X connect 6 0 24 0; +#X connect 7 0 17 1; +#X connect 8 0 17 3; +#X connect 9 0 17 2; +#X connect 10 0 17 4; +#X connect 11 1 3 0; +#X connect 12 0 13 0; +#X connect 13 0 41 0; +#X connect 14 0 13 1; +#X connect 15 0 14 0; +#X connect 16 0 6 1; +#X connect 16 0 5 1; +#X connect 17 1 21 0; +#X connect 18 0 4 0; +#X connect 18 1 50 0; +#X connect 20 0 5 0; +#X connect 20 1 6 0; +#X connect 21 0 11 0; +#X connect 21 1 34 0; +#X connect 23 0 3 1; +#X connect 24 0 3 2; +#X connect 25 0 23 2; +#X connect 25 0 24 2; +#X connect 26 0 12 0; +#X connect 26 1 27 0; +#X connect 27 0 28 0; +#X connect 30 0 23 1; +#X connect 31 0 24 1; +#X connect 32 0 3 3; +#X connect 33 0 32 1; +#X connect 34 0 20 0; +#X connect 34 1 29 0; +#X connect 34 2 35 0; +#X connect 35 0 36 0; +#X connect 36 0 38 0; +#X connect 37 0 32 2; +#X connect 38 0 32 0; +#X connect 39 0 23 0; +#X connect 39 0 24 0; +#X connect 39 0 32 0; +#X connect 40 0 41 1; +#X connect 41 0 2 0; +#X connect 41 1 17 0; +#X connect 43 0 42 0; +#X connect 43 1 45 0; +#X connect 44 0 43 1; +#X connect 50 0 39 0; +#X connect 53 0 26 0; +#X connect 53 1 12 1; +#X connect 53 1 18 0; +#X connect 54 0 21 1; diff --git a/opengl/doc/examples/example16.pd b/opengl/doc/examples/example16.pd new file mode 100644 index 0000000..e9495aa --- /dev/null +++ b/opengl/doc/examples/example16.pd @@ -0,0 +1,107 @@ +#N canvas 196 0 772 525 10; +#X obj 57 25 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 57 153 3dp_blend; +#X floatatom 101 237 5 0 0 0 - - -; +#X floatatom 149 237 5 0 0 0 - - -; +#X floatatom 199 236 5 0 0 0 - - -; +#X floatatom 247 236 5 0 0 0 - - -; +#X obj 167 364 3dp_push; +#X obj 218 434 3dp_view transxyz; +#X msg 276 354 normal; +#X obj 422 255 f; +#X floatatom 484 264 5 0 0 0 - - -; +#X msg 422 220 0; +#X obj 57 177 pdp_t p b; +#X obj 392 185 t b b; +#X msg 591 238 0.2; +#X msg 484 239 0; +#X obj 57 72 3dp_windowcontext; +#X obj 392 112 route press3; +#X obj 57 49 metro 40; +#X obj 167 328 3dp_for 100; +#X obj 227 125 3dp_view transz 5; +#X obj 227 159 3dp_light; +#X obj 57 96 3dp_push; +#X obj 422 289 + 0.2; +#X obj 497 112 loadbang; +#X msg 519 238 0.01; +#N canvas 0 0 577 190 coordinates 0; +#X obj 51 100 *; +#X obj 51 72 elbat 100; +#X obj 165 99 *; +#X obj 165 71 elbat 100; +#X obj 276 97 *; +#X obj 276 69 elbat 100; +#X obj 51 19 inlet; +#X obj 125 18 inlet; +#X text 354 69 <- table read abstraction; +#X obj 51 130 outlet; +#X obj 165 127 outlet; +#X obj 276 125 outlet; +#X connect 0 0 9 0; +#X connect 1 0 0 0; +#X connect 2 0 10 0; +#X connect 3 0 2 0; +#X connect 4 0 11 0; +#X connect 5 0 4 0; +#X connect 6 0 1 0; +#X connect 6 0 3 0; +#X connect 6 0 5 0; +#X connect 7 0 0 1; +#X connect 7 0 2 1; +#X connect 7 0 4 1; +#X restore 239 403 pd coordinates; +#X msg 392 136 bang; +#X text 459 219 <- reset scaling to 0 (infinite density); +#X text 469 290 <- increment scaling for each new frame; +#X text 340 354 <- compute a new normal distributed set of points; +#X text 506 371 (velocity vectors); +#X text 545 264 <- diffusion speed; +#X msg 559 238 0.1; +#X text 182 12 explosion using 100 spheres with normal distributed +velocity vectors; +#X floatatom 367 441 5 0 0 0 - - -; +#X obj 57 125 3dp_mouserotate; +#X obj 57 278 3dp_color 0.1 0.1 0.1 0.27; +#X obj 218 478 3dp_draw sphere 1 8 8; +#X connect 0 0 18 0; +#X connect 1 0 12 0; +#X connect 2 0 37 1; +#X connect 3 0 37 2; +#X connect 4 0 37 3; +#X connect 5 0 37 4; +#X connect 6 1 7 0; +#X connect 7 0 38 0; +#X connect 8 0 26 0; +#X connect 9 0 23 0; +#X connect 10 0 23 1; +#X connect 11 0 9 0; +#X connect 12 0 37 0; +#X connect 12 1 9 0; +#X connect 13 0 8 0; +#X connect 13 1 11 0; +#X connect 14 0 10 0; +#X connect 15 0 10 0; +#X connect 16 0 22 0; +#X connect 16 1 17 0; +#X connect 16 1 36 1; +#X connect 17 0 27 0; +#X connect 18 0 16 0; +#X connect 19 0 6 0; +#X connect 19 1 26 0; +#X connect 20 0 21 0; +#X connect 22 0 36 0; +#X connect 22 1 20 0; +#X connect 23 0 9 1; +#X connect 23 0 26 1; +#X connect 24 0 13 0; +#X connect 25 0 10 0; +#X connect 26 0 7 1; +#X connect 26 1 7 2; +#X connect 26 2 7 3; +#X connect 27 0 13 0; +#X connect 33 0 10 0; +#X connect 35 0 38 2; +#X connect 36 0 1 0; +#X connect 37 1 19 0; diff --git a/opengl/doc/objects/3dp_for.pd b/opengl/doc/objects/3dp_for.pd new file mode 100644 index 0000000..ccaf22d --- /dev/null +++ b/opengl/doc/objects/3dp_for.pd @@ -0,0 +1,91 @@ +#N canvas 545 167 607 718 10; +#X obj 22 40 3dp_windowcontext; +#X obj 22 15 metro 40; +#X obj 22 -5 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 22 67 3dp_push; +#X obj 180 126 3dp_light; +#X floatatom 301 85 5 0 0 0 - - -; +#X obj 22 97 3dp_mouserotate; +#X floatatom 151 228 5 0 0 0 - - -; +#X obj 180 104 3dp_view transz 10; +#X floatatom 81 165 5 0 0 0 - - -; +#X obj 23 191 3dp_for 3; +#X obj 23 251 3dp_view transx 1.5; +#X floatatom 130 280 5 0 0 0 - - -; +#X obj 23 302 3dp_view roty 45; +#X obj 23 389 3dp_draw sphere 1; +#X obj 81 365 + 1; +#X obj 81 343 *; +#X floatatom 129 327 5 0 0 0 - - -; +#X text 135 159 3dp_for sends a rendering context trough a chain multiple +times. the second outlet is the current number \, starting from zero +\, and can be used to change the parameters parameters of the chain. +(i.e. by reading from a table); +#X text 222 252 all the geometry operations are accumulative \,; +#X text 222 266 if you don't want that \, insert a 3dp_push object: +; +#X obj 314 313 3dp_for 3; +#X obj 314 336 3dp_push; +#X obj 365 400 3dp_draw cube 0.5; +#X obj 23 140 3dp_push; +#X obj 365 374 3dp_view transy; +#X obj 465 343 * 1; +#X floatatom 481 319 5 0 0 0 - - -; +#X obj 86 569 pdp_t p p p; +#X obj 86 606 3dp_view transy 1; +#X obj 86 630 3dp_draw cube 0.5; +#X obj 177 465 3dp_for 3; +#X text 72 492 so \, in short \,; +#X text 313 492 is equivalent to; +#X obj 177 491 3dp_view transy 1; +#X obj 177 515 3dp_draw cube 0.5; +#X obj 354 539 3dp_view transy 1; +#X obj 354 563 3dp_draw cube 0.5; +#X obj 354 589 3dp_view transy 1; +#X obj 354 613 3dp_draw cube 0.5; +#X obj 354 638 3dp_view transy 1; +#X obj 354 662 3dp_draw cube 0.5; +#X text 256 596 and; +#X obj 180 84 3dp_view roty; +#X floatatom 266 66 5 0 0 0 - - -; +#X connect 0 0 3 0; +#X connect 0 1 6 1; +#X connect 1 0 0 0; +#X connect 2 0 1 0; +#X connect 3 0 6 0; +#X connect 3 1 43 0; +#X connect 5 0 8 1; +#X connect 6 0 24 0; +#X connect 7 0 11 1; +#X connect 8 0 4 0; +#X connect 9 0 10 1; +#X connect 10 0 11 0; +#X connect 10 1 16 0; +#X connect 11 0 13 0; +#X connect 12 0 13 1; +#X connect 13 0 14 0; +#X connect 15 0 14 2; +#X connect 16 0 15 0; +#X connect 17 0 16 1; +#X connect 21 0 22 0; +#X connect 21 1 26 0; +#X connect 22 1 25 0; +#X connect 24 0 10 0; +#X connect 24 1 21 0; +#X connect 25 0 23 0; +#X connect 26 0 25 1; +#X connect 27 0 26 1; +#X connect 28 0 29 0; +#X connect 28 1 29 0; +#X connect 28 2 29 0; +#X connect 29 0 30 0; +#X connect 31 0 34 0; +#X connect 34 0 35 0; +#X connect 36 0 37 0; +#X connect 37 0 38 0; +#X connect 38 0 39 0; +#X connect 39 0 40 0; +#X connect 40 0 41 0; +#X connect 43 0 8 0; +#X connect 44 0 43 1; diff --git a/opengl/include/Makefile b/opengl/include/Makefile new file mode 100644 index 0000000..f2075ee --- /dev/null +++ b/opengl/include/Makefile @@ -0,0 +1,5 @@ +all: + +clean: + rm -rf *~ + diff --git a/opengl/include/pdp_3Dcontext.h b/opengl/include/pdp_3Dcontext.h new file mode 100644 index 0000000..adef304 --- /dev/null +++ b/opengl/include/pdp_3Dcontext.h @@ -0,0 +1,94 @@ +/* + * pdp system module - 3d render context packet type + * 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. + * + */ + + +/* the 3d render context packet: platform independent data structure + and method prototypes */ + + +#ifndef PDP_3DCONTEXT_H +#define PDP_3DCONTEXT_H + +#include "pdp.h" + + + + +typedef struct _3dcontext +{ + u32 encoding; /* the kind of render context */ + u32 width; /* context width */ + u32 height; /* context height */ + u32 sub_width; /* portion that is currently used */ + u32 sub_height; + void *drawable; /* context's drawable (i.e. Window, GLXPbuffer, ...) */ + void *context; /* context's context object */ + +} t_3Dcontext; + +#define PDP_3DCONTEXT 5 /* 3d context packet id */ +#define PDP_3DCONTEXT_WINDOW 1 /* window context packet id */ +#define PDP_3DCONTEXT_PBUFFER 2 /* pbuf context packet id */ + +/* all symbols are C-style */ +#ifdef __cplusplus +extern "C" +{ +#endif + + /* info methods */ + u32 pdp_packet_3Dcontext_width(int packet); + u32 pdp_packet_3Dcontext_subwidth(int packet); + u32 pdp_packet_3Dcontext_height(int packet); + u32 pdp_packet_3Dcontext_subheight(int packet); + float pdp_packet_3Dcontext_subaspect(int packet); + int pdp_packet_3Dcontext_isvalid(int packet); + t_3Dcontext *pdp_packet_3Dcontext_info(int packet); + + + /* setters */ + void pdp_packet_3Dcontext_set_subwidth(int packet, u32 w); + void pdp_packet_3Dcontext_set_subheight(int packet, u32 h); + + + /* render context activation and initialization */ + void pdp_packet_3Dcontext_set_rendering_context(int packet); + void pdp_packet_3Dcontext_unset_rendering_context(int packet); + void pdp_packet_3Dcontext_setup_3d_context(int p); + void pdp_packet_3Dcontext_setup_2d_context(int p); + + /* constructors */ + int pdp_packet_new_3Dcontext_pbuf(u32 width, u32 height, u32 depth); + int pdp_packet_new_3Dcontext_win(void); + + /* window specific methods */ + void pdp_packet_3Dcontext_win_resize(int packet, int width, int height); + t_pdp_list *pdp_packet_3Dcontext_win_get_eventlist(int packet); + void pdp_packet_3Dcontext_win_cursor(int packet, bool toggle); + void pdp_packet_3Dcontext_win_swapbuffers(int packet); + + /* converters */ + int pdp_packet_3Dcontext_snap_to_bitmap(int packet, int w, int h); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/opengl/include/pdp_3dp_base.h b/opengl/include/pdp_3dp_base.h new file mode 100644 index 0000000..16d5013 --- /dev/null +++ b/opengl/include/pdp_3dp_base.h @@ -0,0 +1,36 @@ +#include "pdp_opengl.h" +#include "pdp_dpd_base.h" + + +typedef struct _pdp_3dp_base +{ + t_pdp_dpd_base b_base; + +} t_pdp_3dp_base; + +/* destructor */ +void pdp_3dp_base_free(void *x); + +/* init method */ +void pdp_3dp_base_init(void *x); + +/* class setup method */ +void pdp_3dp_base_setup(t_class *class); + + +/* base class methods */ +#define pdp_3dp_base_get_context_packet pdp_dpd_base_get_context_packet +#define pdp_3dp_base_set_context_packet pdp_dpd_base_set_context_packet +#define pdp_3dp_base_add_outlet pdp_dpd_base_add_outlet +#define pdp_3dp_base_add_cleanup pdp_dpd_base_add_cleanup +#define pdp_3dp_base_add_inspect pdp_dpd_base_add_inspect +#define pdp_3dp_base_disable_active_inlet pdp_dpd_base_disable_active_inlet +#define pdp_3dp_base_move_context_packet pdp_dpd_base_move_context_packet +#define pdp_3dp_base_bang pdp_dpd_base_bang +#define pdp_3dp_base_get_queue pdp_dpd_base_get_queue +#define pdp_3dp_base_enable_outlet pdp_dpd_base_enable_outlet +#define pdp_3dp_base_register_complete_notify pdp_dpd_base_register_complete_notify +#define pdp_3dp_base_register_get_command_object pdp_dpd_base_register_get_command_object +#define pdp_3dp_base_queue_wait pdp_dpd_base_queue_wait +#define pdp_3dp_base_queue_command pdp_dpd_base_queue_command + diff --git a/opengl/include/pdp_mesh.h b/opengl/include/pdp_mesh.h new file mode 100644 index 0000000..8fd6dff --- /dev/null +++ b/opengl/include/pdp_mesh.h @@ -0,0 +1,210 @@ +/* + * Pure Data Packet module. mesh object specification + * 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 */ + +#ifndef PDP_MESH_H +#define PDP_MESH_H +#include "pdp_list.h" + + +/* VERTEX type + a vertex has a coordinate and normal vector + a list of triangles it is connected to + and a list of vertexes it is connected to (these count as links) */ + +typedef struct _vertex +{ + float c[3]; // coordinates + float n[3]; // normal (or force vector) + t_pdp_list *trilist; + t_pdp_list *vertlist; +} t_vertex; + + +/* TRIANGLE type: + a triangle consist of + - 3 vertices + - 3 optional median vertices (subdivision intermediates) */ +typedef struct _triangle +{ + t_vertex *v[3]; // vertices + t_vertex *m[3]; // median vertices + float n[3]; //triangle normal +} t_triangle; + + +/* MESH type: + a mesh is a list of vertices + and a list of triangles (connections) */ +typedef struct _mesh +{ + t_pdp_list *triangles; + t_pdp_list *vertices; + int normal_type; + int refine_type; +} t_mesh; + + + +/* object configuratie */ +#define MESH_NORMAL_SPHERE 1 // normal = origin -> vertex +#define MESH_NORMAL_PRISM 2 // normal = center of gravity of prism base -> vertex +#define MESH_NORMAL_RANDOM 3 // normal = random vector +#define MESH_NORMAL_AVERAGE 4 // normal = average of surrounding triangles + +/* refinement method */ +#define MESH_REFINE_THREE 1 // triangle -> 3 triangles connecting center of gravity +#define MESH_REFINE_FOUR 2 // triangle -> 4 triangles connecting link medians + +// vector utility stuff + +// fixed size iterators for the lazy +#define I3(i) for(i=0; i<3; i++) +#define I4(i) for(i=0; i<4; i++) + +static inline float _vector3_dot(float *v0, float *v1) +{ + float d; + d = v0[0] * v1[0]; + d += v0[1] * v1[1]; + d += v0[2] * v1[2]; + return d; +} + +static inline void _vector3_scale(float *v, float s) +{ + int k; + I3(k) v[k] *= s; +} + +static inline float _vector3_normalize(float *v) +{ + float length = 0; + float scale = 0; + int k; + length = sqrt(_vector3_dot(v,v)); + scale = 1.0f / length; + _vector3_scale(v, scale); + return length; +} + +static inline void _vector3_cross(float *a, float *b, float *r) +{ + r[0] = a[1]*b[2] - a[2]*b[1]; + r[1] = a[2]*b[0] - a[0]*b[2]; + r[2] = a[0]*b[1] - a[1]*b[0]; +} + +static inline float _rand(void) +{ + long int r = random(); + float f; + r -= (RAND_MAX >> 1); + f = (float)r; + f *= (2.0f / (float)RAND_MAX); + return f; +} + + + + +/* VERTEX methods */ +void vertex_add_triangle(t_vertex *v, t_triangle *t); +void vertex_remove_triangle(t_vertex *v, t_triangle *t); +void vertex_add_neighbour(t_vertex *v, t_vertex *neighbour); + + +/* constructor/destructors are "private" + they may only be called by the mesh object to ensure + the vector list stays sound (i.e. without duplicates) */ +void _vertex_free(t_vertex *v); +t_vertex *_vertex_new(float *c, float *n); + + +void vertex_compute_normal_random(t_vertex *v); +void vertex_compute_normal_sphere(t_vertex *v); +void vertex_compute_normal_prism(t_vertex *v); +float vertex_normalize(t_vertex *v); + + +/* TRIANGLE methods */ + +/* create triangle (a connection between 3 vertices): + counterclockwize with facing front + this method is "private" + you can only create triangles as part of a mesh */ +t_triangle *_triangle_new(t_vertex *v0, t_vertex *v1, t_vertex *v2); + +/* delete a triangle, disconnecting the vertices */ +void _triangle_free(t_triangle *t); + +/* get triangle that shares the link between v0 and v1 */ +t_triangle *triangle_neighbour(t_triangle *t, t_vertex *v0, t_vertex *v1); + +/* add a median vector to a link in a triangle + note: vertices must be in triangle, or behaviour is undefined */ +void triangle_add_median(t_triangle *t, t_vertex *v0, t_vertex *v1, t_vertex *median); + +/* MESH methods */ + +/* add and remove methods for vertices and triangles */ +t_vertex *mesh_vertex_add(t_mesh *m, float *c, float *n); +void mesh_vertex_remove(t_mesh *m, t_vertex *v); +t_triangle *mesh_triangle_add(t_mesh *m, t_vertex *v0, t_vertex *v1, t_vertex *v2); +void mesh_triangle_remove(t_mesh *m, t_triangle *t); + +/* calculate normals */ +void mesh_calculate_normals(t_mesh *m); + +/* split a triangle in 4, using the intermedia median vertex storage */ +void mesh_split_four(t_mesh *m, t_triangle *old_t); + +/* split a triangle in 3 */ +void mesh_split_three(t_mesh *m, t_triangle *old_t); + +void mesh_split_all_four(t_mesh *m); + +void mesh_split_all_three(t_mesh *m); + +void mesh_split_random_three(t_mesh *m); + +void mesh_free(t_mesh *m); + +t_mesh *_mesh_new(void); + +/* new tetra */ +t_mesh *mesh_new_tetra(void); + + + +void _mesh_relax_compute_resultant_spring(t_mesh *m, float *center, float d0, float r0); +void _mesh_relax_apply_force(t_mesh *m, float k); +void mesh_compute_center(t_mesh *m, float *c); +void mesh_translate(t_mesh *m, float *c); + +/* relax a mesh (move toward equal link length) */ +void mesh_relax(t_mesh *m, float step, float d0, float r0); + +/* print some debug information */ +void mesh_debug(t_mesh *m); + + +#endif diff --git a/opengl/include/pdp_opengl.h b/opengl/include/pdp_opengl.h new file mode 100644 index 0000000..c32735d --- /dev/null +++ b/opengl/include/pdp_opengl.h @@ -0,0 +1,33 @@ +/* + * OpenGL Extension Module for pdp - Main header file + * 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. + * + */ + +#ifndef PDP_OPENGL_H +#define PDP_OPENGL_H + + + +#include "pdp.h" +#include "pdp_texture.h" +#include "pdp_3Dcontext.h" + +t_pdp_procqueue* pdp_opengl_get_queue(void); + + +#endif diff --git a/opengl/include/pdp_texture.h b/opengl/include/pdp_texture.h new file mode 100644 index 0000000..7a40cdd --- /dev/null +++ b/opengl/include/pdp_texture.h @@ -0,0 +1,93 @@ +/* + * pdp system module - texture packet type + * 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. + * + */ + +#ifndef PDP_TEXTURE_H +#define PDP_TEXTURE_H + +//#include <GL/gl.h> +//#include <GL/glu.h> +//#include <GL/glx.h> +//#include <GL/glut.h> +#include "pdp.h" + + + + + +/* TEXTURE PACKET */ + +typedef struct +{ + u32 tex_obj; /* gl texture object */ + s32 format; /* texture format */ + u32 width; /* dims */ + u32 height; + + u32 sub_width; /* portion of texture used */ + u32 sub_height; + +} t_texture; + +#define PDP_TEXTURE 4 /* opengl texture object */ + + +/* all symbols are C-style */ +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* check if valid texture packet. all other methods assume packet is valid */ +bool pdp_packet_texture_isvalid(int packet); + +/* returns a pointer to the packet subheader whem the packet contains a texture */ +/* try not to use the header directly, use clone and copy methods instead */ +t_texture *pdp_packet_texture_info(int packet); + +/* texture constructors */ +int pdp_packet_new_texture(u32 width, u32 height, s32 format); /* create a texture packet */ + + +/* texture operators */ +void pdp_packet_texture_make_current(int packet); /* make a texture the current texture context */ +u32 pdp_packet_texture_total_width(int packet); /* width of texture */ +u32 pdp_packet_texture_total_height(int packet); /* get heigth of texture */ +u32 pdp_packet_texture_sub_width(int packet); /* width of subtexture */ +u32 pdp_packet_texture_sub_height(int packet); /* heigth of subtexture */ +float pdp_packet_texture_fracx(int packet); /* x fraction */ +float pdp_packet_texture_fracy(int packet); /* y fraction */ +float pdp_packet_texture_sub_aspect(int packet); + +/* some utility methods */ +void pdp_packet_texture_make_current_enable(int packet); /* make current & enable with default texture settings (for the lazy)*/ +void pdp_packet_texture_setup_2d_context(int packet); /* set up 2d context (viewport, projection, modelview) from texture dims */ + + + + + + + +#ifdef __cplusplus +} +#endif + +#endif //PDP_TEXTURE_H 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 diff --git a/opengl/system/Makefile b/opengl/system/Makefile new file mode 100644 index 0000000..0a31482 --- /dev/null +++ b/opengl/system/Makefile @@ -0,0 +1,8 @@ +include ../Makefile.config + +all: pdp_texture.o pdp_3Dcontext_glx.o pdp_3Dcontext_common.o \ + pdp_opengl.o pdp_3dp_base.o pdp_mesh.o setup.o + +clean: + rm -rf *~ *.o + diff --git a/opengl/system/pdp_3Dcontext_common.c b/opengl/system/pdp_3Dcontext_common.c new file mode 100644 index 0000000..185e2be --- /dev/null +++ b/opengl/system/pdp_3Dcontext_common.c @@ -0,0 +1,267 @@ + +/* + * OpenGL Extension Module for pdp - pbuffer 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 code uses glx. i don't know if it is worth to take into + account portabiliy. since it will take a while until pdp runs + on anything else than linux. but in any case, providing a windows/osx + implementation here should not be too difficult.. +*/ + +#include "pdp_3Dcontext.h" +#include <GL/gl.h> +//#include <GL/glx.h> +#include <GL/glu.h> +//#include <GL/glut.h> + +#define D if (0) + +/* constructor */ + +/* pbuf operators */ + +u32 pdp_packet_3Dcontext_width(int packet) +{ + t_3Dcontext *c = pdp_packet_3Dcontext_info(packet); + if (c) return c->width; + else return 0; +} + +u32 pdp_packet_3Dcontext_height(int packet) +{ + t_3Dcontext *c = pdp_packet_3Dcontext_info(packet); + if (c) return c->height; + else return 0; +} + +u32 pdp_packet_3Dcontext_subwidth(int packet) +{ + t_3Dcontext *c = pdp_packet_3Dcontext_info(packet); + if (c) return c->sub_width; + else return 0; +} + + +u32 pdp_packet_3Dcontext_subheight(int packet) +{ + t_3Dcontext *c = pdp_packet_3Dcontext_info(packet); + if (c) return c->sub_height; + else return 0; +} + + +void pdp_packet_3Dcontext_set_subwidth(int packet, u32 w) +{ + t_3Dcontext *c = pdp_packet_3Dcontext_info(packet); + if (c) c->sub_width = w; +} + + +void pdp_packet_3Dcontext_set_subheight(int packet, u32 h) +{ + t_3Dcontext *c = pdp_packet_3Dcontext_info(packet); + if (c) c->sub_height = h; +} + + +float pdp_packet_3Dcontext_subaspect(int packet) +{ + t_3Dcontext *c = pdp_packet_3Dcontext_info(packet); + if (c) return (float)c->sub_width/c->sub_height; + else return 0; +} + +int pdp_packet_3Dcontext_isvalid(int packet) +{ + t_pdp *header = pdp_packet_header(packet); + t_3Dcontext *c = pdp_packet_3Dcontext_info(packet); + + if (!header) return 0; + if (!c) return 0; + if (PDP_3DCONTEXT != header->type) return 0; + return 1; +} + +t_3Dcontext *pdp_packet_3Dcontext_info(int packet) +{ + t_pdp *header = pdp_packet_header(packet); + if (!header) return 0; + if (PDP_3DCONTEXT != header->type) return 0; + return (t_3Dcontext *)&header->info.raw; +} + + + +void pdp_llconv_flip_top_bottom(char *data, int width, int height, int pixelsize); + +int pdp_packet_3Dcontext_snap_to_bitmap(int packet, int w, int h) +{ + int x, y, new_p, i; + char *data = 0; + // char r; + // int extra = 5; + + if (!pdp_packet_3Dcontext_isvalid(packet)) goto error; + + x = pdp_packet_3Dcontext_subwidth(packet); + y = pdp_packet_3Dcontext_subheight(packet); + + x = (x - w) >> 1; + y = (y - h) >> 1; + x = (x < 0 ) ? 0 : x; + y = (y < 0 ) ? 0 : y; + + new_p = pdp_packet_new_bitmap_rgb(w, h); + data = (char *)pdp_packet_data(new_p); + if (-1 == new_p || !data) goto error; + pdp_packet_3Dcontext_set_rendering_context(packet); + + // D post("BEGIN READPIXELS %d %d %d %d %x", w, h, x, y, data); + + //for (i=0; i<w*h; i++){ + // data[3*i] = 255; + // data[3*i+1] = 255; + // data[3*i+2] = 0; + //} + // r = random(); + // data[w*h*3] = r; + + /* seems nvidia drivers 4191 have a bug + when w % 4 is not zero */ + glReadPixels(x,y, w ,h,GL_RGB,GL_UNSIGNED_BYTE, data); + + /* inplace swap top to bottom (textures and buffers have + another coordinate system than standard images) + instead of fixing this by using a different texture coordinate + system, a memory swap is performed. this is more expensive + but eliminates hassle when converting between buffers, textures + and bitmaps */ + + pdp_llconv_flip_top_bottom(data, w, h, 3); + + // if (r != data[w*h*3]) post("PANIC"); + + // post("END READPIXELS %d %d", w, h); + + + return new_p; + + error: + return -1; + +} + + + + +/* move these to the pdp_3d_context object: they're too specific */ + +/* setup for 2d operation from pbuf dimensions */ +void pdp_packet_3Dcontext_setup_2d_context(int p) +{ + u32 w; + u32 h; + float asp; + if (!pdp_packet_3Dcontext_isvalid(p)) return; + w = pdp_packet_3Dcontext_subwidth(p); + h = pdp_packet_3Dcontext_subheight(p); + asp = pdp_packet_3Dcontext_subaspect(p); + + + /* set the viewport to the size of the sub frame */ + glViewport(0, 0, w, h); + + /* set orthogonal projection, with a relative frame size of (2asp x 2) */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, 2*asp, 0, 2); + + /* set the center of view */ + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(asp, 1, 0); + glScalef(1,-1,1); + + +} + +/* setup for 3d operation from pbuf dimensions */ +void pdp_packet_3Dcontext_setup_3d_context(int p) +{ + u32 w; + u32 h; + int i; + float asp; + float m_perspect[] = {-1.f, /* left */ + 1.f, /* right */ + -1.f, /* bottom */ + 1.f, /* top */ + 1.f, /* front */ + 20.f};/* back */ + + if (!pdp_packet_3Dcontext_isvalid(p)) return; + w = pdp_packet_3Dcontext_subwidth(p); + h = pdp_packet_3Dcontext_subheight(p); + asp = pdp_packet_3Dcontext_subaspect(p); + + + /* set the viewport to the size of the sub frame */ + glViewport(0, 0, w, h); + + /* set orthogonal projection, with a relative frame size of (2asp x 2) */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(m_perspect[0] * asp, m_perspect[1] * asp, // left, right + m_perspect[2], m_perspect[3], // bottom, top + m_perspect[4], m_perspect[5]); // front, back + + /* reset texture matrix */ + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + + + /* set the center of view */ + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0, 0, 4, 0, 0, 0, 0, 1, 0); + //glTranslatef(asp, 1, 0); + + + glEnable(GL_DEPTH_TEST); + glEnable(GL_AUTO_NORMAL); + glEnable(GL_NORMALIZE); + glShadeModel(GL_SMOOTH); + //glShadeModel(GL_FLAT); + + + /* disable everything that is enabled in other modules + this resets the ogl state to its initial conditions */ + glDisable(GL_LIGHTING); + for (i=0; i<8; i++) glDisable(GL_LIGHT0 + i); + glDisable(GL_COLOR_MATERIAL); + + +} + + +void pdp_3Dcontext_common_setup(void) +{ +} diff --git a/opengl/system/pdp_3Dcontext_glx.c b/opengl/system/pdp_3Dcontext_glx.c new file mode 100644 index 0000000..ac25a13 --- /dev/null +++ b/opengl/system/pdp_3Dcontext_glx.c @@ -0,0 +1,393 @@ + +/* + * OpenGL Extension Module for pdp - opengl system stuff + * 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 file contains the platform dependent opengl setup routines (glx) + and pdp_packet_3Dcontext methods */ + +#include "pdp_opengl.h" +#include "pdp_xwindow.h" +#include "pdp_internals.h" +#include <GL/gl.h> +#include <GL/glx.h> +#include <GL/glu.h> +//#include <GL/glut.h> + +/* all symbols are C-style */ +#ifdef __cplusplus +//extern "C" +//{ +#endif + +// this is buggy: disabled +#define PRIVATE_CONTEXT 0 + + +/* structure to hold the (platform dependent) gl environment setup */ +typedef struct _gl_env +{ + bool initialized; /* data structure is consistent */ + + XVisualInfo *visual; /* the visual info structure for the context */ + GLXContext context; /* the rendering context used to render to windows or pbufs */ + GLXFBConfig *config; /* the framebuffer config object */ + + t_pdp_xdisplay *xdpy; /* pdp's x display object */ + + //Display *dpy; /* x display connection */ + //int screen; /* x screen */ + int last_context_packet; /* the packet that is currently rendered too (for caching) */ +} t_gl_env; + +static t_gl_env pdp_glx_env; +static t_pdp_class *context_class; + +/* PDP_3DCONTEXT packet methods */ + +/* set/unset ogl rendering context to pbuf */ +void pdp_packet_3Dcontext_set_rendering_context(int packet) +{ + t_3Dcontext *c = pdp_packet_3Dcontext_info(packet); + + + if (!c) return; + + + /* don't do a glx call if the context is still the same */ + if (pdp_glx_env.last_context_packet == packet) return; + + //post("new current context is %d", packet); + + + /* pbuffer */ + switch(c->encoding){ + case PDP_3DCONTEXT_WINDOW: + //glFinish(); + //glXMakeCurrent(pdp_glx_env.dpy, ((t_pdp_xwindow *)c->drawable)->win, pdp_glx_env.context); + glXMakeCurrent(pdp_glx_env.xdpy->dpy, ((t_pdp_xwindow *)c->drawable)->win, (GLXContext)c->context); + pdp_glx_env.last_context_packet = packet; + break; + case PDP_3DCONTEXT_PBUFFER: + //glXMakeCurrent(pdp_glx_env.dpy, (GLXPbuffer)c->drawable, pdp_glx_env.context); + //glXMakeContextCurrent(c->dpy, c->drawable.pbuf, c->drawable.pbuf, c->context); + pdp_glx_env.last_context_packet = -1; + break; + default: + pdp_glx_env.last_context_packet = -1; + break; + } + +} + +void pdp_packet_3Dcontext_unset_rendering_context(int packet) +{ + t_3Dcontext *c = pdp_packet_3Dcontext_info(packet); + if (!c) return; + + /* pbuffer */ + switch(c->encoding){ + case PDP_3DCONTEXT_WINDOW: + glXMakeCurrent(pdp_glx_env.xdpy->dpy, None, NULL); + pdp_glx_env.last_context_packet = -1; + break; + case PDP_3DCONTEXT_PBUFFER: + //glXMakeCurrent(pdp_glx_env.dpy, None, NULL); + //glXMakeContextCurrent(c->dpy, c->drawable.pbuf, c->drawable.pbuf, c->context); + break; + default: + break; + } +} + + +/* cons/des */ +static void _3Dcontext_clone(t_pdp *dst, t_pdp *src) +{ + post("ERROR: clone not supported for 3Dcontext packets"); +} + +static void _3Dcontext_copy(t_pdp *dst, t_pdp *src) +{ + post("ERROR: copy not supported for 3Dcontext packets"); +} + +static void _3Dcontext_reinit(t_pdp *dst) +{ + /* leave the packet as is */ +} +static void _3Dcontext_cleanup(t_pdp *dst) +{ + t_3Dcontext *c = (t_3Dcontext *)(&dst->info.raw); + + /* reset context packet cache, in case this packet was the current context. */ + pdp_glx_env.last_context_packet = -1; + + switch(c->encoding){ + case PDP_3DCONTEXT_WINDOW: +#if PRIVATE_CONTEXT + glXDestroyContext (pdp_glx_env.dpy, (GLXContext)c->context); +#endif + pdp_xwindow_cleanup((t_pdp_xwindow *)c->drawable); + free(c->drawable); + break; + + case PDP_3DCONTEXT_PBUFFER: + break; + //glXDestroyContext(c->dpy, c->context); + //glXDestroyPbuffer(c->dpy, c->drawable.pbuf); + default: + break; + } +} + + +/* setup packet methods */ +static void _3Dcontext_init_methods(t_pdp *header) +{ + header->theclass = context_class; + header->flags = PDP_FLAG_DONOTCOPY; +} + + + +/* window specific methods */ + + +void _pdp_3Dcontext_set_window_size(t_3Dcontext *c, t_pdp_xwindow *xwin) +{ + c->width = xwin->winwidth; + c->sub_width = xwin->winwidth; + c->height = xwin->winheight; + c->sub_height= xwin->winheight; +} + +/* resize the window */ +void pdp_packet_3Dcontext_win_resize(int packet, int width, int height) +{ + t_pdp_xwindow *xwin; + t_3Dcontext *c = pdp_packet_3Dcontext_info(packet); + if (!c) return; + if (PDP_3DCONTEXT_WINDOW != c->encoding) return; + xwin = (t_pdp_xwindow *)c->drawable; + pdp_xwindow_resize(xwin, width, height); + _pdp_3Dcontext_set_window_size(c, xwin); +} + + +t_pdp_list *pdp_packet_3Dcontext_win_get_eventlist(int packet) +{ + t_pdp_list *eventlist; + t_pdp_xwindow *xwin; + t_3Dcontext *c = pdp_packet_3Dcontext_info(packet); + if (!c) return 0; + if (PDP_3DCONTEXT_WINDOW != c->encoding) return 0; + xwin = (t_pdp_xwindow *)c->drawable; + eventlist = pdp_xwindow_get_eventlist(xwin); + _pdp_3Dcontext_set_window_size(c, xwin); + return eventlist; +} + +void pdp_packet_3Dcontext_win_cursor(int packet, bool toggle) +{ + t_pdp_xwindow *xwin; + t_3Dcontext *c = pdp_packet_3Dcontext_info(packet); + if (!c) return; + if (PDP_3DCONTEXT_WINDOW != c->encoding) return; + xwin = (t_pdp_xwindow *)c->drawable; + pdp_xwindow_cursor(xwin, toggle); + +} + +void pdp_packet_3Dcontext_win_swapbuffers(int packet) +{ + t_pdp_xwindow *xwin; + t_3Dcontext *c = pdp_packet_3Dcontext_info(packet); + if (!c) return; + if (PDP_3DCONTEXT_WINDOW != c->encoding) return; + xwin = (t_pdp_xwindow *)c->drawable; + glXSwapBuffers(xwin->xdisplay->dpy,xwin->win); + //glFinish(); + +} + + +/* constructors */ + +/* construct (or reuse) a window packet */ +int pdp_packet_new_3Dcontext_win(void) +{ + /* $$$FIXME: this assumes packet can't be reused */ + int p = pdp_packet_new(PDP_3DCONTEXT, 0); + t_pdp_xwindow *xwin; + t_3Dcontext *c; + t_pdp *header = pdp_packet_header(p); + if (!header) return -1; /* pool full ? */ + c = (t_3Dcontext *)&header->info.raw; + + if (c->drawable){ + xwin = (t_pdp_xwindow *)c->drawable; + } + else{ + xwin = (t_pdp_xwindow *)malloc(sizeof(*xwin)); + } + + pdp_xwindow_init(xwin); + pdp_xwindow_create_on_display(xwin, pdp_glx_env.xdpy); + + /* init subheader */ +#if PRIVATE_CONTEXT + if (NULL == (c->context = (void *)glXCreateContext(pdp_glx_env.dpy, pdp_glx_env.visual, pdp_glx_env.context, True))){ + post("pdp_packet_new_3Dcontext_wind: ERROR: can't create rendering context"); + } +#else + c->context = (void *)pdp_glx_env.context; +#endif + c->drawable = xwin; + c->encoding = PDP_3DCONTEXT_WINDOW; + _pdp_3Dcontext_set_window_size(c, xwin); + + /* init packet methods */ + _3Dcontext_init_methods(header); + + /* init header */ + header->desc = pdp_gensym("3Dcontext/window"); + header->flags = PDP_FLAG_DONOTCOPY; + + return p; + + +} + +/* pbuf constructor */ +int pdp_packet_new_3Dcontext_pbuf(u32 width, u32 height, u32 depth) +{ + post("ERROR: 3Dcontext/pbuffer packets not implemented"); + return -1; +} + + +/* this is a notifier sent when the processing thread which + executes gl commands is changed. we need to release the current context + before another thread can take it. */ +void pdp_3Dcontext_prepare_for_thread_switch(void) +{ + pdp_packet_3Dcontext_unset_rendering_context(pdp_glx_env.last_context_packet); +} + + + + + +/* setup routine */ +static void pdp_3Dcontext_glx_setup_inthread(void) +{ + /* this opens the connection to the x server and creates a render context + for windows (glx < 1.3) or windows/pbufs (glx >= 1.3) */ + + static int dblBuf24[] = {GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_ALPHA_SIZE, 0, + GLX_DEPTH_SIZE, 1, + GLX_DOUBLEBUFFER, + None}; + + pdp_glx_env.initialized = 0; + + + /* init xlib for thread usage */ + if (!XInitThreads()){ + post("pdp_opengl_system_setup: can't init Xlib for thread usage."); + goto init_failed; + } + + + /* open display: + the first display on the local machine is opened, not DISPLAY. + since pdp_opengl is all about direct rendering, and there + is no way to specify another display, or even close it and + open it again, this seems to be the "least surprise" solution. + it enables the pd interface to be displayed on another display, + using the DISPLAY environment variable. */ + + + + + + if (NULL == (pdp_glx_env.xdpy = pdp_xdisplay_new(":0"))){ + post("pdp_opengl_system_setup: can't open display"); + goto init_failed; + } + + + /* get visual */ + if (NULL == (pdp_glx_env.visual = glXChooseVisual(pdp_glx_env.xdpy->dpy, pdp_glx_env.xdpy->screen, dblBuf24))){ + post("pdp_opengl_system_setup: can't find appropriate visual"); + goto init_failed_close_dpy; + } + + + /* create a (direct) rendering context */ + if (NULL == (pdp_glx_env.context = glXCreateContext(pdp_glx_env.xdpy->dpy, pdp_glx_env.visual, 0, True))){ + post("pdp_opengl_system_setup: can't create rendering context"); + goto init_failed_close_dpy; + } + + + //post("pdp_opengl_system_setup: pdp_opengl init OK."); + pdp_glx_env.last_context_packet = -1; + pdp_glx_env.initialized = 1; + + /* setup class object */ + context_class = pdp_class_new(pdp_gensym("3Dcontext/*"), 0); + context_class->cleanup = _3Dcontext_cleanup; + context_class->wakeup = _3Dcontext_reinit; + //context_class->clone = _3Dcontext_clone; + context_class->copy = _3Dcontext_copy; + + + /* setup conversion programs: NOT IMPLEMENTED */ + return; + + + init_failed_close_dpy: + pdp_xdisplay_free(pdp_glx_env.xdpy); + pdp_glx_env.xdpy = 0; + init_failed: + post("pdp_opengl_system_setup: FATAL ERROR: pdp_opengl init failed."); + exit(1); + +} + +/* run the setup routine in the procqueue thread, and wait for it to finish */ +/* NOTE: this seems to make an Xlib deadlock problem go away when running + pd with realtime scheduling. frankly, i'm very puzzled by this problem + and even more by the way this workaround solves it. anyhow... */ +void pdp_3Dcontext_glx_setup(void) +{ + t_pdp_procqueue *q = pdp_opengl_get_queue(); + pdp_procqueue_add(q, 0, pdp_3Dcontext_glx_setup_inthread, 0, 0); + pdp_procqueue_flush(q); +} + +#ifdef __cplusplus +//} +#endif diff --git a/opengl/system/pdp_3dp_base.c b/opengl/system/pdp_3dp_base.c new file mode 100644 index 0000000..5190c11 --- /dev/null +++ b/opengl/system/pdp_3dp_base.c @@ -0,0 +1,30 @@ +#include "pdp_opengl.h" +#include "pdp_3dp_base.h" + +#define THIS(b) t_pdp_3pd_base *b = (t_pdp_3pd_base *)x + +/* destructor */ +void pdp_3dp_base_free(void *x) +{ + // free super + pdp_dpd_base_free(x); +} + +/* init method */ +void pdp_3dp_base_init(void *x) +{ + // init super + pdp_dpd_base_init(x); + + // set processing queue to pdp_opengl system queue + pdp_dpd_base_set_queue(x, pdp_opengl_get_queue()); + +} + +/* class setup method */ +void pdp_3dp_base_setup(t_class *class) +{ + // setup super + pdp_dpd_base_setup(class); +} + diff --git a/opengl/system/pdp_mesh.c b/opengl/system/pdp_mesh.c new file mode 100644 index 0000000..b319d1e --- /dev/null +++ b/opengl/system/pdp_mesh.c @@ -0,0 +1,560 @@ +/* + * Pure Data Packet module. mesh 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. + * + */ + +/* a very naive approach to triangular meshes */ + + +// $$TODO: some serious memory corruption in this file our the list implementation + + +#include <math.h> + +#include "pdp.h" +#include "pdp_mesh.h" + + +/* VERTEX methods */ +void vertex_add_triangle(t_vertex *v, t_triangle *t) +{ + pdp_list_add_pointer(v->trilist, t); +} +void vertex_remove_triangle(t_vertex *v, t_triangle *t) +{ + pdp_list_remove_pointer(v->trilist, t); +} +void vertex_add_neighbour(t_vertex *v, t_vertex *neighbour) +{ + pdp_list_add_pointer_to_set(v->vertlist, neighbour); +}; + + +/* constructor/destructors are "private" + they may only be called by the mesh object to ensure + the vector list stays sound (i.e. without duplicates) */ +void _vertex_free(t_vertex *v) +{ + if (!v->trilist) post("WARNING: vertex %x has empty trilist", v); + else{ + pdp_list_free(v->trilist); + v->trilist = 0; + } + if (!v->vertlist) post("WARNING: vertex %x has empty vertlist", v); + { + pdp_list_free(v->vertlist); + v->vertlist = 0; + } + pdp_dealloc(v); +} + +t_vertex *_vertex_new(float *c, float *n) +{ + int k; + t_vertex *v = (t_vertex *) pdp_alloc(sizeof(t_vertex)); + I3(k) v->c[k] = c[k]; + I3(k) v->n[k] = n[k]; + v->trilist = pdp_list_new(0); + v->vertlist = pdp_list_new(0); + return v; +} + + +void vertex_compute_normal_random(t_vertex *v){int k; I3(k) v->n[k] = _rand();} +void vertex_compute_normal_sphere(t_vertex *v){int k; I3(k) v->n[k] = v->c[k];} +void vertex_compute_normal_prism(t_vertex *v) +{ + float scale = 0.0f; + float sum[] = {0.0f, 0.0f, 0.0f}; + int k; + t_pdp_atom* i; + t_pdp_list *vl = v->vertlist; + t_vertex *vtx; + + PDP_POINTER_IN(vl, i, vtx) { + I3(k) sum[k] += vtx->c[k]; + scale = scale + 1.0f; + } + scale = 1.0f / scale; + I3(k) sum[k] *= scale; + I3(k) v->n[k] = v->c[k] - sum[k]; + + //post("computed normal (%f, %f, %f) of vertex (%f, %f, %f)", v->n[0], v->n[1], v->n[2], v->c[0], v->c[1], v->c[2]); +}; +void vertex_compute_normal_average(t_vertex *v) +{ + int triangles = pdp_list_size(v->trilist); + float scale = 1.0f / ((float)triangles); + t_pdp_atom* i; + int k; + t_triangle *t; + + I3(k) v->n[k] = 0; //reset normal + PDP_POINTER_IN(v->trilist, i, t){ + I3(k) v->n[k] += t->n[k]; + } + _vector3_scale(v->n, scale); + + +} + + +float vertex_normalize(t_vertex *v) +{ + return _vector3_normalize(v->c); +} + + +/* TRIANGLE methods */ + +/* create triangle (a connection between 3 vertices): + counterclockwize with facing front + this method is "private" + you can only create triangles as part of a mesh */ +t_triangle *_triangle_new(t_vertex *v0, t_vertex *v1, t_vertex *v2) +{ + int k; + + t_triangle *t = (t_triangle *)pdp_alloc(sizeof(t_triangle)); + + /* store vertex references */ + t->v[0] = v0; + t->v[1] = v1; + t->v[2] = v2; + + /* reset median vertices */ + I3(k) t->m[k] = 0; + + /* connect triangle to vertices */ + vertex_add_triangle(v0, t); + vertex_add_triangle(v1, t); + vertex_add_triangle(v2, t); + + /* connect vertices to vertices */ + vertex_add_neighbour(v0, v1); + vertex_add_neighbour(v0, v2); + vertex_add_neighbour(v1, v0); + vertex_add_neighbour(v1, v2); + vertex_add_neighbour(v2, v0); + vertex_add_neighbour(v2, v1); + + return t; +} + +/* delete a triangle, disconnecting the vertices */ +void _triangle_free(t_triangle *t) +{ + int k; + + /* remove the triangle reference of the vertices */ + I3(k) vertex_remove_triangle(t->v[k], t); + + /* set references to zero (bug catcher) */ + I3(k) t->v[k] = 0; + I3(k) t->m[k] = 0; + + /* free struct */ + pdp_dealloc(t); + +} + +/* get triangle that shares the link between v0 and v1 */ +t_triangle *triangle_neighbour(t_triangle *t, t_vertex *v0, t_vertex *v1) +{ + t_pdp_atom* it; + t_triangle *tri; + PDP_POINTER_IN(v1->trilist, it, tri){ + if (tri != t && pdp_list_contains_pointer(v0->trilist, tri)) return tri; + } + return 0; +} + +/* add a median vector to a link in a triangle + note: vertices must be in triangle, or behaviour is undefined */ +void triangle_add_median(t_triangle *t, t_vertex *v0, t_vertex *v1, t_vertex *median) +{ + + /* link 0 1 */ + if (!((v0 == t->v[2]) || (v1 == t->v[2]))) t->m[0] = median; + + /* link 1 2 */ + else if (!((v0 == t->v[0]) || (v1 == t->v[0]))) t->m[1] = median; + + /* link 2 0 */ + else t->m[2] = median; +} + +void triangle_compute_normal(t_triangle *t) +{ + int k; + float v0[3]; + float v1[3]; + I3(k) v0[k] = t->v[1]->c[k] - t->v[0]->c[k]; + I3(k) v1[k] = t->v[2]->c[k] - t->v[0]->c[k]; + _vector3_cross(v0,v1,t->n); +} + +void triangle_compute_unit_normal(t_triangle *t) +{ + triangle_compute_normal(t); + _vector3_normalize(t->n); +} + +/* MESH methods */ + +/* add and remove methods for vertices and triangles */ +t_vertex *mesh_vertex_add(t_mesh *m, float *c, float *n) +{ + t_vertex *v = _vertex_new(c, n); + pdp_list_add_pointer(m->vertices, v); + return v; +} + +void mesh_vertex_remove(t_mesh *m, t_vertex *v) +{ + pdp_list_remove_pointer(m->vertices, v); + _vertex_free(v); +} + +t_triangle *mesh_triangle_add(t_mesh *m, t_vertex *v0, t_vertex *v1, t_vertex *v2) +{ + t_triangle *t = _triangle_new(v0,v1,v2); + pdp_list_add_pointer(m->triangles, t); + return t; +} + +void mesh_triangle_remove(t_mesh *m, t_triangle *t) +{ + pdp_list_remove_pointer(m->triangles, t); + _triangle_free(t); +} + +/* calculate normals */ +void mesh_calculate_normals(t_mesh *m) +{ + t_pdp_atom* it; + t_pdp_atom* it_tri; + t_pdp_list *l = m->vertices; + t_pdp_list *l_tri = m->triangles; + t_vertex *v; + t_triangle *t; + //while (v = pdp_list_getnext_pointer(l, &it)) vertex_compute_normal_sphere(v); + switch(m->normal_type){ + default: + case MESH_NORMAL_SPHERE: PDP_POINTER_IN(l, it, v) vertex_compute_normal_sphere(v); break; + case MESH_NORMAL_PRISM: PDP_POINTER_IN(l, it, v) vertex_compute_normal_prism(v); break; + case MESH_NORMAL_RANDOM: PDP_POINTER_IN(l, it, v) vertex_compute_normal_random(v); break; + case MESH_NORMAL_AVERAGE: + PDP_POINTER_IN(l_tri, it_tri, t) triangle_compute_unit_normal(t); + PDP_POINTER_IN(l, it, v) vertex_compute_normal_average(v); + break; + } +} + +/* split a triangle in 4, using the intermedia median vertex storage */ +void mesh_split_four(t_mesh *m, t_triangle *old_t) +{ + int k; + t_vertex *v[6]; + + /* some intermediates */ + t_triangle *neighbour; + t_float newv[] = {0,0,0}; + t_float nullvect[] = {0,0,0}; + + + /* get main vertices */ + I3(k) v[k] = old_t->v[k]; + + /* get median vertices inserted by neighbouring triangles */ + I3(k) v[k+3] = old_t->m[k]; + +#define GET_MEDIAN(v, v0, v1) \ + if (!v){ \ + I3(k) newv[k] = 0.5f * (v0->c[k] + v1->c[k]); \ + v = mesh_vertex_add(m, newv, nullvect); \ + /*vertex_normalize(v);*/ \ + if (neighbour = triangle_neighbour(old_t, v0, v1)){ \ + triangle_add_median(neighbour, v0, v1, v); \ + } \ + } + + GET_MEDIAN(v[3], v[0], v[1]) + GET_MEDIAN(v[4], v[1], v[2]) + GET_MEDIAN(v[5], v[2], v[0]) + +#undef GET_MEDIAN + + /* remove the old triangle */ + mesh_triangle_remove(m, old_t); + + /* create 4 new triangles */ + mesh_triangle_add(m, v[0], v[3], v[5]); + mesh_triangle_add(m, v[1], v[4], v[3]); + mesh_triangle_add(m, v[2], v[5], v[4]); + mesh_triangle_add(m, v[3], v[4], v[5]); + +} + +/* split a triangle in 3 */ +void mesh_split_three(t_mesh *m, t_triangle *old_t) +{ + int k, l; + t_vertex *v[4]; + t_float newv[] = {0,0,0}; + t_float nullvect[] = {0,0,0}; + + /* get vertices */ + I3(k) v[k] = old_t->v[k]; + + /* remove a triangle */ + mesh_triangle_remove(m, old_t); + + /* compute new vertex coordinates */ + I3(k) I3(l) newv[k] += 0.33333f * v[l]->c[k]; + + /* create new vertex */ + v[3] = mesh_vertex_add(m, newv, nullvect); + //vertex_normalize(v[3]); + + /* create 3 new triangles */ + mesh_triangle_add(m, v[0], v[1], v[3]); + mesh_triangle_add(m, v[1], v[2], v[3]); + mesh_triangle_add(m, v[2], v[0], v[3]); + +} + + + +void mesh_split_all_four(t_mesh *m) +{ + t_triangle *t; + t_pdp_list *l = pdp_list_copy(m->triangles); + + //post("split_all_four: nb triangles %d", pdp_list_size(m->triangles)); + + while (l->elements){ + t = pdp_list_pop(l).w_pointer; + mesh_split_four(m, t); + } + mesh_calculate_normals(m); + pdp_list_free(l); +} + + +void mesh_split_all_three(t_mesh *m) +{ + t_triangle *t; + t_pdp_list *l = pdp_list_copy(m->triangles); + + //post("split_all_three: nb triangles %d", pdp_list_size(m->triangles)); + + while (l->elements){ + t = pdp_list_pop(l).w_pointer; + mesh_split_three(m, t); + } + mesh_calculate_normals(m); + pdp_list_free(l); +} + +void mesh_split_random_three(t_mesh *m) +{ + int size = pdp_list_size(m->triangles); + t_triangle *t = pdp_list_index(m->triangles, (random() % size)).w_pointer; + mesh_split_three(m, t); + mesh_calculate_normals(m); +} + + + +void mesh_free(t_mesh *m) +{ + t_pdp_list *l; + t_triangle *t; + t_vertex *v; + + /* delete all triangles */ + while (m->triangles->elements){ + t = pdp_list_pop(m->triangles).w_pointer; + //post("freeing triangle %x", t); + _triangle_free(t); + } + pdp_list_free(m->triangles); + m->triangles = 0; + + /* delete all vertices */ + while (m->vertices->elements){ + v = pdp_list_pop(m->vertices).w_pointer; + //post("freeing vertex %x", v); + _vertex_free(v); + } + pdp_list_free(m->vertices); + m->vertices = 0; + + pdp_dealloc(m); + +} + + +t_mesh *_mesh_new(void) +{ + t_mesh *m = (t_mesh *)pdp_alloc(sizeof(t_mesh)); + + /* create main vertex and triangle lists */ + m->triangles = pdp_list_new(0); + m->vertices = pdp_list_new(0); + + /* set normal type */ + m->normal_type = MESH_NORMAL_PRISM; + + return m; +} + +/* init tetra */ +t_mesh *mesh_new_tetra(void) +{ + int k; + t_triangle *t[4]; + t_vertex *v[4]; + t_pdp_atom* it; + t_triangle *tri; + t_mesh *m = _mesh_new(); + + float n[] = {0,0,0}; + float fv[4][3] = {{2,0,0},{0,2,0},{0,0,2}, {-1,-1,-1}}; + + /* add vertices */ + I4(k) v[k] = mesh_vertex_add(m, &fv[k][0], n); + I4(k) vertex_normalize(v[k]); + + /* add triangles */ + mesh_triangle_add(m, v[0], v[1], v[2]); + mesh_triangle_add(m, v[1], v[0], v[3]); + mesh_triangle_add(m, v[0], v[2], v[3]); + mesh_triangle_add(m, v[1], v[3], v[2]); + + + /* compute normals */ + mesh_calculate_normals(m); + + return m; +} + + +void _mesh_relax_compute_resultant_spring(t_mesh *m, float *center, float d0, float r0) +{ + int k; + t_pdp_atom *i, *j; + t_vertex *v, *w; + + PDP_POINTER_IN(m->vertices, i, v){ + float scale = 0.0f; + float r; + + /* compute contribution of origin link */ + I3(k) v->n[k] = v->c[k] - center[k]; + r = _vector3_normalize(v->n); + I3(k) v->n[k] *= (r0 - r); + + PDP_POINTER_IN(v->vertlist, j, w){ + int k; + float f[3]; + float d, l; + + /* compute force contribution of one link (model: spring with rest length == d0) */ + I3(k) f[k] = w->c[k] - v->c[k]; // PC: f == distance vector + d = _vector3_normalize(f); // PC: d == distance, vector == unit norm + I3(k) v->n[k] += (d - d0) * f[k]; // PC: n == n_prev + fource resultant + } + } +} + +void _mesh_relax_apply_force(t_mesh *m, float k) +{ + t_pdp_atom* it; + t_vertex *v; + + PDP_POINTER_IN(m->vertices, it, v){ + int i; + /* apply fource vector with step */ + I3(i) v->c[i] += k * v->n[i]; + } + +} + +void mesh_compute_center(t_mesh *m, float *c) +{ + t_pdp_atom*(it); + t_vertex *v; + float scale; + int k; + + I3(k) c[k] = 0; + PDP_POINTER_IN(m->vertices, it, v){ + I3(k) c[k] += v->c[k]; + } + scale = 1.0f / ((float)pdp_list_size(m->vertices)); + I3(k) c[k] *= scale; + +} + +void mesh_translate(t_mesh *m, float *c) +{ + t_pdp_atom *it; + t_vertex *v; + int k; + + PDP_POINTER_IN(m->vertices, it, v){ + I3(k) v->c[k] += c[k]; + } +} + +/* relax a mesh (move toward equal link length) */ +void mesh_relax(t_mesh *m, float step, float d0, float r0) +{ + int k; + float c[3]; + mesh_compute_center(m, c); + I3(k) c[k] = -c[k]; + mesh_translate(m, c); + I3(k) c[k] = 0; + _mesh_relax_compute_resultant_spring(m, c, d0, r0); /* compute force resultant */ + _mesh_relax_apply_force(m, step); /* apply "time step towards desired distance" */ + mesh_calculate_normals(m); /* restore normals */ +} + + + +/* print some debug information */ +void mesh_debug(t_mesh *m) +{ + int k; + int boundary_edges = 0; + t_pdp_atom* it; + t_triangle *t; + post("mesh info"); + post("\tnumber of vertices = %d", pdp_list_size(m->vertices)); + post("\tnumber of triangles = %d", pdp_list_size(m->triangles)); + + PDP_POINTER_IN(m->triangles, it, t){ + I3(k) if (!triangle_neighbour(t, t->v[k], t->v[(k+1)%3])) boundary_edges++; + } + post("\tnumber of boundaray edges = %d", boundary_edges); + + +} diff --git a/opengl/system/pdp_opengl.c b/opengl/system/pdp_opengl.c new file mode 100644 index 0000000..541af75 --- /dev/null +++ b/opengl/system/pdp_opengl.c @@ -0,0 +1,76 @@ + +/* + * OpenGL Extension Module for pdp - opengl system stuff + * 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_control.h" + +#define PDP_3DP_QUEUE_LOGSIZE 16 +#define PDP_3DP_QUEUE_DELTIME 1.0f + + + +void pdp_3Dcontext_prepare_for_thread_switch(void *); +static t_pdp_procqueue _3dp_queue; + + +static void pdp_control_thread(void *x, t_symbol *s, int argc, t_atom *argv) +{ + int t = 0; + float f; + if (argc != 1) return; + if (argv[0].a_type != A_FLOAT) return; + f = argv[0].a_w.w_float; + t = (f != 0.0f); + post("3dp thread switched %s", t ? "on":"off"); + + + /* when we switch threads, the glx system needs to be notified + because it has to release the render context. this is done + in a process method, so it is run in the correct thread. */ + + + pdp_procqueue_add(&_3dp_queue, 0, pdp_3Dcontext_prepare_for_thread_switch, 0, 0); + pdp_procqueue_wait(&_3dp_queue); + + + /* fresh start: enable/disable the thread dispatching */ + pdp_procqueue_use_thread(&_3dp_queue, t); + +} + +/* kernel setup */ +void pdp_opengl_system_setup(void) +{ + /* init the 3dp queue */ + pdp_procqueue_init(&_3dp_queue, PDP_3DP_QUEUE_DELTIME, PDP_3DP_QUEUE_LOGSIZE); + + /* scheduler uses the thread */ + pdp_procqueue_use_thread(&_3dp_queue, 1); + //pdp_procqueue_use_thread(&_3dp_queue, 0); //DEBUG: disable 3dp thread + + /* add pdp_control method for thread */ + pdp_control_addmethod((t_method)pdp_control_thread, gensym("3dthread")); +} + +t_pdp_procqueue* pdp_opengl_get_queue(void){return (&_3dp_queue);} + + + diff --git a/opengl/system/pdp_texture.c b/opengl/system/pdp_texture.c new file mode 100644 index 0000000..8bc7b21 --- /dev/null +++ b/opengl/system/pdp_texture.c @@ -0,0 +1,541 @@ +/* + * 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_create(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->wakeup = _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 diff --git a/opengl/system/setup.c b/opengl/system/setup.c new file mode 100644 index 0000000..18d267a --- /dev/null +++ b/opengl/system/setup.c @@ -0,0 +1,83 @@ +#include "pdp_opengl.h" + +/* 3dp overview: + + - texture packets (gl) + - drawable packets (glX windows and pbufs) + + the 3dp system connects to a display server and creates a common context + this can be a pbuf context (if supported, glx >= 1.3) or a normal glX context + textures are standard opengl + drawable packets are wrappers around glx drawables (windows or pbufs) + they share the central display connection and rendering context + +*/ + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* opengl lib kernel setup */ +void pdp_opengl_system_setup(void); + +/* packet type setup */ +void pdp_3Dcontext_glx_setup(void); /* glx specific part of the 3D context packet */ +void pdp_3Dcontext_common_setup(void); /* common part of the 3D context packet */ +void pdp_texture_setup(void); /* texture packet */ + + +/* module setup */ +void pdp_3d_windowcontext_setup(void); +void pdp_3d_draw_setup(void); +void pdp_3d_view_setup(void); +void pdp_3d_light_setup(void); +void pdp_3d_color_setup(void); +void pdp_3d_push_setup(void); +void pdp_3d_snap_setup(void); +void pdp_3d_dlist_setup(void); +void pdp_3d_drawmesh_setup(void); +void pdp_3d_for_setup(void); +void pdp_3d_state_setup(void); +void pdp_3d_subcontext_setup(void); + + + //#define D(x) { pdp_post_n( #x ".." ); x; pdp_post("done"); } +#define D(x) x + +void pdp_opengl_setup(void) +{ + int i; + post("PDP: pdp_opengl extension library"); + + /* setup system */ + D(pdp_opengl_system_setup()); + + /* setup packet types */ + D(pdp_3Dcontext_glx_setup()); + D(pdp_3Dcontext_common_setup()); + D(pdp_texture_setup()); + + + /* setup modules */ + D(pdp_3d_windowcontext_setup()); + D(pdp_3d_draw_setup()); + D(pdp_3d_view_setup()); + D(pdp_3d_push_setup()); + D(pdp_3d_light_setup()); + D(pdp_3d_dlist_setup()); + D(pdp_3d_color_setup()); + D(pdp_3d_snap_setup()); + D(pdp_3d_drawmesh_setup()); + D(pdp_3d_for_setup()); + D(pdp_3d_state_setup()); + D(pdp_3d_subcontext_setup()); + + +} + + +#ifdef __cplusplus +} +#endif diff --git a/opengl/test/arm.pd b/opengl/test/arm.pd new file mode 100644 index 0000000..4da4ce1 --- /dev/null +++ b/opengl/test/arm.pd @@ -0,0 +1,39 @@ +#N canvas 475 534 450 300 10; +#X obj 51 14 inlet; +#X obj 52 252 outlet; +#X obj 76 133 3dp_push; +#X obj 176 117 3dp_view transx 0.5; +#X obj 71 81 3dp_view rotz; +#X obj 211 52 inlet; +#X obj 177 91 3dp_view scalex \$1; +#X obj 51 194 3dp_view transx \$1; +#X obj 360 105 r texture; +#X obj 40 62 3dp_view roty; +#X obj 159 22 r roty; +#X obj 301 50 r scale; +#X obj 43 37 3dp_draw cube 1; +#X obj 123 5 r cubesize; +#X obj 257 219 3dp_draw torus 0.25 0.5 6; +#X obj 231 176 spigot; +#X obj 264 148 r drawtorus; +#X obj 322 191 r torusr1; +#X obj 355 160 r torusr2; +#X connect 0 0 12 0; +#X connect 2 0 7 0; +#X connect 2 1 6 0; +#X connect 3 0 15 0; +#X connect 4 0 2 0; +#X connect 5 0 4 1; +#X connect 6 0 3 0; +#X connect 7 0 1 0; +#X connect 8 0 14 1; +#X connect 9 0 4 0; +#X connect 10 0 9 1; +#X connect 11 0 6 1; +#X connect 11 0 7 1; +#X connect 12 0 9 0; +#X connect 13 0 12 2; +#X connect 15 0 14 0; +#X connect 16 0 15 1; +#X connect 17 0 14 2; +#X connect 18 0 14 3; diff --git a/opengl/test/meshtest.pd b/opengl/test/meshtest.pd new file mode 100644 index 0000000..4b8d342 --- /dev/null +++ b/opengl/test/meshtest.pd @@ -0,0 +1,200 @@ +#N canvas 561 0 657 860 10; +#X obj 101 61 3dp_windowcontext; +#X obj 101 27 metro 20; +#X obj 101 122 3dp_push; +#X obj 102 11 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 56 40 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X msg 253 32 cursor \$1; +#X obj 253 12 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X obj 90 222 3dp_mouserotate; +#X text 14 250 use the mouse to rotate the model (but not the light +source since it is rendered before the rotation is applied.); +#X obj 67 516 3dp_drawmesh; +#X obj 261 163 3dp_view transxyz 0 0 4; +#X floatatom 412 128 5 0 0 0 - - -; +#X floatatom 193 392 5 0 0 0 - - -; +#X obj 312 293 spigot; +#X obj 362 263 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 +1; +#X obj 119 341 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 179 494 3dp_dlist; +#X msg 188 467 compile; +#X obj 110 466 pdp_route; +#X obj 202 442 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X msg 266 363 reset; +#X obj 180 292 t b b b b b; +#X msg 310 504 normal sphere; +#X msg 309 458 normal prism; +#X msg 310 481 normal random; +#X obj 276 307 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 276 328 t b b b; +#X obj 334 369 f; +#X floatatom 382 317 5 0 0 0 - - -; +#X floatatom 433 318 5 0 0 0 - - -; +#X obj 81 297 pdp_t p b; +#X obj 308 607 t b b; +#X obj 390 612 t b b; +#X obj 251 581 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 428 575 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 483 316 5 0 0 0 - - -; +#X msg 451 288 5; +#X msg 478 287 0; +#X msg 507 290 5; +#X obj 317 399 pack 0 0 0; +#X msg 383 293 0.01; +#X obj 68 420 3dp_view scale 0.5; +#X obj 426 348 abs; +#X obj 470 337 abs; +#X msg 67 569 wireframe \$1; +#X obj 84 545 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X obj 10 322 spigot; +#X obj 60 292 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X msg 518 152 collectgarbage; +#X obj 516 179 pdp_control; +#X msg 317 537 info; +#X msg 226 332 split4; +#X msg 177 334 split3; +#X msg 10 364 split3random; +#X msg 317 421 springrelax \$1 \$2 \$3; +#X obj 471 243 t b b b b; +#X obj 486 219 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 273 199 3dp_light; +#X floatatom 58 147 5 0 0 0 - - -; +#X floatatom 103 146 5 0 0 0 - - -; +#X floatatom 147 145 5 0 0 0 - - -; +#X floatatom 191 143 5 0 0 0 - - -; +#X msg 431 485 normal average; +#X obj 85 590 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X msg 68 614 flatshading \$1; +#X obj 89 196 3dp_view roty; +#X obj 387 54 f; +#X obj 388 82 +; +#X obj 98 78 pdp_t p b; +#X floatatom 431 57 5 0 0 0 - - -; +#X floatatom 181 9 5 0 0 0 - - -; +#X obj 45 785 3dp_snap; +#X floatatom 152 692 5 0 0 0 - - -; +#X obj 221 736 print; +#X obj 21 176 3dp_color 0.74 0.73 0.62 1; +#X obj 32 726 3dp_draw sphere 9; +#X obj 533 88 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X msg 524 111 3dthread \$1; +#X obj 256 672 pdp_v4l; +#X obj 258 644 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 369 682 pdp_convert texture/*/*; +#X obj 365 712 pdp_description; +#X symbolatom 376 746 10 0 0 0 - - -; +#X obj 191 654 metro 40; +#X obj 191 631 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 314 760 pdp_xv; +#X connect 0 0 68 0; +#X connect 0 1 7 1; +#X connect 1 0 0 0; +#X connect 1 0 66 0; +#X connect 2 0 74 0; +#X connect 2 1 10 0; +#X connect 3 0 1 0; +#X connect 4 0 0 0; +#X connect 5 0 0 0; +#X connect 6 0 5 0; +#X connect 7 0 30 0; +#X connect 9 0 75 0; +#X connect 10 0 57 0; +#X connect 11 0 10 3; +#X connect 12 0 41 1; +#X connect 13 0 27 0; +#X connect 14 0 13 1; +#X connect 15 0 9 0; +#X connect 16 0 9 0; +#X connect 17 0 16 0; +#X connect 18 0 9 0; +#X connect 18 1 16 0; +#X connect 19 0 18 1; +#X connect 20 0 9 0; +#X connect 21 0 52 0; +#X connect 21 1 52 0; +#X connect 21 2 51 0; +#X connect 21 4 51 0; +#X connect 22 0 9 0; +#X connect 23 0 9 0; +#X connect 24 0 9 0; +#X connect 25 0 26 0; +#X connect 26 0 62 0; +#X connect 26 1 21 0; +#X connect 26 2 20 0; +#X connect 27 0 39 0; +#X connect 28 0 27 1; +#X connect 29 0 39 1; +#X connect 30 0 41 0; +#X connect 30 1 13 0; +#X connect 30 1 46 0; +#X connect 31 0 52 0; +#X connect 31 1 50 0; +#X connect 32 0 51 0; +#X connect 32 1 50 0; +#X connect 33 0 31 0; +#X connect 34 0 32 0; +#X connect 35 0 43 0; +#X connect 36 0 29 0; +#X connect 37 0 29 0; +#X connect 38 0 35 0; +#X connect 39 0 54 0; +#X connect 40 0 28 0; +#X connect 41 0 18 0; +#X connect 42 0 39 1; +#X connect 43 0 39 2; +#X connect 44 0 9 0; +#X connect 45 0 44 0; +#X connect 46 0 53 0; +#X connect 47 0 46 1; +#X connect 48 0 49 0; +#X connect 50 0 9 0; +#X connect 51 0 9 0; +#X connect 52 0 9 0; +#X connect 53 0 9 0; +#X connect 54 0 9 0; +#X connect 55 0 14 0; +#X connect 55 1 40 0; +#X connect 55 2 37 0; +#X connect 55 3 38 0; +#X connect 56 0 55 0; +#X connect 58 0 74 1; +#X connect 59 0 74 2; +#X connect 60 0 74 3; +#X connect 61 0 74 4; +#X connect 62 0 9 0; +#X connect 63 0 64 0; +#X connect 64 0 9 0; +#X connect 65 0 7 0; +#X connect 66 0 67 0; +#X connect 67 0 66 1; +#X connect 67 0 65 1; +#X connect 68 0 2 0; +#X connect 69 0 67 1; +#X connect 70 0 1 1; +#X connect 72 0 75 2; +#X connect 74 1 65 0; +#X connect 76 0 77 0; +#X connect 77 0 49 0; +#X connect 78 0 80 0; +#X connect 79 0 78 0; +#X connect 80 0 81 0; +#X connect 80 0 75 1; +#X connect 81 0 82 0; +#X connect 83 0 78 0; +#X connect 84 0 83 0; diff --git a/opengl/test/pdp_ogl_draw_limb.pd b/opengl/test/pdp_ogl_draw_limb.pd new file mode 100644 index 0000000..7b76c74 --- /dev/null +++ b/opengl/test/pdp_ogl_draw_limb.pd @@ -0,0 +1,361 @@ +#N canvas 408 287 799 654 10; +#X floatatom 170 39 5 0 0; +#X obj 82 46 metro 40; +#X obj 82 19 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X msg 125 17 10; +#X msg 99 4 stop; +#X floatatom 284 336 5 0 0; +#X obj 83 128 3dp_push; +#X floatatom 502 132 5 0 0; +#X obj 413 193 3dp_view transx 3; +#X obj 404 251 3dp_light; +#X obj 317 23 f; +#X floatatom 356 24 5 0 0; +#X floatatom 155 114 5 0 0; +#X floatatom 575 415 5 0 0; +#X floatatom 405 344 5 0 0; +#X obj 130 456 arm 3; +#X obj 128 482 arm 3; +#X obj 128 516 arm 3; +#X obj 137 430 arm 3; +#X floatatom 288 376 5 0 0; +#X floatatom 286 414 5 0 0; +#X floatatom 290 454 5 0 0; +#X floatatom 285 509 5 0 0; +#X obj 139 608 arm 3; +#X obj 138 641 arm 3; +#X obj 132 671 arm 3; +#X obj 139 583 arm 3; +#X floatatom 289 549 5 0 0; +#X floatatom 287 587 5 0 0; +#X floatatom 291 627 5 0 0; +#X obj 78 226 3dp_view roty; +#X obj 248 358 * 1; +#X obj 251 610 * -1; +#X obj 507 567 s texture; +#X obj 790 506 pdp_v4l; +#X obj 790 478 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 785 434 metro 10; +#X obj 782 408 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X msg 812 403 stop; +#X obj 139 707 arm 3; +#X floatatom 307 661 5 0 0; +#X obj 256 684 * -1.5; +#X obj 474 719 s roty; +#X floatatom 436 644 5 0 0; +#X floatatom 570 687 5 0 0; +#X obj 572 718 s scale; +#X floatatom 180 212 5 0 0; +#X floatatom 285 108 5 0 0; +#X floatatom 347 299 5 0 0; +#X obj 252 398 * -1.01; +#X obj 250 436 * 0.99; +#X obj 254 476 * -1.01; +#X obj 249 531 * 2.1; +#X obj 253 571 * -1.7; +#X obj 133 399 3dp_draw cube 1.4; +#X obj 129 886 3dp_draw cube 1.4; +#X obj 445 68 t b b; +#X msg 615 633 4; +#X msg 503 640 14; +#X obj 323 57 + 3; +#X obj 70 174 3dp_view transz -3; +#X obj 411 164 3dp_view roty 54; +#X obj 398 378 s cubesize; +#X msg 351 255 3.15; +#X obj 68 248 3dp_view scale 0.4; +#X msg 173 15 20; +#X obj 255 649 * 0.11; +#X floatatom 544 163 5 0 0; +#X msg 421 3 0; +#X obj 269 283 * 1; +#X obj 85 203 3dp_view rotx; +#X floatatom 163 172 5 0 0; +#X floatatom 309 690 5 0 0; +#X obj 128 769 arm 3; +#X obj 127 802 arm 3; +#X obj 121 832 arm 3; +#X obj 128 733 arm 3; +#X floatatom 313 730 5 0 0; +#X floatatom 311 768 5 0 0; +#X floatatom 315 808 5 0 0; +#X obj 275 791 * -1; +#X obj 128 868 arm 3; +#X floatatom 331 842 5 0 0; +#X obj 280 865 * -1.5; +#X obj 273 712 * 2.1; +#X obj 277 752 * -1.7; +#X obj 279 830 * 0.11; +#X obj 8 344 3dp_push; +#X obj 148 311 3dp_view transz; +#X floatatom 212 262 5 0 0; +#X obj 44 365 3dp_view transz; +#X obj 88 326 * -1; +#X msg 267 165 2; +#X obj 222 118 * 0.05; +#X obj 518 805 s drawtorus; +#X obj 518 778 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 +1; +#X obj 515 853 s torusr1; +#X floatatom 513 830 5 0 0; +#X floatatom 611 831 5 0 0; +#X obj 613 854 s torusr2; +#X msg 569 761 1; +#X obj 418 678 *; +#X obj 422 292 metro 100; +#X obj 418 266 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 167 366 3dp_dlist; +#X msg 174 335 compile; +#X floatatom 27 142 5 0 0; +#X obj 82 150 3dp_push; +#X obj 449 801 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 400 772 metro 40; +#X obj 375 780 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj -20 368 3dp_push; +#X obj -23 453 3dp_view rotx; +#X floatatom 64 432 5 0 0; +#X msg -4 56 dim 640 480; +#X obj -15 533 3dp_draw sphere 30 40; +#X msg 635 291 dim 512 512; +#X obj 445 424 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 637 360 pdp_t p p; +#X msg 434 617; +#X msg 478 613 0.001; +#X obj -11 573 3dp_snap; +#X obj 701 192 pdp_control; +#X msg 731 157 thread 1; +#X msg 731 126 thread 0; +#X obj 438 580 / 1000; +#X floatatom 432 545 5 0 0; +#X obj 156 89 3dp_view roty; +#X floatatom 264 67 5 0 0; +#X obj 591 104 print een; +#X obj 595 129 print twee; +#X obj 380 866 pdp_tex; +#X obj 389 836 pdp_noise; +#X msg 376 806 dim 64 64; +#X obj 376 748 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X msg 476 880 dim 32 32; +#X obj 341 894 print tex; +#X obj 452 858 print noise; +#X obj 505 16 loadbang; +#X obj 460 13 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 440 821 pdp_v4l; +#X obj 38 25 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 597 243 osc~ 400; +#X obj 582 275 dac~; +#X msg 601 50 \; pd dsp 1; +#X obj 137 68 3dp_windowcontext; +#X msg 575 188 stop; +#X obj 569 211 metro 1000; +#X floatatom 620 181 5 0 0; +#X obj 551 188 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj -13 98 3dp_windowcontext; +#X obj 82 66 t b b; +#X floatatom 361 84 5 0 0; +#X obj 14 281 3dp_push; +#X obj 96 273 pdp_t p b; +#X obj 9 307 pdp_t p b; +#X obj 428 43 t b b; +#X msg 510 42 open; +#X msg 304 213 400; +#X msg 241 209 -400; +#X obj 274 254 +; +#X obj 748 595 pdp_xv; +#X obj 750 544 pdp_abs; +#X obj 504 465 print; +#X obj 504 441 route done; +#X obj -17 170 3dp_color; +#X obj 8 696 pdp_description; +#X symbolatom -14 773 40 0 0; +#X msg 695 82 collectgarbage; +#X obj -9 738 symbol; +#X obj -11 717 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 14 628 pdp_del 50; +#X connect 0 0 1 1; +#X connect 1 0 10 0; +#X connect 1 0 151 0; +#X connect 2 0 1 0; +#X connect 3 0 1 1; +#X connect 4 0 1 0; +#X connect 5 0 31 1; +#X connect 6 0 107 0; +#X connect 6 1 61 0; +#X connect 7 0 61 1; +#X connect 8 0 9 0; +#X connect 10 0 59 0; +#X connect 11 0 59 1; +#X connect 12 0 60 1; +#X connect 14 0 62 0; +#X connect 15 0 16 0; +#X connect 16 0 17 0; +#X connect 17 0 26 0; +#X connect 18 0 15 0; +#X connect 19 0 49 1; +#X connect 20 0 50 1; +#X connect 21 0 51 1; +#X connect 22 0 52 1; +#X connect 23 0 24 0; +#X connect 24 0 25 0; +#X connect 25 0 39 0; +#X connect 26 0 23 0; +#X connect 27 0 53 1; +#X connect 28 0 32 1; +#X connect 29 0 66 1; +#X connect 30 0 64 0; +#X connect 31 0 49 0; +#X connect 31 0 18 1; +#X connect 32 0 66 0; +#X connect 32 0 24 1; +#X connect 34 0 162 0; +#X connect 35 0 34 0; +#X connect 36 0 35 0; +#X connect 37 0 36 0; +#X connect 38 0 36 0; +#X connect 39 0 76 0; +#X connect 40 0 41 1; +#X connect 41 0 39 1; +#X connect 41 0 84 0; +#X connect 43 0 101 1; +#X connect 44 0 45 0; +#X connect 46 0 64 1; +#X connect 47 0 93 1; +#X connect 48 0 54 2; +#X connect 48 0 55 2; +#X connect 49 0 50 0; +#X connect 49 0 15 1; +#X connect 50 0 51 0; +#X connect 50 0 16 1; +#X connect 51 0 52 0; +#X connect 51 0 17 1; +#X connect 52 0 53 0; +#X connect 52 0 26 1; +#X connect 53 0 32 0; +#X connect 53 0 23 1; +#X connect 54 0 18 0; +#X connect 56 0 2 0; +#X connect 56 0 63 0; +#X connect 56 0 65 0; +#X connect 56 0 92 0; +#X connect 56 1 57 0; +#X connect 56 1 144 0; +#X connect 56 1 147 0; +#X connect 57 0 44 0; +#X connect 57 0 58 0; +#X connect 57 0 100 0; +#X connect 58 0 42 0; +#X connect 59 0 10 1; +#X connect 59 0 93 0; +#X connect 59 0 101 0; +#X connect 59 0 160 1; +#X connect 60 0 70 0; +#X connect 61 0 8 0; +#X connect 63 0 48 0; +#X connect 64 0 153 0; +#X connect 65 0 0 0; +#X connect 66 0 41 0; +#X connect 66 0 25 1; +#X connect 67 0 8 1; +#X connect 68 0 10 0; +#X connect 69 0 31 0; +#X connect 70 0 30 0; +#X connect 71 0 70 1; +#X connect 72 0 84 1; +#X connect 73 0 74 0; +#X connect 74 0 75 0; +#X connect 75 0 81 0; +#X connect 76 0 73 0; +#X connect 77 0 85 1; +#X connect 78 0 80 1; +#X connect 79 0 86 1; +#X connect 80 0 86 0; +#X connect 80 0 74 1; +#X connect 81 0 55 0; +#X connect 82 0 83 1; +#X connect 83 0 81 1; +#X connect 84 0 85 0; +#X connect 85 0 80 0; +#X connect 85 0 73 1; +#X connect 86 0 83 0; +#X connect 86 0 75 1; +#X connect 87 0 111 0; +#X connect 87 1 90 0; +#X connect 88 0 54 0; +#X connect 89 0 88 1; +#X connect 89 0 91 0; +#X connect 90 0 54 0; +#X connect 91 0 90 1; +#X connect 92 0 89 0; +#X connect 93 0 30 1; +#X connect 95 0 94 0; +#X connect 97 0 96 0; +#X connect 98 0 99 0; +#X connect 100 0 95 0; +#X connect 101 0 42 0; +#X connect 103 0 102 0; +#X connect 104 0 54 0; +#X connect 105 0 104 0; +#X connect 106 0 165 3; +#X connect 107 0 60 0; +#X connect 108 0 140 0; +#X connect 110 0 132 0; +#X connect 111 0 112 0; +#X connect 112 0 115 0; +#X connect 113 0 112 1; +#X connect 114 0 150 0; +#X connect 115 0 121 0; +#X connect 117 0 134 0; +#X connect 120 0 43 0; +#X connect 121 1 171 0; +#X connect 123 0 122 0; +#X connect 124 0 122 0; +#X connect 125 0 43 0; +#X connect 126 0 125 0; +#X connect 127 0 6 0; +#X connect 128 0 127 1; +#X connect 133 0 132 0; +#X connect 134 0 108 0; +#X connect 135 0 132 0; +#X connect 138 0 139 0; +#X connect 139 0 156 0; +#X connect 141 0 151 0; +#X connect 142 0 143 0; +#X connect 142 0 143 1; +#X connect 145 0 127 0; +#X connect 145 1 130 0; +#X connect 146 0 147 0; +#X connect 148 0 147 1; +#X connect 149 0 147 0; +#X connect 150 0 165 0; +#X connect 151 0 150 0; +#X connect 153 0 155 0; +#X connect 153 1 154 0; +#X connect 154 0 88 0; +#X connect 154 1 159 0; +#X connect 155 0 87 0; +#X connect 155 1 158 0; +#X connect 156 1 56 0; +#X connect 157 0 145 0; +#X connect 158 0 160 0; +#X connect 159 0 160 0; +#X connect 160 0 69 0; +#X connect 162 0 161 0; +#X connect 164 0 163 0; +#X connect 165 0 6 0; +#X connect 166 0 169 1; +#X connect 168 0 122 0; +#X connect 169 0 167 0; +#X connect 170 0 169 0; +#X connect 171 0 115 1; diff --git a/opengl/test/textest.pd b/opengl/test/textest.pd new file mode 100644 index 0000000..3640d94 --- /dev/null +++ b/opengl/test/textest.pd @@ -0,0 +1,54 @@ +#N canvas 561 0 657 860 10; +#X obj 106 106 3dp_windowcontext; +#X obj 101 27 metro 20; +#X obj 102 11 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 56 40 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 181 9 5 0 0 0 - - -; +#X floatatom 106 663 5 0 0 0 - - -; +#X obj 221 736 print; +#X obj 229 541 pdp_v4l; +#X obj 231 513 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 369 682 pdp_convert texture/*/*; +#X obj 314 760 pdp_xv; +#X obj 365 712 pdp_description; +#X symbolatom 376 746 10 0 0 0 - - -; +#X obj 369 657 pdp_convert bitmap/*/*; +#X obj 164 523 metro 40; +#X obj 164 500 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 +1; +#X floatatom 214 466 5 0 0 0 - - -; +#X obj 363 235 pdp_control; +#X msg 366 199 3dthread \$1; +#X obj 374 167 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 +1; +#X obj 109 135 3dp_mouserotate; +#X obj 32 726 3dp_draw sphere 9; +#X msg 167 417 open /dev/video1; +#X obj 379 558 pdp_chrot; +#X floatatom 429 519 5 0 0 0 - - -; +#X connect 0 0 20 0; +#X connect 0 1 20 1; +#X connect 1 0 0 0; +#X connect 2 0 1 0; +#X connect 3 0 0 0; +#X connect 4 0 1 1; +#X connect 5 0 21 2; +#X connect 7 0 23 0; +#X connect 8 0 7 0; +#X connect 9 0 11 0; +#X connect 9 0 21 1; +#X connect 11 0 12 0; +#X connect 13 0 9 0; +#X connect 14 0 7 0; +#X connect 15 0 14 0; +#X connect 16 0 14 1; +#X connect 18 0 17 0; +#X connect 19 0 18 0; +#X connect 20 0 21 0; +#X connect 22 0 7 0; +#X connect 23 0 13 0; +#X connect 23 0 10 0; +#X connect 24 0 23 1; |