📄 plasmafun.cpp.in
字号:
/**************************************************************************\ * * This file is part of a set of example programs for the Coin library. * Copyright (C) 2000-2003 by Systems in Motion. All rights reserved. * * <URL:http://www.coin3d.org> * * This sourcecode can be redistributed and/or modified under the * terms of the GNU General Public License version 2 as published by * the Free Software Foundation. See the file COPYING at the root * directory of the distribution for more details. * * As a special exception, all sourcecode of the demo examples can be * used for any purpose for licensees of the Coin Professional * Edition License, without the restrictions of the GNU GPL. See our * web pages for information about how to acquire a Professional Edition * License. * * Systems in Motion, <URL:http://www.sim.no>, <mailto:support@sim.no> *\**************************************************************************//* ********************************************************************** * * plasmafun * * Demo application for showcasing Coin. * * Written by Peder Blekken <pederb@coin3d.org>. * Additional copyright (C) 2001, Peder Blekken. * ********************************************************************** */#include <Inventor/@Gui@/So@Gui@.h>#include <Inventor/@Gui@/viewers/So@Gui@ExaminerViewer.h>#include <Inventor/SbBasic.h>#include <Inventor/nodes/SoShapeHints.h>#include <Inventor/nodes/SoSeparator.h>#include <Inventor/nodes/SoTexture2.h>#include <Inventor/nodes/SoCoordinate3.h>#include <Inventor/nodes/SoTextureCoordinate2.h>#include <Inventor/nodes/SoNormal.h>#include <Inventor/nodes/SoQuadMesh.h>#include <Inventor/nodes/SoTextureCoordinateEnvironment.h>#include <Inventor/sensors/SoTimerSensor.h>#include <Inventor/nodes/SoMaterial.h>#include <Inventor/nodes/SoEventCallback.h>#include <Inventor/events/SoKeyboardEvent.h>#include <Inventor/actions/SoGLRenderAction.h>#include <Inventor/elements/SoGLCacheContextElement.h>#include <Inventor/nodes/SoRotor.h>#ifdef HAVE_CONFIG_H#include <config.h>#define CAN_USE_OPENGL#endif // ! HAVE_CONFIG_H#ifdef HAVE_WINDOWS_H#include <windows.h>#endif // HAVE_WINDOWS_H#ifdef HAVE_GL_GL_H#include <GL/gl.h>#endif // HAVE_GL_GL_H#ifdef HAVE_OPENGL_GL_H#include <OpenGL/gl.h>#endif // HAVE_OPENGL_GL_H// These are from OpenGL version >= 1.2 (which is checked runtime).#ifndef GL_LIGHT_MODEL_COLOR_CONTROL#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8#endif // !GL_LIGHT_MODEL_COLOR_CONTROL#ifndef GL_SEPARATE_SPECULAR_COLOR#define GL_SEPARATE_SPECULAR_COLOR 0x81FA#endif // !GL_SEPARATE_SPECULAR_COLOR#include <math.h>#include <stdio.h>#include <stdlib.h> // exit()#include <time.h>typedef struct{ unsigned char r,g,b,a;} myrgb;// yeah, statics :)static int * plasma;static unsigned int palette[256];static myrgb colors[256];static unsigned short rpos1, rpos2, rpos3, rpos4;static unsigned short gpos1, gpos2, gpos3, gpos4;static unsigned short bpos1, bpos2, bpos3, bpos4;static short adders[18];static SoQuadMesh * qm;static SoNormal * n;static SoCoordinate3 * c;static SoTextureCoordinate2 * tc;static int nsides = 66;static int nrings = 66;static voidgentorus(double r, double R, int nsides, int rings, SoCoordinate3 * c, SoNormal * n, SoQuadMesh * qm, SoTextureCoordinate2 * tc){ double theta, phi, theta1; double costheta, sintheta; double ringdelta, sidedelta; double cosPhi, sinPhi, dist; qm->verticesPerColumn = rings+1; qm->verticesPerRow = nsides+1; tc->point.setNum((rings+1)*(nsides+1)); c->point.setNum((rings+1)*(nsides+1)); n->vector.setNum((rings+1)*(nsides+1)); SbVec3f * cptr = c->point.startEditing(); SbVec3f * nptr = n->vector.startEditing(); SbVec2f * tcptr = tc->point.startEditing(); ringdelta = 2.0 * M_PI / rings; sidedelta = 2.0 * M_PI / nsides; theta = 0.0; costheta = 1.0; sintheta = 0.0; double tmul = 0.9f / (M_PI*2.0); double tadd = 0.05f; double nt = R + r; int cnt = 0; while (rings-- >= 0) { costheta = cos(theta); sintheta = sin(theta); phi = 0.0; for (int i = 0; i <= nsides; i++) { cosPhi = cos(phi); sinPhi = sin(phi); dist = R + r * cosPhi; nptr[cnt] = SbVec3f((float) (costheta * cosPhi), (float)(-sintheta * cosPhi), (float)sinPhi); cptr[cnt] = SbVec3f((float) (costheta * dist), (float)(-sintheta * dist), (float)(r * sinPhi)); float tx = (float) (phi * tmul); float ty = (float) (theta * tmul);#if 0 tcptr[cnt] = SbVec2f(tadd + tx, tadd + ty);#else tcptr[cnt][0] = cptr[cnt][0] + nt; tcptr[cnt][0] /= nt*2.0; tcptr[cnt][1] = cptr[cnt][1] + nt; tcptr[cnt][1] /= nt*2.0;#endif cnt++; phi += sidedelta; } theta += ringdelta; } c->point.finishEditing(); n->vector.finishEditing(); tc->point.finishEditing();}voidevent_cb(void * userdata, SoEventCallback * node){ const SoEvent * event = node->getEvent(); int add = 1; if (event->wasShiftDown()) add = -1; if (SO_KEY_PRESS_EVENT(event, NUMBER_1)) { adders[0] += add; } if (SO_KEY_PRESS_EVENT(event, NUMBER_2)) { adders[1] += add; } if (SO_KEY_PRESS_EVENT(event, NUMBER_3)) { adders[2] += add; } if (SO_KEY_PRESS_EVENT(event, NUMBER_4)) { adders[3] += add; } if (SO_KEY_PRESS_EVENT(event, NUMBER_5)) { adders[4] += add; } if (SO_KEY_PRESS_EVENT(event, NUMBER_6)) { adders[5] += add; } if (SO_KEY_PRESS_EVENT(event, NUMBER_7)) { adders[6] += add; } if (SO_KEY_PRESS_EVENT(event, NUMBER_8)) { adders[7] += add; } if (SO_KEY_PRESS_EVENT(event, NUMBER_9)) { adders[8] += add; } if (SO_KEY_PRESS_EVENT(event, NUMBER_0)) { adders[9] += add; } if (SO_KEY_PRESS_EVENT(event, UP_ARROW)) { nsides++; // gentorus(0.8, 1.0, nsides, nrings, c, n, qm, tc); } if (SO_KEY_PRESS_EVENT(event, DOWN_ARROW)) { nsides--; if (nsides < 5) nsides = 5; //gentorus(0.8, 1.0, nsides, nrings, c, n, qm, tc); } if (SO_KEY_PRESS_EVENT(event, LEFT_ARROW)) { nrings--; if (nrings < 5) nrings = 5; } if (SO_KEY_PRESS_EVENT(event, RIGHT_ARROW)) { nrings++; //gentorus(0.8, 1.0, nsides, nrings, c, n, qm, tc); }}static const int imagewidth = 256;static const int imageheight = 256;static SbBool bigendian = FALSE;static intrandom(int maxval){ return rand() % (maxval+1);}static voidredraw_plasma(unsigned char * buffer){ int i,j; unsigned char color; unsigned short rtpos1,rtpos2, rtpos3,rtpos4; unsigned short gtpos1,gtpos2, gtpos3,gtpos4; unsigned short btpos1,btpos2, btpos3,btpos4; rtpos3 = rpos3; rtpos4 = rpos4; gtpos3 = gpos3; gtpos4 = gpos4; btpos3 = bpos3; btpos4 = bpos4; unsigned char * ptr = buffer; unsigned int * c = (unsigned int*)colors; unsigned int col; for (i = 0; i < imageheight; i++) { rtpos1 = rpos1; rtpos2 = rpos2; gtpos1 = gpos1; gtpos2 = gpos2; btpos1 = bpos1; btpos2 = bpos2; for (j = 0; j < imagewidth; j++) { color = plasma[rtpos1]+plasma[rtpos2]+plasma[rtpos3]+ plasma[rtpos4]+plasma[i%0xff]+plasma[j&0xff]; col = palette[color]; color = plasma[gtpos1]+plasma[gtpos2]+plasma[gtpos3]+ plasma[gtpos4]+plasma[i%0xff]+plasma[j&0xff]; col |= palette[color]<<8; color = plasma[btpos1]+plasma[btpos2]+plasma[btpos3]+ plasma[btpos4]+plasma[i%0xff]+plasma[j&0xff]; col |= palette[color]<<16; if (bigendian) { *ptr++ = col>>24; *ptr++ = (col>>16)&0xff; *ptr++ = (col>>8)&0xff; } else { *ptr++ = col & 0xff; *ptr++ = (col>>8)&0xff; *ptr++ = (col>>16)&0xff; } rtpos1 = rtpos1+adders[0]; rtpos2 = rtpos2+adders[1]; gtpos1 = gtpos1+adders[6]; gtpos2 = gtpos2+adders[7]; btpos1 = btpos1+adders[12]; btpos2 = btpos2+adders[13]; } rtpos3 = rtpos3+adders[2]; rtpos4 = rtpos4+adders[3]; gtpos3 = gtpos3+adders[8]; gtpos4 = gtpos4+adders[9]; btpos3 = btpos3+adders[14]; btpos4 = btpos4+adders[15]; } rpos1 = rpos1 + adders[4]; rpos3 = rpos3 + adders[5]; gpos1 = gpos1 + adders[10]; gpos3 = gpos3 + adders[11]; bpos1 = bpos1 + adders[16]; bpos3 = bpos3 + adders[17];}static voidsetup_plasma(void){ rpos1 = rand(); rpos2 = rand(); rpos3 = rand(); rpos4 = rand(); gpos1 = rand(); gpos2 = rand(); gpos3 = rand(); gpos4 = rand(); bpos1 = rand(); bpos2 = rand(); bpos3 = rand(); bpos4 = rand(); int i; plasma = new int[65536];// for (i =0; i < 65536; i++)// plasma[i] = cos((i/4096.0f)*M_PI*2.0) * 512; double inc0 = M_PI*2.0f / (256.0f*(random(128)+1)); double inc1 = M_PI*2.0f / (256.0f*(random(64)+1)); double inc2 = M_PI*2.0f / (256.0f*(random(32)+1)); double inc3 = M_PI*2.0f / (256.0f*(random(1)+1)); double v0, v1, v2, v3; v0 = v1 = v2 = v3 = 0.0; for (i = 0; i < 65536; i++) { plasma[i] = (int) ((sin(v0) + sin(v1) + sin(v2) + sin(v3)) * 32.0); v0 += inc0; v1 += inc1; v2 += inc2; v3 += inc3; } int maxval = random(10); int maxval2 = random(16); int maxval3 = random(24); for (i = 0; i < 18; i++) { if ((i % 6) < 2) adders[i] = random(maxval) - maxval/2; else if ((i % 6) < 4) adders[i] = random(maxval2) - maxval2/2; else adders[i] = random(maxval3) - maxval3/2; } for (i = 0; i < 128; i++) { palette[i] = (i*2); palette[i+128] = (255-i*2); }// // this is pretty cool!!!// for (i = 0; i < 64; i++) {// palette[i] = i*4;// palette[i+64] = 255;// palette[i+128] = 255 - i*4;// palette[i+192] = 0;// } double inc = M_PI / 256.0f; double val = 0.0; for (i = 0; i < 255; i++) { palette[i] = (unsigned int) (sin(val) * 255); val += inc; } for (i = 0; i < 64; i++) { colors[i].r = 255; colors[i].g = i*4; colors[i].b = 0; colors[i].a = 255; } for (i = 0; i < 64; i++) { colors[i+64].r = 255-i*4; colors[i+64].g = 255; colors[i+64].b = i*4; colors[i+64].a = 255; } for (i = 0; i < 64; i++) { colors[i+128].r = 0; colors[i+128].g = i*4; colors[i+128].b = 255; colors[i+128].a = 255; } for (i = 0; i < 64; i++) { colors[i+192].r = i*4; colors[i+192].g = 255 - i*4; colors[i+192].b = 255 - i*4; colors[i+192].a = 255; }}static double scnt1 = 0.1;static double scnt2 = 0.5;static double sadd1 = 0.1;static double sadd2 = -0.1;static double bcnt1 = 0.2;static double bcnt2 = 0.3;static double badd1 = 0.2;static double badd2 = 0.05;static double smallr = 0.8;static double bigr = 1.0;static voidtimersensorcallback(void * data, SoSensor *){ SoTexture2 * texnode = (SoTexture2*) data; SbVec2s size; int nc; unsigned char * image = texnode->image.startEditing(size, nc); redraw_plasma(image); texnode->image.finishEditing(); smallr = cos(scnt1) - cos(scnt2); scnt1 += sadd1; scnt2 += sadd2; smallr += 2.0; smallr *= 0.25 * 0.5; // normalize between 0 and 0.5 smallr += 0.5; // between 0.5 and 1 bigr = cos(bcnt1) - cos(bcnt2); bigr += 2.0; bigr *= 0.25f; // normalize bigr += 1.0; // between 1 and 2 bcnt1 += badd1; bcnt2 += badd2; gentorus(smallr, bigr, nsides, nrings, c, n, qm, tc);}#ifdef __COIN__voidpre_render(void * userdata, class SoGLRenderAction * action){ static int first = 1; if (first) { first = 0; int major, minor; SoGLCacheContextElement::getOpenGLVersion(action->getState(), major, minor); if (major > 1 || (major == 1 && minor >= 2)) {#ifdef CAN_USE_OPENGL// (void)printf("OpenGL v1.2 detected, using separate specular color\n"); glLightModeli((GLenum) GL_LIGHT_MODEL_COLOR_CONTROL, (GLenum) GL_SEPARATE_SPECULAR_COLOR);#endif // CAN_USE_OPENGL } }}#endifintmain(int argc, char **argv){ // Initialize @WIDGET@ window = So@Gui@::init(argv[0]); if (window == NULL) exit(1); SoSeparator * root = new SoSeparator; root->ref(); // enable backface culling SoShapeHints * sh = new SoShapeHints; sh->vertexOrdering = SoShapeHints::CLOCKWISE; sh->shapeType = SoShapeHints::SOLID; sh->faceType = SoShapeHints::CONVEX; root->addChild(sh); SoEventCallback * cb = new SoEventCallback; cb->addEventCallback(SoKeyboardEvent::getClassTypeId(), event_cb, NULL); root->insertChild(cb, 0); (void)printf("This example shows how to draw plasma in a SoTexture2 node.\n"); (void)printf(" * Use arrow keys to adjust torus resolution.\n"); (void)printf(" * Use keys 0-9 + SHIFT to adjust plasma.\n\n\n"); srand((unsigned int) time(NULL)); SoRotor * rot = new SoRotor; SbVec3f axis(random(512) / 256.0f, random(512) / 256.0f, 0.5f); axis.normalize(); rot->rotation = SbRotation(axis, 0.01f); rot->speed = 0.1; rot->on = TRUE; root->insertChild(rot, 0); setup_plasma(); SoTexture2 * texnode = new SoTexture2; texnode->wrapS = SoTexture2::CLAMP; texnode->wrapT = SoTexture2::CLAMP; // FIXME: this crashes when running on SGI // Inventor. Investigate. 20010919 mortene. texnode->image.setValue(SbVec2s((short) imagewidth, (short) imageheight), 3, NULL); SoMaterial * mat = new SoMaterial; mat->diffuseColor = SbColor(0.8f, 0.8f, 0.8f); mat->specularColor = SbColor(1.0f, 1.0f, 1.0f); mat->shininess = 0.9f; // Timer sensor SoTimerSensor * texturetimer = new SoTimerSensor(timersensorcallback, texnode); texturetimer->setInterval(0.05); texturetimer->schedule(); root->insertChild(mat, 0); root->insertChild(texnode, 0); qm = new SoQuadMesh; n = new SoNormal; c = new SoCoordinate3; tc = new SoTextureCoordinate2; timersensorcallback((void*)texnode, texturetimer); root->addChild(c); root->addChild(n); root->addChild(tc); root->addChild(qm); // Setting up the examiner viewer So@Gui@ExaminerViewer * viewer = new So@Gui@ExaminerViewer(window); viewer->setSceneGraph(root); viewer->setTitle("Environment plasma"); viewer->viewAll(); viewer->setViewing(FALSE); viewer->show();#ifdef __COIN__ viewer->getGLRenderAction()->addPreRenderCallback(pre_render, NULL);#endif So@Gui@::show(window); // display the main window So@Gui@::mainLoop(); // main Coin event loop delete viewer; root->unref(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -