SVN-fs-dump-format-version: 2 UUID: 5aee0c02-c622-0410-bcf2-d8652e674aa7 Revision-number: 0 Prop-content-length: 56 Content-length: 56 K 8 svn:date V 27 2006-11-21T18:29:00.163589Z PROPS-END Revision-number: 1 Prop-content-length: 119 Content-length: 119 K 7 svn:log V 17 Importing Project K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2006-11-21T18:30:14.908594Z PROPS-END Node-path: app Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: app/ofAppGlutGlue.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1804 Text-content-md5: 007ef7654a2988cf41c9e3ac14f21569 Content-length: 1814 PROPS-END void display(void); void mouse_cb(int button, int state, int x, int y); void motion_cb(int x, int y); void passive_motion_cb(int x, int y); void idle_cb(void); void keyboard_cb(unsigned char key, int x, int y); void special_key_cb(int key, int x, int y) ; //------------------------------------------------------------ void display(void){ ofGetWindowSize( &width, &height ); height = height > 0 ? height : 1; // set viewport, clear the screen glViewport( 0, 0, width, height ); float * bgPtr = ofBgColorPtr(); glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); OFSAptr->draw(); glutSwapBuffers(); } //------------------------------------------------------------ void mouse_cb(int button, int state, int x, int y) { if (state == GLUT_DOWN) { OFSAptr->mouseDown(x, height - y, button); } else if (state == GLUT_UP) { OFSAptr->mouseUp(x, height - y, button); } } //------------------------------------------------------------ void motion_cb(int x, int y) { OFSAptr->mouseDrag((float)x, height - (float)y, 0); } //------------------------------------------------------------ void passive_motion_cb(int x, int y) { OFSAptr->mouseMove(x, height - y); } //------------------------------------------------------------ void idle_cb(void) { OFSAptr->idle(); glutPostRedisplay(); } //------------------------------------------------------------ void keyboard_cb(unsigned char key, int x, int y) { OFSAptr->keyDown(key); if (key == 27) std::exit(0); // quit! } //------------------------------------------------------------ void special_key_cb(int key, int x, int y) { //acApp::theApp->specialKeyDown(key); // nothing yet, coming soon... } Node-path: app/ofAppRunner.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1623 Text-content-md5: 28c54c6308d69b315afd285955657d94 Content-length: 1633 PROPS-END #include "ofAppRunner.h" #include //======================================================================== // static variables: static ofSimpleApp * OFSAptr; bool bMousePressed; bool bRightButton; float mousex, mousey; int width, height; //======================================================================== // callbacks: #include "ofAppGlutGlue.h" //-------------------------------------- void ofGetWindowSize( int * w, int * h){ *w = glutGet(GLUT_WINDOW_WIDTH); *h = glutGet(GLUT_WINDOW_HEIGHT); } //-------------------------------------- float ofGetTimef(){ return (float)(glutGet(GLUT_ELAPSED_TIME))/1000.0f; } //-------------------------------------- int ofGetTimeMillis(){ return (int)(glutGet(GLUT_ELAPSED_TIME)); } //-------------------------------------- void ofSetupOpenGL(){ int argc = 1; char *argv = "openframeworks"; char **vptr = &argv; glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA); glutInit(&argc, vptr); } //-------------------------------------- void ofRunApp(int w, int h, int screenMode, ofSimpleApp * OFSA){ OFSAptr = OFSA; // window if (screenMode == OF_WINDOW) glutInitWindowSize(w, h); glutCreateWindow(""); if (screenMode == OF_FULLSCREEN) glutFullScreen(); // callbacks glutMouseFunc(mouse_cb); glutMotionFunc(motion_cb); glutPassiveMotionFunc(passive_motion_cb); glutIdleFunc(idle_cb); glutDisplayFunc(display); glutKeyboardFunc(keyboard_cb); glutSpecialFunc(special_key_cb); OFSA->init(); glutMainLoop(); } Node-path: app/ofAppRunner.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1286 Text-content-md5: 587c0771e575edfc76daa7c31e1f4379 Content-length: 1296 PROPS-END /************************************************************ OpenFrameworks Library File: ofAppRunner.h Description: I am the glue Last Modified: 2004.11.03 Creator: Zachary Lieberman Last Modified By: Notes: // alot to fix here! // can we construct the simpleApp extension in this class, thus allowing for // opengl like calls in the constructor, we get hosed, // for example, if you make a texture in the constructor of your simpleApp extension // which is why we have init... // better keyboard support : // no handling of system keys (glfwKeyFunc) // just a-z, A-Z 0-9 and other symbols... // results passed as ints in ASCII // SEE // http://www.ascii.cl/ // for info // name callbacks nicer? ************************************************************/ #ifndef _OF_APP_RUNNER #define _OF_APP_RUNNER #include "ofConstants.h" #include "ofSimpleApp.h" #include "ofGraphics.h" void ofSetupOpenGL(); // sets up the opengl context! void ofRunApp(int w, int h, int screenMode, ofSimpleApp * OFSA); #endif Node-path: app/ofSimpleApp.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 690 Text-content-md5: ac3541760253bce1c658a66577b77d62 Content-length: 700 PROPS-END #include "ofSimpleApp.h" void ofSimpleApp::ofSetupScreen(){ int w, h; ofGetWindowSize( &w, &h ); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } Node-path: app/ofSimpleApp.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 666 Text-content-md5: 1712a72de0e03f7c6dc1a5c1eca057bf Content-length: 676 PROPS-END #ifndef _OF_SIMPLE_APP #define _OF_SIMPLE_APP #include "ofConstants.h" class ofSimpleApp{ public: ofSimpleApp(){} virtual void idle(){} virtual void init(){} virtual void draw(){} virtual void keyDown (char c){} virtual void mouseMove( float x, float y ){} virtual void mouseDrag( float x, float y, int button ){} virtual void mouseDown( float x, float y, int button ){} virtual void mouseUp ( float x, float y, int button ){} virtual void processAudioInput (float * input, int bufferSize) {} virtual void processAudioOutput (float * input, int bufferSize) {} void ofSetupScreen(); }; #endif Node-path: graphics Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 3693 Text-content-md5: f25297371eeb0cc20c402f0a94e8dd81 Content-length: 3703 PROPS-END #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); //---------------------------------------------------------- //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- void ofSetBgColor(float r, float g, float b, float a){ bgColor[0] = r; bgColor[1] = g; bgColor[2] = b; bgColor[3] = a; } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = max(0,min(r,1.0f)); float g = (float)_g / 255.0f; g = max(0,min(g,1.0f)); float b = (float)_b / 255.0f; b = max(0,min(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } Node-path: graphics/ofGraphics.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2036 Text-content-md5: fa5cc24f979bb47b4767c0aca31735b1 Content-length: 2046 PROPS-END #ifndef OF_GEOM #define OF_GEOM /************************************************************ OpenFrameworks Library File: ofGeom.h Description: I make shapes via openGl Last Modified: 2004.11.03 Creator: Carlos Giffoni Last Modified By: Notes: this class handles the drawing of shapes, making is slightly easier for you to drawing things like circles, quads, ellipses, etc, for example, in opengl, in order to draw a line, you need to write: glBegin(GL_LINES); glVertex2f(0,0); glVertex2f(100,100); glEnd(); we wrap those kinds of functions so that you can just write: ofLine(0,0,100,100); much simpler, huh? the fill, noFill control how shapes are drawn. currently, circle is pre-cached at 22 points, this is defined in constants.h feel free to change that number and recompile, we could also use some smartness, and have multiple resolutions of circles, etc.... anyone want to help? ************************************************************/ #include "ofConstants.h" #define CIRC_RESOLUTION 22 // 22 pts for a circle... // bg color float * ofBgColorPtr(); void ofSetBgColor(float r, float g, float b, float a); // geometry void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3); void ofCircle(float radius,float x,float y); void ofEllipse(float width, float height, float x,float y); void ofLine(float x1,float y1,float x2,float y2); void ofRect(float x1,float y1,float w, float h); void ofSetCircleResolution(int res); // if there 22 is a problem, you can change it here // drawing options void ofNoFill(); void ofFill(); // color options void ofSetColor(int r, int g, int b); // 0-255 void ofSetColor(int hexColor); // hex, like web 0xFF0033; // transparency #endif Node-path: graphics/ofImage.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2724 Text-content-md5: d9c80ceb3bbd46f2efdb247d3fddddc6 Content-length: 2734 PROPS-END #include "ofImage.h" static bool bInited = false; //---------------------------------------------------------- ofImage::ofImage(){ //----------------------- init free image if necessary if (!bInited){ FreeImage_Initialise(); bInited = true; } //----------------------- IMG = new fipImage(); w = h = bpp = 0; type = OF_IMAGE_UNDEFINED; } //---------------------------------------------------------- void ofImage::loadImage(char * fileName){ if (IMG->load(fileName)){ // some diagnostics: // printf("loaded %s width = %i height = %i \n", fileName, IMG->getWidth(), IMG->getHeight()); // printf("img bits %i \n", IMG->getBitsPerPixel()); w = IMG->getWidth(); h = IMG->getHeight(); bpp = IMG->getBitsPerPixel(); switch (bpp){ case 8: type = OF_IMAGE_GRAYSCALE; break; case 24: type = OF_IMAGE_COLOR; break; case 32: type = OF_IMAGE_GRAYSCALE; break; default: // we better transform this into something we can work with: setImageType(OF_IMAGE_COLOR); break; } } else { w = h = bpp = 0; } } //---------------------------------------------------------- unsigned char * ofImage::getDataPtr(){ //------------------------------------ // note, this seems a bit dangerous, if you didn't get the image allocated right... // maybe better: // bool setDataPtr(ungned char * data); // and bool is if it actually was set?? // now, the burden is on the user to check: // unsigned char * temp = OFIMG->getDataPtr(); // if (temp != NULL) ... if (IMG->isValid()){ return (unsigned char *)IMG->accessPixels(); } else { return NULL; } } //---------------------------------------------------------- void ofImage::resize(int newWidth, int newHeight){ if (IMG->isValid()){ IMG->rescale(newWidth,newHeight,FILTER_BICUBIC); } } //---------------------------------------------------------- void ofImage::setImageType(int newType){ if (IMG->isValid()){ switch (newType){ //------------------------------------ case OF_IMAGE_GRAYSCALE: if (type != OF_IMAGE_GRAYSCALE){ IMG->convertToGrayscale(); type = OF_IMAGE_GRAYSCALE; } break; //------------------------------------ case OF_IMAGE_COLOR: if (type != OF_IMAGE_COLOR){ IMG->convertTo24Bits(); type = OF_IMAGE_COLOR; } break; //------------------------------------ case OF_IMAGE_COLOR_ALPHA: if (type != OF_IMAGE_COLOR_ALPHA){ IMG->convertTo32Bits(); type = OF_IMAGE_GRAYSCALE; } break; } bpp = IMG->getBitsPerPixel(); } } Node-path: graphics/ofImage.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1621 Text-content-md5: 374b26a3289c1823b4b192af8c3bb367 Content-length: 1631 PROPS-END #ifndef _OF_IMAGE_H_ #define _OF_IMAGE_H_ /************************************************************ openFrameworks Library File: ofImage.h Description: Image class notes: // I load in and save images via freeImage / freeImagePlus // I also allow for various imaging techniques: // - resize // - compositing // ************************************************************/ #include "ofConstants.h" #include "freeImagePlus.h" #define OF_IMAGE_GRAYSCALE 0x00 #define OF_IMAGE_COLOR 0x01 #define OF_IMAGE_COLOR_ALPHA 0x02 #define OF_IMAGE_UNDEFINED 0x03 class ofImage { public : ofImage(); void loadImage(char * fileName); void saveImage(char * fileName); void setDimensions(int w, int h); unsigned char * getDataPtr(); // up to you to get this right void setImageType(int type); void resize(int newWidth, int newHeight); int type; // what type of image it is (as above) int w, h, bpp; // w,h, bits per pixel fipImage * IMG; private: }; //-------------------- // // !!!! = or copy, please !!!! // // copySubImage // pasteSubImage // crop // // (x) convertToRgb(); // (x) convertToGrayscale(); // flipHorizontal(); // flipVertical(); // adjustGamma(double gamma); // adjustBrightness(double percentage); // adjustContrast(double percentage); // //-------------------- #endif Node-path: graphics/ofTexture.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2259 Text-content-md5: 551f2b2fc06172b3715c564caa627f67 Content-length: 2269 PROPS-END #include "ofTexture.h" ofTexture::ofTexture(int w, int h, int internalGlDataType){ tex_w = w; tex_h = h; tex_u = 1.0f; tex_t = 1.0f; // if w, h are not powers of 2 you will not see anything. // create the named texture: texName = new GLuint[1]; //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // not necessary, I think glGenTextures(1, texName); // could be more then one, but for now, just one glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texName[0]); glTexImage2D(GL_TEXTURE_2D, 0, internalGlDataType, tex_w, tex_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); // init to black... glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); } void ofTexture::loadImageData(unsigned char * data, int w, int h, int glDataType){ if ( w > tex_w || h > tex_h) { printf("image data too big - bailing \n"); return; } //compute new tex co-ords based on the ratio of data's w, h to texture w,h; tex_t = (float)w / (float)tex_w; tex_u = (float)h / (float)tex_h; // update the texture image: glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texName[0]); glTexSubImage2D(GL_TEXTURE_2D,0,0,0,w,h,glDataType,GL_UNSIGNED_BYTE,data); glDisable(GL_TEXTURE_2D); } //================================================================================= void ofTexture::renderTexture(int x, int y, int w, int h){ glEnable(GL_TEXTURE_2D); // bind the texture glBindTexture( GL_TEXTURE_2D, texName[0] ); float px0 = x ; // up to you to get the aspect ratio right float py0 = y ; float px1 = x+w; float py1 = y+h; glBegin( GL_QUADS ); glTexCoord2f(0.0, 0.0); glVertex3f(px0, py0,0); glTexCoord2f(tex_t, 0.0); glVertex3f(px1, py0,0); glTexCoord2f(tex_t, tex_u); glVertex3f(px1, py1,0); glTexCoord2f(0.0, tex_u); glVertex3f(px0, py1,0); glEnd(); glDisable(GL_TEXTURE_2D); } Node-path: graphics/ofTexture.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1259 Text-content-md5: f5ee76269afc4535a8e8368d1acd8a05 Content-length: 1269 PROPS-END #ifndef _IMAGE_TEXTURE_H_ #define _IMAGE_TEXTURE_H_ /************************************************************ openFrameworks Library File: ofTexture.h Description: ofImageTexture class notes: // internalGlDataType = how the texture is stored in the card // types include : GL_LUMINANCE, GL_RGB, etc // glDataType = the type of data being uploaded // in the construction, // if w, h are not powers of 2 you will not see anything!!! // please read about opengl textures to understand why this is // your w,h, in loadImageData must be <= the w/h you specify in the constructor... // but they DONT have to be powers of 2 ************************************************************/ #include "ofConstants.h" class ofTexture { public : ofTexture(int w, int h, int internalGlDataType); void loadImageData(unsigned char * data, int w, int h, int glDataType); void renderTexture(int x, int y, int w, int h); float tex_t, tex_u; private: int tex_w, tex_h; GLuint * texName; }; #endif Node-path: graphics/ofTrueTypeFont.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 8101 Text-content-md5: c0529886f68a1c09f28ad8bab4b7b8ef Content-length: 8111 PROPS-END #include "ofTrueTypeFont.h" //=========================================================================== ofTrueTypeFont::ofTrueTypeFont(const char *filename, int fontsize) { ofTTFont_texW = 64; ofTTFont_texH = 64; FT_FONT_SIZE = (fontsize > 0) ? fontsize : 48; int i; bLoadedOk = false; FT_Library library; if (FT_Init_FreeType( &library )){ printf("PROBLEM WITH FT lib \n"); return; } FT_Face face; if (FT_New_Face( library, filename, 0, &face )) { return; } FT_Set_Char_Size( face, FT_FONT_SIZE << 6, FT_FONT_SIZE << 6,96,96); mboxY = (face->height) >> 6; ////printf("lineheight = %f \n", face->height); // load this char set - 0-numChars numChars = NUM_CHARACTERS_TO_LOAD; // get the character properties: cps = new charProps[numChars]; texNames = new GLuint[numChars]; charAreas = new float[numChars]; glGenTextures(numChars, texNames); //--------------------- load each char ----------------------- int largest_texW = 0; int largest_texH = 0; for (int i = 0 ; i < numChars; i++){ if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)i ), FT_LOAD_DEFAULT )){ printf("errora with %i \n", i); } //Move the face's glyph into a Glyph object. FT_Glyph glyph; if(FT_Get_Glyph( face->glyph, &glyph )){ printf("errorb with %i \n", i); } //Convert the glyph to a bitmap. FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1 ); FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph; //This reference will make accessing the bitmap easier FT_Bitmap& bitmap=bitmap_glyph->bitmap; //Use our helper function to get the widths of //the bitmap data that we will need in order to create //our texture. //printf("char = %c, width = %i \n", (unsigned char)i, bitmap.width); //printf("%f %f \n", (float)bitmap_glyph->top, (float)bitmap.rows); int width = ofNextPow2( bitmap.width ); int height = ofNextPow2( bitmap.rows );; if (width > largest_texW) { largest_texW = width;} if (height > largest_texH) { largest_texH = height;} cps[i].value = i; cps[i].height = bitmap_glyph->top; cps[i].width = bitmap.width; cps[i].setWidth = face->glyph->advance.x >> 6; cps[i].topExtent = bitmap.rows; cps[i].leftExtent = bitmap_glyph->left; // texture internals cps[i].tTex = (float)bitmap.width / (float)width; cps[i].vTex = (float)bitmap.rows / (float)height; // Allocate Memory For The Texture Data. GLubyte* expanded_data = new GLubyte[ 2 * width * height]; // Here We Fill In The Data For The Expanded Bitmap. // Notice That We Are Using A Two Channel Bitmap (One For // Channel Luminosity And One For Alpha), But We Assign // Both Luminosity And Alpha To The Value That We // Find In The FreeType Bitmap. // We Use The ?: Operator To Say That Value Which We Use // Will Be 0 If We Are In The Padding Zone, And Whatever // Is The FreeType Bitmap Otherwise. int nOnPixels = 0; for(int j=0; j =bitmap.width || j>=bitmap.rows) ? 0 : 255; GLubyte pixval = 0; expanded_data[2*(k+j*width)+1] = (k>=bitmap.width || j>=bitmap.rows) ? 0 : (pixval = bitmap.buffer[k + bitmap.width*j]); if (pixval > 0){ nOnPixels++; } } } charAreas[i] = (float)nOnPixels; //Now we just setup some texture paramaters. glBindTexture( GL_TEXTURE_2D, texNames[i]); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); //Here we actually create the texture itself, notice //that we are using GL_LUMINANCE_ALPHA to indicate that //we are using 2 channel data. bool b_use_mipmaps = true; if (b_use_mipmaps){ gluBuild2DMipmaps( GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, width, height, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data); } else { glTexImage2D( GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data ); } //With the texture created, we don't need to expanded data anymore delete [] expanded_data; } ofTTFont_texW = (largest_texW > 0) ? largest_texW : 64; ofTTFont_texH = (largest_texH > 0) ? largest_texH : 64; for (int i=0; i 32) && (c < numChars)); } float ofTrueTypeFont::charArea (unsigned char c){ return (charAreas[c]); } void ofTrueTypeFont::drawChar(int c, float x, float y) { if (!charExists(c)){ return; } int cu = c; float height = charHeight(cu); float bwidth = charBitmapWidth(cu); float top = charTop(cu); float lextent = charLeftExtent(cu); float t = cps[cu].tTex; float v = cps[cu].vTex; if (glIsTexture(texNames[cu])) { /*acuNamedTexRectf(x, y+height, x+bwidth, y-top, texNames[cu], t,v); */ glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texNames[cu]); glNormal3f(0, 0, 1); glBegin(GL_QUADS); glTexCoord2d(0,0); glVertex2f(x, y + height); glTexCoord2d(0,v); glVertex2f(x, y-top); glTexCoord2d(t,v); glVertex2f(x + bwidth,y-top); glTexCoord2d(t,0); glVertex2f(x + bwidth,y + height); glEnd(); glDisable(GL_TEXTURE_2D); } else { printf("ofTTFONT - texture not bound for character \n"); } } float ofTrueTypeFont::charWidth(unsigned char c) { return (float)(cps[c].setWidth) / (float)ofTTFont_texW; /* if (c == ' '){ return charWidth ('n'); } else { return (float)(cps[c].setWidth) / (float)ofTTFont_texW; } */ // width of the horizontal space char takes up } float ofTrueTypeFont::stringWidth(char *s) { float wide = 0; float pwide = 0; while (*s != 0) { if (*s == '\n') { if (wide > pwide) pwide = wide; wide = 0; } else { unsigned char c = (unsigned char)(s[0]); float cw = charWidth(c); if ((cw < 0.0) || (cw > 1.0)){ cw = charWidth('n');} float ce = charLeftExtent(c); wide += cw; wide += ce; } s++; } return (pwide > wide) ? pwide : wide; } //===================================================================== void ofTrueTypeFont::drawString(char *c, float x, float y) { glPushMatrix(); float startX = x; int index = 0; while (c[index] != 0) { int cy = (unsigned char)c[index]; if (c[index] == '\n') { x = startX; y -= getHeight() * 1.2; //printf("adding leading\n"); } else { x += charLeftExtent(cy); drawChar(cy, x, y); x += cps[cy].setWidth/ (float)ofTTFont_texW; //charWidth(cy); } index++; } glPopMatrix(); } Node-path: graphics/ofTrueTypefont.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2183 Text-content-md5: 5c70c409152479f44686efa3c4e40a5d Content-length: 2193 PROPS-END /************************************************************ OpenFrameworks Library File: ofTTFont.h Description: I load true type fonts to use w/ opengl Last Modified: 2004.11.03 Creator: Zachary Lieberman Last Modified By: Notes: // GL_INTENSITY SEEMS THE BEST for internal texture format / blending modes // - ZACH // // can we investigate the FT_FONT_SIZE and options for small, // non anti-aliased type ? // need to spend some moments thinking about how free type renders type // and how to pick good sizes, etc. // // ************************************************************/ #ifndef _OF_TTF_FONT_H_ #define _OF_TTF_FONT_H_ // freetype: #include "ofConstants.h" #include #include #include #include #include typedef struct { int value; int height; int width; int setWidth; int topExtent; int leftExtent; float tTex; float vTex; //0-1 pct of bitmap... } charProps; #define NUM_CHARACTERS_TO_LOAD 256 // ascii char set class ofTrueTypeFont{ public: ofTrueTypeFont(const char *filename, int fontsize); bool bLoadedOk; float getDescent(); float getHeight(); float charWidth(unsigned char c); float charHeight(int c); bool charExists(char c); void drawChar(int c, float x, float y); float charArea(unsigned char c); float charLeftExtent(unsigned char c); float charBitmapWidth(int c); float charBitmapHeight(int c); float charTop(int c); float charTopExtent(int c); //void ftLoadGlyph( ) float stringWidth(char *s); void drawString(char *c, float x, float y); int ofNextPow2 ( int a ); protected: int FT_FONT_SIZE; int numChars; int numBits; int mboxX; int mboxY; int baseHt; charProps * cps; // properties for each character unsigned char **images; float *charAreas; GLuint *texNames; int ofTTFont_texW; int ofTTFont_texH; }; #endif Node-path: ofMain.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 609 Text-content-md5: 3e214438b2963a2f43357e3b4188fd0c Content-length: 619 PROPS-END #ifndef OF_MAIN_H #define OF_MAIN_H //-------------------------- // utils #include "ofConstants.h" #include "ofMath.h" #include "ofUtils.h" #include "ofVec3f.h" //-------------------------- // graphics #include "ofTexture.h" #include "ofTrueTypeFont.h" #include "ofGraphics.h" #include "ofImage.h" //-------------------------- // app #include "ofSimpleApp.h" #include "ofAppRunner.h" //-------------------------- // audio #include "ofAudio.h" //#include "ofMidi.h" //-------------------------- // video #include "ofQtVideoGrabber.h" #include "ofQtVideoPlayer.h" #include "ofQtVideoSaver.h" #endif Node-path: sound Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: sound/ofAudio.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 4154 Text-content-md5: 622ec11b09c1a3bec53b3f16d73a3995 Content-length: 4164 PROPS-END #include "ofAudio.h" //----------------------------------- static variables: static ofSimpleApp * OFSAptr; RtAudio * audio; //----------------------------------- int receiveAudioBufferAndCallSimpleApp(char *buffer, int bufferSize, void *data); int receiveAudioBufferAndCallSimpleApp(char *buffer, int bufferSize, void *data){ // rtAudio uses a system by which the audio // can be of different formats // char, float, etc. // we will avoid confusion by // fixing it to float // -1 <-> 1, just like port audio, // so that students // don't have to suffer // however, if you want to change it, // please change it here... // printf("bufferSize = %i \n", bufferSize); // [zach] memset output to zero before output call // this is because of how rtAudio works. seems to duplex // you need to cut in the middle. if the simpleApp // doesn't produce audio, we pass silence instead of duplex... float * fPtr = (float *)buffer; //printf("%f \n", fPtr[0]); if (true) OFSAptr->processAudioInput(fPtr, 256); //memset(fPtr, bufferSize //if (true) OFSAptr->processAudioOuput(fPtr, 256); return 0; } //--------------------------------------------------------- void ofAudioSetup(int nInputChannels, int nOutputChannels, ofSimpleApp * OFSA){ int channels = 2; int sampleRate = 44100; int bufferSize = 256; // 256 sample frames int nBuffers = 4; // number of internal buffers used by device int device = 0; // 0 indicates the default or first available device OFSAptr = OFSA; // Open a stream during RtAudio instantiation try { audio = new RtAudio(); audio->openStream( device, channels, device, channels, RTAUDIO_FLOAT32, sampleRate, &bufferSize, nBuffers); } catch (RtError &error) { //printf("here \n"); error.printMessage(); //std::exit(EXIT_FAILURE); // need case here } try { // Set the stream callback function //[zach] can you look up this pointer nonsense, can this be NULL? audio->setStreamCallback(&receiveAudioBufferAndCallSimpleApp, (void *)NULL); // Start the stream audio->startStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioStopStream(){ try { audio->stopStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioStartStream(){ try{ audio->startStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioEndStream(){ try { audio->stopStream(); audio->closeStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioEnumerateDevices(){ RtAudio *audioTemp = 0; // Default RtAudio constructor try { audioTemp = new RtAudio(); } catch (RtError &error) { error.printMessage(); //exit(EXIT_FAILURE); // need some case here } // Determine the number of devices available int devices = audioTemp->getDeviceCount(); // Scan through devices for various capabilities RtAudioDeviceInfo info; for (int i=1; i<=devices; i++) { try { info = audioTemp->getDeviceInfo(i); } catch (RtError &error) { error.printMessage(); break; } // Print, for example, the maximum number of output channels for each device std::cout << "device = " << i << " (" << info.name << ")\n"; if (info.isDefault) std::cout << "***** default ***** \n"; std::cout << "maximum output channels = " << info.outputChannels << "\n"; std::cout << "maximum input channels = " << info.inputChannels << "\n"; std::cout << "-----------------------------------------\n"; } // Clean up delete audioTemp; } /* try { // Stop and close the stream audio->stopStream(); audio->closeStream(); } catch (RtError &error) { error.printMessage(); } */ Node-path: sound/ofAudio.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 344 Text-content-md5: d2653f0232b4c877862c90d4aa13e6f8 Content-length: 354 PROPS-END #ifndef _OF_AUDIO #define _OF_AUDIO #include "ofMain.h" #include "ofSimpleApp.h" #include "rtAudio.h" // fix exits / errors void ofAudioSetup(int nInputChannels, int nOutputChannels, ofSimpleApp * OFSA); void ofAudioStopStream(); void ofAudioStartStream(); void ofAudioEndStream(); void ofAudioEnumerateDevices(); #endif Node-path: sound/ofMidi.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 19 Text-content-md5: b0266a40cd79fc970747cc0cbeec5dd6 Content-length: 29 PROPS-END #include "ofMidi.h" Node-path: sound/ofMidi.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 247 Text-content-md5: a28d9a6e07897737440d8b2c7093c720 Content-length: 257 PROPS-END #ifndef _OF_MIDI #define _OF_MIDI #include "rtMidi.h" // ---------------------------------------------------------------------------- class ofMidi{ public: ofMidi(); void listPorts(); }; #endif // _OF_MIDI Node-path: utils Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: utils/ofConstants.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1708 Text-content-md5: e6b6e7950548d34b46b8d420c59939cd Content-length: 1718 PROPS-END /************************************************************ OpenFrameworks Library File: ofConstants.h Description: constants, h file stuff, #define multi OS trickery Notes: PI, min, max, etc, etc ************************************************************/ #ifndef OF_CONSTANTS #define OF_CONSTANTS #define TARGET_WIN32 //#define TARGET_OSX #ifdef TARGET_WIN32 #include #include "glut.h" #endif #ifdef TARGET_OSX #include #endif // core: --------------------------- #include #include #include #include #include #ifndef PI #define PI 3.14159265358979323846 #endif #ifndef TWO_PI #define TWO_PI 6.28318530717958647693 #endif #ifndef M_TWO_PI #define M_TWO_PI 6.28318530717958647693 #endif #ifndef FOUR_PI #define FOUR_PI 12.56637061435917295385 #endif #ifndef HALF_PI #define HALF_PI 1.57079632679489661923 #endif #ifndef DEG_TO_RAD #define DEG_TO_RAD (PI/180.0) #endif #ifndef RAD_TO_DEG #define RAD_TO_DEG (180.0/PI) #endif #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #endif #ifndef ABS #define ABS(x) (((x) < 0) ? -(x) : (x)) #endif #define OF_FILLED 0x01 #define OF_OUTLINE 0x02 #define OF_WINDOW 0 #define OF_FULLSCREEN 1 // these are in the "ofAppRunner.cpp" based on the various windowing options. //-------------------------------------- void ofGetWindowSize( int * w, int * h); float ofGetTimef(); int ofGetTimeMillis(); #endif Node-path: utils/ofMath.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1630 Text-content-md5: d3dec216b822c6fa67e31c89c251c55b Content-length: 1640 PROPS-END /************************************************************/ // // // OpenFrameworks Library // // // // File: ofMathLibrary.cpp // // // // Last Modified: 2004.11.03 // // // /************************************************************/ #include "ofMath.h" //-------------------------------------------------- void ofSeedRandom() { // seed random with time srand(time(NULL)); } //-------------------------------------------------- float ofSimpleRandomSF (float x, float y) { float high = 0; float low = 0; float randNum = 0; // if there is no range, return the value if (x == y) return x; high = MAX(x,y); low = MIN(x,y); randNum = low + ((high-low) * rand()/(RAND_MAX + 1.0)); return randNum; } //-------------------------------------------------- int ofSimpleRandomSI (float x, float y) { float high = 0; float low = 0; float randNum = 0; // if there is no range, return the value if (x == y) return (int)x; high = MAX(x,y); low = MIN(x,y); randNum = low + ((high-low) * rand()/(RAND_MAX + 1.0)); return int(randNum); } //-------------------------------------------------- float ofRandomF() { float randNum = 0; randNum = (rand()/(RAND_MAX + 1.0)) * 2.0 - 1.0; return randNum; } //-------------------------------------------------- float ofRandomUF() { float randNum = 0; randNum = rand()/(RAND_MAX + 1.0); return randNum; } //-------------------------------------------------- Node-path: utils/ofMath.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1800 Text-content-md5: 64d7342c614a75805a89e0f8f32b940d Content-length: 1810 PROPS-END /************************************************************/ // // // OpenFrameworks Library // // // // File: ofMathLibrary.h // // Description: Generic Math Functionality // // Main File of the Math Library // // // // Last Modified: 2004.11.03 // // Creator: Clay Johnson // // Last Modified By: Clay Johnson // // // // Notes: // // // for fast things look here: http://musicdsp.org/archive.php?classid=5#115 // // /************************************************************/ #ifndef _OF_MATH_H #define _OF_MATH_H #include "ofMain.h" // definitions ------------------------ // functions -------------------------- // --------------------------------------------------- // // Simply seeds the random number generator with the time // Takes in nothing // Returns a signed float void ofSeedRandom(); // --------------------------------------------------- // // Returns a random number between two floats // Takes in two floats // Returns a signed float float ofSimpleRandomSF(float x, float y); // --------------------------------------------------- // // Returns a random number between two floats // Takes in two floats // Returns a signed int int ofSimpleRandomSI(float x, float y); // --------------------------------------------------- // // Returns a random number between -1 and 1 // Takes in nothing // Returns a signed float float ofRandomF(); // --------------------------------------------------- // // Returns a random number between 0 and 1 // Takes in nothing // Returns an unsigned float float ofRandomUF(); #endif Node-path: utils/ofUtils.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 5382 Text-content-md5: 4a6cddd8adc29adb4597cafd00bbaa27 Content-length: 5392 PROPS-END #include "ofUtils.h" //-------------------------------------------------- static float timeNow, timeThen, fps; static int zframes; static float fpsBlur = 0.0f; float ofGetFps() { // (a) get time timeNow = ofGetTimef(); // (b) calculate and display FPS (frames per second) if( (timeNow-timeThen) > 1.0 || zframes == 0 ) { fps = (double)zframes / (timeNow-timeThen); timeThen = timeNow; zframes = 0; fpsBlur = 0.93f * fpsBlur + 0.07f * fps; } zframes++; return fpsBlur; } //-------------------------------------------------- // from nehe.gamedev.net lesson 43 int ofNextPow2 ( int a ) { int rval=1; while(rval sw) width = sw-x; if (height+y > sh) height = sh-y; char *ScreenImageBuffer = (char*)malloc(width*height*3); char *flippedScreenImageBuffer = (char*)malloc(width*height*3); char fileName[255]; sprintf(fileName, "screen_grab__%ix%i__%0.4i.raw", width, height, frameNum++); FILE* OutputFile = fopen(fileName, "wb"); glReadPixels(x,y,width,height,GL_RGB,GL_UNSIGNED_BYTE,ScreenImageBuffer); // need to flip image for (int i = 0; i < height; i++) { memcpy(flippedScreenImageBuffer+(sizeof(char)*i*width*3), ScreenImageBuffer+(sizeof(char)*(height-i)*width*3), sizeof(char)*width*3); } fwrite(flippedScreenImageBuffer,width*height*3,1,OutputFile); fclose(OutputFile); free(ScreenImageBuffer); free(flippedScreenImageBuffer); } //-------------------------------------------------- //from www.easyrgb.com/math.php?MATH=M21#text21 void ofHsbToRgb(GLfloat *hsb, GLfloat *rgb) { if ( hsb[1] == 0 ) { rgb[0] = hsb[2] * 255; rgb[1] = hsb[2] * 255; rgb[2] = hsb[2] * 255; } else { float var_h = hsb[0] * 6; float var_i = floor( var_h ) ; //Or ... var_i = floor( var_h ) float var_1 = hsb[2] * ( 1 - hsb[1] ); float var_2 = hsb[2] * ( 1 - hsb[1] * ( var_h - var_i ) ); float var_3 = hsb[2] * ( 1 - hsb[1] * ( 1 - ( var_h - var_i ) ) ); if ( var_i == 0 ) { rgb[0] = hsb[2] ; rgb[1] = var_3 ; rgb[2] = var_1; } else if ( var_i == 1 ) { rgb[0] = var_2 ; rgb[1] = hsb[2] ; rgb[2] = var_1; } else if ( var_i == 2 ) { rgb[0] = var_1 ; rgb[1] = hsb[2] ; rgb[2] = var_3; } else if ( var_i == 3 ) { rgb[0] = var_1 ; rgb[1] = var_2 ; rgb[2] = hsb[2]; } else if ( var_i == 4 ) { rgb[0] = var_3 ; rgb[1] = var_1 ; rgb[2] = hsb[2]; } else { rgb[0] = hsb[2] ; rgb[1] = var_1 ; rgb[2] = var_2; } rgb[0]; rgb[1]; rgb[2]; } } //-------------------------------------------------- void ofRgbToHsb(GLfloat *hsb, GLfloat *rgb) { float var_R = rgb[0]; float var_G = rgb[1]; float var_B = rgb[2]; //find min float var_Min = 0; if(var_R < var_G) { ( var_R < var_B ) ? var_Min = var_R : var_Min = var_B; } else ( var_G < var_B ) ? var_Min = var_G : var_Min = var_B; // find max float var_Max = 0; if(var_R > var_G) { ( var_R > var_B ) ? var_Max = var_R : var_Max = var_B; } else ( var_G > var_B ) ? var_Max = var_G : var_Max = var_B; float del_Max = var_Max - var_Min; //Delta RGB value hsb[2] = var_Max; if ( del_Max == 0 ) //This is a gray, no chroma... { hsb[0] = 0; //hsb[0]hsb[1]V results = 0 Ö 1 hsb[1] = 0; } else //Chromatic data... { hsb[1] = del_Max / var_Max; float del_R = ( ( ( var_Max - var_R ) / 6 ) + ( del_Max / 2 ) ) / del_Max; float del_G = ( ( ( var_Max - var_G ) / 6 ) + ( del_Max / 2 ) ) / del_Max; float del_B = ( ( ( var_Max - var_B ) / 6 ) + ( del_Max / 2 ) ) / del_Max; if ( var_R == var_Max ) hsb[0] = del_B - del_G; else if ( var_G == var_Max ) hsb[0] = ( 1 / 3 ) + del_R - del_B; else if ( var_B == var_Max ) hsb[0] = ( 2 / 3 ) + del_G - del_R; if ( hsb[0] < 0 ) ; hsb[0] += 1; if ( hsb[0] > 1 ) ; hsb[0] -= 1; } } //-------------------------------------------------- Node-path: utils/ofUtils.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1525 Text-content-md5: f1821037c4e06b1915a5caa0891daba1 Content-length: 1535 PROPS-END /************************************************************ OpenFrameworks Library File: ofUtils.h Description: Generic Util Functionality Main File of the Util Library Last Modified: 2005.07.29 Last Modified By: Zachary Lieberman Notes: 2005.06.21 - (theo) switched hsbrgb code 2005.07.29 - (zach) added (per theo's request) interpolation on fps() // to do: // add output raw, input raw (for setpixel like things) // GET fps to not fail if called multiple times per frame!!! // (static frame counter???) ************************************************************/ #ifndef _OF_UTIL #define _OF_UTIL // includes --------------------------- #include "ofConstants.h" // definitions ------------------------ // functions -------------------------- // --------------------------------------------------- // // Frames Per Second call // returns FPS as a float float ofGetFps(void); int ofReadInt(FILE *fp); // read an int out of file, perform endian swap if needed int ofNextPow2( int input); void ofScreenCapRaw(); void ofScreenCapRaw(int x, int y, int w, int h); void ofHsbToRgb(GLfloat *hsb, GLfloat *rgb); //hsv in format H (0-360.0/360.0) | S (0-100/100.0) | V (0-100/100.0) void ofRgbToHsb(GLfloat *rgb, GLfloat *hsb); //rgb in opengl format #endif Node-path: utils/ofVec3f.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 3 Text-content-md5: 3bcab0e6a049b4267b8786cdf7ee8afb Content-length: 13 PROPS-END ; Node-path: utils/ofVec3f.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 4662 Text-content-md5: f03e05c763619784ac7fb7949aca0fc5 Content-length: 4672 PROPS-END #ifndef _OF_VEC3f #define _OF_VEC3f #include "ofConstants.h" class ofVec3f{ public: ofVec3f( const float _x = 0.0f, const float _y = 0.0f, const float _z = 0.0f ) { x = _x; y = _y; z = _z; } ofVec3f( const ofVec3f &vec ) { x = vec.x; y = vec.y; z = vec.z; } //virtual ~ofVec3f() // { } // DATA MEMBERS ///////////////// float x; float y; float z; // FUNCTION MEMEBERS //================== void set( float _x, float _y, float _z ) { x= _x; y =_y; z=_z; } void set( const ofVec3f &vec ) { x = vec.x; y = vec.y; z = vec.z; } // Accessor float &operator[]( const int &i ) // [0], [1], [2] return x, y, z { switch(i) { case 0: return x; case 1: return y; case 2: return z; default: return x; } } // Vector Addition ofVec3f operator+( const ofVec3f & vec ) const // returns this + vec { return ofVec3f(x+vec.x, y+vec.y, z+vec.z); } ofVec3f &operator+=( const ofVec3f & vec ) // this += vec { x+=vec.x; y+=vec.y; z+=vec.z; return *this; } // Vector Subtraction ofVec3f operator-() const // returns -this { return ofVec3f(-x, -y, -z); } ofVec3f operator-( const ofVec3f & vec ) const // returns this - vec { return ofVec3f(x-vec.x, y-vec.y, z-vec.z); } ofVec3f &operator-=( const ofVec3f & vec ) // this -= vec { x-=vec.x; y-=vec.y; z-=vec.z; return *this; } // Scaling Multiplication ofVec3f operator*( const float f ) const // returns this * f { return ofVec3f(x*f, y*f, z*f); } friend ofVec3f operator*( const float f, const ofVec3f &vec ) // returns f * this { return ofVec3f(vec.x*f, vec.y*f, vec.z*f); } ofVec3f &operator*=( const float f ) // this *= f { x*=f; y*=f; z*=f; return *this; } // Scaling Division ofVec3f operator/( const float f ) const // returns this / f { return ofVec3f(x/f, y/f, z/f); } ofVec3f &operator/=( const float f ) // this /= f { x/=f; y/=f; z/=f; return *this; } // Vector Multiplication ofVec3f operator*( const ofVec3f & vec ) const // !WARNING (MEMBERWISE): returns this.? * vec.? { return ofVec3f(x*vec.x, y*vec.y, z*vec.z); } ofVec3f &operator*=( const ofVec3f & vec ) // !WARNING (MEMBERWISE): this.? *= vec.? { x*=vec.x; y*=vec.y; z*=vec.z; return *this; } // Vector Division ofVec3f operator/( const ofVec3f & vec ) const // !WARNING (MEMBERWISE): returns this.? / vec.? { return ofVec3f(x/vec.x, y/vec.y, z/vec.z); } ofVec3f &operator/=( const ofVec3f & vec ) // !WARNING (MEMBERWISE): this.? /= vec.? { x/=vec.x; y/=vec.y; z/=vec.z; return *this; } // Dot Product float dot( const ofVec3f & vec ) const // returns dot value of this and vec { return x*vec.x + y*vec.y + z*vec.z; } // Cross Product ofVec3f cross( const ofVec3f & vec ) const // returns cross product of this and vec { return ofVec3f(y*vec.z - z*vec.y, z*vec.x - x*vec.z, x*vec.y - y*vec.x); } // Length float length() const // returns length { return (float)sqrt(x*x + y*y + z*z); } // Normalize ofVec3f &normalize() // normalizes this { float f=length(); x/=f; y/=f; z/=f; return *this; } ofVec3f norm_value() const // returns normalized value, does not modify this { float f=length(); return ofVec3f(x/f, y/f, z/f); } /* // a vector through a matrix ofVec3f operator* (const Matrix& mat) const { ofVec3f ret; ret.x = x*mat.mat[0][0] + y*mat.mat[1][0] + z*mat.mat[2][0] + mat.mat[3][0]; ret.y = x*mat.mat[0][1] + y*mat.mat[1][1] + z*mat.mat[2][1] + mat.mat[3][1]; return ret; } // a vector through a matrix void operator*=(const Matrix& mat) { ofVec3f vec = *this; x = vec.x*mat.mat[0][0] + vec.y*mat.mat[1][0] + vec.z*mat.mat[2][0] + mat.mat[3][0]; y = vec.x*mat.mat[0][1] + vec.y*mat.mat[1][1] + vec.z*mat.mat[2][1] + mat.mat[3][1]; z = vec.x*mat.mat[0][2] + vec.y*mat.mat[1][2] + vec.z*mat.mat[2][2] + mat.mat[3][2]; } */ }; #endif Node-path: video Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: video/ofQtVideoGrabber.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 5753 Text-content-md5: 4bbe3fef9e34c276526e9b8b90378563 Content-length: 5763 PROPS-END #include "ofQtVideoGrabber.h" //-------------------------------------------------------------------- //-------------------------------------------------------------------- // static stuff I don't understand exactly, looks like most legacy mac code :( static pascal Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon){ #pragma unused(theDialog, itemHit) // Ordinarily, if we had multiple windows we cared about, we'd handle // updating them in here, but since we don't, we'll just clear out // any update events meant for us Boolean handled = false; if ((theEvent->what == updateEvt) && ((WindowPtr) theEvent->message == (WindowPtr) refCon)) { BeginUpdate ((WindowPtr) refCon); EndUpdate ((WindowPtr) refCon); handled = true; } return (handled); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- //-------------------------------------------------------------------- ofQtVideoGrabber::ofQtVideoGrabber(int w, int h){ capSizeW = w; capSizeH = h; initVideo(); } //-------------------------------------------------------------------- void ofQtVideoGrabber::fillBufferWithVideoData(unsigned char * data){ unsigned char * vidPtr = (unsigned char *) baseAddr; for (int i = 0; i < capSizeH; i++){ memcpy(data, vidPtr, capSizeW*QT_VG_BYTES_PER_PIXEL); vidPtr += rowBytes; data += capSizeW*QT_VG_BYTES_PER_PIXEL; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::grabFrame(){ SGIdle(gSeqGrabber); } //-------------------------------------------------------------------- void ofQtVideoGrabber::close(){ } //-------------------------------------------------------------------- void ofQtVideoGrabber::videoSettings(void) { Rect newActiveVideoRect; Rect adjustedActiveVideoRect; Rect curBounds, curVideoRect, newVideoRect, newBounds; short width, height; ComponentResult err; GrafPtr savedPort; RgnHandle deadRgn; SGModalFilterUPP seqGragModalFilterUPP; // Get our current state err = SGGetChannelBounds (gVideoChannel, &curBounds); err = SGGetVideoRect (gVideoChannel, &curVideoRect); // Pause err = SGPause (gSeqGrabber, true); // Do the dialog thang static SGModalFilterUPP gSeqGrabberModalFilterUPP = NewSGModalFilterUPP(SeqGrabberModalFilterUPP); int result = SGSettingsDialog(gSeqGrabber, gVideoChannel, 0, nil, seqGrabSettingsPreviewOnly, gSeqGrabberModalFilterUPP, nil); //printf("%d\n", result); #if !TARGET_OS_MAC // This is necessary, for now, to get the grab to start again afer the // dialog goes away. For some reason the video destRect never gets reset to point // back to the monitor window. SGSetChannelBounds(gVideoChannel, &videoRect); #endif // The pause that refreshes err = SGPause (gSeqGrabber, false); } //-------------------------------------------------------------------- void ofQtVideoGrabber::initVideo(){ ComponentDescription theDesc; ComponentResult theresult; Component sgCompID = NULL; char name[256]; char info[256]; Handle componentName=NULL; Handle componentInfo=NULL; ComponentDescription info_description; EnterMovies(); componentName=NewHandle(sizeof(name)); componentInfo=NewHandle(sizeof(info)); gSeqGrabber = 0L; gVideoChannel = 0L; theDesc.componentType = SeqGrabComponentType; theDesc.componentSubType = 0L; theDesc.componentManufacturer = 0L; //'appl'; theDesc.componentFlags = 0L; theDesc.componentFlagsMask = 0L; sgCompID = FindNextComponent(sgCompID, &theDesc); while (sgCompID != 0){ GetComponentInfo(sgCompID,&info_description, componentName, componentInfo,nil); printf("found a device to capture with \n"); printf("Type: %s\n", &info_description.componentType); printf("Manufacturer: %s\n", &info_description.componentManufacturer); printf("Name: %s\n", *componentName ? p2cstr((StringPtr)*componentName) : "-" ); printf("Name: %s\n", *componentInfo ? p2cstr((StringPtr)*componentInfo) : "-"); gSeqGrabber = (VideoDigitizerComponent)OpenComponent(sgCompID); //gSeqGrabber == 0L; sgCompID = FindNextComponent(sgCompID, &theDesc); } DigitizerInfo vdigInfo; VDGetDigitizerInfo(gSeqGrabber, &vdigInfo); if ( vdigInfo.inputCapabilityFlags & digiInDoesComposite){ // finding out about composite... } MacSetRect(&videoRect,0, 0, capSizeW, capSizeH); // Get the digitizer rect to test destination params SGInitialize(gSeqGrabber); QTNewGWorld( &videogworld , k32ARGBPixelFormat , &videoRect, nil, nil, 0); // IV-2817 GWorldPtr offWorld = (GWorldPtr)videogworld; baseAddr = GetPixBaseAddr(GetGWorldPixMap(offWorld)); rowBytes = GetPixRowBytes(GetGWorldPixMap(offWorld)); videoPixMapH = GetGWorldPixMap(videogworld); videoBuffer = (unsigned char *)GetPixBaseAddr(videoPixMapH ); SGSetGWorld(gSeqGrabber, videogworld, nil); SGNewChannel(gSeqGrabber, VideoMediaType, &gVideoChannel); SGSetChannelUsage(gVideoChannel, seqGrabPreview | seqGrabRecord | seqGrabPlayDuringRecord); if (SGSetFrameRate(gVideoChannel,30) != noErr) printf( "error setting 30 fps \n"); else printf ("set to capture at 30 fps \n"); SGSetChannelBounds(gVideoChannel, &videoRect); SGStartPreview(gSeqGrabber); ComponentInstance vdig; vdig = SGGetVideoDigitizerComponent(gVideoChannel); if(VDSetInput(vdig, 0)!=noErr)printf("VDSetInput error\n"); if(VDSetInputStandard (vdig, ntscIn)!=noErr)printf("VDSetInputStandard error\n"); videoSettings(); } //-------------------------------------------------------------------- Node-path: video/ofQtVideoGrabber.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1260 Text-content-md5: f31e35de4d5dbcf5daf5c1d2d5c42252 Content-length: 1270 PROPS-END #ifndef _QT_VIDEO_GRABBER #define _QT_VIDEO_GRABBER // windows / mac keep qt in different places: #if TARGET_OS_MAC #include #include #include #else #include #include #include #include #include "TextUtils.h" #include #include "QDOffscreen.h" #endif #include "ofConstants.h" #include "stdio.h" #include "string.h" #define QT_VG_BYTES_PER_PIXEL 4 class ofQtVideoGrabber{ public : ofQtVideoGrabber(int w, int h); void fillBufferWithVideoData(unsigned char *); unsigned char * returnDataPtr(); void grabFrame(); void close(); void initVideo(); int getBytesPerPixel() { return QT_VG_BYTES_PER_PIXEL; }; void videoSettings(); int capSizeW; int capSizeH; Ptr baseAddr; long rowBytes; private: GWorldPtr videogworld; SeqGrabComponent gSeqGrabber; SGChannel gVideoChannel; PixMapHandle videoPixMapH; unsigned char * videoBuffer; int videoRowWidth; Rect videoRect; }; #endif Node-path: video/ofQtVideoPlayer.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 7345 Text-content-md5: d06f08cdf8a1c008614fda5ebba46699 Content-length: 7355 PROPS-END #include "ofQtVideoPlayer.h" #include #include //--------------------------------------------------------------------------- ofQtVideoPlayer::ofQtVideoPlayer (char * fileName){ loadMovie(fileName); } //--------------------------------------------------------------------------- ofQtVideoPlayer::ofQtVideoPlayer (){ theMovie = nil; thePlayer = nil; w = 0; h = 0; pctBlur = 0; } //--------------------------------------------------------------------------- void ofQtVideoPlayer::fillBufferWithVideoData(unsigned char * data){ #ifdef TARGET_WIN32 memcpy(data, videoBuffer, totalImageSize); #endif #ifdef TARGET_OSX unsigned char a; //apple is ARGB so to get it to RGBA you have to slide each one down and put A on the end. for (int i = 0; i < totalImageSize; i += 4) { //R data[i] = videoBuffer[i+1]; //RG data[i+1] = videoBuffer[i+2]; //RGB data[i+2] = videoBuffer[i+3]; //RGBA data[i+3] = videoBuffer[i]; } #endif } //--------------------------------------------------------------------------- void ofQtVideoPlayer::goToTime(float pct){ } //--------------------------------------------------------------------------- void ofQtVideoPlayer::getNextFrame(float pct){ } static int counter = 0; //--------------------------------------------------------------------------- // zach -- how often should I call moviesTask? // where is this documented? void ofQtVideoPlayer::grabFrame(){ counter++; MoviesTask(theMovie,0); } //--------------------------------------------------------------------------- void ofQtVideoPlayer::close(){ DisposeMovie (theMovie); #ifdef TARGET_WIN32 DisposeMovieDrawingCompleteUPP (myDrawCompleteProc); #endif ExitMovies (); // Finalize Quicktime; } bool ofQtVideoPlayer::createMovieFromPath(char * path, Movie * movie) { Boolean isdir; OSErr result = 0; FSSpec theFSSpec; FSRef fsref; short resRefNum = -1; short actualResId = DoTheRightThing; #ifdef TARGET_WIN32 result = NativePathNameToFSSpec (path, &theFSSpec, 0 /* flags */); if (result) { printf("NativePathNameToFSSpec failed %d\n", result); printf("ERROR LOADING MOVIE \n"); return false; } #endif #ifdef TARGET_OSX result = FSPathMakeRef((const UInt8*)path, &fsref, &isdir); if (result) { printf("FSPathMakeRef failed %d\n", result); printf("ERROR LOADING MOVIE \n"); return false; } result = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL); if (result) { printf("FSGetCatalogInfo failed %d\n", result); printf("ERROR LOADING MOVIE \n"); return false; } #endif result = OpenMovieFile (&theFSSpec, &resRefNum, 0); if (result) { printf("OpenMovieFile failed %d\n", result); printf("ERROR LOADING MOVIE \n"); return false; } result = NewMovieFromFile (&theMovie, resRefNum, &actualResId, (unsigned char *) 0, 0, (Boolean *) 0); if (result) { printf("NewMovieFromFile failed %d\n", result); printf("ERROR LOADING MOVIE \n"); return false; } if (resRefNum != -1) CloseMovieFile (resRefNum); return true; } //--------------------------------------------------------------------------- bool ofQtVideoPlayer::loadMovie(char * name){ int i; OSErr result = 0; short resRefNum = -1; #ifdef TARGET_WIN32 InitializeQTML(0); #endif EnterMovies (); // Initialize Quicktime createMovieFromPath(name, &theMovie); GetMovieBox(theMovie, &rectMovie); rectMovie.right -= rectMovie.left; rectMovie.left -= rectMovie.left; rectMovie.bottom -= rectMovie.top; rectMovie.top -= rectMovie.top; SetMovieBox(theMovie, &rectMovie); w = rectMovie.right; h = rectMovie.bottom; totalImageSize = w * h * 4; // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. videoBuffer = (unsigned char*)malloc(4 * w * h + 32); #ifdef TARGET_WIN32 //QTNewGWorld(&offWorld, k32RGBAPixelFormat, &rectMovie, NULL, NULL, keepLocal); QTNewGWorldFromPtr (&offWorld, k32RGBAPixelFormat, &rectMovie, NULL, NULL, 0, videoBuffer, 4 * w); #endif #ifdef TARGET_OSX QTNewGWorldFromPtr (&offWorld, k32ARGBPixelFormat, &rectMovie, NULL, NULL, 0, videoBuffer, 4 * w); #endif SetGWorld (offWorld, NULL); SetMovieGWorld (theMovie, offWorld, nil); SetMovieActive (theMovie, true); GoToBeginningOfMovie( theMovie ); SetMovieVolume(theMovie, 0); int loop = 1; SetMoviePlayHints(theMovie, hintsLoop, 1); SetMovieActiveSegment(theMovie, -1,-1); int loopState = 0; TimeBase myTimeBase; long myFlags = 0L; if (theMovie == NULL) return false; myTimeBase = GetMovieTimeBase(theMovie); myFlags = GetTimeBaseFlags(myTimeBase); switch (loopState) { case 0: SetMoviePlayHints(theMovie, hintsLoop, hintsLoop); SetMoviePlayHints(theMovie, 0L, hintsPalindrome); myFlags |= loopTimeBase; myFlags &= ~palindromeLoopTimeBase; break; case 1: SetMoviePlayHints(theMovie, hintsLoop, hintsLoop); SetMoviePlayHints(theMovie, hintsPalindrome, hintsPalindrome); myFlags |= loopTimeBase; myFlags |= palindromeLoopTimeBase; break; case 2: default: myFlags &= ~loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(theMovie, 0L, hintsLoop | hintsPalindrome); break; } SetTimeBaseFlags(myTimeBase, myFlags); StartMovie(theMovie); return true; } //--------------------------------------------------------------------------- void ofQtVideoPlayer::setMoviePct(float pct){ TimeRecord tr; tr.base = GetMovieTimeBase(theMovie); long total = GetMovieDuration( theMovie ); long newPos = (long)((float)total * pct); SetMovieTimeValue(theMovie, newPos); //info: //http://viewcvs.osafoundation.org/chandler/trunk/internal/wx/src/msw/mediactrl.cpp?rev=6281&view=markup } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getMovieDuration(){ return GetMovieDuration (theMovie) / (double) GetMovieTimeScale (theMovie); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getMoviePct(){ // can be precached: long total = GetMovieDuration( theMovie ); long current = GetMovieTime( theMovie, nil); float pct = ((float)current/(float)total); pctBlur = 0.2f * pctBlur + 0.2f * pct; if (lastTime != current){ float timeNow =0;// glueGetTime(); durationTime = timeNow - lastTimeStamp; durationPct = pct - ((float)lastTime /(float)total); lastTimeStamp = timeNow; } else { // attempt to do a subtime here: // this is strange, but works.... //float cur_m_lastTimeStamp = glueGetTime() - lastTimeStamp; float cur_m_lastTimeStamp = 0 - lastTimeStamp; if (durationTime < 0.0001) durationTime = 0.0001; float pctTemp = cur_m_lastTimeStamp / durationTime; pctTemp = MIN(1.0f, pctTemp); lastTime = current; return pct + pctTemp * durationPct; } lastTime = current; return pct; } //--------------------------------------------------------------------------- void ofQtVideoPlayer::setSpeed(float _speed){ speed = _speed; SetMovieRate(theMovie, X2Fix(speed)); } float ofQtVideoPlayer::getSpeed(){ return speed; } //http://developer.apple.com/documentation/QuickTime/INMAC/QT/iqMovieToolbox.34.htm Node-path: video/ofQtVideoPlayer.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1575 Text-content-md5: 1d5b435c7504c896a3bb1c3c4918b4ba Content-length: 1585 PROPS-END #ifndef _QT_VIDEO_PLAYER #define _QT_VIDEO_PLAYER #include "ofConstants.h" #ifdef TARGET_WIN32 #include // Quicktime Headers #include #include #include #include "TextUtils.h" #include "QuickDraw.h" #endif #ifdef TARGET_OSX #include #include #include #endif #include "stdio.h" #include "string.h" #include "ofMain.h" #include #include #include #define BYTES_PER_PIXEL 4 class ofQtVideoPlayer{ public: ofQtVideoPlayer (char * fileName); ofQtVideoPlayer (); void fillBufferWithVideoData(unsigned char *); void grabFrame(); void goToTime(float pct); void getNextFrame(float pct); void close(); float getMovieDuration(); float getMoviePct(); void setSpeed(float speed); float getSpeed(); bool loadMovie(char * name); int w, h; int totalImageSize; int totalNumFrames; int currentFrame; float speed; bool createMovieFromPath(char * path, Movie * movie); GWorldPtr offWorld; GWorldPtr gw; Movie theMovie; MovieController thePlayer; Rect rectMovie; PixMapHandle videoPixMapH; unsigned char * videoBuffer; unsigned char * videoBuffer2; void setMoviePct(float pct); float pctBlur; // zach's insane time idea: long lastTime; float lastTimeStamp; float durationTime; float durationPct; }; #endif Node-path: video/ofQtVideoSaver.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 15072 Text-content-md5: 112cc93ab566757afec3c07a244b6962 Content-length: 15082 PROPS-END #include "ofQtVideoSaver.h" // quality, size ofQtVideoSaver::ofQtVideoSaver(int _w, int _h){ w = _w; h = _h; pszFilename = "../my.mov"; pszFlatFilename = "../myflat.mov"; sResRefNum = 0; movie = nil; track = NULL; media = NULL; pMovieGWorld = NULL; pixMapHandle = NULL; pCompressedData = NULL; pSavedPort = NULL; hSavedDevice = NULL; hCompressedData = NULL; lMaxCompressionSize = 0L; hImageDescription = NULL; printf(" 02 \n"); #ifdef TARGET_WIN32 InitializeQTML(0); #endif EnterMovies(); printf(" 0 \n"); /* Load the FSSpec structure to describe the receiving file. For a description of this and related calls see http://developer.apple.com/quicktime/icefloe/dispatch004.html. ================================================================ */ osErr = NativePathNameToFSSpec (pszFilename, &fsSpec, 0); if (osErr && (osErr != fnfErr)) /* File-not-found error is ok */ { printf ("NativePathNameToFSSpec failed %d\n", osErr); goto bail; } printf(" 1 \n"); /* Step 1: Create a new, empty movie file and a movie that references that file (CreateMovieFile). ======================================================================== */ osErr = CreateMovieFile ( &fsSpec, /* FSSpec specifier */ FOUR_CHAR_CODE('TVOD'), /* file creator type, TVOD = QT player*/ smCurrentScript, /* movie script system to use */ createMovieFileDeleteCurFile /* movie file creation flags */ | createMovieFileDontCreateResFile, &sResRefNum, /* returned file ref num to data fork */ &movie /* returned handle to open empty movie*/ /* that references the created file */ ); if (osErr) { printf ("CreateMovieFile failed %d\n", osErr); goto bail; } printf(" 2 \n"); /* Step 2: Add a new track to that movie (NewMovieTrack). ======================================================= */ track = NewMovieTrack ( movie, /* the movie to add track to */ ((long) w << 16), /* width of track in pixels (Fixed) */ FixRatio (h, 1), /* height of track in pixels (Fixed) */ kNoVolume /* default volume level */ ); osErr = GetMoviesError (); if (osErr) { printf ("NewMovieTrack failed %d\n", osErr); goto bail; } printf(" 3 \n"); /* Step 3: Add a new media to that track (NewTrackMedia). ======================================================= */ media = NewTrackMedia ( track, /* the track to add the media to */ VideoMediaType, /* media type, e.g. SoundMediaType */ 600, /* num media time units that elapse/sec*/ NULL, /* ptr to file that holds media sampls*/ 0 /* type of ptr to media samples */ ); osErr = GetMoviesError (); if (osErr) { printf ("NewTrackMedia failed %d\n", osErr); goto bail; } printf(" 4 \n"); /* Step 4: Add media samples to the media. ======================================== */ BeginMediaEdits (media); /* Inform the Movie Toolbox that we */ /* want to change the media samples */ /* referenced by a track's media. */ /* This opens the media container */ /* and makes it ready to receive */ /* and/or remove sample data. */ printf(" 5 \n"); // Step 5: setup graphics port for qt movie and compression type --- /* Create a new offscreen graphics world that will hold the movie's drawing surface. draw_image() copies the image of IceFlow to this surface with varying amounts of transparency. ================================================================= */ MacSetRect (&rect, 0, 0, w, h); osErr = NewGWorld ( &pMovieGWorld, /* receives the new GWorld. */ 24, /* pixel depth in bits/pixel */ &rect, /* desired size of the GWorld. */ NULL, NULL, (GWorldFlags) 0 ); if (osErr != noErr) { printf ("NewGWorld 1 failed %d\n", osErr); goto bail; } printf(" 6 \n"); /* Retrieve the pixel map associated with that graphics world and lock the pixel map in memory. GetMaxCompressionSize() and CompressImage() only operate on pixel maps, not graphics worlds. ===================================================================== */ pixMapHandle = GetGWorldPixMap (pMovieGWorld); if (pixMapHandle == NULL) { printf ("GetGWorldPixMap failed\n"); goto bail; } LockPixels (pixMapHandle); /* Get the maximum number of bytes required to hold an image having the specified characteristics compressed using the specified compressor. ==================================================================== */ codecType = kJPEGCodecType; osErr = GetMaxCompressionSize ( pixMapHandle, /* the pixel map to compress from. */ &rect, /* the image rectangle. */ 0, /* let ICM choose image bit depth. */ codecHighQuality, /* compression quality specifier. */ codecType, /* desired compression type */ (CompressorComponent) anyCodec, /* codec specifier. */ &lMaxCompressionSize /* receives max bytes needed for cmp. */ ); if (osErr != noErr) { printf ("GetMaxCompressionSize failed %d\n", osErr); goto bail; } /* Allocate a buffer to hold the compressed image data by creating a new handle. ===================================================================== */ printf(" 7 \n"); hCompressedData = NewHandle (lMaxCompressionSize); if (hCompressedData == NULL) { printf ("NewHandle(%ld) failed\n", lMaxCompressionSize); goto bail; } printf(" 8 \n"); /* Lock the handle and then dereference it to obtain a pointer to the data buffer because CompressImage() wants us to pass it a pointer, not a handle. ======================================================================= */ HLockHi (hCompressedData); pCompressedData = *hCompressedData; printf(" 9 \n"); /* Create an image description object in memory of minimum size to pass to CompressImage(). CompressImage() will resize the memory as necessary so create it small here. ==================================================================== */ hImageDescription = (ImageDescriptionHandle) NewHandle (4); if (hImageDescription == NULL) { printf ("NewHandle(4) failed\n"); goto bail; } printf(" 10 \n"); return; bail: if (sResRefNum != 0) CloseMovieFile (sResRefNum); if (movie != NULL) DisposeMovie (movie); //ExitMovies (); /* Finalize Quicktime */ return; } //----------------------------------------------------------------------------- void ofQtVideoSaver::finishMovie(bool bFlatten){ EndMediaEdits (media); /* Inform the Movie Toolbox that they */ /* can close the media container. */ /* Step 5: Insert a reference into the track that specifies which of the media samples to play and when to start playing them. ====================================================================== */ InsertMediaIntoTrack ( track, /* the track to update. */ 0, /* time in track where the specified */ /* media samples should start playg */ /* using movie time scale. */ 0, /* time in media samples of the first */ /* sample to play using media time */ /* scale. */ GetMediaDuration (media), /* duration of media samples to play */ /* using media time scale. */ 1L<<16 //fixed1 /* rate at which to play the samples. */ ); /* Step 6: Append the movie atom to the movie file (AddMovieResource). ==================================================================== */ sResId = movieInDataForkResID; osErr = AddMovieResource ( movie, /* movie to create moov atom from */ sResRefNum, /* file to receive the moov atom */ &sResId, /* id num of movie resource (res fork)*/ (unsigned char *) pszFilename /* name of movie resource (res fork) */ ); if (osErr) { printf ("AddMovieResource failed %d\n", osErr); goto bail; } if (sResRefNum != 0) { CloseMovieFile (sResRefNum); /* close file CreateMovieFile opened */ sResRefNum = 0; } /* Step 7 (optional): Place the movie atom as the first atom in a new movie file, and interleave the media data (FlattenMovieData). =================================================================== */ //if (bFlatten) flatten_my_movie (movie, pszFlatFilename); /* Step 8: Close the movie file that CreateMovieFile opened (if necessary) and dispose of the movie memory structures (DisposeMovie). ======================================================================== */ bail: if (sResRefNum != 0) CloseMovieFile (sResRefNum); if (movie != NULL) DisposeMovie (movie); //ExitMovies (); /* Finalize Quicktime */ //return (0); } void ofQtVideoSaver::addFrame(unsigned char * data){ /* Save the current GWorld and set the offscreen GWorld as current. ================================================================ */ GetGWorld (&pSavedPort, &hSavedDevice); SetGWorld (pMovieGWorld, NULL); Ptr gwAddress, gwAddressBase; long gwWidth; gwAddressBase = GetPixBaseAddr( GetGWorldPixMap( pMovieGWorld ) ); /* Get head address of offscreen */ gwWidth = ( **GetGWorldPixMap( pMovieGWorld ) ).rowBytes & 0x3fff; /* Get with of offscreen */ //gwAddress = gwAddressBase + ( x * 3 ) + ( y * gwWidth ); /* Get adress for current pixel */ int myWidth = w*3; for (int i = 0; i < h; i++){ gwAddress = gwAddressBase + i * gwWidth; memcpy(gwAddress, data, myWidth); data += myWidth; } /* Compress the pixel map that has just been drawn on. Also resize and fill in the image description. Resulting image size can be discovered by consulting the image description field dataSize. ================================================================ */ osErr = CompressImage ( pixMapHandle, /* the pixel map of the offscreen img */ &rect, /* portion of the image to compress */ codecHighQuality, /* same compression quality as above */ codecType, /* same codec specifier as above */ hImageDescription, /* the created image description. */ pCompressedData /* ptr to bufr that receives cmp image*/ ); if (osErr != noErr) { printf ("CompressImage failed %d\n", osErr); goto bail; } printf(" 3 \n"); /* Add the compressed image to the movie. ====================================== */ osErr = AddMediaSample ( media, /* the media to add the image to. */ hCompressedData, /* the compressed image to add. */ 0, /* byte offs into data to begin readg */ (**hImageDescription).dataSize,/* num bytes to be copied into media. */ 600 / 30, /* duration of the frame (media time) */ (SampleDescriptionHandle) hImageDescription, /* image desc cast to */ /* a sample description since both */ /* both structures start with same */ /* fields. */ 1, /* num samples in the data buffer. */ 0, /* default flags */ NULL /* ptr to receive media time in which */ /* the image was added. */ ); if (osErr != noErr) { printf ("AddMediaSample failed %d\n", osErr); //goto bail; } printf(" 4 \n"); return; bail: SetGWorld (pSavedPort, hSavedDevice); if (hImageDescription != NULL) DisposeHandle ((Handle) hImageDescription); if (hCompressedData != NULL) DisposeHandle (hCompressedData); if (pMovieGWorld != NULL) DisposeGWorld (pMovieGWorld); } //-------------------------------------------------------- void ofQtVideoSaver::setGworldPixel( GWorldPtr gwPtr, int r, int g, int b, short x, short y){ Ptr gwAddress, gwAddressBase; long gwWidth; char red, blue, green; gwAddressBase = GetPixBaseAddr( GetGWorldPixMap( gwPtr ) ); /* Get head address of offscreen */ gwWidth = ( **GetGWorldPixMap( gwPtr ) ).rowBytes & 0x3fff; /* Get with of offscreen */ gwAddress = gwAddressBase + ( x * 3 ) + ( y * gwWidth ); /* Get adress for current pixel */ *gwAddress = (unsigned char)r; /* Put red and move address forward */ *(gwAddress+1) = (unsigned char)g; /* Put green and move address forward */ *(gwAddress+2) = (unsigned char)b; /* Put blue */ } Node-path: video/ofQtVideoSaver.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1880 Text-content-md5: 6295b8c496f4a707d319e87611408911 Content-length: 1890 PROPS-END #ifndef _QT_VIDEO_GRABBER #define _QT_VIDEO_GRABBER #if TARGET_OS_MAC #include #include #include #else #include #include #include #include #include #include "TextUtils.h" #include #include "QDOffscreen.h" #endif #include "ofConstants.h" #include "ofMain.h" /* in qt, in addition to choosing the codec, we choose the quality: codecLosslessQuality = 0x00000400, codecMaxQuality = 0x000003FF, codecMinQuality = 0x00000000, codecLowQuality = 0x00000100, codecNormalQuality = 0x00000200, codecHighQuality = 0x00000300 how to get this through? */ class ofQtVideoSaver{ public : ofQtVideoSaver(int _w, int _h); void ofQtVideoSaver::finishMovie(bool bFlatten); void ofQtVideoSaver::addFrame(unsigned char * data); //EnterMovies (); void setGworldPixel( GWorldPtr gwPtr, int r, int g, int b, short x, short y); private: //-------------------------------- movie int w; int h; OSErr osErr; short sResId; short sResRefNum; FSSpec fsSpec; Movie movie; Track track; Media media; char *pszFilename; char *pszFlatFilename; // ------------------------------- frame Rect rect; RGBColor rgbColor; CodecType codecType; GWorldPtr pMovieGWorld; PixMapHandle pixMapHandle; Ptr pCompressedData; CGrafPtr pSavedPort; GDHandle hSavedDevice; Handle hCompressedData; long lMaxCompressionSize; ImageDescriptionHandle hImageDescription; }; #endif Revision-number: 2 Prop-content-length: 228 Content-length: 228 K 7 svn:log V 125 Macified everything, changed ofConstants.h, ofGeometry.h, ofQtVideoSaver, ofTrueTypeFont.h, example app now compiles on a mac K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2006-11-21T23:25:55.279958Z PROPS-END Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: change Text-content-length: 3693 Text-content-md5: f9cbc20ba0ee265b0052fa14351ae675 Content-length: 3693 #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); //---------------------------------------------------------- //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- void ofSetBgColor(float r, float g, float b, float a){ bgColor[0] = r; bgColor[1] = g; bgColor[2] = b; bgColor[3] = a; } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } Node-path: graphics/ofTrueTypefont.h Node-kind: file Node-action: change Text-content-length: 2347 Text-content-md5: ddb24d8f4ea988eae915c8da87a4d864 Content-length: 2347 /************************************************************ OpenFrameworks Library File: ofTTFont.h Description: I load true type fonts to use w/ opengl Last Modified: 2004.11.03 Creator: Zachary Lieberman Last Modified By: Notes: // GL_INTENSITY SEEMS THE BEST for internal texture format / blending modes // - ZACH // // can we investigate the FT_FONT_SIZE and options for small, // non anti-aliased type ? // need to spend some moments thinking about how free type renders type // and how to pick good sizes, etc. // // ************************************************************/ #ifndef _OF_TTF_FONT_H_ #define _OF_TTF_FONT_H_ // freetype: #include "ofConstants.h" #ifdef TARGET_WIN32 #include #include #include #include #include #endif #ifdef TARGET_OSX #include "ft2build.h" #include "freetype.h" #include "ftglyph.h" #include "ftoutln.h" #include "fttrigon.h" #endif typedef struct { int value; int height; int width; int setWidth; int topExtent; int leftExtent; float tTex; float vTex; //0-1 pct of bitmap... } charProps; #define NUM_CHARACTERS_TO_LOAD 256 // ascii char set class ofTrueTypeFont{ public: ofTrueTypeFont(const char *filename, int fontsize); bool bLoadedOk; float getDescent(); float getHeight(); float charWidth(unsigned char c); float charHeight(int c); bool charExists(char c); void drawChar(int c, float x, float y); float charArea(unsigned char c); float charLeftExtent(unsigned char c); float charBitmapWidth(int c); float charBitmapHeight(int c); float charTop(int c); float charTopExtent(int c); //void ftLoadGlyph( ) float stringWidth(char *s); void drawString(char *c, float x, float y); int ofNextPow2 ( int a ); protected: int FT_FONT_SIZE; int numChars; int numBits; int mboxX; int mboxY; int baseHt; charProps * cps; // properties for each character unsigned char **images; float *charAreas; GLuint *texNames; int ofTTFont_texW; int ofTTFont_texH; }; #endif Node-path: utils/ofConstants.h Node-kind: file Node-action: change Text-content-length: 1781 Text-content-md5: 7a8fbd0ab56cbdc60dd4a1f7bb27de00 Content-length: 1781 /************************************************************ OpenFrameworks Library File: ofConstants.h Description: constants, h file stuff, #define multi OS trickery Notes: PI, min, max, etc, etc ************************************************************/ #ifndef OF_CONSTANTS #define OF_CONSTANTS //#define TARGET_WIN32 #define TARGET_OSX #ifdef TARGET_WIN32 #include #include "glut.h" #define __WINDOWS_DS__ #define __WINDOWS_MM__ #endif #ifdef TARGET_OSX #define __MACOSX_CORE__ #include #endif // core: --------------------------- #include #include #include #include #include #ifndef PI #define PI 3.14159265358979323846 #endif #ifndef TWO_PI #define TWO_PI 6.28318530717958647693 #endif #ifndef M_TWO_PI #define M_TWO_PI 6.28318530717958647693 #endif #ifndef FOUR_PI #define FOUR_PI 12.56637061435917295385 #endif #ifndef HALF_PI #define HALF_PI 1.57079632679489661923 #endif #ifndef DEG_TO_RAD #define DEG_TO_RAD (PI/180.0) #endif #ifndef RAD_TO_DEG #define RAD_TO_DEG (180.0/PI) #endif #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #endif #ifndef ABS #define ABS(x) (((x) < 0) ? -(x) : (x)) #endif #define OF_FILLED 0x01 #define OF_OUTLINE 0x02 #define OF_WINDOW 0 #define OF_FULLSCREEN 1 // these are in the "ofAppRunner.cpp" based on the various windowing options. //-------------------------------------- void ofGetWindowSize( int * w, int * h); float ofGetTimef(); int ofGetTimeMillis(); #endif Node-path: video/ofQtVideoSaver.cpp Node-kind: file Node-action: change Text-content-length: 15299 Text-content-md5: 544a4786779f3968ed0810655d39f00e Content-length: 15299 #include "ofQtVideoSaver.h" // quality, size ofQtVideoSaver::ofQtVideoSaver(int _w, int _h){ w = _w; h = _h; pszFilename = "../my.mov"; pszFlatFilename = "../myflat.mov"; sResRefNum = 0; movie = nil; track = NULL; media = NULL; pMovieGWorld = NULL; pixMapHandle = NULL; pCompressedData = NULL; pSavedPort = NULL; hSavedDevice = NULL; hCompressedData = NULL; lMaxCompressionSize = 0L; hImageDescription = NULL; printf(" 02 \n"); #ifdef TARGET_WIN32 InitializeQTML(0); #endif EnterMovies(); printf(" 0 \n"); /* Load the FSSpec structure to describe the receiving file. For a description of this and related calls see http://developer.apple.com/quicktime/icefloe/dispatch004.html. ================================================================ */ #ifdef TARGET_WIN32 osErr = NativePathNameToFSSpec (pszFilename, &fsSpec, 0); #endif #ifdef TARGET_OSX Boolean isdir; osErr = FSPathMakeRef((const UInt8*)pszFilename, &fsref, &isdir); osErr = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &fsSpec, NULL); #endif if (osErr && (osErr != fnfErr)) /* File-not-found error is ok */ { printf ("NativePathNameToFSSpec failed %d\n", osErr); goto bail; } printf(" 1 \n"); /* Step 1: Create a new, empty movie file and a movie that references that file (CreateMovieFile). ======================================================================== */ osErr = CreateMovieFile ( &fsSpec, /* FSSpec specifier */ FOUR_CHAR_CODE('TVOD'), /* file creator type, TVOD = QT player*/ smCurrentScript, /* movie script system to use */ createMovieFileDeleteCurFile /* movie file creation flags */ | createMovieFileDontCreateResFile, &sResRefNum, /* returned file ref num to data fork */ &movie /* returned handle to open empty movie*/ /* that references the created file */ ); if (osErr) { printf ("CreateMovieFile failed %d\n", osErr); goto bail; } printf(" 2 \n"); /* Step 2: Add a new track to that movie (NewMovieTrack). ======================================================= */ track = NewMovieTrack ( movie, /* the movie to add track to */ ((long) w << 16), /* width of track in pixels (Fixed) */ FixRatio (h, 1), /* height of track in pixels (Fixed) */ kNoVolume /* default volume level */ ); osErr = GetMoviesError (); if (osErr) { printf ("NewMovieTrack failed %d\n", osErr); goto bail; } printf(" 3 \n"); /* Step 3: Add a new media to that track (NewTrackMedia). ======================================================= */ media = NewTrackMedia ( track, /* the track to add the media to */ VideoMediaType, /* media type, e.g. SoundMediaType */ 600, /* num media time units that elapse/sec*/ NULL, /* ptr to file that holds media sampls*/ 0 /* type of ptr to media samples */ ); osErr = GetMoviesError (); if (osErr) { printf ("NewTrackMedia failed %d\n", osErr); goto bail; } printf(" 4 \n"); /* Step 4: Add media samples to the media. ======================================== */ BeginMediaEdits (media); /* Inform the Movie Toolbox that we */ /* want to change the media samples */ /* referenced by a track's media. */ /* This opens the media container */ /* and makes it ready to receive */ /* and/or remove sample data. */ printf(" 5 \n"); // Step 5: setup graphics port for qt movie and compression type --- /* Create a new offscreen graphics world that will hold the movie's drawing surface. draw_image() copies the image of IceFlow to this surface with varying amounts of transparency. ================================================================= */ MacSetRect (&rect, 0, 0, w, h); osErr = NewGWorld ( &pMovieGWorld, /* receives the new GWorld. */ 24, /* pixel depth in bits/pixel */ &rect, /* desired size of the GWorld. */ NULL, NULL, (GWorldFlags) 0 ); if (osErr != noErr) { printf ("NewGWorld 1 failed %d\n", osErr); goto bail; } printf(" 6 \n"); /* Retrieve the pixel map associated with that graphics world and lock the pixel map in memory. GetMaxCompressionSize() and CompressImage() only operate on pixel maps, not graphics worlds. ===================================================================== */ pixMapHandle = GetGWorldPixMap (pMovieGWorld); if (pixMapHandle == NULL) { printf ("GetGWorldPixMap failed\n"); goto bail; } LockPixels (pixMapHandle); /* Get the maximum number of bytes required to hold an image having the specified characteristics compressed using the specified compressor. ==================================================================== */ codecType = kJPEGCodecType; osErr = GetMaxCompressionSize ( pixMapHandle, /* the pixel map to compress from. */ &rect, /* the image rectangle. */ 0, /* let ICM choose image bit depth. */ codecHighQuality, /* compression quality specifier. */ codecType, /* desired compression type */ (CompressorComponent) anyCodec, /* codec specifier. */ &lMaxCompressionSize /* receives max bytes needed for cmp. */ ); if (osErr != noErr) { printf ("GetMaxCompressionSize failed %d\n", osErr); goto bail; } /* Allocate a buffer to hold the compressed image data by creating a new handle. ===================================================================== */ printf(" 7 \n"); hCompressedData = NewHandle (lMaxCompressionSize); if (hCompressedData == NULL) { printf ("NewHandle(%ld) failed\n", lMaxCompressionSize); goto bail; } printf(" 8 \n"); /* Lock the handle and then dereference it to obtain a pointer to the data buffer because CompressImage() wants us to pass it a pointer, not a handle. ======================================================================= */ HLockHi (hCompressedData); pCompressedData = *hCompressedData; printf(" 9 \n"); /* Create an image description object in memory of minimum size to pass to CompressImage(). CompressImage() will resize the memory as necessary so create it small here. ==================================================================== */ hImageDescription = (ImageDescriptionHandle) NewHandle (4); if (hImageDescription == NULL) { printf ("NewHandle(4) failed\n"); goto bail; } printf(" 10 \n"); return; bail: if (sResRefNum != 0) CloseMovieFile (sResRefNum); if (movie != NULL) DisposeMovie (movie); //ExitMovies (); /* Finalize Quicktime */ return; } //----------------------------------------------------------------------------- void ofQtVideoSaver::finishMovie(bool bFlatten){ EndMediaEdits (media); /* Inform the Movie Toolbox that they */ /* can close the media container. */ /* Step 5: Insert a reference into the track that specifies which of the media samples to play and when to start playing them. ====================================================================== */ InsertMediaIntoTrack ( track, /* the track to update. */ 0, /* time in track where the specified */ /* media samples should start playg */ /* using movie time scale. */ 0, /* time in media samples of the first */ /* sample to play using media time */ /* scale. */ GetMediaDuration (media), /* duration of media samples to play */ /* using media time scale. */ 1L<<16 //fixed1 /* rate at which to play the samples. */ ); /* Step 6: Append the movie atom to the movie file (AddMovieResource). ==================================================================== */ sResId = movieInDataForkResID; osErr = AddMovieResource ( movie, /* movie to create moov atom from */ sResRefNum, /* file to receive the moov atom */ &sResId, /* id num of movie resource (res fork)*/ (unsigned char *) pszFilename /* name of movie resource (res fork) */ ); if (osErr) { printf ("AddMovieResource failed %d\n", osErr); goto bail; } if (sResRefNum != 0) { CloseMovieFile (sResRefNum); /* close file CreateMovieFile opened */ sResRefNum = 0; } /* Step 7 (optional): Place the movie atom as the first atom in a new movie file, and interleave the media data (FlattenMovieData). =================================================================== */ //if (bFlatten) flatten_my_movie (movie, pszFlatFilename); /* Step 8: Close the movie file that CreateMovieFile opened (if necessary) and dispose of the movie memory structures (DisposeMovie). ======================================================================== */ bail: if (sResRefNum != 0) CloseMovieFile (sResRefNum); if (movie != NULL) DisposeMovie (movie); //ExitMovies (); /* Finalize Quicktime */ //return (0); } void ofQtVideoSaver::addFrame(unsigned char * data){ /* Save the current GWorld and set the offscreen GWorld as current. ================================================================ */ GetGWorld (&pSavedPort, &hSavedDevice); SetGWorld (pMovieGWorld, NULL); Ptr gwAddress, gwAddressBase; long gwWidth; gwAddressBase = GetPixBaseAddr( GetGWorldPixMap( pMovieGWorld ) ); /* Get head address of offscreen */ gwWidth = ( **GetGWorldPixMap( pMovieGWorld ) ).rowBytes & 0x3fff; /* Get with of offscreen */ //gwAddress = gwAddressBase + ( x * 3 ) + ( y * gwWidth ); /* Get adress for current pixel */ int myWidth = w*3; for (int i = 0; i < h; i++){ gwAddress = gwAddressBase + i * gwWidth; memcpy(gwAddress, data, myWidth); data += myWidth; } /* Compress the pixel map that has just been drawn on. Also resize and fill in the image description. Resulting image size can be discovered by consulting the image description field dataSize. ================================================================ */ osErr = CompressImage ( pixMapHandle, /* the pixel map of the offscreen img */ &rect, /* portion of the image to compress */ codecHighQuality, /* same compression quality as above */ codecType, /* same codec specifier as above */ hImageDescription, /* the created image description. */ pCompressedData /* ptr to bufr that receives cmp image*/ ); if (osErr != noErr) { printf ("CompressImage failed %d\n", osErr); goto bail; } printf(" 3 \n"); /* Add the compressed image to the movie. ====================================== */ osErr = AddMediaSample ( media, /* the media to add the image to. */ hCompressedData, /* the compressed image to add. */ 0, /* byte offs into data to begin readg */ (**hImageDescription).dataSize,/* num bytes to be copied into media. */ 600 / 30, /* duration of the frame (media time) */ (SampleDescriptionHandle) hImageDescription, /* image desc cast to */ /* a sample description since both */ /* both structures start with same */ /* fields. */ 1, /* num samples in the data buffer. */ 0, /* default flags */ NULL /* ptr to receive media time in which */ /* the image was added. */ ); if (osErr != noErr) { printf ("AddMediaSample failed %d\n", osErr); //goto bail; } printf(" 4 \n"); return; bail: SetGWorld (pSavedPort, hSavedDevice); if (hImageDescription != NULL) DisposeHandle ((Handle) hImageDescription); if (hCompressedData != NULL) DisposeHandle (hCompressedData); if (pMovieGWorld != NULL) DisposeGWorld (pMovieGWorld); } //-------------------------------------------------------- void ofQtVideoSaver::setGworldPixel( GWorldPtr gwPtr, int r, int g, int b, short x, short y){ Ptr gwAddress, gwAddressBase; long gwWidth; char red, blue, green; gwAddressBase = GetPixBaseAddr( GetGWorldPixMap( gwPtr ) ); /* Get head address of offscreen */ gwWidth = ( **GetGWorldPixMap( gwPtr ) ).rowBytes & 0x3fff; /* Get with of offscreen */ gwAddress = gwAddressBase + ( x * 3 ) + ( y * gwWidth ); /* Get adress for current pixel */ *gwAddress = (unsigned char)r; /* Put red and move address forward */ *(gwAddress+1) = (unsigned char)g; /* Put green and move address forward */ *(gwAddress+2) = (unsigned char)b; /* Put blue */ } Node-path: video/ofQtVideoSaver.h Node-kind: file Node-action: change Text-content-length: 1898 Text-content-md5: b335e642d79ffb811d0db2b2ac99a3b2 Content-length: 1898 #ifndef _QT_VIDEO_GRABBER #define _QT_VIDEO_GRABBER #if TARGET_OS_MAC #include #include #include #else #include #include #include #include #include #include "TextUtils.h" #include #include "QDOffscreen.h" #endif #include "ofConstants.h" #include "ofMain.h" /* in qt, in addition to choosing the codec, we choose the quality: codecLosslessQuality = 0x00000400, codecMaxQuality = 0x000003FF, codecMinQuality = 0x00000000, codecLowQuality = 0x00000100, codecNormalQuality = 0x00000200, codecHighQuality = 0x00000300 how to get this through? */ class ofQtVideoSaver{ public : ofQtVideoSaver(int _w, int _h); void ofQtVideoSaver::finishMovie(bool bFlatten); void ofQtVideoSaver::addFrame(unsigned char * data); //EnterMovies (); void setGworldPixel( GWorldPtr gwPtr, int r, int g, int b, short x, short y); private: //-------------------------------- movie int w; int h; OSErr osErr; short sResId; short sResRefNum; FSSpec fsSpec; Movie movie; Track track; Media media; char *pszFilename; char *pszFlatFilename; FSRef fsref; // ------------------------------- frame Rect rect; RGBColor rgbColor; CodecType codecType; GWorldPtr pMovieGWorld; PixMapHandle pixMapHandle; Ptr pCompressedData; CGrafPtr pSavedPort; GDHandle hSavedDevice; Handle hCompressedData; long lMaxCompressionSize; ImageDescriptionHandle hImageDescription; }; #endif Revision-number: 3 Prop-content-length: 124 Content-length: 124 K 7 svn:log V 22 RGB for qtVideoGrabber K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2006-11-23T08:08:42.852246Z PROPS-END Node-path: video/ofQtVideoGrabber.cpp Node-kind: file Node-action: change Text-content-length: 6369 Text-content-md5: 671d4e6ddd7cc95285f4aa7664c039aa Content-length: 6369 #include "ofQtVideoGrabber.h" //-------------------------------------------------------------------- //-------------------------------------------------------------------- // static stuff I don't understand exactly, looks like most legacy mac code :( static pascal Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon){ #pragma unused(theDialog, itemHit) // Ordinarily, if we had multiple windows we cared about, we'd handle // updating them in here, but since we don't, we'll just clear out // any update events meant for us Boolean handled = false; if ((theEvent->what == updateEvt) && ((WindowPtr) theEvent->message == (WindowPtr) refCon)) { BeginUpdate ((WindowPtr) refCon); EndUpdate ((WindowPtr) refCon); handled = true; } return (handled); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- //-------------------------------------------------------------------- ofQtVideoGrabber::ofQtVideoGrabber(int w, int h){ capSizeW = w; capSizeH = h; initVideo(); } //-------------------------------------------------------------------- void ofQtVideoGrabber::fillBufferWithVideoData(unsigned char * data){ //Now we remove the alpha from the image as we return it int totalPixels = capSizeW * capSizeH * 3; //Get the total image size int imgRowBytes = capSizeW*4; //Get the width in bytes of the image data int padding = rowBytes - imgRowBytes; //Figure out how much padding (empty) data is on each row unsigned char * vidPtr = (unsigned char *) baseAddr; //Set them to start at the same place int ref = 0; //So we know where we are for(int i = 0; i < totalPixels-4; i+=4) //Go through 4 pixels at a time. { if(ref%imgRowBytes == 0) vidPtr += padding; //When we get to padding we go to the next row memcpy(data, vidPtr+1, 3); //Copy the RGB data from the ARGB pixel - hence the shift by 1 //Is memcpy effecient enough?? vidPtr+= 4; ref += 4; data+= 3; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::grabFrame(){ SGIdle(gSeqGrabber); } //-------------------------------------------------------------------- void ofQtVideoGrabber::close(){ } //-------------------------------------------------------------------- void ofQtVideoGrabber::videoSettings(void) { Rect newActiveVideoRect; Rect adjustedActiveVideoRect; Rect curBounds, curVideoRect, newVideoRect, newBounds; short width, height; ComponentResult err; GrafPtr savedPort; RgnHandle deadRgn; SGModalFilterUPP seqGragModalFilterUPP; // Get our current state err = SGGetChannelBounds (gVideoChannel, &curBounds); err = SGGetVideoRect (gVideoChannel, &curVideoRect); // Pause err = SGPause (gSeqGrabber, true); // Do the dialog thang static SGModalFilterUPP gSeqGrabberModalFilterUPP = NewSGModalFilterUPP(SeqGrabberModalFilterUPP); int result = SGSettingsDialog(gSeqGrabber, gVideoChannel, 0, nil, seqGrabSettingsPreviewOnly, gSeqGrabberModalFilterUPP, nil); //printf("%d\n", result); #if !TARGET_OS_MAC // This is necessary, for now, to get the grab to start again afer the // dialog goes away. For some reason the video destRect never gets reset to point // back to the monitor window. SGSetChannelBounds(gVideoChannel, &videoRect); #endif // The pause that refreshes err = SGPause (gSeqGrabber, false); } //-------------------------------------------------------------------- void ofQtVideoGrabber::initVideo(){ ComponentDescription theDesc; ComponentResult theresult; Component sgCompID = NULL; char name[256]; char info[256]; Handle componentName=NULL; Handle componentInfo=NULL; ComponentDescription info_description; EnterMovies(); componentName=NewHandle(sizeof(name)); componentInfo=NewHandle(sizeof(info)); gSeqGrabber = 0L; gVideoChannel = 0L; theDesc.componentType = SeqGrabComponentType; theDesc.componentSubType = 0L; theDesc.componentManufacturer = 0L; //'appl'; theDesc.componentFlags = 0L; theDesc.componentFlagsMask = 0L; sgCompID = FindNextComponent(sgCompID, &theDesc); while (sgCompID != 0){ GetComponentInfo(sgCompID,&info_description, componentName, componentInfo,nil); printf("found a device to capture with \n"); printf("Type: %s\n", &info_description.componentType); printf("Manufacturer: %s\n", &info_description.componentManufacturer); printf("Name: %s\n", *componentName ? p2cstr((StringPtr)*componentName) : "-" ); printf("Name: %s\n", *componentInfo ? p2cstr((StringPtr)*componentInfo) : "-"); gSeqGrabber = (VideoDigitizerComponent)OpenComponent(sgCompID); //gSeqGrabber == 0L; sgCompID = FindNextComponent(sgCompID, &theDesc); } DigitizerInfo vdigInfo; VDGetDigitizerInfo(gSeqGrabber, &vdigInfo); if ( vdigInfo.inputCapabilityFlags & digiInDoesComposite){ // finding out about composite... } MacSetRect(&videoRect,0, 0, capSizeW, capSizeH); // Get the digitizer rect to test destination params SGInitialize(gSeqGrabber); QTNewGWorld( &videogworld , k32ARGBPixelFormat , &videoRect, nil, nil, 0); // IV-2817 GWorldPtr offWorld = (GWorldPtr)videogworld; baseAddr = GetPixBaseAddr(GetGWorldPixMap(offWorld)); rowBytes = GetPixRowBytes(GetGWorldPixMap(offWorld)); videoPixMapH = GetGWorldPixMap(videogworld); videoBuffer = (unsigned char *)GetPixBaseAddr(videoPixMapH ); SGSetGWorld(gSeqGrabber, videogworld, nil); SGNewChannel(gSeqGrabber, VideoMediaType, &gVideoChannel); SGSetChannelUsage(gVideoChannel, seqGrabPreview | seqGrabRecord | seqGrabPlayDuringRecord); if (SGSetFrameRate(gVideoChannel,30) != noErr) printf( "error setting 30 fps \n"); else printf ("set to capture at 30 fps \n"); SGSetChannelBounds(gVideoChannel, &videoRect); SGStartPreview(gSeqGrabber); ComponentInstance vdig; vdig = SGGetVideoDigitizerComponent(gVideoChannel); if(VDSetInput(vdig, 0)!=noErr)printf("VDSetInput error\n"); if(VDSetInputStandard (vdig, ntscIn)!=noErr)printf("VDSetInputStandard error\n"); videoSettings(); } //-------------------------------------------------------------------- Node-path: video/ofQtVideoGrabber.h Node-kind: file Node-action: change Text-content-length: 1189 Text-content-md5: 153f4eaa2df867b186a069ade775bc92 Content-length: 1189 #ifndef _QT_VIDEO_GRABBER #define _QT_VIDEO_GRABBER // windows / mac keep qt in different places: #if TARGET_OS_MAC #include #include #include #else #include #include #include #include #include "TextUtils.h" #include #include "QDOffscreen.h" #endif #include "ofConstants.h" #include "stdio.h" #include "string.h" #define QT_VG_BYTES_PER_PIXEL 3 class ofQtVideoGrabber{ public : ofQtVideoGrabber(int w, int h); void fillBufferWithVideoData(unsigned char *); unsigned char * returnDataPtr(); void grabFrame(); void close(); void initVideo(); int getBytesPerPixel() { return QT_VG_BYTES_PER_PIXEL; }; void videoSettings(); int capSizeW; int capSizeH; Ptr baseAddr; long rowBytes; private: GWorldPtr videogworld; SeqGrabComponent gSeqGrabber; SGChannel gVideoChannel; PixMapHandle videoPixMapH; unsigned char * videoBuffer; int videoRowWidth; Rect videoRect; }; #endif Node-path: video/ofQtVideoPlayer.h Node-kind: file Node-action: change Text-content-length: 1575 Text-content-md5: fff9d45cb06a037342e30302c6ff0ee8 Content-length: 1575 #ifndef _QT_VIDEO_PLAYER #define _QT_VIDEO_PLAYER #include "ofConstants.h" #ifdef TARGET_WIN32 #include // Quicktime Headers #include #include #include #include "TextUtils.h" #include "QuickDraw.h" #endif #ifdef TARGET_OSX #include #include #include #endif #include "stdio.h" #include "string.h" #include "ofMain.h" #include #include #include #define BYTES_PER_PIXEL 3 class ofQtVideoPlayer{ public: ofQtVideoPlayer (char * fileName); ofQtVideoPlayer (); void fillBufferWithVideoData(unsigned char *); void grabFrame(); void goToTime(float pct); void getNextFrame(float pct); void close(); float getMovieDuration(); float getMoviePct(); void setSpeed(float speed); float getSpeed(); bool loadMovie(char * name); int w, h; int totalImageSize; int totalNumFrames; int currentFrame; float speed; bool createMovieFromPath(char * path, Movie * movie); GWorldPtr offWorld; GWorldPtr gw; Movie theMovie; MovieController thePlayer; Rect rectMovie; PixMapHandle videoPixMapH; unsigned char * videoBuffer; unsigned char * videoBuffer2; void setMoviePct(float pct); float pctBlur; // zach's insane time idea: long lastTime; float lastTimeStamp; float durationTime; float durationPct; }; #endif Revision-number: 4 Prop-content-length: 179 Content-length: 179 K 7 svn:log V 77 mac/pc working - returns rgb image, look for a qt solution to do this instead K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2006-11-24T15:34:33.877161Z PROPS-END Node-path: video/ofQtVideoGrabber.cpp Node-kind: file Node-action: change Text-content-length: 6638 Text-content-md5: aab47e2e6f66bfb6fcfb0dbf26cac611 Content-length: 6638 #include "ofQtVideoGrabber.h" //-------------------------------------------------------------------- //-------------------------------------------------------------------- // static stuff I don't understand exactly, looks like most legacy mac code :( static pascal Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon){ #pragma unused(theDialog, itemHit) // Ordinarily, if we had multiple windows we cared about, we'd handle // updating them in here, but since we don't, we'll just clear out // any update events meant for us Boolean handled = false; if ((theEvent->what == updateEvt) && ((WindowPtr) theEvent->message == (WindowPtr) refCon)) { BeginUpdate ((WindowPtr) refCon); EndUpdate ((WindowPtr) refCon); handled = true; } return (handled); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- //-------------------------------------------------------------------- ofQtVideoGrabber::ofQtVideoGrabber(int w, int h){ capSizeW = w; capSizeH = h; initVideo(); } //-------------------------------------------------------------------- void ofQtVideoGrabber::fillBufferWithVideoData(unsigned char * data){ //Now we remove the alpha from the image as we return it int totalPixels = capSizeW * capSizeH * 4; //Get the total image size int imgRowBytes = capSizeW*4; //Get the width in bytes of the image data int padding = rowBytes - imgRowBytes; //Figure out how much padding (empty) data is on each row unsigned char * vidPtr = (unsigned char *) baseAddr; //Set them to start at the same place int ref = 0; //So we know where we are for(int i = 0; i < totalPixels-4; i+=4) //Go through 4 pixels at a time. { if(ref%imgRowBytes == 0) vidPtr += padding; //When we get to padding we go to the next row memcpy(data, vidPtr+1, 3); //Copy the RGB data from the ARGB pixel - hence the shift by 1 //Is memcpy effecient enough?? vidPtr+= 4; ref += 4; data+= 3; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::grabFrame(){ SGIdle(gSeqGrabber); } //-------------------------------------------------------------------- void ofQtVideoGrabber::close(){ } //-------------------------------------------------------------------- void ofQtVideoGrabber::videoSettings(void) { Rect newActiveVideoRect; Rect adjustedActiveVideoRect; Rect curBounds, curVideoRect, newVideoRect, newBounds; short width, height; ComponentResult err; GrafPtr savedPort; RgnHandle deadRgn; SGModalFilterUPP seqGragModalFilterUPP; // Get our current state err = SGGetChannelBounds (gVideoChannel, &curBounds); err = SGGetVideoRect (gVideoChannel, &curVideoRect); // Pause err = SGPause (gSeqGrabber, true); // Do the dialog thang #ifdef TARGET_OSX static SGModalFilterUPP gSeqGrabberModalFilterUPP = NewSGModalFilterUPP(SeqGrabberModalFilterUPP); int result = SGSettingsDialog(gSeqGrabber, gVideoChannel, 0, nil, seqGrabSettingsPreviewOnly, gSeqGrabberModalFilterUPP, nil); printf("%d\n", result); #else err = SGSettingsDialog(gSeqGrabber, gVideoChannel, 0, nil, 0L, NULL, nil); #endif #ifdef TARGET_WIN32 // This is necessary, for now, to get the grab to start again afer the // dialog goes away. For some reason the video destRect never gets reset to point // back to the monitor window. SGSetChannelBounds(gVideoChannel, &videoRect); #endif // The pause that refreshes err = SGPause (gSeqGrabber, false); } //-------------------------------------------------------------------- void ofQtVideoGrabber::initVideo(){ ComponentDescription theDesc; ComponentResult theresult; Component sgCompID = NULL; char name[256]; char info[256]; Handle componentName=NULL; Handle componentInfo=NULL; ComponentDescription info_description; #ifdef TARGET_WIN32 InitializeQTML(0); #endif EnterMovies(); componentName=NewHandle(sizeof(name)); componentInfo=NewHandle(sizeof(info)); gSeqGrabber = 0L; gVideoChannel = 0L; theDesc.componentType = SeqGrabComponentType; theDesc.componentSubType = 0L; theDesc.componentManufacturer = 0L; //'appl'; theDesc.componentFlags = 0L; theDesc.componentFlagsMask = 0L; sgCompID = FindNextComponent(sgCompID, &theDesc); while (sgCompID != 0){ GetComponentInfo(sgCompID,&info_description, componentName, componentInfo,nil); printf("found a device to capture with \n"); printf("Type: %s\n", &info_description.componentType); printf("Manufacturer: %s\n", &info_description.componentManufacturer); printf("Name: %s\n", *componentName ? p2cstr((StringPtr)*componentName) : "-" ); printf("Name: %s\n", *componentInfo ? p2cstr((StringPtr)*componentInfo) : "-"); gSeqGrabber = OpenComponent(sgCompID); //gSeqGrabber == 0L; sgCompID = FindNextComponent(sgCompID, &theDesc); } DigitizerInfo vdigInfo; VDGetDigitizerInfo(gSeqGrabber, &vdigInfo); if ( vdigInfo.inputCapabilityFlags & digiInDoesComposite){ // finding out about composite... } // Get the digitizer rect to test destination params SGInitialize(gSeqGrabber); MacSetRect(&videoRect,0, 0, capSizeW, capSizeH); QTNewGWorld( &videogworld , k32ARGBPixelFormat , &videoRect, nil, nil, 0); // IV-2817 videoPixMapH = GetGWorldPixMap(videogworld); videoBuffer = (unsigned char *)GetPixBaseAddr(videoPixMapH ); GWorldPtr offWorld = (GWorldPtr)videogworld; baseAddr = GetPixBaseAddr(GetGWorldPixMap(offWorld)); #ifdef TARGET_OSX rowBytes = GetPixRowBytes(GetGWorldPixMap(offWorld)); #else rowBytes = (**GetGWorldPixMap(offWorld)).rowBytes & 0x3fff; #endif SGSetGWorld(gSeqGrabber, videogworld, nil); SGNewChannel(gSeqGrabber, VideoMediaType, &gVideoChannel); SGSetChannelUsage(gVideoChannel, seqGrabPreview | seqGrabRecord | seqGrabPlayDuringRecord); if (SGSetFrameRate(gVideoChannel,30) != noErr) printf( "error setting 30 fps \n"); else printf ("set to capture at 30 fps \n"); OSStatus err; SGSetChannelBounds(gVideoChannel, &videoRect); SGStartPreview(gSeqGrabber); ComponentInstance vdig; vdig = SGGetVideoDigitizerComponent(gVideoChannel); if(VDSetInput(vdig, 0)!=noErr)printf("VDSetInput error\n"); if(VDSetInputStandard (vdig, ntscIn)!=noErr)printf("VDSetInputStandard error\n"); videoSettings(); } //-------------------------------------------------------------------- Revision-number: 5 Prop-content-length: 143 Content-length: 143 K 7 svn:log V 41 zach - changes for the near-first release K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-01-15T14:56:32.796191Z PROPS-END Node-path: ofMain.h Node-kind: file Node-action: change Text-content-length: 538 Text-content-md5: 72cc83043c69f12879e2bbacf6750553 Content-length: 538 #ifndef OF_MAIN_H #define OF_MAIN_H //-------------------------- // utils #include "ofConstants.h" #include "ofMath.h" #include "ofUtils.h" //-------------------------- // graphics #include "ofTexture.h" #include "ofTrueTypeFont.h" #include "ofGraphics.h" #include "ofImage.h" //-------------------------- // app #include "ofSimpleApp.h" #include "ofAppRunner.h" //-------------------------- // audio #include "ofAudio.h" //-------------------------- // video #include "ofQtVideoGrabber.h" #include "ofQtVideoPlayer.h" #endif Revision-number: 6 Prop-content-length: 168 Content-length: 168 K 7 svn:log V 66 zach - qt changes, alot cleaner, w/ callbacks or semi-callbacks... K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-01-15T15:01:41.621049Z PROPS-END Node-path: video/ofQtUtils.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1892 Text-content-md5: 2367da86d6065f60823b88b13d3ddebe Content-length: 1902 PROPS-END #include "ofQtUtils.h" static bool bQuicktimeInitialized = true; //---------------------------------------- void initializeQuicktime(){ if (bQuicktimeInitialized == true){ //---------------------------------- // do we have quicktime installed at all? // http://www.apple.com/quicktime/download/win.html // can gestalt help with versions, or is that only after init? long myAttrs; OSErr myErr = noErr; #ifdef TARGET_WIN32 myErr = InitializeQTML(0); if (myErr != noErr){ printf("----------------------------------------------------- \n"); printf("sorry, there is a problem with quicktime starting up \nplease check!"); std::exit(0); } #endif myErr = EnterMovies (); if (myErr != noErr){ printf("----------------------------------------------------- \n"); printf("sorry, there is a problem with quicktime starting up \nplease check!"); std::exit(0); } bQuicktimeInitialized = false; } } //---------------------------------------- void convertPixels(unsigned char * gWorldPixels, unsigned char * rgbPixels, int w, int h){ // ok for macs? // ok for intel macs? int * rgbaPtr = (int *) gWorldPixels; pix24 * rgbPtr = (pix24 *) rgbPixels; int totalPixelCount = w * h; unsigned char * rgbaStart; bool bFlipVertically = true; if (!bFlipVertically){ //----- argb->rgb for (int i = 0; i < totalPixelCount; i++){ rgbaStart = (unsigned char *)rgbaPtr; memcpy (rgbPtr, rgbaStart+1, sizeof(pix24)); rgbPtr++; rgbaPtr++; } } else { //----- flip while argb->rgb for (int i = 0; i < h; i++){ pix24 * rgbPtr = (pix24 *) rgbPixels + ((h-i-1) * w); for (int j = 0; j < w; j++){ rgbaStart = (unsigned char *)rgbaPtr; memcpy (rgbPtr, rgbaStart+1, sizeof(pix24)); rgbPtr++; rgbaPtr++; } } } } Node-path: video/ofQtUtils.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 612 Text-content-md5: 5b39c67bdd107123d180e1517a25ed0a Content-length: 622 PROPS-END #ifndef _QT_UTILS #define _QT_UTILS #include "ofConstants.h" #if TARGET_OS_MAC #include #include #include #else #include #include #include #include #endif typedef struct{ unsigned char r; unsigned char g; unsigned char b; } pix24; //---------------------------------------- void initializeQuicktime(); void convertPixels(unsigned char * gWorldPixels, unsigned char * rgbPixels, int w, int h); #endif Node-path: video/ofQtVideoGrabber.cpp Node-kind: file Node-action: change Text-content-length: 6851 Text-content-md5: ad6f1b87838b48576a7600005dfb88a9 Content-length: 6851 #include "ofQtVideoGrabber.h" //-------------------------------------------------------------------- Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon); Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon){ #pragma unused(theDialog, itemHit) Boolean handled = false; if ((theEvent->what == updateEvt) && ((WindowPtr) theEvent->message == (WindowPtr) refCon)) { BeginUpdate ((WindowPtr) refCon); EndUpdate ((WindowPtr) refCon); handled = true; } return (handled); } //-------------------------------------------------------------------- ofQtVideoGrabber::ofQtVideoGrabber(){ initializeQuicktime(); vgd = new videoGrabberData(); bVerbose = false; bSgGrabberInited = false; } //-------------------------------------------------------------------- void ofQtVideoGrabber::setVerbose(bool bTalkToMe){ bVerbose = bTalkToMe; } //--------------------------------------------------------------------------- unsigned char * ofQtVideoGrabber::getPixels(){ return vgd->pixels; } //--------------------------------------------------------------------------- bool ofQtVideoGrabber::isFrameNew(){ if (bSgGrabberInited == true){ bool bNew = false; if (vgd->bHavePixelsChanged == true){ bNew = true; vgd->bHavePixelsChanged = false; } return bNew; } else { return false; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::grabFrame(){ if (bSgGrabberInited == true){ SGIdle(vgd->gSeqGrabber); // set the top pixel alpha = 0, so we can know if it // was a new frame or not.. // or else we will process way more than necessary // (ie opengl is running at 60fps +, capture at 30fps) if (vgd->offscreenGWorldPixels[0] != 0x00){ vgd->offscreenGWorldPixels[0] = 0x00; vgd->bHavePixelsChanged = true; convertPixels(vgd->offscreenGWorldPixels, vgd->pixels, vgd->w, vgd->h); } } } //-------------------------------------------------------------------- void ofQtVideoGrabber::close(){ // } //-------------------------------------------------------------------- void ofQtVideoGrabber::videoSettings(void){ Rect curBounds, curVideoRect; short width, height; ComponentResult err; // Get our current state err = SGGetChannelBounds (vgd->gVideoChannel, &curBounds); if (err != noErr){ printf("Error in SGGetChannelBounds \n"); return; } err = SGGetVideoRect (vgd->gVideoChannel, &curVideoRect); if (err != noErr){ printf("Error in SGGetVideoRect \n"); return; } // Pause err = SGPause (vgd->gSeqGrabber, true); if (err != noErr){ printf("Error in SGPause\n"); return; } #ifdef TARGET_OSX static SGModalFilterUPP gSeqGrabberModalFilterUPP = NewSGModalFilterUPP(SeqGrabberModalFilterUPP); SGSettingsDialog(vgd->gSeqGrabber, gVideoChannel, 0, nil, seqGrabSettingsPreviewOnly, gSeqGrabberModalFilterUPP, nil); #else SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, 0L, NULL, nil); #endif #ifdef TARGET_WIN32 SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); #endif SGPause (vgd->gSeqGrabber, false); } //-------------------------------------------------------------------- void ofQtVideoGrabber::initGrabber(int _w, int _h){ w = _w; h = _h; vgd->w = w; vgd->h = h; ComponentDescription theDesc; Component sgCompID = NULL; char name[256]; char info[256]; Handle componentName=NULL; Handle componentInfo=NULL; ComponentDescription info_description; componentName=NewHandle(sizeof(name)); componentInfo=NewHandle(sizeof(info)); if (bVerbose == true){ printf ("\n"); printf ("-------------------------------------\n"); printf ("attempting to set up ofQtVideoGrabber\n"); } vgd->gSeqGrabber = 0L; vgd->gVideoChannel = 0L; theDesc.componentType = SeqGrabComponentType; theDesc.componentSubType = 0L; theDesc.componentManufacturer = 0L; theDesc.componentFlags = 0L; theDesc.componentFlagsMask = 0L; sgCompID = FindNextComponent(sgCompID, &theDesc); while (sgCompID != 0){ GetComponentInfo(sgCompID,&info_description, componentName, componentInfo,nil); if (bVerbose == true){ printf("found a device to capture with \n"); printf("Type: %s\n", &info_description.componentType); printf("Manufacturer: %s\n", &info_description.componentManufacturer); printf("Name: %s\n", *componentName ? p2cstr((StringPtr)*componentName) : "-" ); printf("Name: %s\n", *componentInfo ? p2cstr((StringPtr)*componentInfo) : "-"); } vgd->gSeqGrabber = OpenComponent(sgCompID); sgCompID = FindNextComponent(sgCompID, &theDesc); } //-------------------------------------------- // setup the gworld and digitizing. OSStatus err; err = SGInitialize(vgd->gSeqGrabber); if (err != noErr){ printf("***** Error in SGInitialize (check cam drivers, vdig or winvidg)*****\n"); return; } MacSetRect(&(vgd->videoRect),0, 0, w, h); //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vgd->offscreenGWorldPixels = (unsigned char*)malloc(4 * w * h + 32); vgd->pixels = new unsigned char[w*h*3]; QTNewGWorldFromPtr (&vgd->videogworld, k32ARGBPixelFormat, &vgd->videoRect, NULL, NULL, 0, vgd->offscreenGWorldPixels, 4 * w); LockPixels(GetGWorldPixMap(vgd->videogworld)); SetGWorld (vgd->videogworld, NULL); err = SGSetGWorld(vgd->gSeqGrabber, vgd->videogworld, nil); if ( err != noErr ) goto bail; err = SGNewChannel(vgd->gSeqGrabber, VideoMediaType, &vgd->gVideoChannel); if ( err != noErr ) goto bail; err = SGSetDataRef(vgd->gSeqGrabber, 0, 0, seqGrabDontMakeMovie); if ( err != noErr ) goto bail; err = SGSetChannelUsage(vgd->gVideoChannel,seqGrabPreview); if ( err != noErr ) goto bail; err = SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); if ( err != noErr ) goto bail; if (SGSetFrameRate(vgd->gVideoChannel,30) != noErr) printf( "error setting 30 fps \n"); else{ if (bVerbose == true){ printf ("set to capture at 30 fps \n"); } } err = SGPrepare(vgd->gSeqGrabber, false, true); if ( err != noErr ) goto bail; err = SGStartPreview(vgd->gSeqGrabber); if ( err != noErr ) goto bail; if (bVerbose){ printf ("end setup ofQtVideoGrabber\n"); printf ("-------------------------------------\n"); printf ("\n"); } bSgGrabberInited = true; bail: if (bVerbose){ printf ("***** ofQtVideoGrabber error *****\n"); printf ("-------------------------------------\n"); printf ("\n"); } bSgGrabberInited = false; return; } //-------------------------------------------------------------------- Node-path: video/ofQtVideoGrabber.h Node-kind: file Node-action: change Text-content-length: 2633 Text-content-md5: b348cfc458b0b75345beaa90467e6433 Content-length: 2633 #ifndef _QT_VIDEO_GRABBER #define _QT_VIDEO_GRABBER #include "ofConstants.h" #include "ofQtUtils.h" //----------------------------------------- // windows users check out winvdig: // // -[wvdig free]- // http://www.vdig.com/WinVDIG/ // but maybe older versions are better (at least w/ quicktime < 7.0) // try this one: (v 0.99) // www.vjshow.net/vart/WinVDIG_099.exe // uninstall instructions for winvdig in the winvdig forum // http://www.videoscript.com/forum/viewtopic.php?t=21 // // -[wvdig $]- // (also, www.abstractplane.com/products/vdig.jsp) // never tried... // 30 day demo available // // you will need a vdig to see video // try "hackTv" to test if you can use // quicktime to grab video // (pc) ftp://ftp.apple.com/developer/Quicktime/Windows_Tools/Programmers_Tools/Hack_TV/Hack_TV.zip // (mac) ftp://ftp.apple.com/developer/Quicktime/Tools/Programmers_Tools/Hack_TV.sit.hqx // // very good info here: // http://www.proce55ing.net/reference/libraries/video/ // (java stuff doesn't apply, but info on winvdig, vdig, etc) // // windows / direct show thoughts: // dShow capture via dsVideoLib coming soon ... // it's a c++ compiled lib, and tremendously difficult to work // in different c++ compilers. dope lib, but trouble with dev-c++... // look also at the reactable video input, useful? // wraps also v4l... // other cross platform video input options? // - opencv (cvAux?) //----------------------------------------- // todo: // -enumerate devices (ala wengo?) // -enumerate inputs // -allow input selection // -ntsc, pal format options... // -callback, via SGSetDataProc - couldn't get this to work yet // image decompress options ala mung... //--------------------------------------------- // this struct has all the info we need to grab pixels // typedef struct { unsigned char * offscreenGWorldPixels; // 32 bit: argb (qt k32ARGBPixelFormat) unsigned char * pixels; // 24 bit: rgb int w,h; bool bHavePixelsChanged; GWorldPtr videogworld; SeqGrabComponent gSeqGrabber; SGChannel gVideoChannel; Rect videoRect; } videoGrabberData; //--------------------------------------------- class ofQtVideoGrabber{ public : ofQtVideoGrabber(); bool isFrameNew(); void grabFrame(); void close(); void initGrabber(int w, int h); void videoSettings(); unsigned char * getPixels(); void setVerbose(bool bTalkToMe); int w; int h; private: bool bSgGrabberInited; videoGrabberData * vgd; bool bVerbose; }; #endif Node-path: video/ofQtVideoPlayer.cpp Node-kind: file Node-action: change Text-content-length: 8097 Text-content-md5: dfda348323ec78af9bb6bc3971f46d1e Content-length: 8097 #include "ofQtVideoPlayer.h" //-------------------------------------------------------------- bool createMovieFromPath(char * path, Movie * movie); bool createMovieFromPath(char * path, Movie * movie){ Boolean isdir; OSErr result = 0; FSSpec theFSSpec; FSRef fsref; short resRefNum = -1; short actualResId = DoTheRightThing; #ifdef TARGET_WIN32 result = NativePathNameToFSSpec (path, &theFSSpec, 0); if (result) { printf("NativePathNameToFSSpec failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } #endif #ifdef TARGET_OSX result = FSPathMakeRef((const UInt8*)path, &fsref, &isdir); if (result) { printf("FSPathMakeRef failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } result = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL); if (result) { printf("FSGetCatalogInfo failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } #endif result = OpenMovieFile (&theFSSpec, &resRefNum, 0); if (result) { printf("OpenMovieFile failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } result = NewMovieFromFile (movie, resRefNum, &actualResId, (unsigned char *) 0, 0, (Boolean *) 0); if (result) { printf("NewMovieFromFile failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } if (resRefNum != -1) CloseMovieFile (resRefNum); return true; } //-------------------------------------------------------------- OSErr DrawCompleteProc(Movie theMovie, long refCon); OSErr DrawCompleteProc(Movie theMovie, long refCon){ videoPlayerData * vd = (videoPlayerData *)refCon; convertPixels(vd->offscreenGWorldPixels, vd->pixels, vd->offscreenWidth, vd->offscreenHeight); vd->bHavePixelsChanged = true; return noErr; } //--------------------------------------------------------------------------- ofQtVideoPlayer::ofQtVideoPlayer (char * fileName){ vpd = new videoPlayerData(); loadMovie(fileName); } //--------------------------------------------------------------------------- ofQtVideoPlayer::ofQtVideoPlayer (){ bLoadedMovie = false; w = 0; h = 0; vpd = new videoPlayerData(); vpd->moviePtr = NULL; vpd->offscreenWidth = 0; vpd->offscreenHeight = 0; } //--------------------------------------------------------------------------- unsigned char * ofQtVideoPlayer::getPixels(){ return vpd->pixels; } //--------------------------------------------------------------------------- bool ofQtVideoPlayer::isFrameNew(){ if (bLoadedMovie == true){ bool bChanged = vpd->bHavePixelsChanged; if (vpd->bHavePixelsChanged == true) { vpd->bHavePixelsChanged = false; } return bChanged; } else { return false; } } //--------------------------------------------------------------------------- void ofQtVideoPlayer::grabFrame(){ if (bLoadedMovie == true){ MoviesTask(vpd->moviePtr,0); } } //--------------------------------------------------------------------------- void ofQtVideoPlayer::closeMovie(){ Movie moviePtr = vpd->moviePtr; DisposeMovie (vpd->moviePtr); #ifdef TARGET_WIN32 DisposeMovieDrawingCompleteUPP (myDrawCompleteProc); #endif ExitMovies (); } //--------------------------------------------------------------------------- bool ofQtVideoPlayer::loadMovie(char * name){ int i; OSErr result = 0; short resRefNum = -1; bLoadedMovie = false; Rect bounds; //----------------- callback method MovieDrawingCompleteUPP myDrawCompleteProc; myDrawCompleteProc = NewMovieDrawingCompleteUPP (DrawCompleteProc); initializeQuicktime(); vpd->bHavePixelsChanged = false; Movie * moviePtr = &(vpd->moviePtr); createMovieFromPath(name, moviePtr); //----------------------------------movie box GetMovieBox(vpd->moviePtr, &(vpd->movieRect)); w = vpd->movieRect.right; h = vpd->movieRect.bottom; vpd->offscreenWidth = vpd->movieRect.right; vpd->offscreenHeight = vpd->movieRect.bottom; //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vpd->offscreenGWorldPixels = (unsigned char*)malloc(4 * w * h + 32); vpd->pixels = new unsigned char[w*h*3]; //---------------------------------- gworld allocation QTNewGWorldFromPtr (&(vpd->offscreenGWorld), k32ARGBPixelFormat, &(vpd->movieRect), NULL, NULL, 0, (vpd->offscreenGWorldPixels), 4 * w); LockPixels(GetGWorldPixMap(vpd->offscreenGWorld)); SetGWorld (vpd->offscreenGWorld, NULL); SetMovieGWorld (vpd->moviePtr, vpd->offscreenGWorld, nil); //----------------- callback method SetMovieDrawingCompleteProc (vpd->moviePtr, movieDrawingCallWhenChanged, myDrawCompleteProc, (long)vpd); //---------------------------------- reset themovie, get ready to roll GoToBeginningOfMovie(vpd->moviePtr); SetMovieActiveSegment(vpd->moviePtr, -1,-1); if (vpd->moviePtr == NULL){ return false; } SetMovieActive(vpd->moviePtr, true); StartMovie(vpd->moviePtr); //------------------ set the movie rate to default //------------------ and preroll, so the first frames come correct TimeValue timeNow; Fixed playRate; timeNow = GetMovieTime(vpd->moviePtr, 0); playRate =GetMoviePreferredRate(vpd->moviePtr); PrePrerollMovie(vpd->moviePtr, timeNow, playRate, 0, 0); PrerollMovie(vpd->moviePtr, timeNow, playRate); SetMovieRate(vpd->moviePtr, playRate); setLoopState(OF_QT_LOOP_NORMAL); bLoadedMovie = true; // get some pixels in there right away. MoviesTask(vpd->moviePtr,0); convertPixels(vpd->offscreenGWorldPixels, vpd->pixels, vpd->offscreenWidth, vpd->offscreenHeight); return true; } //-------------------------------------------------------- void ofQtVideoPlayer::setVolume(int volume){ Movie moviePtr = vpd->moviePtr; SetMovieVolume(moviePtr, volume); } //-------------------------------------------------------- void ofQtVideoPlayer::setLoopState(int state){ Movie moviePtr = vpd->moviePtr; TimeBase myTimeBase; long myFlags = 0L; myTimeBase = GetMovieTimeBase(moviePtr); myFlags = GetTimeBaseFlags(myTimeBase); switch (state) { case OF_QT_LOOP_NORMAL: myFlags |= loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, hintsLoop, hintsLoop); SetMoviePlayHints(moviePtr, 0L, hintsPalindrome); break; case OF_QT_LOOP_PALINDROME: myFlags |= loopTimeBase; myFlags |= palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, hintsLoop, hintsLoop); SetMoviePlayHints(moviePtr, hintsPalindrome, hintsPalindrome); break; case OF_QT_LOOP_NONE: default: myFlags &= ~loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, 0L, hintsLoop | hintsPalindrome); break; } SetTimeBaseFlags(myTimeBase, myFlags); } //--------------------------------------------------------------------------- void ofQtVideoPlayer::setPosition(float pct){ TimeRecord tr; Movie moviePtr = vpd->moviePtr; tr.base = GetMovieTimeBase(moviePtr); long total = GetMovieDuration(moviePtr ); long newPos = (long)((float)total * pct); SetMovieTimeValue(moviePtr, newPos); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getDuration(){ Movie moviePtr = vpd->moviePtr; return GetMovieDuration (moviePtr) / (double) GetMovieTimeScale (moviePtr); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getPosition(){ Movie moviePtr = vpd->moviePtr; long total = GetMovieDuration(moviePtr); long current = GetMovieTime(moviePtr, nil); float pct = ((float)current/(float)total); return pct; } //--------------------------------------------------------------------------- void ofQtVideoPlayer::setSpeed(float _speed){ Movie moviePtr = vpd->moviePtr; speed = _speed; SetMovieRate(moviePtr, X2Fix(speed)); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getSpeed(){ return speed; } Node-path: video/ofQtVideoPlayer.h Node-kind: file Node-action: change Text-content-length: 2468 Text-content-md5: aa18e41c0fad22ea592af69b7e3e15d4 Content-length: 2468 #ifndef _QT_VIDEO_PLAYER #define _QT_VIDEO_PLAYER #include "ofConstants.h" #include "ofQtUtils.h" //------------------------------------------------- // (notes, links, etc) // // intersting technique employed here to get to RGB24 // from YUV2 - worthwhile? // paste.lisp.org/display/1051 //----------------------------- // http://viewcvs.osafoundation.org/chandler/trunk/internal/wx/src/msw/mediactrl.cpp?rev=6281&view=markup // http://developer.apple.com/documentation/QuickTime/INMAC/QT/iqMovieToolbox.34.htm // look for "QTURL_NewMovieFromURL", useful for loading URL based movies.. //------------------------------------------------- // note about callbacks: // // we use here a callback provided by quicktime to see if pixels have actually changed // the callback is "DrawCompleteProc" and int he quicktime code, // is defined as "static pascal OsErr ...." // in windows, I have dropped the pascal declaration as my compiler was // having trouble with that... necessary for mac? // // the alternative is to do what is done in qtVideoGrabber // set the alpha of the top pixel to 0x00 and every idle call // check to see if there are new pixels... #define OF_QT_LOOP_NONE 0x01 #define OF_QT_LOOP_PALINDROME 0x02 #define OF_QT_LOOP_NORMAL 0x03 //--------------------------------------------- // this struct has all the info we need to play 1 movie // kept in a struct, because the callback will // need to reference it... typedef struct { MovieController thePlayer; GWorldPtr offscreenGWorld; Movie moviePtr; Rect movieRect; unsigned char * offscreenGWorldPixels; // 32 bit: argb (qt k32ARGBPixelFormat) unsigned char * pixels; // 24 bit: rgb int offscreenWidth; int offscreenHeight; bool bHavePixelsChanged; } videoPlayerData; //--------------------------------------------- class ofQtVideoPlayer{ public: ofQtVideoPlayer (char * fileName); ofQtVideoPlayer (); void closeMovie(); bool loadMovie(char * name); void grabFrame(); int w, h; float speed; bool bLoadedMovie; bool isFrameNew(); unsigned char * getPixels(); float getPosition(); float getSpeed(); float getDuration(); void setPosition(float pct); void setVolume(int volume); void setLoopState(int state); void setSpeed(float speed); private: //--------------------------- videoPlayerData * vpd; }; #endif Node-path: video/ofQtVideoSaver.cpp Node-action: delete Node-path: video/ofQtVideoSaver.h Node-action: delete Revision-number: 7 Prop-content-length: 135 Content-length: 135 K 7 svn:log V 33 zach - cleaner, vec3f out for now K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-01-15T15:03:36.271085Z PROPS-END Node-path: utils/ofConstants.h Node-kind: file Node-action: change Text-content-length: 1317 Text-content-md5: 8cf08820064066f5fe9a5792ad0d5656 Content-length: 1317 #ifndef OF_CONSTANTS #define OF_CONSTANTS //------------------------------- // pc or mac ? // soon: pc, mac or linux... #ifndef __APPLE_CC__ #define TARGET_WIN32 #else #define TARGET_OSX #endif //------------------------------- #ifdef TARGET_WIN32 #include #include "glut.h" #define __WINDOWS_DS__ #define __WINDOWS_MM__ #endif #ifdef TARGET_OSX #define __MACOSX_CORE__ #include #endif // core: --------------------------- #include #include #include #include #include #ifndef PI #define PI 3.14159265358979323846 #endif #ifndef TWO_PI #define TWO_PI 6.28318530717958647693 #endif #ifndef M_TWO_PI #define M_TWO_PI 6.28318530717958647693 #endif #ifndef FOUR_PI #define FOUR_PI 12.56637061435917295385 #endif #ifndef HALF_PI #define HALF_PI 1.57079632679489661923 #endif #ifndef DEG_TO_RAD #define DEG_TO_RAD (PI/180.0) #endif #ifndef RAD_TO_DEG #define RAD_TO_DEG (180.0/PI) #endif #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #endif #ifndef ABS #define ABS(x) (((x) < 0) ? -(x) : (x)) #endif #define OF_FILLED 0x01 #define OF_OUTLINE 0x02 #define OF_WINDOW 0 #define OF_FULLSCREEN 1 #endif Node-path: utils/ofMath.cpp Node-kind: file Node-action: change Text-content-length: 1003 Text-content-md5: b7bc261128bb0450cc37e1feaefd2b59 Content-length: 1003 #include "ofMath.h" //-------------------------------------------------- void ofSeedRandom() { // use time srand(time(NULL)); } //-------------------------------------------------- void ofSeedRandom(int val) { srand((long) val); } //-------------------------------------------------- float ofRandom(float x, float y) { float high = 0; float low = 0; float randNum = 0; // if there is no range, return the value if (x == y) return x; // float == ?, wise? epsilon? high = MAX(x,y); low = MIN(x,y); randNum = low + ((high-low) * rand()/(RAND_MAX + 1.0)); return randNum; } //-------------------------------------------------- float ofRandomf() { float randNum = 0; randNum = (rand()/(RAND_MAX + 1.0)) * 2.0 - 1.0; return randNum; } //-------------------------------------------------- float ofRandomuf() { float randNum = 0; randNum = rand()/(RAND_MAX + 1.0); return randNum; } //-------------------------------------------------- Node-path: utils/ofMath.h Node-kind: file Node-action: change Text-content-length: 758 Text-content-md5: 2b570f11aeeb897bb4c845276e049334 Content-length: 758 // notes: // ----------------------------------------------------------- // for fast things look here: http://musicdsp.org/archive.php?classid=5#115 // ----------------------------------------------------------- // the random () calls are based on misconceptions described here: // http://www.azillionmonkeys.com/qed/random.html // (Bad advice from C.L.C. FAQ) // we should correct this -- // ----------------------------------------------------------- #ifndef _OF_MATH_H #define _OF_MATH_H #include "ofMain.h" void ofSeedRandom(); void ofSeedRandom(int val); float ofRandom(float val0, float val1); // random (x - y) float ofRandomf(); // random (-1 - 1) float ofRandomuf(); // random (0 - 1) #endif Node-path: utils/ofUtils.cpp Node-kind: file Node-action: change Text-content-length: 3369 Text-content-md5: 7b10e74f7c02909c34ce2a7f17ad4cd9 Content-length: 3369 #include "ofUtils.h" //-------------------------------------------------- // from nehe.gamedev.net lesson 43 int ofNextPow2 ( int a ) { int rval=1; while(rval sw) width = sw-x; if (height+y > sh) height = sh-y; char *ScreenImageBuffer = (char*)malloc(width*height*3); char *flippedScreenImageBuffer = (char*)malloc(width*height*3); char fileName[255]; sprintf(fileName, "screen_grab__%ix%i__%0.4i.raw", width, height, frameNum++); FILE* OutputFile = fopen(fileName, "wb"); glReadPixels(x,y,width,height,GL_RGB,GL_UNSIGNED_BYTE,ScreenImageBuffer); // need to flip image for (int i = 0; i < height; i++) { memcpy(flippedScreenImageBuffer+(sizeof(char)*i*width*3), ScreenImageBuffer+(sizeof(char)*(height-i)*width*3), sizeof(char)*width*3); } fwrite(flippedScreenImageBuffer,width*height*3,1,OutputFile); fclose(OutputFile); free(ScreenImageBuffer); free(flippedScreenImageBuffer); } //-------------------------------------- int ofGetElapsedMillis(){ return (int)(glutGet(GLUT_ELAPSED_TIME)); } //-------------------------------------- float ofGetElapsedTimef(){ return (float)(glutGet(GLUT_ELAPSED_TIME))/1000.0f; } //-------------------------------------- int ofGetMillis(){ // this is a hack now... should be based on system time // time_t is not in millisecond resolution. what to replace this with? // for not millis is elapsed milliseconds, not clock millis... return (int)(glutGet(GLUT_ELAPSED_TIME) % 1000); // http://man.he.net/man2/gettimeofday } //-------------------------------------------------- int ofGetSeconds(){ time_t curr; tm local; time(&curr); local =*(localtime(&curr)); return local.tm_sec; } //-------------------------------------------------- int ofGetMinutes(){ time_t curr; tm local; time(&curr); local =*(localtime(&curr)); return local.tm_min; } //-------------------------------------------------- int ofGetHours(){ time_t curr; tm local; time(&curr); local =*(localtime(&curr)); return local.tm_hour; } Node-path: utils/ofUtils.h Node-kind: file Node-action: change Text-content-length: 438 Text-content-md5: 1d94f826fc99e7cd023988bcb4d932ee Content-length: 438 #ifndef _OF_UTIL #define _OF_UTIL #include "ofConstants.h" float ofGetFps(void); int ofNextPow2( int input); float ofGetElapsedTimef(); int ofGetElapsedTimeMillis(); int ofGetMillis(); // should be different then above.. int ofGetSeconds(); int ofGetMinutes(); int ofGetHours(); void ofGetWindowSize( int * w, int * h); void ofScreenCapRaw(); void ofScreenCapRaw(int x, int y, int w, int h); #endif Node-path: utils/ofVec3f.h Node-action: delete Node-path: utils/ofVec3f.cpp Node-action: delete Revision-number: 8 Prop-content-length: 166 Content-length: 166 K 7 svn:log V 64 zach - fixed some bugs with ofAudio, ofMidi is out of SVN branch K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-01-15T15:05:03.535321Z PROPS-END Node-path: sound/ofAudio.cpp Node-kind: file Node-action: change Text-content-length: 3661 Text-content-md5: 1492db6dbed4c1bc0a2b1e8483ef9dc8 Content-length: 3661 #include "ofAudio.h" #include "rtAudio.h" //----------------------------------- static variables: static ofSimpleApp * OFSAptr; RtAudio * audio; int nInputChannels; int nOutputChannels; //----------------------------------- int receiveAudioBufferAndCallSimpleApp(char *buffer, int bufferSize, void *data); int receiveAudioBufferAndCallSimpleApp(char *buffer, int bufferSize, void *data){ // rtAudio uses a system by which the audio // can be of different formats // char, float, etc. // we choose float float * fPtr = (float *)buffer; // [zach] memset output to zero before output call // this is because of how rtAudio works. seems to duplex // you need to cut in the middle. if the simpleApp // doesn't produce audio, we pass silence instead of duplex... if (nInputChannels > 0){ OFSAptr->processAudioInput(fPtr, bufferSize, nInputChannels); memset(fPtr, 0, bufferSize * nInputChannels * sizeof(float)); } if (nOutputChannels > 0) OFSAptr->processAudioOutput(fPtr, bufferSize, nOutputChannels); return 0; } //--------------------------------------------------------- void ofAudioSetup(int nOutputs, int nInputs, ofSimpleApp * OFSA){ ofAudioSetup(nOutputs, nInputs, OFSA, 44100, 256*4, 4); } //--------------------------------------------------------- void ofAudioSetup(int nOutputs, int nInputs, ofSimpleApp * OFSA, int sampleRate, int bufferSize, int nBuffers){ nInputChannels = nInputs; nOutputChannels = nOutputs; int device = 0; // default OFSAptr = OFSA; try { audio = new RtAudio(); audio->openStream( device, nOutputs, device, nInputs, RTAUDIO_FLOAT32, sampleRate, &bufferSize, nBuffers); } catch (RtError &error) { error.printMessage(); //std::exit(EXIT_FAILURE); // need case here } try { audio->setStreamCallback(&receiveAudioBufferAndCallSimpleApp, (void *)NULL); audio->startStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioStopStream(){ try { audio->stopStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioStartStream(){ try{ audio->startStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioEndStream(){ try { audio->stopStream(); audio->closeStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioEnumerateDevices(){ RtAudio *audioTemp = 0; try { audioTemp = new RtAudio(); } catch (RtError &error) { error.printMessage(); } int devices = audioTemp->getDeviceCount(); RtAudioDeviceInfo info; for (int i=1; i<=devices; i++) { try { info = audioTemp->getDeviceInfo(i); } catch (RtError &error) { error.printMessage(); break; } std::cout << "device = " << i << " (" << info.name << ")\n"; if (info.isDefault) std::cout << "***** default ***** \n"; std::cout << "maximum output channels = " << info.outputChannels << "\n"; std::cout << "maximum input channels = " << info.inputChannels << "\n"; std::cout << "-----------------------------------------\n"; } delete audioTemp; } /* try { // Stop and close the stream audio->stopStream(); audio->closeStream(); } catch (RtError &error) { error.printMessage(); } */ Node-path: sound/ofAudio.h Node-kind: file Node-action: change Text-content-length: 422 Text-content-md5: 69807d867d9b7d5036edec1d2d9961b0 Content-length: 422 #ifndef _OF_AUDIO #define _OF_AUDIO #include "ofMain.h" #include "ofSimpleApp.h" void ofAudioSetup(int nOutputChannels, int nInputChannels, ofSimpleApp * OFSA); void ofAudioSetup(int nOutputChannels, int nInputChannels, ofSimpleApp * OFSA, int sampleRate, int bufferSize, int nBuffers); void ofAudioStopStream(); void ofAudioStartStream(); void ofAudioEndStream(); void ofAudioEnumerateDevices(); #endif Node-path: sound/ofMidi.cpp Node-action: delete Node-path: sound/ofMidi.h Node-action: delete Revision-number: 9 Prop-content-length: 239 Content-length: 239 K 7 svn:log V 136 zach - lots of changes, ofImage no longer uses freeImagePlus (because of dev-c++ compile issues), ofGraphics got some more functionality K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-01-15T15:06:07.989753Z PROPS-END Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: change Text-content-length: 5337 Text-content-md5: c5de2cf6ec750de2b6b9c1a47ac6bb97 Content-length: 5337 #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- void ofSetBgColor(float r, float g, float b, float a){ bgColor[0] = r; bgColor[1] = g; bgColor[2] = b; bgColor[3] = a; } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } //---------------------------------------------------------- void ofEnableAlphaBlending(){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void ofDisableAlphaBlending(){ glDisable(GL_BLEND); } //-------------------------------------------------- void ofDrawBitmapString(char *string, float x, float y){ //--------------------------------------------------- // for now this is fixed to the 8_BY_13 glut character // http://pyopengl.sourceforge.net/documentation/manual/glutBitmapCharacter.3GLUT.html //--------------------------------------------------- char *c; int yOffset = 0; float fontSize = 8.0f; glRasterPos2f(x,y); for (c=string; *c != '\0'; c++) { if(*c == '\n') { yOffset -= (fontSize*1.4); glRasterPos2f(x,y + yOffset); } else glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c); } } //---------------------------------------------------------- void ofSetupScreen(){ int w, h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } Node-path: graphics/ofGraphics.h Node-kind: file Node-action: change Text-content-length: 1164 Text-content-md5: e208e92a823e62469c7d042738ed7a1c Content-length: 1164 #ifndef OF_GEOM #define OF_GEOM #include "ofConstants.h" #define CIRC_RESOLUTION 22 // 22 pts for a circle... // bg color float * ofBgColorPtr(); void ofSetBgColor(float r, float g, float b, float a); // geometry void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3); void ofCircle(float x,float y, float radius); void ofEllipse(float x, float y, float width, float height); void ofLine(float x1,float y1,float x2,float y2); void ofRect(float x1,float y1,float w, float h); void ofSetCircleResolution(int res); // if there 22 is a problem, you can change it here // drawing options void ofNoFill(); void ofFill(); // color options void ofSetColor(int r, int g, int b); // 0-255 void ofSetColor(int hexColor); // hex, like web 0xFF0033; // transparency void ofEnableAlphaBlending(); // this just turns on and off opengl blending, the common mode void ofDisableAlphaBlending(); // bitmapped type // ** note, this uses glDrawPixels and may be SLOW on some graphics cards void ofDrawBitmapString( char *string, float x, float y); // matrix screen things... void ofSetupScreen(); #endif Node-path: graphics/ofImage.cpp Node-kind: file Node-action: change Text-content-length: 5201 Text-content-md5: 2c396275b24e8928df83ca01f4a94176 Content-length: 5201 #include "ofImage.h" #include "freeImage.h" static bool bFreeImageInited = false; //----------------------------------------- // class freeImageBitmap{ public: FIBITMAP * bmp; //----------------------- freeImageBitmap(){ bmp = NULL; } //----------------------- //swap my image out in a (hopefully) non-memory leakish way void swap(FIBITMAP *dst) { if(dst == NULL) return; if(bmp != NULL) FreeImage_Unload(bmp); bmp = dst; } //----------------------- void setSize(FREE_IMAGE_TYPE image_type, WORD width, WORD height, WORD bpp) { if(bmp == NULL) { FreeImage_Unload(bmp); } bmp = FreeImage_AllocateT(image_type, width, height, bpp); } //----------------------- bool isValid(){ return (bmp != NULL) ? true : false; } }; //---------------------------------------------------------- ofImage::ofImage(){ //----------------------- init free image if necessary if (!bFreeImageInited){ FreeImage_Initialise(); bFreeImageInited = true; } //----------------------- IMG = new freeImageBitmap(); w = h = bpp = 0; type = OF_IMAGE_UNDEFINED; } //---------------------------------------------------------- void ofImage::grabScreen(int _x, int _y, int _w, int _h){ if (IMG->isValid()){ if (!(w == _w && h == _h)){ resize(_w, _h); } unsigned char * pixels = getPixels(); switch (bpp){ case 8: glReadPixels(_x, _y, _w, _h, GL_LUMINANCE,GL_UNSIGNED_BYTE, pixels); break; case 24: glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); break; case 32: glReadPixels(_x, _y, _w, _h, GL_RGBA,GL_UNSIGNED_BYTE, pixels); break; } } else { // assume that this is color.... IMG->setSize(FIT_BITMAP, _w, _h, 24); unsigned char * pixels = getPixels(); glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE,pixels); update(); } } //---------------------------------------------------------- void ofImage::allocate(int _w, int _h, int _type){ int newbpp; switch (_type){ case OF_IMAGE_GRAYSCALE: newbpp = 8; break; case OF_IMAGE_COLOR: newbpp = 24; break; case OF_IMAGE_COLOR_ALPHA: newbpp = 32; break; default: newbpp = 24; break; } IMG->setSize(FIT_BITMAP, _w, _h, newbpp); } //---------------------------------------------------------- void ofImage::update(){ w = FreeImage_GetWidth(IMG->bmp); h = FreeImage_GetHeight(IMG->bmp); bpp = FreeImage_GetBPP(IMG->bmp); } //---------------------------------------------------------- void ofImage::loadImage(char * fileName){ bool bLoaded = false; //----------------------------- find the format FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { if(IMG->isValid()) { FreeImage_Unload(IMG->bmp); } IMG->bmp = FreeImage_Load(fif, fileName, 0); bLoaded = true; if(!IMG->isValid()){ bLoaded = false; } } //----------------------------- if (bLoaded){ update(); switch (bpp){ case 8: type = OF_IMAGE_GRAYSCALE; break; case 24: type = OF_IMAGE_COLOR; break; case 32: type = OF_IMAGE_COLOR_ALPHA; break; default: setImageType(OF_IMAGE_COLOR); break; } } else { w = h = bpp = 0; } } //---------------------------------------------------------- void ofImage::saveImage(char * fileName){ if (IMG->isValid()){ //IMG->save(fileName); } } //---------------------------------------------------------- unsigned char * ofImage::getPixels(){ // be careful! if (IMG->isValid()){ return (unsigned char *)FreeImage_GetBits(IMG->bmp); } else { return NULL; } } //---------------------------------------------------------- void ofImage::resize(int newWidth, int newHeight){ if (IMG->isValid()){ FIBITMAP * scaledBmp = FreeImage_Rescale(IMG->bmp, newWidth, newHeight, FILTER_BICUBIC); IMG->swap(scaledBmp); update(); } } //---------------------------------------------------------- void ofImage::setImageType(int newType){ if (IMG->isValid()){ switch (newType){ //------------------------------------ case OF_IMAGE_GRAYSCALE: if (type != OF_IMAGE_GRAYSCALE){ FIBITMAP * convertedBmp = FreeImage_ConvertToGreyscale(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; //------------------------------------ case OF_IMAGE_COLOR: if (type != OF_IMAGE_COLOR){ FIBITMAP * convertedBmp = FreeImage_ConvertTo24Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR; } break; //------------------------------------ case OF_IMAGE_COLOR_ALPHA: if (type != OF_IMAGE_COLOR_ALPHA){ FIBITMAP * convertedBmp = FreeImage_ConvertTo32Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; } update(); } } Node-path: graphics/ofImage.h Node-kind: file Node-action: change Text-content-length: 1073 Text-content-md5: 60075ae2b2d6e1b2eeab55de1775556e Content-length: 1073 #ifndef _OF_IMAGE_H_ #define _OF_IMAGE_H_ #include "ofConstants.h" #define OF_IMAGE_GRAYSCALE 0x00 #define OF_IMAGE_COLOR 0x01 #define OF_IMAGE_COLOR_ALPHA 0x02 #define OF_IMAGE_UNDEFINED 0x03 //------------------------- // forward class declaration, something // we will need in order to compile "OF" as a lib // so that you don't need freeImage, quicktime, etc.. class freeImageBitmap; //------------------------- class ofImage { public : ofImage(); void loadImage(char * fileName); void saveImage(char * fileName); void allocate(int w, int h, int type); unsigned char * getPixels(); // up to you to get this right void setImageType(int type); void resize(int newWidth, int newHeight); void grabScreen(int x, int y, int w, int h); // grab pixels from opengl, using glreadpixels int type; // what type of image it is (as above) int w, h, bpp; // w,h, bits per pixel private: void update(); freeImageBitmap * IMG; }; #endif Node-path: graphics/ofTexture.cpp Node-kind: file Node-action: change Text-content-length: 2282 Text-content-md5: 25e084e99f88d877f36abf668ed74d52 Content-length: 2282 #include "ofTexture.h" ofTexture::ofTexture(){ } void ofTexture::setFormat(int w, int h, int internalGlDataType){ tex_w = w; tex_h = h; tex_u = 1.0f; tex_t = 1.0f; // if w, h are not powers of 2 you will not see anything. // create the named texture: texName = new GLuint[1]; //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // not necessary, I think glGenTextures(1, texName); // could be more then one, but for now, just one glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texName[0]); glTexImage2D(GL_TEXTURE_2D, 0, internalGlDataType, tex_w, tex_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); // init to black... glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); } void ofTexture::loadData(unsigned char * data, int w, int h, int glDataType){ if ( w > tex_w || h > tex_h) { printf("image data too big - bailing \n"); return; } //compute new tex co-ords based on the ratio of data's w, h to texture w,h; tex_t = (float)w / (float)tex_w; tex_u = (float)h / (float)tex_h; // update the texture image: glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texName[0]); glTexSubImage2D(GL_TEXTURE_2D,0,0,0,w,h,glDataType,GL_UNSIGNED_BYTE,data); glDisable(GL_TEXTURE_2D); } //================================================================================= void ofTexture::render(int x, int y, int w, int h){ glEnable(GL_TEXTURE_2D); // bind the texture glBindTexture( GL_TEXTURE_2D, texName[0] ); float px0 = x ; // up to you to get the aspect ratio right float py0 = y ; float px1 = x+w; float py1 = y+h; glBegin( GL_QUADS ); glTexCoord2f(0.0, 0.0); glVertex3f(px0, py0,0); glTexCoord2f(tex_t, 0.0); glVertex3f(px1, py0,0); glTexCoord2f(tex_t, tex_u); glVertex3f(px1, py1,0); glTexCoord2f(0.0, tex_u); glVertex3f(px0, py1,0); glEnd(); glDisable(GL_TEXTURE_2D); } Node-path: graphics/ofTexture.h Node-kind: file Node-action: change Text-content-length: 417 Text-content-md5: 35169dcd0c434b60362fd3f7c3e98f0e Content-length: 417 #ifndef _IMAGE_TEXTURE_H_ #define _IMAGE_TEXTURE_H_ #include "ofConstants.h" class ofTexture { public : ofTexture(); void setFormat(int w, int h, int internalGlDataType); void loadData(unsigned char * data, int w, int h, int glDataType); void render(int x, int y, int w, int h); float tex_t, tex_u; private: int tex_w, tex_h; GLuint * texName; }; #endif Node-path: graphics/ofTrueTypeFont.cpp Node-kind: file Node-action: change Text-content-length: 10662 Text-content-md5: 8f2f9d1b6bf2ebb25f20c0e6f514c24d Content-length: 10662 #include "ofTrueTypeFont.h" //-------------------------- #include #include #include #include #include //------------------------------------------------------------------ ofTrueTypeFont::ofTrueTypeFont(){ bLoadedOk = false; } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize){ // load anti-aliased, non-full character set: loadFont(filename, fontsize, true, false); } //------------------------------------------------------------------ void ofTrueTypeFont::ofTrueTypeFont::loadFont(const char *filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet){ bLoadedOk = false; bAntiAlised = _bAntiAliased; bFullCharacterSet = _bFullCharacterSet; //--------------- load the library and typeface FT_Library library; if (FT_Init_FreeType( &library )){ printf("PROBLEM WITH FT lib \n"); return; } FT_Face face; if (FT_New_Face( library, filename, 0, &face )) { return; } FT_Set_Char_Size( face,fontsize << 6,fontsize << 6,96,96); lineHeight = fontsize * 1.43f; //------------------------------------------------------ //kerning would be great to support: //printf("FT_HAS_KERNING ? %i \n", FT_HAS_KERNING(face)); //------------------------------------------------------ nCharacters = bFullCharacterSet ? 256 : 128 - NUM_CHARACTER_TO_START; //--------------- initialize character info and textures cps = new charProps[nCharacters]; texNames = new GLuint[nCharacters]; glGenTextures(nCharacters, texNames); //--------------------- load each char ----------------------- for (int i = 0 ; i < nCharacters; i++){ //------------------------------------------ anti aliased or not: if (bAntiAlised == true){ if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph %i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); } else { if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph%i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO); } //------------------------------------------ FT_Bitmap& bitmap= face->glyph->bitmap; // 1 pixel border around the glyph int border = 2; // prepare the texture: int width = ofNextPow2( bitmap.width + border); int height = ofNextPow2( bitmap.rows + border); // ------------------------- this is fixing a bug with small type // ------------------------- appearantly, opengl has trouble with // ------------------------- width or height textures of 1, so we // ------------------------- we just set it to 2... if (width == 1) width = 2; if (height == 1) height = 2; // ------------------------- // info about the character: cps[i].value = i; cps[i].height = face->glyph->bitmap_top; cps[i].width = face->glyph->bitmap.width; cps[i].setWidth = face->glyph->advance.x >> 6; cps[i].topExtent = face->glyph->bitmap.rows; cps[i].leftExtent = face->glyph->bitmap_left; // texture internals cps[i].tTex = (float)bitmap.width / (float)width; cps[i].vTex = (float)bitmap.rows / (float)height; cps[i].xOff = ((1.0+(float)bitmap.width) / (float)width) - cps[i].tTex; cps[i].yOff = ((1.0+(float)bitmap.rows) / (float)height) - cps[i].vTex; /* sanity check: printf("%i %i %i %i %i %i \n", cps[i].value , cps[i].height , cps[i].width , cps[i].setWidth , cps[i].topExtent , cps[i].leftExtent ); */ // Allocate Memory For The Texture Data. unsigned char* expanded_data = new unsigned char[ 2 * width * height]; //-------------------------------- clear data: for(int j=0; j =bitmap.width || j-1>=bitmap.rows) ? 0 : 255; expanded_data[2*(k+j*width)+1] = (k-1>=bitmap.width || j-1>=bitmap.rows) ? 0 : bitmap.buffer[k-1 + bitmap.width*(j-1)]; } } //----------------------------------- } else { //----------------------------------- // true type packs monochrome info in a // 1-bit format, hella funky // here we unpack it: unsigned char *src = bitmap.buffer; for(int j=0; j = nCharacters){ printf("Error : char (%i) not allocated -- line %d in %s\n", (c + NUM_CHARACTER_TO_START), __LINE__,__FILE__); return; } //----------------------- int cu = c; float height = cps[cu].height; float bwidth = cps[cu].width; float top = cps[cu].topExtent - cps[cu].height; float lextent = cps[cu].leftExtent; float t = cps[cu].tTex; float v = cps[cu].vTex; float xOff = cps[cu].xOff; float yOff = cps[cu].yOff; if (glIsTexture(texNames[cu])) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texNames[cu]); glNormal3f(0, 0, 1); glBegin(GL_QUADS); glTexCoord2d(xOff,yOff); glVertex2f(x + lextent, y + height); glTexCoord2d(xOff,v+yOff); glVertex2f(x + lextent, y-top); glTexCoord2d(t+xOff,v+yOff); glVertex2f(x + lextent + bwidth,y-top); glTexCoord2d(t+xOff,yOff); glVertex2f(x + + lextent + bwidth,y + height); glEnd(); glDisable(GL_TEXTURE_2D); } else { printf("Error : texture not bound for character -- line %d in %s\n", __LINE__,__FILE__); } } //----------------------------------------------------------- float ofTrueTypeFont::stringWidth(char *c) { float width = 0; int index = 0; float widthTemp = 0; bool bMultiLine = false; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { width = max(width, widthTemp); widthTemp = 0; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; widthTemp += cps[cy].width; } else { widthTemp += cps[cy].setWidth; } } index++; } width = max(width, widthTemp); return width; } //----------------------------------------------------------- float ofTrueTypeFont::stringHeight(char *c) { float height = 0; int index = 0; float maxHeight = 0; bool bFirstLineOfMultiLine = true; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { if (bFirstLineOfMultiLine == true){ bFirstLineOfMultiLine = false; height += maxHeight; } else { height += lineHeight; } maxHeight = 0; } else if (c[index] == ' ') { } else { float ht = cps[cy].height; if (ht > maxHeight) maxHeight = ht; } } index++; } height += maxHeight; return height; } //===================================================================== void ofTrueTypeFont::drawString(char *c, float x, float y) { if (!bLoadedOk){ printf("Error : font not allocated -- line %d in %s\n", __LINE__,__FILE__); return; }; float startX = x; int index = 0; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { x = startX; int cy = (int)'M' - NUM_CHARACTER_TO_START; y -= lineHeight; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; x += cps[cy].width; } else { drawChar(cy, x, y); x += cps[cy].setWidth; } } index++; } } Node-path: graphics/ofTrueTypefont.h Node-kind: file Node-action: change Text-content-length: 1241 Text-content-md5: fbb5029eb04e6e836093fdc59947b42c Content-length: 1241 #ifndef _OF_TTF_FONT_H_ #define _OF_TTF_FONT_H_ #include "ofConstants.h" //-------------------------------------------------- typedef struct { int value; int height; int width; int setWidth; int topExtent; int leftExtent; float tTex; float vTex; //0-1 pct of bitmap... float xOff; float yOff; } charProps; //-------------------------------------------------- #define NUM_CHARACTER_TO_START 33 // 0 - 32 are control characters, no graphics needed. class ofTrueTypeFont{ public: ofTrueTypeFont(); // -- default, non-full char set, anti aliased: void loadFont(const char *filename, int fontsize); void loadFont(const char *filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet); bool bLoadedOk; bool bAntiAlised; bool bFullCharacterSet; float getLineHeight(); void setLineHeight(float height); float stringWidth(char *s); float stringHeight(char *c); void drawString(char *c, float x, float y); int nCharacters; protected: float lineHeight; charProps * cps; // properties for each character unsigned int * texNames; // textures for each character void drawChar(int c, float x, float y); int ofNextPow2 (int a); }; #endif Revision-number: 10 Prop-content-length: 124 Content-length: 124 K 7 svn:log V 22 zach - general cleanup K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-01-15T15:07:25.758324Z PROPS-END Node-path: app/ofAppGlutGlue.h Node-kind: file Node-action: change Text-content-length: 2207 Text-content-md5: dfe4d140edd512ba60002dad627df770 Content-length: 2207 void display(void); void mouse_cb(int button, int state, int x, int y); void motion_cb(int x, int y); void passive_motion_cb(int x, int y); void idle_cb(void); void keyboard_cb(unsigned char key, int x, int y); void special_key_cb(int key, int x, int y) ; static int buttonInUse = 0; //-------------------------------- static float timeNow, timeThen, fps; static int nFrames; //------------------------------------------------------------ void display(void){ ofGetWindowSize( &width, &height ); height = height > 0 ? height : 1; // set viewport, clear the screen glViewport( 0, 0, width, height ); float * bgPtr = ofBgColorPtr(); glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); OFSAptr->draw(); glutSwapBuffers(); // -------------- fps: timeNow = ofGetElapsedTimef(); if( (timeNow-timeThen) > 0.05f || nFrames == 0 ) { fps = (double)nFrames / (timeNow-timeThen); timeThen = timeNow; nFrames = 0; ofFrameRate = 0.9f * ofFrameRate + 0.1f * fps; } nFrames++; // -------------- } //------------------------------------------------------------ void mouse_cb(int button, int state, int x, int y) { if (state == GLUT_DOWN) { OFSAptr->mouseDown(x, height - y, button); } else if (state == GLUT_UP) { OFSAptr->mouseUp(x, height - y, button); } buttonInUse = button; } //------------------------------------------------------------ void motion_cb(int x, int y) { OFSAptr->mouseDrag(x, height - y, buttonInUse); } //------------------------------------------------------------ void passive_motion_cb(int x, int y) { OFSAptr->mouseMove(x, height - y); } //------------------------------------------------------------ void idle_cb(void) { OFSAptr->idle(); glutPostRedisplay(); } //------------------------------------------------------------ void keyboard_cb(unsigned char key, int x, int y) { OFSAptr->keyDown((int)key); if (key == 27) std::exit(0); // quit! } //------------------------------------------------------------ void special_key_cb(int key, int x, int y) { OFSAptr->keyDown((int)key); } Node-path: app/ofAppRunner.cpp Node-kind: file Node-action: change Text-content-length: 1374 Text-content-md5: 6f7c2a27b75c673cfbf7c6308cadf4ab Content-length: 1374 #include "ofAppRunner.h" //======================================================================== // static variables: static ofSimpleApp * OFSAptr; bool bMousePressed; bool bRightButton; int width, height; static float ofFrameRate; //======================================================================== // callbacks: #include "ofAppGlutGlue.h" //-------------------------------------- void ofSetupOpenGL(int w, int h, int screenMode){ int argc = 1; char *argv = "openframeworks"; char **vptr = &argv; glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA); glutInit(&argc, vptr); if (screenMode == OF_WINDOW) glutInitWindowSize(w, h); glutCreateWindow(""); if (screenMode == OF_FULLSCREEN) glutFullScreen(); } //-------------------------------------- void ofRunApp(ofSimpleApp * OFSA){ OFSAptr = OFSA; // window // callbacks glutMouseFunc(mouse_cb); glutMotionFunc(motion_cb); glutPassiveMotionFunc(passive_motion_cb); glutIdleFunc(idle_cb); glutDisplayFunc(display); glutKeyboardFunc(keyboard_cb); glutSpecialFunc(special_key_cb); OFSA->init(); glutMainLoop(); } float ofGetFrameRate(){ return ofFrameRate; } void ofHideCursor(){ glutSetCursor(GLUT_CURSOR_NONE); } void ofShowCursor(){ glutSetCursor(GLUT_CURSOR_RIGHT_ARROW); } Node-path: app/ofAppRunner.h Node-kind: file Node-action: change Text-content-length: 361 Text-content-md5: a7ed938dd89b3e4a4f0369567c3befe1 Content-length: 361 #ifndef _OF_APP_RUNNER #define _OF_APP_RUNNER #include "ofConstants.h" #include "ofSimpleApp.h" #include "ofGraphics.h" #include "ofUtils.h" void ofSetupOpenGL(int w, int h, int screenMode); // sets up the opengl context! void ofRunApp(ofSimpleApp * OFSA); float ofGetFrameRate(); void ofHideCursor(); void ofShowCursor(); #endif Node-path: app/ofSimpleApp.cpp Node-kind: file Node-action: change Text-content-length: 34 Text-content-md5: e30e818b9a432a48df41ef8ef1c1253d Content-length: 34 #include "ofSimpleApp.h" Node-path: app/ofSimpleApp.h Node-kind: file Node-action: change Text-content-length: 678 Text-content-md5: adcb0cb2aad42749d8af0f41b58aca17 Content-length: 678 #ifndef _OF_SIMPLE_APP #define _OF_SIMPLE_APP #include "ofConstants.h" #include "ofUtils.h" class ofSimpleApp{ public: ofSimpleApp(){} virtual void idle(){} virtual void init(){}; virtual void draw(){} virtual void keyDown (int c){} virtual void mouseMove( int x, int y ){} virtual void mouseDrag( int x, int y, int button ){} virtual void mouseDown( int x, int y, int button ){} virtual void mouseUp ( int x, int y, int button ){} virtual void processAudioInput (float * input, int bufferSize, int nChannels) {} virtual void processAudioOutput (float * output, int bufferSize, int nChannels) {} }; #endif Revision-number: 11 Prop-content-length: 136 Content-length: 136 K 7 svn:log V 34 zach - fix for compile via dev-c++ K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-01-15T15:47:55.678404Z PROPS-END Node-path: app/ofAppGlutGlue.h Node-kind: file Node-action: change Text-content-length: 2336 Text-content-md5: 8433112e77677f39ec89391ceacd85fa Content-length: 2336 void display(void); void mouse_cb(int button, int state, int x, int y); void motion_cb(int x, int y); void passive_motion_cb(int x, int y); void idle_cb(void); void keyboard_cb(unsigned char key, int x, int y); void special_key_cb(int key, int x, int y) ; static int buttonInUse = 0; //-------------------------------- static float timeNow, timeThen, fps; static int nFrames; //------------------------------------------------------------ void display(void){ ofGetWindowSize( &width, &height ); height = height > 0 ? height : 1; // set viewport, clear the screen glViewport( 0, 0, width, height ); float * bgPtr = ofBgColorPtr(); glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); OFSAptr->draw(); glutSwapBuffers(); // -------------- fps calculation: timeNow = ofGetElapsedTimef(); if( (timeNow-timeThen) > 0.05f || nFrames == 0 ) { fps = (double)nFrames / (timeNow-timeThen); timeThen = timeNow; nFrames = 0; ofFrameRate = 0.9f * ofFrameRate + 0.1f * fps; } nFrames++; // -------------- } //------------------------------------------------------------ void mouse_cb(int button, int state, int x, int y) { if (state == GLUT_DOWN) { OFSAptr->mouseDown(x, height - y, button); } else if (state == GLUT_UP) { OFSAptr->mouseUp(x, height - y, button); } buttonInUse = button; } //------------------------------------------------------------ void motion_cb(int x, int y) { OFSAptr->mouseDrag(x, height - y, buttonInUse); } //------------------------------------------------------------ void passive_motion_cb(int x, int y) { OFSAptr->mouseMove(x, height - y); } //------------------------------------------------------------ void idle_cb(void) { OFSAptr->idle(); glutPostRedisplay(); } //------------------------------------------------------------ void keyboard_cb(unsigned char key, int x, int y) { OFSAptr->keyDown((int)key); // std exit has trouble on dev-c++ #ifndef __MINGW32__ if (key == 27) std::exit(0); // quit! #else if (key == 27) exit(0); // quit! #endif } //------------------------------------------------------------ void special_key_cb(int key, int x, int y) { OFSAptr->keyDown((int)key); } Revision-number: 12 Prop-content-length: 153 Content-length: 153 K 7 svn:log V 51 zach - dev-c++ for compile (std::exit()) things ... K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-01-15T15:58:28.065048Z PROPS-END Node-path: video/ofQtUtils.cpp Node-kind: file Node-action: change Text-content-length: 2237 Text-content-md5: e410f12463aa90724f92541590d12d77 Content-length: 2237 #include "ofQtUtils.h" static bool bQuicktimeInitialized = true; //---------------------------------------- void initializeQuicktime(){ if (bQuicktimeInitialized == true){ //---------------------------------- // do we have quicktime installed at all? // http://www.apple.com/quicktime/download/win.html // can gestalt help with versions, or is that only after init? long myAttrs; OSErr myErr = noErr; #ifdef TARGET_WIN32 myErr = InitializeQTML(0); if (myErr != noErr){ printf("----------------------------------------------------- \n"); printf("sorry, there is a problem with quicktime starting up \nplease check!"); // std exit has trouble on dev-c++ #ifndef __MINGW32__ std::exit(0); // quit! #else exit(0); // quit! #endif } #endif myErr = EnterMovies (); if (myErr != noErr){ printf("----------------------------------------------------- \n"); printf("sorry, there is a problem with quicktime starting up \nplease check!"); #ifndef __MINGW32__ std::exit(0); // quit! #else exit(0); // quit! #endif } bQuicktimeInitialized = false; } } //---------------------------------------- void convertPixels(unsigned char * gWorldPixels, unsigned char * rgbPixels, int w, int h){ // ok for macs? // ok for intel macs? int * rgbaPtr = (int *) gWorldPixels; pix24 * rgbPtr = (pix24 *) rgbPixels; int totalPixelCount = w * h; unsigned char * rgbaStart; bool bFlipVertically = true; if (!bFlipVertically){ //----- argb->rgb for (int i = 0; i < totalPixelCount; i++){ rgbaStart = (unsigned char *)rgbaPtr; memcpy (rgbPtr, rgbaStart+1, sizeof(pix24)); rgbPtr++; rgbaPtr++; } } else { //----- flip while argb->rgb for (int i = 0; i < h; i++){ pix24 * rgbPtr = (pix24 *) rgbPixels + ((h-i-1) * w); for (int j = 0; j < w; j++){ rgbaStart = (unsigned char *)rgbaPtr; memcpy (rgbPtr, rgbaStart+1, sizeof(pix24)); rgbPtr++; rgbaPtr++; } } } } Revision-number: 13 Prop-content-length: 167 Content-length: 167 K 7 svn:log V 65 theo mac fixes updated ofGlutGlue ofQtVideoGrabber ofTrueTypeFont K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-01-18T17:38:45.120137Z PROPS-END Node-path: app/ofAppGlutGlue.h Node-kind: file Node-action: change Text-content-length: 2349 Text-content-md5: bbcc8bcfe327e2688b0102aecb4e3d26 Content-length: 2349 void display(void); void mouse_cb(int button, int state, int x, int y); void motion_cb(int x, int y); void passive_motion_cb(int x, int y); void idle_cb(void); void keyboard_cb(unsigned char key, int x, int y); void special_key_cb(int key, int x, int y) ; static int buttonInUse = 0; //-------------------------------- static float timeNow, timeThen, fps; static int nFrames; //------------------------------------------------------------ void display(void){ ofGetWindowSize( &width, &height ); height = height > 0 ? height : 1; // set viewport, clear the screen glViewport( 0, 0, width, height ); float * bgPtr = ofBgColorPtr(); glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); OFSAptr->draw(); glutSwapBuffers(); // -------------- fps calculation: timeNow = ofGetElapsedTimef(); if( (timeNow-timeThen) > 0.05f || nFrames == 0 ) { fps = (double)nFrames / (timeNow-timeThen); timeThen = timeNow; nFrames = 0; ofFrameRate = 0.9f * ofFrameRate + 0.1f * fps; } nFrames++; // -------------- } //------------------------------------------------------------ void mouse_cb(int button, int state, int x, int y) { if (state == GLUT_DOWN) { OFSAptr->mouseDown(x, height - y, button); } else if (state == GLUT_UP) { OFSAptr->mouseUp(x, height - y, button); } buttonInUse = button; } //------------------------------------------------------------ void motion_cb(int x, int y) { OFSAptr->mouseDrag(x, height - y, buttonInUse); } //------------------------------------------------------------ void passive_motion_cb(int x, int y) { OFSAptr->mouseMove(x, height - y); } //------------------------------------------------------------ void idle_cb(void) { OFSAptr->idle(); glutPostRedisplay(); } //------------------------------------------------------------ void keyboard_cb(unsigned char key, int x, int y) { OFSAptr->keyDown((int)key); // std exit has trouble on dev-c++ #ifdef TARGET_OSX if (key == 27) exit(0); // quit! #endif #ifndef __MINGW32__ #ifdef TARGET_WIN32 if (key == 27) std::exit(0); // quit! #endif #else if (key == 27) exit(0); // quit! #endif } //------------------------------------------------------------ void special_key_cb(int key, int x, int y) { OFSAptr->keyDown((int)key); } Node-path: graphics/ofGraphics.h Node-kind: file Node-action: change Text-content-length: 1125 Text-content-md5: 2931c647c8bbf41dc669946f9cd6a044 Content-length: 1125 #ifndef OF_GEOM #define OF_GEOM #include "ofConstants.h" #define CIRC_RESOLUTION 22 // 22 pts for a circle... // bg color float * ofBgColorPtr(); void ofSetBgColor(float r, float g, float b, float a); // geometry void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3); void ofCircle(float x,float y, float radius); void ofEllipse(float x, float y, float width, float height); void ofLine(float x1,float y1,float x2,float y2); void ofRect(float x1,float y1,float w, float h); void ofSetCircleResolution(int res); // if there 22 is a problem, you can change it here // drawing options void ofNoFill(); void ofFill(); // color options void ofSetColor(int r, int g, int b); // 0-255 void ofSetColor(int hexColor); // hex, like web 0xFF0033; // transparency void ofEnableAlphaBlending(); // this just turns on and off opengl blending, the common mode void ofDisableAlphaBlending(); // bitmapped type // ** note, this uses glDrawPixels and may be SLOW on some graphics cards void ofDrawBitmapString( char *string, float x, float y); // matrix screen things... void ofSetupScreen(); #endif Node-path: graphics/ofTrueTypeFont.cpp Node-kind: file Node-action: change Text-content-length: 10833 Text-content-md5: 7b9862b3a5f5cebd5ff8cba69ad2f149 Content-length: 10833 #include "ofTrueTypeFont.h" //-------------------------- #ifdef TARGET_WIN32 #include #include #include #include #include #endif #ifdef TARGET_OSX #include "ft2build.h" #include "freetype.h" #include "ftglyph.h" #include "ftoutln.h" #include "fttrigon.h" #endif //------------------------------------------------------------------ ofTrueTypeFont::ofTrueTypeFont(){ bLoadedOk = false; } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize){ // load anti-aliased, non-full character set: loadFont(filename, fontsize, true, false); } //------------------------------------------------------------------ void ofTrueTypeFont::ofTrueTypeFont::loadFont(const char *filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet){ bLoadedOk = false; bAntiAlised = _bAntiAliased; bFullCharacterSet = _bFullCharacterSet; //--------------- load the library and typeface FT_Library library; if (FT_Init_FreeType( &library )){ printf("PROBLEM WITH FT lib \n"); return; } FT_Face face; if (FT_New_Face( library, filename, 0, &face )) { return; } FT_Set_Char_Size( face,fontsize << 6,fontsize << 6,96,96); lineHeight = fontsize * 1.43f; //------------------------------------------------------ //kerning would be great to support: //printf("FT_HAS_KERNING ? %i \n", FT_HAS_KERNING(face)); //------------------------------------------------------ nCharacters = bFullCharacterSet ? 256 : 128 - NUM_CHARACTER_TO_START; //--------------- initialize character info and textures cps = new charProps[nCharacters]; texNames = new GLuint[nCharacters]; glGenTextures(nCharacters, texNames); //--------------------- load each char ----------------------- for (int i = 0 ; i < nCharacters; i++){ //------------------------------------------ anti aliased or not: if (bAntiAlised == true){ if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph %i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); } else { if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph%i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO); } //------------------------------------------ FT_Bitmap& bitmap= face->glyph->bitmap; // 1 pixel border around the glyph int border = 2; // prepare the texture: int width = ofNextPow2( bitmap.width + border); int height = ofNextPow2( bitmap.rows + border); // ------------------------- this is fixing a bug with small type // ------------------------- appearantly, opengl has trouble with // ------------------------- width or height textures of 1, so we // ------------------------- we just set it to 2... if (width == 1) width = 2; if (height == 1) height = 2; // ------------------------- // info about the character: cps[i].value = i; cps[i].height = face->glyph->bitmap_top; cps[i].width = face->glyph->bitmap.width; cps[i].setWidth = face->glyph->advance.x >> 6; cps[i].topExtent = face->glyph->bitmap.rows; cps[i].leftExtent = face->glyph->bitmap_left; // texture internals cps[i].tTex = (float)bitmap.width / (float)width; cps[i].vTex = (float)bitmap.rows / (float)height; cps[i].xOff = ((1.0+(float)bitmap.width) / (float)width) - cps[i].tTex; cps[i].yOff = ((1.0+(float)bitmap.rows) / (float)height) - cps[i].vTex; /* sanity check: printf("%i %i %i %i %i %i \n", cps[i].value , cps[i].height , cps[i].width , cps[i].setWidth , cps[i].topExtent , cps[i].leftExtent ); */ // Allocate Memory For The Texture Data. unsigned char* expanded_data = new unsigned char[ 2 * width * height]; //-------------------------------- clear data: for(int j=0; j =bitmap.width || j-1>=bitmap.rows) ? 0 : 255; expanded_data[2*(k+j*width)+1] = (k-1>=bitmap.width || j-1>=bitmap.rows) ? 0 : bitmap.buffer[k-1 + bitmap.width*(j-1)]; } } //----------------------------------- } else { //----------------------------------- // true type packs monochrome info in a // 1-bit format, hella funky // here we unpack it: unsigned char *src = bitmap.buffer; for(int j=0; j = nCharacters){ printf("Error : char (%i) not allocated -- line %d in %s\n", (c + NUM_CHARACTER_TO_START), __LINE__,__FILE__); return; } //----------------------- int cu = c; float height = cps[cu].height; float bwidth = cps[cu].width; float top = cps[cu].topExtent - cps[cu].height; float lextent = cps[cu].leftExtent; float t = cps[cu].tTex; float v = cps[cu].vTex; float xOff = cps[cu].xOff; float yOff = cps[cu].yOff; if (glIsTexture(texNames[cu])) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texNames[cu]); glNormal3f(0, 0, 1); glBegin(GL_QUADS); glTexCoord2d(xOff,yOff); glVertex2f(x + lextent, y + height); glTexCoord2d(xOff,v+yOff); glVertex2f(x + lextent, y-top); glTexCoord2d(t+xOff,v+yOff); glVertex2f(x + lextent + bwidth,y-top); glTexCoord2d(t+xOff,yOff); glVertex2f(x + + lextent + bwidth,y + height); glEnd(); glDisable(GL_TEXTURE_2D); } else { printf("Error : texture not bound for character -- line %d in %s\n", __LINE__,__FILE__); } } //----------------------------------------------------------- float ofTrueTypeFont::stringWidth(char *c) { float width = 0; int index = 0; float widthTemp = 0; bool bMultiLine = false; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { width = MAX(width, widthTemp); widthTemp = 0; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; widthTemp += cps[cy].width; } else { widthTemp += cps[cy].setWidth; } } index++; } width = MAX(width, widthTemp); return width; } //----------------------------------------------------------- float ofTrueTypeFont::stringHeight(char *c) { float height = 0; int index = 0; float maxHeight = 0; bool bFirstLineOfMultiLine = true; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { if (bFirstLineOfMultiLine == true){ bFirstLineOfMultiLine = false; height += maxHeight; } else { height += lineHeight; } maxHeight = 0; } else if (c[index] == ' ') { } else { float ht = cps[cy].height; if (ht > maxHeight) maxHeight = ht; } } index++; } height += maxHeight; return height; } //===================================================================== void ofTrueTypeFont::drawString(char *c, float x, float y) { if (!bLoadedOk){ printf("Error : font not allocated -- line %d in %s\n", __LINE__,__FILE__); return; }; float startX = x; int index = 0; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { x = startX; int cy = (int)'M' - NUM_CHARACTER_TO_START; y -= lineHeight; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; x += cps[cy].width; } else { drawChar(cy, x, y); x += cps[cy].setWidth; } } index++; } } Node-path: graphics/ofTrueTypefont.h Node-kind: file Node-action: change Text-content-length: 1236 Text-content-md5: fa0b9399ef6e074bc72eb057b0766b30 Content-length: 1236 #ifndef _OF_TTF_FONT_H_ #define _OF_TTF_FONT_H_ #include "ofConstants.h" //-------------------------------------------------- typedef struct { int value; int height; int width; int setWidth; int topExtent; int leftExtent; float tTex; float vTex; //0-1 pct of bitmap... float xOff; float yOff; } charProps; //-------------------------------------------------- #define NUM_CHARACTER_TO_START 33 // 0 - 32 are control characters, no graphics needed. class ofTrueTypeFont{ public: ofTrueTypeFont(); // -- default, non-full char set, anti aliased: void loadFont(const char *filename, int fontsize); void loadFont(const char *filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet); bool bLoadedOk; bool bAntiAlised; bool bFullCharacterSet; float getLineHeight(); void setLineHeight(float height); float stringWidth(char *s); float stringHeight(char *c); void drawString(char *c, float x, float y); int nCharacters; protected: float lineHeight; charProps * cps; // properties for each character GLuint * texNames; // textures for each character void drawChar(int c, float x, float y); int ofNextPow2 (int a); }; #endif Node-path: video/ofQtUtils.cpp Node-kind: file Node-action: change Text-content-length: 2210 Text-content-md5: 1a29ff3120669d8c3c697abdafd3fdcd Content-length: 2210 #include "ofQtUtils.h" static bool bQuicktimeInitialized = true; //---------------------------------------- void initializeQuicktime(){ if (bQuicktimeInitialized == true){ //---------------------------------- // do we have quicktime installed at all? // http://www.apple.com/quicktime/download/win.html // can gestalt help with versions, or is that only after init? long myAttrs; OSErr myErr = noErr; #ifdef TARGET_WIN32 myErr = InitializeQTML(0); if (myErr != noErr){ printf("----------------------------------------------------- \n"); printf("sorry, there is a problem with quicktime starting up \nplease check!"); // std exit has trouble on dev-c++ #ifdef TARGET_OSX exit(0); // quit! #endif #ifndef __MINGW32__ #ifdef TARGET_WIN32 std::exit(0); // quit! #endif #else exit(0); // quit! #endif } #endif myErr = EnterMovies (); if (myErr != noErr){ printf("----------------------------------------------------- \n"); printf("sorry, there is a problem with quicktime starting up \nplease check!"); #ifdef TARGET_OSX exit(0); // quit! #endif #ifndef __MINGW32__ #ifdef TARGET_WIN32 std::exit(0); // quit! #endif #else exit(0); // quit! #endif } bQuicktimeInitialized = false; } } //---------------------------------------- void convertPixels(unsigned char * gWorldPixels, unsigned char * rgbPixels, int w, int h){ // ok for macs? // ok for intel macs? int * rgbaPtr = (int *) gWorldPixels; pix24 * rgbPtr = (pix24 *) rgbPixels; int totalPixelCount = w * h; unsigned char * rgbaStart; bool bFlipVertically = true; if (!bFlipVertically){ //----- argb->rgb for (int i = 0; i < totalPixelCount; i++){ rgbaStart = (unsigned char *)rgbaPtr; memcpy (rgbPtr, rgbaStart+1, sizeof(pix24)); rgbPtr++; rgbaPtr++; } } else { //----- flip while argb->rgb for (int i = 0; i < h; i++){ pix24 * rgbPtr = (pix24 *) rgbPixels + ((h-i-1) * w); for (int j = 0; j < w; j++){ rgbaStart = (unsigned char *)rgbaPtr; memcpy (rgbPtr, rgbaStart+1, sizeof(pix24)); rgbPtr++; rgbaPtr++; } } } } Node-path: video/ofQtVideoGrabber.cpp Node-kind: file Node-action: change Text-content-length: 6960 Text-content-md5: 3849cdefc7ec03b623425623dd316d1c Content-length: 6960 #include "ofQtVideoGrabber.h" //-------------------------------------------------------------------- Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon); Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon){ #pragma unused(theDialog, itemHit) Boolean handled = false; if ((theEvent->what == updateEvt) && ((WindowPtr) theEvent->message == (WindowPtr) refCon)) { BeginUpdate ((WindowPtr) refCon); EndUpdate ((WindowPtr) refCon); handled = true; } return (handled); } //-------------------------------------------------------------------- ofQtVideoGrabber::ofQtVideoGrabber(){ initializeQuicktime(); vgd = new videoGrabberData(); bVerbose = false; bSgGrabberInited = false; } //-------------------------------------------------------------------- void ofQtVideoGrabber::setVerbose(bool bTalkToMe){ bVerbose = bTalkToMe; } //--------------------------------------------------------------------------- unsigned char * ofQtVideoGrabber::getPixels(){ return vgd->pixels; } //--------------------------------------------------------------------------- bool ofQtVideoGrabber::isFrameNew(){ if (bSgGrabberInited == true){ bool bNew = false; if (vgd->bHavePixelsChanged == true){ bNew = true; vgd->bHavePixelsChanged = false; } return bNew; } else { return false; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::grabFrame(){ if (bSgGrabberInited == true){ SGIdle(vgd->gSeqGrabber); // set the top pixel alpha = 0, so we can know if it // was a new frame or not.. // or else we will process way more than necessary // (ie opengl is running at 60fps +, capture at 30fps) if (vgd->offscreenGWorldPixels[0] != 0x00){ vgd->offscreenGWorldPixels[0] = 0x00; vgd->bHavePixelsChanged = true; convertPixels(vgd->offscreenGWorldPixels, vgd->pixels, vgd->w, vgd->h); } } } //-------------------------------------------------------------------- void ofQtVideoGrabber::close(){ // } //-------------------------------------------------------------------- void ofQtVideoGrabber::videoSettings(void){ Rect curBounds, curVideoRect; short width, height; ComponentResult err; // Get our current state err = SGGetChannelBounds (vgd->gVideoChannel, &curBounds); if (err != noErr){ printf("Error in SGGetChannelBounds \n"); return; } err = SGGetVideoRect (vgd->gVideoChannel, &curVideoRect); if (err != noErr){ printf("Error in SGGetVideoRect \n"); return; } // Pause err = SGPause (vgd->gSeqGrabber, true); if (err != noErr){ printf("Error in SGPause\n"); return; } #ifdef TARGET_OSX printf("HERE\n"); static SGModalFilterUPP gSeqGrabberModalFilterUPP = NewSGModalFilterUPP(SeqGrabberModalFilterUPP); ComponentResult result = SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, 0L, gSeqGrabberModalFilterUPP, nil); if (err != noErr){ printf("error in dialogue\n"); return; } #else SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, 0L, NULL, nil); #endif #ifdef TARGET_WIN32 SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); #endif SGPause (vgd->gSeqGrabber, false); } //-------------------------------------------------------------------- void ofQtVideoGrabber::initGrabber(int _w, int _h){ w = _w; h = _h; vgd->w = w; vgd->h = h; ComponentDescription theDesc; Component sgCompID = NULL; char name[256]; char info[256]; Handle componentName=NULL; Handle componentInfo=NULL; ComponentDescription info_description; componentName=NewHandle(sizeof(name)); componentInfo=NewHandle(sizeof(info)); if (bVerbose == true){ printf ("\n"); printf ("-------------------------------------\n"); printf ("attempting to set up ofQtVideoGrabber\n"); } vgd->gSeqGrabber = 0L; vgd->gVideoChannel = 0L; theDesc.componentType = SeqGrabComponentType; theDesc.componentSubType = 0L; theDesc.componentManufacturer = 0L; theDesc.componentFlags = 0L; theDesc.componentFlagsMask = 0L; sgCompID = FindNextComponent(sgCompID, &theDesc); while (sgCompID != 0){ GetComponentInfo(sgCompID,&info_description, componentName, componentInfo,nil); if (bVerbose == true){ printf("found a device to capture with \n"); printf("Type: %s\n", &info_description.componentType); printf("Manufacturer: %s\n", &info_description.componentManufacturer); printf("Name: %s\n", *componentName ? p2cstr((StringPtr)*componentName) : "-" ); printf("Name: %s\n", *componentInfo ? p2cstr((StringPtr)*componentInfo) : "-"); } vgd->gSeqGrabber = OpenComponent(sgCompID); sgCompID = FindNextComponent(sgCompID, &theDesc); } //-------------------------------------------- // setup the gworld and digitizing. OSStatus err; err = SGInitialize(vgd->gSeqGrabber); if (err != noErr){ printf("***** Error in SGInitialize (check cam drivers, vdig or winvidg)*****\n"); return; } MacSetRect(&(vgd->videoRect),0, 0, w, h); //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vgd->offscreenGWorldPixels = (unsigned char*)malloc(4 * w * h + 32); vgd->pixels = new unsigned char[w*h*3]; QTNewGWorldFromPtr (&vgd->videogworld, k32ARGBPixelFormat, &vgd->videoRect, NULL, NULL, 0, vgd->offscreenGWorldPixels, 4 * w); LockPixels(GetGWorldPixMap(vgd->videogworld)); SetGWorld (vgd->videogworld, NULL); err = SGSetGWorld(vgd->gSeqGrabber, vgd->videogworld, nil); if ( err != noErr ) goto bail; err = SGNewChannel(vgd->gSeqGrabber, VideoMediaType, &vgd->gVideoChannel); if ( err != noErr ) goto bail; err = SGSetDataRef(vgd->gSeqGrabber, 0, 0, seqGrabDontMakeMovie); if ( err != noErr ) goto bail; err = SGSetChannelUsage(vgd->gVideoChannel,seqGrabPreview); if ( err != noErr ) goto bail; err = SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); if ( err != noErr ) goto bail; if (SGSetFrameRate(vgd->gVideoChannel,30) != noErr) printf( "error setting 30 fps \n"); else{ if (bVerbose == true){ printf ("set to capture at 30 fps \n"); } } err = SGPrepare(vgd->gSeqGrabber, false, true); if ( err != noErr ) goto bail; err = SGStartPreview(vgd->gSeqGrabber); if ( err != noErr ) goto bail; if (bVerbose){ printf ("end setup ofQtVideoGrabber\n"); printf ("-------------------------------------\n"); printf ("\n"); } bSgGrabberInited = true; return; bail: if (bVerbose){ printf ("***** ofQtVideoGrabber error *****\n"); printf ("-------------------------------------\n"); printf ("\n"); } bSgGrabberInited = false; return; } //-------------------------------------------------------------------- Revision-number: 14 Prop-content-length: 160 Content-length: 160 K 7 svn:log V 58 made the exit() routines nicer & a bug fixe in quicktimeSG K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-01-24T13:29:47.229152Z PROPS-END Node-path: app/ofAppGlutGlue.h Node-kind: file Node-action: change Text-content-length: 2121 Text-content-md5: befcb95d63b522888d79649b9cb59729 Content-length: 2121 void display(void); void mouse_cb(int button, int state, int x, int y); void motion_cb(int x, int y); void passive_motion_cb(int x, int y); void idle_cb(void); void keyboard_cb(unsigned char key, int x, int y); void special_key_cb(int key, int x, int y) ; static int buttonInUse = 0; //-------------------------------- static float timeNow, timeThen, fps; static int nFrames; //------------------------------------------------------------ void display(void){ ofGetWindowSize( &width, &height ); height = height > 0 ? height : 1; // set viewport, clear the screen glViewport( 0, 0, width, height ); float * bgPtr = ofBgColorPtr(); glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); OFSAptr->draw(); glutSwapBuffers(); // -------------- fps calculation: timeNow = ofGetElapsedTimef(); if( (timeNow-timeThen) > 0.05f || nFrames == 0 ) { fps = (double)nFrames / (timeNow-timeThen); timeThen = timeNow; nFrames = 0; ofFrameRate = 0.9f * ofFrameRate + 0.1f * fps; } nFrames++; // -------------- } //------------------------------------------------------------ void mouse_cb(int button, int state, int x, int y) { if (state == GLUT_DOWN) { OFSAptr->mouseDown(x, height - y, button); } else if (state == GLUT_UP) { OFSAptr->mouseUp(x, height - y, button); } buttonInUse = button; } //------------------------------------------------------------ void motion_cb(int x, int y) { OFSAptr->mouseDrag(x, height - y, buttonInUse); } //------------------------------------------------------------ void passive_motion_cb(int x, int y) { OFSAptr->mouseMove(x, height - y); } //------------------------------------------------------------ void idle_cb(void) { OFSAptr->idle(); glutPostRedisplay(); } //------------------------------------------------------------ void keyboard_cb(unsigned char key, int x, int y) { OFSAptr->keyDown((int)key); OF_EXIT_APP(0); } //------------------------------------------------------------ void special_key_cb(int key, int x, int y) { OFSAptr->keyDown((int)key); } Node-path: app/ofAppRunner.cpp Node-kind: file Node-action: change Text-content-length: 1363 Text-content-md5: 1d7579cb41641e4982a81c3bae337f1e Content-length: 1363 #include "ofAppRunner.h" //======================================================================== // static variables: static ofSimpleApp * OFSAptr; bool bMousePressed; bool bRightButton; int width, height; static float ofFrameRate; //======================================================================== // callbacks: #include "ofAppGlutGlue.h" //-------------------------------------- void ofSetupOpenGL(int w, int h, int screenMode){ int argc = 1; char *argv = "openframeworks"; char **vptr = &argv; glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA); glutInit(&argc, vptr); if (screenMode == OF_WINDOW) glutInitWindowSize(w, h); glutCreateWindow(""); if (screenMode == OF_FULLSCREEN) glutFullScreen(); } //-------------------------------------- void ofRunApp(ofSimpleApp * OFSA){ OFSAptr = OFSA; // window // callbacks glutMouseFunc(mouse_cb); glutMotionFunc(motion_cb); glutPassiveMotionFunc(passive_motion_cb); glutIdleFunc(idle_cb); glutDisplayFunc(display); glutKeyboardFunc(keyboard_cb); glutSpecialFunc(special_key_cb); OFSA->init(); glutMainLoop(); } float ofGetFrameRate(){ return ofFrameRate; } void ofHideCursor(){ glutSetCursor(GLUT_CURSOR_NONE); } void ofShowCursor(){ glutSetCursor(GLUT_CURSOR_RIGHT_ARROW); } Node-path: utils/ofConstants.h Node-kind: file Node-action: change Text-content-length: 1430 Text-content-md5: 5f2c8a86d9238a7f798bac3473b10688 Content-length: 1430 #ifndef OF_CONSTANTS #define OF_CONSTANTS //------------------------------- // pc or mac ? // soon: pc, mac or linux... #ifndef __APPLE_CC__ #define TARGET_WIN32 #else #define TARGET_OSX #endif //------------------------------- #ifdef TARGET_WIN32 #include #include "glut.h" #define __WINDOWS_DS__ #define __WINDOWS_MM__ #endif #ifdef TARGET_OSX #define __MACOSX_CORE__ #include #endif #ifndef __MWERKS__ #define OF_EXIT_APP(val) exit(val); #else #define OF_EXIT_APP(val) std::exit(val); #endif // core: --------------------------- #include #include #include #include #include #ifndef PI #define PI 3.14159265358979323846 #endif #ifndef TWO_PI #define TWO_PI 6.28318530717958647693 #endif #ifndef M_TWO_PI #define M_TWO_PI 6.28318530717958647693 #endif #ifndef FOUR_PI #define FOUR_PI 12.56637061435917295385 #endif #ifndef HALF_PI #define HALF_PI 1.57079632679489661923 #endif #ifndef DEG_TO_RAD #define DEG_TO_RAD (PI/180.0) #endif #ifndef RAD_TO_DEG #define RAD_TO_DEG (180.0/PI) #endif #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #endif #ifndef ABS #define ABS(x) (((x) < 0) ? -(x) : (x)) #endif #define OF_FILLED 0x01 #define OF_OUTLINE 0x02 #define OF_WINDOW 0 #define OF_FULLSCREEN 1 #endif Node-path: utils/ofUtils.cpp Node-kind: file Node-action: change Text-content-length: 3370 Text-content-md5: 1991cf57d6973709ee68a271298fcfc4 Content-length: 3370 #include "ofUtils.h" //-------------------------------------------------- int ofNextPow2 ( int a ){ // from nehe.gamedev.net lesson 43 int rval=1; while(rval sw) width = sw-x; if (height+y > sh) height = sh-y; char *ScreenImageBuffer = (char*)malloc(width*height*3); char *flippedScreenImageBuffer = (char*)malloc(width*height*3); char fileName[255]; sprintf(fileName, "screen_grab__%ix%i__%0.4i.raw", width, height, frameNum++); FILE* OutputFile = fopen(fileName, "wb"); glReadPixels(x,y,width,height,GL_RGB,GL_UNSIGNED_BYTE,ScreenImageBuffer); // need to flip image for (int i = 0; i < height; i++) { memcpy(flippedScreenImageBuffer+(sizeof(char)*i*width*3), ScreenImageBuffer+(sizeof(char)*(height-i)*width*3), sizeof(char)*width*3); } fwrite(flippedScreenImageBuffer,width*height*3,1,OutputFile); fclose(OutputFile); free(ScreenImageBuffer); free(flippedScreenImageBuffer); } //-------------------------------------- int ofGetElapsedTimeMillis(){ return (int)(glutGet(GLUT_ELAPSED_TIME)); } //-------------------------------------- float ofGetElapsedTimef(){ return (float)(glutGet(GLUT_ELAPSED_TIME))/1000.0f; } //-------------------------------------- int ofGetMillis(){ // this is a hack now... should be based on system time // time_t is not in millisecond resolution. what to replace this with? // for not millis is elapsed milliseconds, not clock millis... return (int)(glutGet(GLUT_ELAPSED_TIME) % 1000); // http://man.he.net/man2/gettimeofday } //-------------------------------------------------- int ofGetSeconds(){ time_t curr; tm local; time(&curr); local =*(localtime(&curr)); return local.tm_sec; } //-------------------------------------------------- int ofGetMinutes(){ time_t curr; tm local; time(&curr); local =*(localtime(&curr)); return local.tm_min; } //-------------------------------------------------- int ofGetHours(){ time_t curr; tm local; time(&curr); local =*(localtime(&curr)); return local.tm_hour; } Node-path: video/ofQtUtils.cpp Node-kind: file Node-action: change Text-content-length: 1877 Text-content-md5: 0add7837fda62f09773f5d18770453be Content-length: 1877 #include "ofQtUtils.h" static bool bQuicktimeInitialized = true; //---------------------------------------- void initializeQuicktime(){ if (bQuicktimeInitialized == true){ //---------------------------------- // do we have quicktime installed at all? // http://www.apple.com/quicktime/download/win.html // can gestalt help with versions, or is that only after init? long myAttrs; OSErr myErr = noErr; #ifdef TARGET_WIN32 myErr = InitializeQTML(0); if (myErr != noErr){ printf("----------------------------------------------------- \n"); printf("sorry, there is a problem with quicktime starting up \nplease check!"); // std exit has trouble on dev-c++ OF_EXIT_APP(0); } #endif myErr = EnterMovies (); if (myErr != noErr){ printf("----------------------------------------------------- \n"); printf("sorry, there is a problem with quicktime starting up \nplease check!"); OF_EXIT_APP(0); } bQuicktimeInitialized = false; } } //---------------------------------------- void convertPixels(unsigned char * gWorldPixels, unsigned char * rgbPixels, int w, int h){ // ok for macs? // ok for intel macs? int * rgbaPtr = (int *) gWorldPixels; pix24 * rgbPtr = (pix24 *) rgbPixels; int totalPixelCount = w * h; unsigned char * rgbaStart; bool bFlipVertically = true; if (!bFlipVertically){ //----- argb->rgb for (int i = 0; i < totalPixelCount; i++){ rgbaStart = (unsigned char *)rgbaPtr; memcpy (rgbPtr, rgbaStart+1, sizeof(pix24)); rgbPtr++; rgbaPtr++; } } else { //----- flip while argb->rgb for (int i = 0; i < h; i++){ pix24 * rgbPtr = (pix24 *) rgbPixels + ((h-i-1) * w); for (int j = 0; j < w; j++){ rgbaStart = (unsigned char *)rgbaPtr; memcpy (rgbPtr, rgbaStart+1, sizeof(pix24)); rgbPtr++; rgbaPtr++; } } } } Node-path: video/ofQtVideoGrabber.cpp Node-kind: file Node-action: change Text-content-length: 7066 Text-content-md5: 5d048dfb596bdb418ccc336d296e6ba0 Content-length: 7066 #include "ofQtVideoGrabber.h" //-------------------------------------------------------------------- Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon); Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon){ #pragma unused(theDialog, itemHit) Boolean handled = false; if ((theEvent->what == updateEvt) && ((WindowPtr) theEvent->message == (WindowPtr) refCon)) { BeginUpdate ((WindowPtr) refCon); EndUpdate ((WindowPtr) refCon); handled = true; } return (handled); } //-------------------------------------------------------------------- ofQtVideoGrabber::ofQtVideoGrabber(){ initializeQuicktime(); vgd = new videoGrabberData(); bVerbose = false; bSgGrabberInited = false; } //-------------------------------------------------------------------- void ofQtVideoGrabber::setVerbose(bool bTalkToMe){ bVerbose = bTalkToMe; } //--------------------------------------------------------------------------- unsigned char * ofQtVideoGrabber::getPixels(){ return vgd->pixels; } //--------------------------------------------------------------------------- bool ofQtVideoGrabber::isFrameNew(){ if (bSgGrabberInited == true){ bool bNew = false; if (vgd->bHavePixelsChanged == true){ bNew = true; vgd->bHavePixelsChanged = false; } return bNew; } else { return false; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::grabFrame(){ if (bSgGrabberInited == true){ SGIdle(vgd->gSeqGrabber); // set the top pixel alpha = 0, so we can know if it // was a new frame or not.. // or else we will process way more than necessary // (ie opengl is running at 60fps +, capture at 30fps) if (vgd->offscreenGWorldPixels[0] != 0x00){ vgd->offscreenGWorldPixels[0] = 0x00; vgd->bHavePixelsChanged = true; convertPixels(vgd->offscreenGWorldPixels, vgd->pixels, vgd->w, vgd->h); } } } //-------------------------------------------------------------------- void ofQtVideoGrabber::close(){ //thanks eloi! if (vgd->gSeqGrabber != 0L){ CloseComponent (vgd->gSeqGrabber); vgd->gSeqGrabber = 0L; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::videoSettings(void){ Rect curBounds, curVideoRect; short width, height; ComponentResult err; // Get our current state err = SGGetChannelBounds (vgd->gVideoChannel, &curBounds); if (err != noErr){ printf("Error in SGGetChannelBounds \n"); return; } err = SGGetVideoRect (vgd->gVideoChannel, &curVideoRect); if (err != noErr){ printf("Error in SGGetVideoRect \n"); return; } // Pause err = SGPause (vgd->gSeqGrabber, true); if (err != noErr){ printf("Error in SGPause\n"); return; } #ifdef TARGET_OSX printf("HERE\n"); static SGModalFilterUPP gSeqGrabberModalFilterUPP = NewSGModalFilterUPP(SeqGrabberModalFilterUPP); ComponentResult result = SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, 0L, gSeqGrabberModalFilterUPP, nil); if (err != noErr){ printf("error in dialogue\n"); return; } #else SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, 0L, NULL, nil); #endif #ifdef TARGET_WIN32 SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); #endif SGPause (vgd->gSeqGrabber, false); } //-------------------------------------------------------------------- void ofQtVideoGrabber::initGrabber(int _w, int _h){ w = _w; h = _h; vgd->w = w; vgd->h = h; ComponentDescription theDesc; Component sgCompID = NULL; char name[256]; char info[256]; Handle componentName=NULL; Handle componentInfo=NULL; ComponentDescription info_description; componentName=NewHandle(sizeof(name)); componentInfo=NewHandle(sizeof(info)); if (bVerbose == true){ printf ("\n"); printf ("-------------------------------------\n"); printf ("attempting to set up ofQtVideoGrabber\n"); } vgd->gSeqGrabber = 0L; vgd->gVideoChannel = 0L; theDesc.componentType = SeqGrabComponentType; theDesc.componentSubType = 0L; theDesc.componentManufacturer = 0L; theDesc.componentFlags = 0L; theDesc.componentFlagsMask = 0L; sgCompID = FindNextComponent(sgCompID, &theDesc); while (sgCompID != 0){ GetComponentInfo(sgCompID,&info_description, componentName, componentInfo,nil); if (bVerbose == true){ printf("found a device to capture with \n"); printf("Type: %s\n", &info_description.componentType); printf("Manufacturer: %s\n", &info_description.componentManufacturer); printf("Name: %s\n", *componentName ? p2cstr((StringPtr)*componentName) : "-" ); printf("Name: %s\n", *componentInfo ? p2cstr((StringPtr)*componentInfo) : "-"); } vgd->gSeqGrabber = OpenComponent(sgCompID); sgCompID = FindNextComponent(sgCompID, &theDesc); } //-------------------------------------------- // setup the gworld and digitizing. OSStatus err; err = SGInitialize(vgd->gSeqGrabber); if (err != noErr){ printf("***** Error in SGInitialize (check cam drivers, vdig or winvidg)*****\n"); return; } MacSetRect(&(vgd->videoRect),0, 0, w, h); //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vgd->offscreenGWorldPixels = (unsigned char*)malloc(4 * w * h + 32); vgd->pixels = new unsigned char[w*h*3]; QTNewGWorldFromPtr (&vgd->videogworld, k32ARGBPixelFormat, &vgd->videoRect, NULL, NULL, 0, vgd->offscreenGWorldPixels, 4 * w); LockPixels(GetGWorldPixMap(vgd->videogworld)); SetGWorld (vgd->videogworld, NULL); err = SGSetGWorld(vgd->gSeqGrabber, vgd->videogworld, nil); if ( err != noErr ) goto bail; err = SGNewChannel(vgd->gSeqGrabber, VideoMediaType, &vgd->gVideoChannel); if ( err != noErr ) goto bail; err = SGSetDataRef(vgd->gSeqGrabber, 0, 0, seqGrabDontMakeMovie); if ( err != noErr ) goto bail; err = SGSetChannelUsage(vgd->gVideoChannel,seqGrabPreview); if ( err != noErr ) goto bail; err = SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); if ( err != noErr ) goto bail; if (SGSetFrameRate(vgd->gVideoChannel,30) != noErr) printf( "error setting 30 fps \n"); else{ if (bVerbose == true){ printf ("set to capture at 30 fps \n"); } } err = SGPrepare(vgd->gSeqGrabber, false, true); if ( err != noErr ) goto bail; err = SGStartPreview(vgd->gSeqGrabber); if ( err != noErr ) goto bail; if (bVerbose){ printf ("end setup ofQtVideoGrabber\n"); printf ("-------------------------------------\n"); printf ("\n"); } bSgGrabberInited = true; return; bail: if (bVerbose){ printf ("***** ofQtVideoGrabber error *****\n"); printf ("-------------------------------------\n"); printf ("\n"); } bSgGrabberInited = false; return; } //-------------------------------------------------------------------- Revision-number: 15 Prop-content-length: 185 Content-length: 185 K 7 svn:log V 83 fixed bgr/rgb load issue on windows now with a new function called "swapChannels()" K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-01-24T14:23:20.976937Z PROPS-END Node-path: graphics/ofImage.cpp Node-kind: file Node-action: change Text-content-length: 5878 Text-content-md5: f19305b671e17476a3ce9e5f63b3bcf5 Content-length: 5878 #include "ofImage.h" #include "freeImage.h" static bool bFreeImageInited = false; //----------------------------------------- // class freeImageBitmap{ public: FIBITMAP * bmp; //----------------------- freeImageBitmap(){ bmp = NULL; } //----------------------- //swap my image out in a (hopefully) non-memory leakish way void swap(FIBITMAP *dst) { if(dst == NULL) return; if(bmp != NULL) FreeImage_Unload(bmp); bmp = dst; } //----------------------- void setSize(FREE_IMAGE_TYPE image_type, WORD width, WORD height, WORD bpp) { if(bmp == NULL) { FreeImage_Unload(bmp); } bmp = FreeImage_AllocateT(image_type, width, height, bpp); } //----------------------- bool isValid(){ return (bmp != NULL) ? true : false; } }; //---------------------------------------------------------- ofImage::ofImage(){ //----------------------- init free image if necessary if (!bFreeImageInited){ FreeImage_Initialise(); bFreeImageInited = true; } //----------------------- IMG = new freeImageBitmap(); w = h = bpp = 0; type = OF_IMAGE_UNDEFINED; } //---------------------------------------------------------- void ofImage::grabScreen(int _x, int _y, int _w, int _h){ if (IMG->isValid()){ if (!(w == _w && h == _h)){ resize(_w, _h); } unsigned char * pixels = getPixels(); switch (bpp){ case 8: glReadPixels(_x, _y, _w, _h, GL_LUMINANCE,GL_UNSIGNED_BYTE, pixels); break; case 24: glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); break; case 32: glReadPixels(_x, _y, _w, _h, GL_RGBA,GL_UNSIGNED_BYTE, pixels); break; } } else { // assume that this is color.... IMG->setSize(FIT_BITMAP, _w, _h, 24); unsigned char * pixels = getPixels(); glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE,pixels); update(); } } //---------------------------------------------------------- void ofImage::allocate(int _w, int _h, int _type){ int newbpp; switch (_type){ case OF_IMAGE_GRAYSCALE: newbpp = 8; break; case OF_IMAGE_COLOR: newbpp = 24; break; case OF_IMAGE_COLOR_ALPHA: newbpp = 32; break; default: newbpp = 24; break; } IMG->setSize(FIT_BITMAP, _w, _h, newbpp); } //---------------------------------------------------------- void ofImage::update(){ w = FreeImage_GetWidth(IMG->bmp); h = FreeImage_GetHeight(IMG->bmp); bpp = FreeImage_GetBPP(IMG->bmp); } //---------------------------------------------------------- void ofImage::loadImage(char * fileName){ bool bLoaded = false; //----------------------------- find the format FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { if(IMG->isValid()) { FreeImage_Unload(IMG->bmp); } IMG->bmp = FreeImage_Load(fif, fileName, 0); bLoaded = true; if(!IMG->isValid()){ bLoaded = false; } } //----------------------------- if (bLoaded){ update(); switch (bpp){ case 8: type = OF_IMAGE_GRAYSCALE; break; case 24: type = OF_IMAGE_COLOR; //--------------- on windows, we need to change BGR to RGB #ifdef TARGET_WIN32 swapChannels(); #endif break; case 32: type = OF_IMAGE_COLOR_ALPHA; break; default: setImageType(OF_IMAGE_COLOR); break; } } else { w = h = bpp = 0; } } //---------------------------------------------------------- void ofImage::saveImage(char * fileName){ if (IMG->isValid()){ //IMG->save(fileName); } } //---------------------------------------------------------- unsigned char * ofImage::getPixels(){ // be careful! if (IMG->isValid()){ return (unsigned char *)FreeImage_GetBits(IMG->bmp); } else { return NULL; } } //---------------------------------------------------------- void ofImage::resize(int newWidth, int newHeight){ if (IMG->isValid()){ FIBITMAP * scaledBmp = FreeImage_Rescale(IMG->bmp, newWidth, newHeight, FILTER_BICUBIC); IMG->swap(scaledBmp); update(); } } //---------------------------------------------------------- void ofImage::setImageType(int newType){ if (IMG->isValid()){ switch (newType){ //------------------------------------ case OF_IMAGE_GRAYSCALE: if (type != OF_IMAGE_GRAYSCALE){ FIBITMAP * convertedBmp = FreeImage_ConvertToGreyscale(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; //------------------------------------ case OF_IMAGE_COLOR: if (type != OF_IMAGE_COLOR){ FIBITMAP * convertedBmp = FreeImage_ConvertTo24Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR; } break; //------------------------------------ case OF_IMAGE_COLOR_ALPHA: if (type != OF_IMAGE_COLOR_ALPHA){ FIBITMAP * convertedBmp = FreeImage_ConvertTo32Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; } update(); } } //------------------------------------ void ofImage::swapChannels(){ // this swaps the red and blue channel of an image // turning an bgr image to rgb and vice versa... // needed because of windows byte order... if (IMG->isValid() && type == OF_IMAGE_COLOR){ unsigned char * pixels = getPixels(); int nTotalPixels = w*h; unsigned char temp; // unoptimized for now... for (int i = 0; i < nTotalPixels; i++){ temp = pixels[i*3]; pixels[i*3] = pixels[i*3 + 2]; pixels[i*3 + 2] = temp; } } } Node-path: graphics/ofImage.h Node-kind: file Node-action: change Text-content-length: 1101 Text-content-md5: d63f85f88a839e3f7897695224b4fd53 Content-length: 1101 #ifndef _OF_IMAGE_H_ #define _OF_IMAGE_H_ #include "ofConstants.h" #define OF_IMAGE_GRAYSCALE 0x00 #define OF_IMAGE_COLOR 0x01 #define OF_IMAGE_COLOR_ALPHA 0x02 #define OF_IMAGE_UNDEFINED 0x03 //------------------------- // forward class declaration, something // we will need in order to compile "OF" as a lib // so that you don't need freeImage, quicktime, etc.. class freeImageBitmap; //------------------------- class ofImage { public : ofImage(); void loadImage(char * fileName); void saveImage(char * fileName); void allocate(int w, int h, int type); unsigned char * getPixels(); // up to you to get this right void setImageType(int type); void resize(int newWidth, int newHeight); void grabScreen(int x, int y, int w, int h); // grab pixels from opengl, using glreadpixels int type; // what type of image it is (as above) int w, h, bpp; // w,h, bits per pixel private: void swapChannels(); void update(); freeImageBitmap * IMG; }; #endif Revision-number: 16 Prop-content-length: 192 Content-length: 192 K 7 svn:log V 90 zach - updated for MSVC warnings, renamed grabFrame() in QTVP and some additional comments K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-01-25T13:58:41.449985Z PROPS-END Node-path: utils/ofConstants.h Node-kind: file Node-action: change Text-content-length: 1685 Text-content-md5: 6527a63d89d6910e10cb963ff17b9361 Content-length: 1685 #ifndef OF_CONSTANTS #define OF_CONSTANTS //------------------------------- // pc or mac ? // soon: pc, mac or linux... #ifndef __APPLE_CC__ #define TARGET_WIN32 #else #define TARGET_OSX #endif //------------------------------- #ifdef TARGET_WIN32 #include #include "glut.h" #define __WINDOWS_DS__ #define __WINDOWS_MM__ #if (_MSC_VER) // microsoft visual studio #pragma warning(disable : 4996) // disable all deprecation warnings #pragma warning(disable : 4068) // unknown pragmas #pragma warning(disable : 4101) // unreferenced local variable #endif #endif #ifdef TARGET_OSX #define __MACOSX_CORE__ #include #endif #ifndef __MWERKS__ #define OF_EXIT_APP(val) exit(val); #else #define OF_EXIT_APP(val) std::exit(val); #endif // core: --------------------------- #include #include #include #include #include #ifndef PI #define PI 3.14159265358979323846 #endif #ifndef TWO_PI #define TWO_PI 6.28318530717958647693 #endif #ifndef M_TWO_PI #define M_TWO_PI 6.28318530717958647693 #endif #ifndef FOUR_PI #define FOUR_PI 12.56637061435917295385 #endif #ifndef HALF_PI #define HALF_PI 1.57079632679489661923 #endif #ifndef DEG_TO_RAD #define DEG_TO_RAD (PI/180.0) #endif #ifndef RAD_TO_DEG #define RAD_TO_DEG (180.0/PI) #endif #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #endif #ifndef ABS #define ABS(x) (((x) < 0) ? -(x) : (x)) #endif #define OF_FILLED 0x01 #define OF_OUTLINE 0x02 #define OF_WINDOW 0 #define OF_FULLSCREEN 1 #endif Node-path: video/ofQtUtils.cpp Node-kind: file Node-action: change Text-content-length: 2200 Text-content-md5: 948b43a826d8086ee5f217672d47f73d Content-length: 2200 #include "ofQtUtils.h" static bool bQuicktimeInitialized = true; //---------------------------------------- void initializeQuicktime(){ if (bQuicktimeInitialized == true){ //---------------------------------- // do we have quicktime installed at all? // http://www.apple.com/quicktime/download/win.html // can gestalt help with versions, or is that only after init? long myAttrs; OSErr myErr = noErr; #ifdef TARGET_WIN32 myErr = InitializeQTML(0); if (myErr != noErr){ printf("----------------------------------------------------- \n"); printf("sorry, there is a problem with quicktime starting up \nplease check!"); // std exit has trouble on dev-c++ OF_EXIT_APP(0); } #endif myErr = EnterMovies (); if (myErr != noErr){ printf("----------------------------------------------------- \n"); printf("sorry, there is a problem with quicktime starting up \nplease check!"); OF_EXIT_APP(0); } bQuicktimeInitialized = false; } } //---------------------------------------- void convertPixels(unsigned char * gWorldPixels, unsigned char * rgbPixels, int w, int h){ // ok for macs? // ok for intel macs? int * rgbaPtr = (int *) gWorldPixels; pix24 * rgbPtr = (pix24 *) rgbPixels; int totalPixelCount = w * h; unsigned char * rgbaStart; bool bFlipVertically = true; // ------------------------------------------- // we flip vertically because the 0,0 position in OF // is the bottom left (not top left, like processing) // since the 0,0 of a picture is top left // if we upload and draw the data as is // it will be upside-down.... // ------------------------------------------- if (!bFlipVertically){ //----- argb->rgb for (int i = 0; i < totalPixelCount; i++){ rgbaStart = (unsigned char *)rgbaPtr; memcpy (rgbPtr, rgbaStart+1, sizeof(pix24)); rgbPtr++; rgbaPtr++; } } else { //----- flip while argb->rgb for (int i = 0; i < h; i++){ pix24 * rgbPtr = (pix24 *) rgbPixels + ((h-i-1) * w); for (int j = 0; j < w; j++){ rgbaStart = (unsigned char *)rgbaPtr; memcpy (rgbPtr, rgbaStart+1, sizeof(pix24)); rgbPtr++; rgbaPtr++; } } } } Node-path: video/ofQtVideoGrabber.cpp Node-kind: file Node-action: change Text-content-length: 7050 Text-content-md5: e5e3589ab3c887bf4b07bfa73694cf63 Content-length: 7050 #include "ofQtVideoGrabber.h" //-------------------------------------------------------------------- Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon); Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon){ #pragma unused(theDialog, itemHit) Boolean handled = false; if ((theEvent->what == updateEvt) && ((WindowPtr) theEvent->message == (WindowPtr) refCon)) { BeginUpdate ((WindowPtr) refCon); EndUpdate ((WindowPtr) refCon); handled = true; } return (handled); } //-------------------------------------------------------------------- ofQtVideoGrabber::ofQtVideoGrabber(){ initializeQuicktime(); vgd = new videoGrabberData(); bVerbose = false; bSgGrabberInited = false; } //-------------------------------------------------------------------- void ofQtVideoGrabber::setVerbose(bool bTalkToMe){ bVerbose = bTalkToMe; } //--------------------------------------------------------------------------- unsigned char * ofQtVideoGrabber::getPixels(){ return vgd->pixels; } //--------------------------------------------------------------------------- bool ofQtVideoGrabber::isFrameNew(){ if (bSgGrabberInited == true){ bool bNew = false; if (vgd->bHavePixelsChanged == true){ bNew = true; vgd->bHavePixelsChanged = false; } return bNew; } else { return false; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::grabFrame(){ if (bSgGrabberInited == true){ SGIdle(vgd->gSeqGrabber); // set the top pixel alpha = 0, so we can know if it // was a new frame or not.. // or else we will process way more than necessary // (ie opengl is running at 60fps +, capture at 30fps) if (vgd->offscreenGWorldPixels[0] != 0x00){ vgd->offscreenGWorldPixels[0] = 0x00; vgd->bHavePixelsChanged = true; convertPixels(vgd->offscreenGWorldPixels, vgd->pixels, vgd->w, vgd->h); } } } //-------------------------------------------------------------------- void ofQtVideoGrabber::close(){ //thanks eloi! if (vgd->gSeqGrabber != 0L){ CloseComponent (vgd->gSeqGrabber); vgd->gSeqGrabber = 0L; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::videoSettings(void){ Rect curBounds, curVideoRect; ComponentResult err; // Get our current state err = SGGetChannelBounds (vgd->gVideoChannel, &curBounds); if (err != noErr){ printf("Error in SGGetChannelBounds \n"); return; } err = SGGetVideoRect (vgd->gVideoChannel, &curVideoRect); if (err != noErr){ printf("Error in SGGetVideoRect \n"); return; } // Pause err = SGPause (vgd->gSeqGrabber, true); if (err != noErr){ printf("Error in SGPause\n"); return; } #ifdef TARGET_OSX static SGModalFilterUPP gSeqGrabberModalFilterUPP = NewSGModalFilterUPP(SeqGrabberModalFilterUPP); ComponentResult result = SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, 0L, gSeqGrabberModalFilterUPP, nil); if (err != noErr){ printf("error in dialogue\n"); return; } #else SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, 0L, NULL, nil); #endif #ifdef TARGET_WIN32 SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); #endif SGPause (vgd->gSeqGrabber, false); } //-------------------------------------------------------------------- void ofQtVideoGrabber::initGrabber(int _w, int _h){ w = _w; h = _h; vgd->w = w; vgd->h = h; ComponentDescription theDesc; Component sgCompID = NULL; char name[256]; char info[256]; Handle componentName=NULL; Handle componentInfo=NULL; ComponentDescription info_description; componentName=NewHandle(sizeof(name)); componentInfo=NewHandle(sizeof(info)); if (bVerbose == true){ printf ("\n"); printf ("-------------------------------------\n"); printf ("attempting to set up ofQtVideoGrabber\n"); } vgd->gSeqGrabber = 0L; vgd->gVideoChannel = 0L; theDesc.componentType = SeqGrabComponentType; theDesc.componentSubType = 0L; theDesc.componentManufacturer = 0L; theDesc.componentFlags = 0L; theDesc.componentFlagsMask = 0L; sgCompID = FindNextComponent(sgCompID, &theDesc); while (sgCompID != 0){ GetComponentInfo(sgCompID,&info_description, componentName, componentInfo,nil); if (bVerbose == true){ printf("found a device to capture with \n"); printf("Type: %s\n", &info_description.componentType); printf("Manufacturer: %s\n", &info_description.componentManufacturer); printf("Name: %s\n", *componentName ? p2cstr((StringPtr)*componentName) : "-" ); printf("Name: %s\n", *componentInfo ? p2cstr((StringPtr)*componentInfo) : "-"); } vgd->gSeqGrabber = OpenComponent(sgCompID); sgCompID = FindNextComponent(sgCompID, &theDesc); } //-------------------------------------------- // setup the gworld and digitizing. OSStatus err; err = SGInitialize(vgd->gSeqGrabber); if (err != noErr){ printf("***** Error in SGInitialize (check cam drivers, vdig or winvidg)*****\n"); return; } MacSetRect(&(vgd->videoRect),0, 0, w, h); //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vgd->offscreenGWorldPixels = (unsigned char*)malloc(4 * w * h + 32); vgd->pixels = new unsigned char[w*h*3]; QTNewGWorldFromPtr (&vgd->videogworld, k32ARGBPixelFormat, &vgd->videoRect, NULL, NULL, 0, vgd->offscreenGWorldPixels, 4 * w); LockPixels(GetGWorldPixMap(vgd->videogworld)); SetGWorld (vgd->videogworld, NULL); err = SGSetGWorld(vgd->gSeqGrabber, vgd->videogworld, nil); if ( err != noErr ) goto bail; err = SGNewChannel(vgd->gSeqGrabber, VideoMediaType, &vgd->gVideoChannel); if ( err != noErr ) goto bail; err = SGSetDataRef(vgd->gSeqGrabber, 0, 0, seqGrabDontMakeMovie); if ( err != noErr ) goto bail; err = SGSetChannelUsage(vgd->gVideoChannel,seqGrabPreview); if ( err != noErr ) goto bail; err = SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); if ( err != noErr ) goto bail; if (SGSetFrameRate(vgd->gVideoChannel,30) != noErr) printf( "error setting 30 fps \n"); else{ if (bVerbose == true){ printf ("set to capture at 30 fps \n"); } } err = SGPrepare(vgd->gSeqGrabber, false, true); if ( err != noErr ) goto bail; err = SGStartPreview(vgd->gSeqGrabber); if ( err != noErr ) goto bail; if (bVerbose){ printf ("end setup ofQtVideoGrabber\n"); printf ("-------------------------------------\n"); printf ("\n"); } bSgGrabberInited = true; return; // good catch eloi/theo bail: if (bVerbose){ printf ("***** ofQtVideoGrabber error *****\n"); printf ("-------------------------------------\n"); printf ("\n"); } bSgGrabberInited = false; return; } //-------------------------------------------------------------------- Node-path: video/ofQtVideoPlayer.cpp Node-kind: file Node-action: change Text-content-length: 8099 Text-content-md5: 1e96c930c012a919cba70bef970ace9e Content-length: 8099 #include "ofQtVideoPlayer.h" //-------------------------------------------------------------- bool createMovieFromPath(char * path, Movie * movie); bool createMovieFromPath(char * path, Movie * movie){ Boolean isdir = false; OSErr result = 0; FSSpec theFSSpec; FSRef fsref; short resRefNum = -1; short actualResId = DoTheRightThing; #ifdef TARGET_WIN32 result = NativePathNameToFSSpec (path, &theFSSpec, 0); if (result) { printf("NativePathNameToFSSpec failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } #endif #ifdef TARGET_OSX result = FSPathMakeRef((const UInt8*)path, &fsref, &isdir); if (result) { printf("FSPathMakeRef failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } result = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL); if (result) { printf("FSGetCatalogInfo failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } #endif result = OpenMovieFile (&theFSSpec, &resRefNum, 0); if (result) { printf("OpenMovieFile failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } result = NewMovieFromFile (movie, resRefNum, &actualResId, (unsigned char *) 0, 0, (Boolean *) 0); if (result) { printf("NewMovieFromFile failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } if (resRefNum != -1) CloseMovieFile (resRefNum); return true; } //-------------------------------------------------------------- OSErr DrawCompleteProc(Movie theMovie, long refCon); OSErr DrawCompleteProc(Movie theMovie, long refCon){ videoPlayerData * vd = (videoPlayerData *)refCon; convertPixels(vd->offscreenGWorldPixels, vd->pixels, vd->offscreenWidth, vd->offscreenHeight); vd->bHavePixelsChanged = true; return noErr; } //--------------------------------------------------------------------------- ofQtVideoPlayer::ofQtVideoPlayer (char * fileName){ vpd = new videoPlayerData(); loadMovie(fileName); } //--------------------------------------------------------------------------- ofQtVideoPlayer::ofQtVideoPlayer (){ bLoadedMovie = false; w = 0; h = 0; vpd = new videoPlayerData(); vpd->moviePtr = NULL; vpd->offscreenWidth = 0; vpd->offscreenHeight = 0; } //--------------------------------------------------------------------------- unsigned char * ofQtVideoPlayer::getPixels(){ return vpd->pixels; } //--------------------------------------------------------------------------- bool ofQtVideoPlayer::isFrameNew(){ if (bLoadedMovie == true){ bool bChanged = vpd->bHavePixelsChanged; if (vpd->bHavePixelsChanged == true) { vpd->bHavePixelsChanged = false; } return bChanged; } else { return false; } } //--------------------------------------------------------------------------- void ofQtVideoPlayer::idleMovie(){ if (bLoadedMovie == true){ MoviesTask(vpd->moviePtr,0); } } //--------------------------------------------------------------------------- void ofQtVideoPlayer::closeMovie(){ Movie moviePtr = vpd->moviePtr; DisposeMovie (vpd->moviePtr); #ifdef TARGET_WIN32 DisposeMovieDrawingCompleteUPP (myDrawCompleteProc); #endif ExitMovies (); } //--------------------------------------------------------------------------- bool ofQtVideoPlayer::loadMovie(char * name){ OSErr result = 0; short resRefNum = -1; bLoadedMovie = false; Rect bounds; //----------------- callback method MovieDrawingCompleteUPP myDrawCompleteProc; myDrawCompleteProc = NewMovieDrawingCompleteUPP (DrawCompleteProc); initializeQuicktime(); vpd->bHavePixelsChanged = false; Movie * moviePtr = &(vpd->moviePtr); createMovieFromPath(name, moviePtr); //----------------------------------movie box GetMovieBox(vpd->moviePtr, &(vpd->movieRect)); w = vpd->movieRect.right; h = vpd->movieRect.bottom; vpd->offscreenWidth = vpd->movieRect.right; vpd->offscreenHeight = vpd->movieRect.bottom; //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vpd->offscreenGWorldPixels = (unsigned char*)malloc(4 * w * h + 32); vpd->pixels = new unsigned char[w*h*3]; //---------------------------------- gworld allocation QTNewGWorldFromPtr (&(vpd->offscreenGWorld), k32ARGBPixelFormat, &(vpd->movieRect), NULL, NULL, 0, (vpd->offscreenGWorldPixels), 4 * w); LockPixels(GetGWorldPixMap(vpd->offscreenGWorld)); SetGWorld (vpd->offscreenGWorld, NULL); SetMovieGWorld (vpd->moviePtr, vpd->offscreenGWorld, nil); //----------------- callback method SetMovieDrawingCompleteProc (vpd->moviePtr, movieDrawingCallWhenChanged, myDrawCompleteProc, (long)vpd); //---------------------------------- reset themovie, get ready to roll GoToBeginningOfMovie(vpd->moviePtr); SetMovieActiveSegment(vpd->moviePtr, -1,-1); if (vpd->moviePtr == NULL){ return false; } SetMovieActive(vpd->moviePtr, true); StartMovie(vpd->moviePtr); //------------------ set the movie rate to default //------------------ and preroll, so the first frames come correct TimeValue timeNow; Fixed playRate; timeNow = GetMovieTime(vpd->moviePtr, 0); playRate =GetMoviePreferredRate(vpd->moviePtr); PrePrerollMovie(vpd->moviePtr, timeNow, playRate, 0, 0); PrerollMovie(vpd->moviePtr, timeNow, playRate); SetMovieRate(vpd->moviePtr, playRate); setLoopState(OF_QT_LOOP_NORMAL); bLoadedMovie = true; // get some pixels in there right away. MoviesTask(vpd->moviePtr,0); convertPixels(vpd->offscreenGWorldPixels, vpd->pixels, vpd->offscreenWidth, vpd->offscreenHeight); return true; } //-------------------------------------------------------- void ofQtVideoPlayer::setVolume(int volume){ Movie moviePtr = vpd->moviePtr; SetMovieVolume(moviePtr, volume); } //-------------------------------------------------------- void ofQtVideoPlayer::setLoopState(int state){ Movie moviePtr = vpd->moviePtr; TimeBase myTimeBase; long myFlags = 0L; myTimeBase = GetMovieTimeBase(moviePtr); myFlags = GetTimeBaseFlags(myTimeBase); switch (state) { case OF_QT_LOOP_NORMAL: myFlags |= loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, hintsLoop, hintsLoop); SetMoviePlayHints(moviePtr, 0L, hintsPalindrome); break; case OF_QT_LOOP_PALINDROME: myFlags |= loopTimeBase; myFlags |= palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, hintsLoop, hintsLoop); SetMoviePlayHints(moviePtr, hintsPalindrome, hintsPalindrome); break; case OF_QT_LOOP_NONE: default: myFlags &= ~loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, 0L, hintsLoop | hintsPalindrome); break; } SetTimeBaseFlags(myTimeBase, myFlags); } //--------------------------------------------------------------------------- void ofQtVideoPlayer::setPosition(float pct){ TimeRecord tr; Movie moviePtr = vpd->moviePtr; tr.base = GetMovieTimeBase(moviePtr); long total = GetMovieDuration(moviePtr ); long newPos = (long)((float)total * pct); SetMovieTimeValue(moviePtr, newPos); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getDuration(){ Movie moviePtr = vpd->moviePtr; return GetMovieDuration (moviePtr) / (double) GetMovieTimeScale (moviePtr); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getPosition(){ Movie moviePtr = vpd->moviePtr; long total = GetMovieDuration(moviePtr); long current = GetMovieTime(moviePtr, nil); float pct = ((float)current/(float)total); return pct; } //--------------------------------------------------------------------------- void ofQtVideoPlayer::setSpeed(float _speed){ Movie moviePtr = vpd->moviePtr; speed = _speed; SetMovieRate(moviePtr, X2Fix(speed)); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getSpeed(){ return speed; } Node-path: video/ofQtVideoPlayer.h Node-kind: file Node-action: change Text-content-length: 2468 Text-content-md5: 87de187425bf648e93cafee31878fe96 Content-length: 2468 #ifndef _QT_VIDEO_PLAYER #define _QT_VIDEO_PLAYER #include "ofConstants.h" #include "ofQtUtils.h" //------------------------------------------------- // (notes, links, etc) // // intersting technique employed here to get to RGB24 // from YUV2 - worthwhile? // paste.lisp.org/display/1051 //----------------------------- // http://viewcvs.osafoundation.org/chandler/trunk/internal/wx/src/msw/mediactrl.cpp?rev=6281&view=markup // http://developer.apple.com/documentation/QuickTime/INMAC/QT/iqMovieToolbox.34.htm // look for "QTURL_NewMovieFromURL", useful for loading URL based movies.. //------------------------------------------------- // note about callbacks: // // we use here a callback provided by quicktime to see if pixels have actually changed // the callback is "DrawCompleteProc" and int he quicktime code, // is defined as "static pascal OsErr ...." // in windows, I have dropped the pascal declaration as my compiler was // having trouble with that... necessary for mac? // // the alternative is to do what is done in qtVideoGrabber // set the alpha of the top pixel to 0x00 and every idle call // check to see if there are new pixels... #define OF_QT_LOOP_NONE 0x01 #define OF_QT_LOOP_PALINDROME 0x02 #define OF_QT_LOOP_NORMAL 0x03 //--------------------------------------------- // this struct has all the info we need to play 1 movie // kept in a struct, because the callback will // need to reference it... typedef struct { MovieController thePlayer; GWorldPtr offscreenGWorld; Movie moviePtr; Rect movieRect; unsigned char * offscreenGWorldPixels; // 32 bit: argb (qt k32ARGBPixelFormat) unsigned char * pixels; // 24 bit: rgb int offscreenWidth; int offscreenHeight; bool bHavePixelsChanged; } videoPlayerData; //--------------------------------------------- class ofQtVideoPlayer{ public: ofQtVideoPlayer (char * fileName); ofQtVideoPlayer (); void closeMovie(); bool loadMovie(char * name); void idleMovie(); int w, h; float speed; bool bLoadedMovie; bool isFrameNew(); unsigned char * getPixels(); float getPosition(); float getSpeed(); float getDuration(); void setPosition(float pct); void setVolume(int volume); void setLoopState(int state); void setSpeed(float speed); private: //--------------------------- videoPlayerData * vpd; }; #endif Revision-number: 17 Prop-content-length: 128 Content-length: 128 K 7 svn:log V 26 zach - small modifications K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-01-26T07:20:27.018668Z PROPS-END Node-path: app/ofAppGlutGlue.h Node-kind: file Node-action: change Text-content-length: 2158 Text-content-md5: d48aad73b5cd2522aeaaa19bb63f9a81 Content-length: 2158 void display(void); void mouse_cb(int button, int state, int x, int y); void motion_cb(int x, int y); void passive_motion_cb(int x, int y); void idle_cb(void); void keyboard_cb(unsigned char key, int x, int y); void special_key_cb(int key, int x, int y) ; static int buttonInUse = 0; //-------------------------------- static float timeNow, timeThen, fps; static int nFrames; //------------------------------------------------------------ void display(void){ ofGetWindowSize( &width, &height ); height = height > 0 ? height : 1; // set viewport, clear the screen glViewport( 0, 0, width, height ); float * bgPtr = ofBgColorPtr(); glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); OFSAptr->draw(); glutSwapBuffers(); // -------------- fps calculation: timeNow = ofGetElapsedTimef(); if( (timeNow-timeThen) > 0.05f || nFrames == 0 ) { fps = (double)nFrames / (timeNow-timeThen); timeThen = timeNow; nFrames = 0; ofFrameRate = 0.9f * ofFrameRate + 0.1f * fps; } nFrames++; // -------------- } //------------------------------------------------------------ void mouse_cb(int button, int state, int x, int y) { if (state == GLUT_DOWN) { OFSAptr->mouseDown(x, height - y, button); } else if (state == GLUT_UP) { OFSAptr->mouseUp(x, height - y, button); } buttonInUse = button; } //------------------------------------------------------------ void motion_cb(int x, int y) { OFSAptr->mouseDrag(x, height - y, buttonInUse); } //------------------------------------------------------------ void passive_motion_cb(int x, int y) { OFSAptr->mouseMove(x, height - y); } //------------------------------------------------------------ void idle_cb(void) { OFSAptr->idle(); glutPostRedisplay(); } //------------------------------------------------------------ void keyboard_cb(unsigned char key, int x, int y) { OFSAptr->keyDown((int)key); if (key == 27){ // "escape" OF_EXIT_APP(0); } } //------------------------------------------------------------ void special_key_cb(int key, int x, int y) { OFSAptr->keyDown((int)key); } Node-path: app/ofAppRunner.cpp Node-kind: file Node-action: change Text-content-length: 1489 Text-content-md5: 300fbc0d690b9d8648861dd3159a1262 Content-length: 1489 #include "ofAppRunner.h" //======================================================================== // static variables: static ofSimpleApp * OFSAptr; bool bMousePressed; bool bRightButton; int width, height; static float ofFrameRate; //======================================================================== // callbacks: #include "ofAppGlutGlue.h" //-------------------------------------- void ofSetupOpenGL(int w, int h, int screenMode){ int argc = 1; char *argv = "openframeworks"; char **vptr = &argv; glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA); glutInit(&argc, vptr); if (screenMode == OF_WINDOW) glutInitWindowSize(w, h); glutCreateWindow(""); if (screenMode == OF_FULLSCREEN) glutFullScreen(); } //-------------------------------------- void ofRunApp(ofSimpleApp * OFSA){ OFSAptr = OFSA; // window // callbacks glutMouseFunc(mouse_cb); glutMotionFunc(motion_cb); glutPassiveMotionFunc(passive_motion_cb); glutIdleFunc(idle_cb); glutDisplayFunc(display); glutKeyboardFunc(keyboard_cb); glutSpecialFunc(special_key_cb); OFSA->init(); glutMainLoop(); } //-------------------------------------- float ofGetFrameRate(){ return ofFrameRate; } //-------------------------------------- void ofHideCursor(){ glutSetCursor(GLUT_CURSOR_NONE); } //-------------------------------------- void ofShowCursor(){ glutSetCursor(GLUT_CURSOR_RIGHT_ARROW); } Node-path: video/ofQtVideoPlayer.cpp Node-kind: file Node-action: change Text-content-length: 8612 Text-content-md5: 44736695d28c4b8426221c5b1a4f8860 Content-length: 8612 #include "ofQtVideoPlayer.h" //-------------------------------------------------------------- bool createMovieFromPath(char * path, Movie * movie); bool createMovieFromPath(char * path, Movie * movie){ Boolean isdir = false; OSErr result = 0; FSSpec theFSSpec; FSRef fsref; short resRefNum = -1; short actualResId = DoTheRightThing; #ifdef TARGET_WIN32 result = NativePathNameToFSSpec (path, &theFSSpec, 0); if (result) { printf("NativePathNameToFSSpec failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } #endif #ifdef TARGET_OSX result = FSPathMakeRef((const UInt8*)path, &fsref, &isdir); if (result) { printf("FSPathMakeRef failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } result = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL); if (result) { printf("FSGetCatalogInfo failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } #endif result = OpenMovieFile (&theFSSpec, &resRefNum, 0); if (result) { printf("OpenMovieFile failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } result = NewMovieFromFile (movie, resRefNum, &actualResId, (unsigned char *) 0, 0, (Boolean *) 0); if (result) { printf("NewMovieFromFile failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } if (resRefNum != -1) CloseMovieFile (resRefNum); return true; } //-------------------------------------------------------------- OSErr DrawCompleteProc(Movie theMovie, long refCon); OSErr DrawCompleteProc(Movie theMovie, long refCon){ videoPlayerData * vd = (videoPlayerData *)refCon; convertPixels(vd->offscreenGWorldPixels, vd->pixels, vd->offscreenWidth, vd->offscreenHeight); vd->bHavePixelsChanged = true; return noErr; } //--------------------------------------------------------------------------- ofQtVideoPlayer::ofQtVideoPlayer (char * fileName){ vpd = new videoPlayerData(); loadMovie(fileName); } //--------------------------------------------------------------------------- ofQtVideoPlayer::ofQtVideoPlayer (){ bLoadedMovie = false; w = 0; h = 0; vpd = new videoPlayerData(); vpd->moviePtr = NULL; vpd->offscreenWidth = 0; vpd->offscreenHeight = 0; } //--------------------------------------------------------------------------- unsigned char * ofQtVideoPlayer::getPixels(){ return vpd->pixels; } //--------------------------------------------------------------------------- bool ofQtVideoPlayer::isFrameNew(){ if (bLoadedMovie == true){ bool bChanged = vpd->bHavePixelsChanged; if (vpd->bHavePixelsChanged == true) { vpd->bHavePixelsChanged = false; } return bChanged; } else { return false; } } //--------------------------------------------------------------------------- void ofQtVideoPlayer::idleMovie(){ // [zach] my question is how often to call this? // I don't want to call it too often, and up cpu usage // // shockingly,(or not) on a mac, it seems it's not even necessary to call it // the callback just works... // google " site:lists.apple.com MoviesTask windows mac // some code I've seen uses a thread to call this "JUCE" // maybe I could use ofElapsedTimeMillis() // or a system clock call (not glut call) // and make this less frequent if (bLoadedMovie == true){ MoviesTask(vpd->moviePtr,0); } } //--------------------------------------------------------------------------- void ofQtVideoPlayer::closeMovie(){ Movie moviePtr = vpd->moviePtr; DisposeMovie (vpd->moviePtr); #ifdef TARGET_WIN32 DisposeMovieDrawingCompleteUPP (myDrawCompleteProc); #endif ExitMovies (); } //--------------------------------------------------------------------------- bool ofQtVideoPlayer::loadMovie(char * name){ OSErr result = 0; short resRefNum = -1; bLoadedMovie = false; Rect bounds; //----------------- callback method MovieDrawingCompleteUPP myDrawCompleteProc; myDrawCompleteProc = NewMovieDrawingCompleteUPP (DrawCompleteProc); initializeQuicktime(); vpd->bHavePixelsChanged = false; Movie * moviePtr = &(vpd->moviePtr); createMovieFromPath(name, moviePtr); //----------------------------------movie box GetMovieBox(vpd->moviePtr, &(vpd->movieRect)); w = vpd->movieRect.right; h = vpd->movieRect.bottom; vpd->offscreenWidth = vpd->movieRect.right; vpd->offscreenHeight = vpd->movieRect.bottom; //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vpd->offscreenGWorldPixels = (unsigned char*)malloc(4 * w * h + 32); vpd->pixels = new unsigned char[w*h*3]; //---------------------------------- gworld allocation QTNewGWorldFromPtr (&(vpd->offscreenGWorld), k32ARGBPixelFormat, &(vpd->movieRect), NULL, NULL, 0, (vpd->offscreenGWorldPixels), 4 * w); LockPixels(GetGWorldPixMap(vpd->offscreenGWorld)); SetGWorld (vpd->offscreenGWorld, NULL); SetMovieGWorld (vpd->moviePtr, vpd->offscreenGWorld, nil); //----------------- callback method SetMovieDrawingCompleteProc (vpd->moviePtr, movieDrawingCallWhenChanged, myDrawCompleteProc, (long)vpd); //---------------------------------- reset themovie, get ready to roll GoToBeginningOfMovie(vpd->moviePtr); SetMovieActiveSegment(vpd->moviePtr, -1,-1); if (vpd->moviePtr == NULL){ return false; } SetMovieActive(vpd->moviePtr, true); StartMovie(vpd->moviePtr); //------------------ set the movie rate to default //------------------ and preroll, so the first frames come correct TimeValue timeNow; Fixed playRate; timeNow = GetMovieTime(vpd->moviePtr, 0); playRate =GetMoviePreferredRate(vpd->moviePtr); PrePrerollMovie(vpd->moviePtr, timeNow, playRate, 0, 0); PrerollMovie(vpd->moviePtr, timeNow, playRate); SetMovieRate(vpd->moviePtr, playRate); setLoopState(OF_QT_LOOP_NORMAL); bLoadedMovie = true; // get some pixels in there right away. MoviesTask(vpd->moviePtr,0); convertPixels(vpd->offscreenGWorldPixels, vpd->pixels, vpd->offscreenWidth, vpd->offscreenHeight); return true; } //-------------------------------------------------------- void ofQtVideoPlayer::setVolume(int volume){ Movie moviePtr = vpd->moviePtr; SetMovieVolume(moviePtr, volume); } //-------------------------------------------------------- void ofQtVideoPlayer::setLoopState(int state){ Movie moviePtr = vpd->moviePtr; TimeBase myTimeBase; long myFlags = 0L; myTimeBase = GetMovieTimeBase(moviePtr); myFlags = GetTimeBaseFlags(myTimeBase); switch (state) { case OF_QT_LOOP_NORMAL: myFlags |= loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, hintsLoop, hintsLoop); SetMoviePlayHints(moviePtr, 0L, hintsPalindrome); break; case OF_QT_LOOP_PALINDROME: myFlags |= loopTimeBase; myFlags |= palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, hintsLoop, hintsLoop); SetMoviePlayHints(moviePtr, hintsPalindrome, hintsPalindrome); break; case OF_QT_LOOP_NONE: default: myFlags &= ~loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, 0L, hintsLoop | hintsPalindrome); break; } SetTimeBaseFlags(myTimeBase, myFlags); } //--------------------------------------------------------------------------- void ofQtVideoPlayer::setPosition(float pct){ TimeRecord tr; Movie moviePtr = vpd->moviePtr; tr.base = GetMovieTimeBase(moviePtr); long total = GetMovieDuration(moviePtr ); long newPos = (long)((float)total * pct); SetMovieTimeValue(moviePtr, newPos); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getDuration(){ Movie moviePtr = vpd->moviePtr; return GetMovieDuration (moviePtr) / (double) GetMovieTimeScale (moviePtr); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getPosition(){ Movie moviePtr = vpd->moviePtr; long total = GetMovieDuration(moviePtr); long current = GetMovieTime(moviePtr, nil); float pct = ((float)current/(float)total); return pct; } //--------------------------------------------------------------------------- void ofQtVideoPlayer::setSpeed(float _speed){ Movie moviePtr = vpd->moviePtr; speed = _speed; SetMovieRate(moviePtr, X2Fix(speed)); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getSpeed(){ return speed; } Node-path: video/ofQtVideoPlayer.h Node-kind: file Node-action: change Text-content-length: 2603 Text-content-md5: 18492c39d96cebfc5d1b6f7618845dd0 Content-length: 2603 #ifndef _QT_VIDEO_PLAYER #define _QT_VIDEO_PLAYER #include "ofConstants.h" #include "ofQtUtils.h" //------------------------------------------------- // (notes, links, etc) // // intersting technique employed here to get to RGB24 // from YUV2 - worthwhile? // paste.lisp.org/display/1051 //----------------------------- // http://viewcvs.osafoundation.org/chandler/trunk/internal/wx/src/msw/mediactrl.cpp?rev=6281&view=markup // http://developer.apple.com/documentation/QuickTime/INMAC/QT/iqMovieToolbox.34.htm // look for "QTURL_NewMovieFromURL", useful for loading URL based movies.. //------------------------------------------------- // // http://lists.apple.com/archives/QuickTime-API/2002/Feb/msg00118.html // //------------------------------------------------- // // note about callbacks: // // we use here a callback provided by quicktime to see if pixels have actually changed // the callback is "DrawCompleteProc" and int he quicktime code, // is defined as "static pascal OsErr ...." // in windows, I have dropped the pascal declaration as my compiler was // having trouble with that... necessary for mac? // // the alternative is to do what is done in qtVideoGrabber // set the alpha of the top pixel to 0x00 and every idle call // check to see if there are new pixels... #define OF_QT_LOOP_NONE 0x01 #define OF_QT_LOOP_PALINDROME 0x02 #define OF_QT_LOOP_NORMAL 0x03 //--------------------------------------------- // this struct has all the info we need to play 1 movie // kept in a struct, because the callback will // need to reference it... typedef struct { MovieController thePlayer; GWorldPtr offscreenGWorld; Movie moviePtr; Rect movieRect; unsigned char * offscreenGWorldPixels; // 32 bit: argb (qt k32ARGBPixelFormat) unsigned char * pixels; // 24 bit: rgb int offscreenWidth; int offscreenHeight; bool bHavePixelsChanged; } videoPlayerData; //--------------------------------------------- class ofQtVideoPlayer{ public: ofQtVideoPlayer (char * fileName); ofQtVideoPlayer (); void closeMovie(); bool loadMovie(char * name); void idleMovie(); int w, h; float speed; bool bLoadedMovie; bool isFrameNew(); unsigned char * getPixels(); float getPosition(); float getSpeed(); float getDuration(); void setPosition(float pct); void setVolume(int volume); void setLoopState(int state); void setSpeed(float speed); private: //--------------------------- videoPlayerData * vpd; }; #endif Revision-number: 18 Prop-content-length: 197 Content-length: 197 K 7 svn:log V 95 // zach - removed ofSimpleApp.cpp (empty), fixed the bug with ofBitmapText and carriage returns K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-01-26T07:31:26.119975Z PROPS-END Node-path: app/ofSimpleApp.h Node-kind: file Node-action: change Text-content-length: 677 Text-content-md5: 4e5b22aca489ba696a75c352f42f3d16 Content-length: 677 #ifndef _OF_SIMPLE_APP #define _OF_SIMPLE_APP #include "ofConstants.h" #include "ofUtils.h" class ofSimpleApp{ public: ofSimpleApp(){} virtual void idle(){} virtual void init(){} virtual void draw(){} virtual void keyDown (int c){} virtual void mouseMove( int x, int y ){} virtual void mouseDrag( int x, int y, int button ){} virtual void mouseDown( int x, int y, int button ){} virtual void mouseUp ( int x, int y, int button ){} virtual void processAudioInput (float * input, int bufferSize, int nChannels) {} virtual void processAudioOutput (float * output, int bufferSize, int nChannels) {} }; #endif Node-path: app/ofSimpleApp.cpp Node-action: delete Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: change Text-content-length: 5503 Text-content-md5: b99b799d8ea9b45dea082f2a1b1e11bf Content-length: 5503 #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- void ofSetBgColor(float r, float g, float b, float a){ bgColor[0] = r; bgColor[1] = g; bgColor[2] = b; bgColor[3] = a; } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } //---------------------------------------------------------- void ofEnableAlphaBlending(){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void ofDisableAlphaBlending(){ glDisable(GL_BLEND); } //-------------------------------------------------- void ofDrawBitmapString(char *string, float x, float y){ //--------------------------------------------------- // for now this is fixed to the 8_BY_13 glut character // http://pyopengl.sourceforge.net/documentation/manual/glutBitmapCharacter.3GLUT.html //--------------------------------------------------- char *c; int yOffset = 0; float fontSize = 8.0f; glRasterPos2f(x,y); for (c=string; *c != '\0'; c++) { if(*c == '\n') { yOffset -= (fontSize*1.4); glRasterPos2f(x,y + yOffset); } else if (((int)*c) > 32){ // < 32 = control characters - don't draw // solves a bug with newline characters // getting drawn when they ought to not be glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c); } } } //---------------------------------------------------------- void ofSetupScreen(){ int w, h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } Revision-number: 19 Prop-content-length: 533 Content-length: 533 K 7 svn:log V 430 zach - fixed ofImage, ofQtVideoGrabber, and ofQtVideoPlayer to use ofTexture internally (as per theo's emphatic request). Fixed default audio buffer info. ofTexture now has an opengl texture memory freeing function (since ofImage might call the texture creation multiple times as the image changes). ofTrueTypeFont now uses transparency internally (so no more white boxes), and records and resets the current state of blending. K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-01-28T22:45:31.284085Z PROPS-END Node-path: app/ofAppGlutGlue.h Node-kind: file Node-action: change Text-content-length: 2156 Text-content-md5: 314f8e95091709388dfa23d341ea9884 Content-length: 2156 void display(void); void mouse_cb(int button, int state, int x, int y); void motion_cb(int x, int y); void passive_motion_cb(int x, int y); void idle_cb(void); void keyboard_cb(unsigned char key, int x, int y); void special_key_cb(int key, int x, int y) ; static int buttonInUse = 0; //-------------------------------- static float timeNow, timeThen, fps; static int nFrames; //------------------------------------------------------------ void display(void){ ofGetWindowSize( &width, &height ); height = height > 0 ? height : 1; // set viewport, clear the screen glViewport( 0, 0, width, height ); float * bgPtr = ofBgColorPtr(); glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); OFSAptr->draw(); glutSwapBuffers(); // -------------- fps calculation: timeNow = ofGetElapsedTimef(); if( (timeNow-timeThen) > 0.05f || nFrames == 0 ) { fps = (double)nFrames / (timeNow-timeThen); timeThen = timeNow; nFrames = 0; ofFrameRate = 0.9f * ofFrameRate + 0.1f * fps; } nFrames++; // -------------- } //------------------------------------------------------------ void mouse_cb(int button, int state, int x, int y) { if (state == GLUT_DOWN) { OFSAptr->mousePressed(x, height - y, button); } else if (state == GLUT_UP) { OFSAptr->mouseReleased(); } buttonInUse = button; } //------------------------------------------------------------ void motion_cb(int x, int y) { OFSAptr->mouseDragged(x, height - y, buttonInUse); } //------------------------------------------------------------ void passive_motion_cb(int x, int y) { OFSAptr->mouseMoved(x, height - y); } //------------------------------------------------------------ void idle_cb(void) { OFSAptr->idle(); glutPostRedisplay(); } //------------------------------------------------------------ void keyboard_cb(unsigned char key, int x, int y) { OFSAptr->keyPressed((int)key); if (key == 27){ // "escape" OF_EXIT_APP(0); } } //------------------------------------------------------------ void special_key_cb(int key, int x, int y) { OFSAptr->keyPressed((int)key); } Node-path: app/ofSimpleApp.h Node-kind: file Node-action: change Text-content-length: 669 Text-content-md5: 002821d864fb76987465169fcac7ce74 Content-length: 669 #ifndef _OF_SIMPLE_APP #define _OF_SIMPLE_APP #include "ofConstants.h" #include "ofUtils.h" class ofSimpleApp{ public: ofSimpleApp(){} virtual void idle(){} virtual void init(){} virtual void draw(){} virtual void keyPressed(int key ){} virtual void mouseMoved( int x, int y ){} virtual void mouseDragged( int x, int y, int button ){} virtual void mousePressed( int x, int y, int button ){} virtual void mouseReleased(){} virtual void processAudioInput (float * input, int bufferSize, int nChannels) {} virtual void processAudioOutput (float * output, int bufferSize, int nChannels) {} }; #endif Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: change Text-content-length: 5503 Text-content-md5: 928655e6f90153ad7e12b59c41f13062 Content-length: 5503 #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- void ofSetBgColor(float r, float g, float b, float a){ bgColor[0] = r; bgColor[1] = g; bgColor[2] = b; bgColor[3] = a; } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } //---------------------------------------------------------- void ofEnableAlphaBlending(){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void ofDisableAlphaBlending(){ glDisable(GL_BLEND); } //-------------------------------------------------- void ofDrawBitmapString(char *string, float x, float y){ //--------------------------------------------------- // for now this is fixed to the 8_BY_13 glut character // http://pyopengl.sourceforge.net/documentation/manual/glutBitmapCharacter.3GLUT.html //--------------------------------------------------- char *c; int yOffset = 0; float fontSize = 8.0f; glRasterPos2f(x,y); for (c=string; *c != '\0'; c++) { if(*c == '\n') { yOffset -= (fontSize*1.4); glRasterPos2f(x,y + yOffset); } else if (((int)*c) > 32){ // < 32 = control characters - don't draw // solves a bug with control characters // getting drawn when they ought to not be glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c); } } } //---------------------------------------------------------- void ofSetupScreen(){ int w, h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } Node-path: graphics/ofGraphics.h Node-kind: file Node-action: change Text-content-length: 1132 Text-content-md5: edb5564189501788425c47068362825f Content-length: 1132 #ifndef OF_GEOM #define OF_GEOM #include "ofConstants.h" #define CIRC_RESOLUTION 22 // 22 pts for a circle... // bg color float * ofBgColorPtr(); void ofSetBgColor(float r, float g, float b, float a); // geometry void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3); void ofCircle(float x,float y, float radius); void ofEllipse(float x, float y, float width, float height); void ofLine(float x1,float y1,float x2,float y2); void ofRect(float x1,float y1,float w, float h); void ofSetCircleResolution(int res); // if there 22 is a problem, you can change it here // drawing options void ofNoFill(); void ofFill(); // color options void ofSetColor(int r, int g, int b); // 0-255 void ofSetColor(int hexColor); // hex, like web 0xFF0033; // transparency void ofEnableAlphaBlending(); // this just turns on and off opengl blending, the common mode void ofDisableAlphaBlending(); // bitmapped type // ** note, this uses glDrawPixels and may be S L 0 W on some graphics cards void ofDrawBitmapString( char *string, float x, float y); // screen coordinate things... void ofSetupScreen(); #endif Node-path: graphics/ofImage.cpp Node-kind: file Node-action: change Text-content-length: 7532 Text-content-md5: 4bfacd90d09df5ca69cfc8ab351a4439 Content-length: 7532 #include "ofImage.h" #include "freeImage.h" static bool bFreeImageInited = false; //----------------------------------------- // class freeImageBitmap{ public: FIBITMAP * bmp; //----------------------- freeImageBitmap(){ bmp = NULL; } //----------------------- //swap my image out in a (hopefully) non-memory leakish way void swap(FIBITMAP *dst) { if(dst == NULL) return; if(bmp != NULL) FreeImage_Unload(bmp); bmp = dst; } //----------------------- void setSize(FREE_IMAGE_TYPE image_type, WORD width, WORD height, WORD bpp) { if(bmp == NULL) { FreeImage_Unload(bmp); } bmp = FreeImage_AllocateT(image_type, width, height, bpp); } //----------------------- bool isValid(){ return (bmp != NULL) ? true : false; } }; //---------------------------------------------------------- ofImage::ofImage(){ //----------------------- init free image if necessary if (!bFreeImageInited){ FreeImage_Initialise(); bFreeImageInited = true; } //----------------------- IMG = new freeImageBitmap(); w = h = bpp = 0; type = OF_IMAGE_UNDEFINED; bUseTexture = true; // the default is, yes, use a texture } //---------------------------------------------------------- void ofImage::grabScreen(int _x, int _y, int _w, int _h){ if (IMG->isValid()){ if (!(w == _w && h == _h)){ resize(_w, _h); } unsigned char * pixels = getPixels(); switch (bpp){ case 8: glReadPixels(_x, _y, _w, _h, GL_LUMINANCE,GL_UNSIGNED_BYTE, pixels); break; case 24: glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); break; case 32: glReadPixels(_x, _y, _w, _h, GL_RGBA,GL_UNSIGNED_BYTE, pixels); break; } } else { // assume that this is color.... IMG->setSize(FIT_BITMAP, _w, _h, 24); unsigned char * pixels = getPixels(); glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE,pixels); update(); } } //---------------------------------------------------------- void ofImage::allocate(int _w, int _h, int _type){ int newbpp; switch (_type){ case OF_IMAGE_GRAYSCALE: newbpp = 8; break; case OF_IMAGE_COLOR: newbpp = 24; break; case OF_IMAGE_COLOR_ALPHA: newbpp = 32; break; default: newbpp = 24; break; } IMG->setSize(FIT_BITMAP, _w, _h, newbpp); } //---------------------------------------------------------- void ofImage::update(){ w = FreeImage_GetWidth(IMG->bmp); h = FreeImage_GetHeight(IMG->bmp); bpp = FreeImage_GetBPP(IMG->bmp); switch (bpp){ case 8: type = OF_IMAGE_GRAYSCALE; break; case 24: type = OF_IMAGE_COLOR; break; case 32: type = OF_IMAGE_COLOR_ALPHA; break; default: // if we've got here, something is wrong, the image // is not 8bit, 24bit or 32bit, so let's at least // make it color: setImageType(OF_IMAGE_COLOR); break; } // if we are using a texture and the ofImage is upadate, // allocate (or reallocate) the texture and upload the data if (bUseTexture){ switch (type){ case OF_IMAGE_GRAYSCALE: tex.setFormat(w,h,GL_LUMINANCE); tex.loadData(getPixels(), w, h, GL_LUMINANCE); break; case OF_IMAGE_COLOR: tex.setFormat(w,h,GL_RGB); tex.loadData(getPixels(), w, h, GL_RGB); break; case OF_IMAGE_COLOR_ALPHA: tex.setFormat(w,h,GL_RGBA); tex.loadData(getPixels(), w, h, GL_RGBA); break; } } } //---------------------------------------------------------- void ofImage::loadImage(char * fileName){ bool bLoaded = false; //----------------------------- find the format FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { if(IMG->isValid()) { FreeImage_Unload(IMG->bmp); } IMG->bmp = FreeImage_Load(fif, fileName, 0); bLoaded = true; if(!IMG->isValid()){ bLoaded = false; } } //----------------------------- if (bLoaded){ update(); //--------------- on windows, we need to change BGR to RGB // (also on intel macs? also with RGBA images?) #ifdef TARGET_WIN32 if (type == OF_IMAGE_COLOR){ swapChannels(); } #endif } else { w = h = bpp = 0; } } //---------------------------------------------------------- void ofImage::saveImage(char * fileName){ if (IMG->isValid()){ FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { FreeImage_Save(fif, IMG->bmp, fileName, 0); } } } //---------------------------------------------------------- unsigned char * ofImage::getPixels(){ // be careful! if (IMG->isValid()){ return (unsigned char *)FreeImage_GetBits(IMG->bmp); } else { return NULL; } } //---------------------------------------------------------- void ofImage::resize(int newWidth, int newHeight){ if (IMG->isValid()){ FIBITMAP * scaledBmp = FreeImage_Rescale(IMG->bmp, newWidth, newHeight, FILTER_BICUBIC); IMG->swap(scaledBmp); update(); } } //---------------------------------------------------------- void ofImage::setImageType(int newType){ if (IMG->isValid()){ switch (newType){ //------------------------------------ case OF_IMAGE_GRAYSCALE: if (type != OF_IMAGE_GRAYSCALE){ FIBITMAP * convertedBmp = FreeImage_ConvertToGreyscale(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; //------------------------------------ case OF_IMAGE_COLOR: if (type != OF_IMAGE_COLOR){ FIBITMAP * convertedBmp = FreeImage_ConvertTo24Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR; } break; //------------------------------------ case OF_IMAGE_COLOR_ALPHA: if (type != OF_IMAGE_COLOR_ALPHA){ FIBITMAP * convertedBmp = FreeImage_ConvertTo32Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; } update(); } } //------------------------------------ void ofImage::swapChannels(){ // this swaps the red and blue channel of an image // turning an bgr image to rgb and vice versa... // needed because of windows byte order... if (IMG->isValid() && type == OF_IMAGE_COLOR){ unsigned char * pixels = getPixels(); int nTotalPixels = w*h; unsigned char temp; // unoptimized for now... for (int i = 0; i < nTotalPixels; i++){ temp = pixels[i*3]; pixels[i*3] = pixels[i*3 + 2]; pixels[i*3 + 2] = temp; } } update(); // this is a redundant hack. please fix me // the thing is we need to update to texture, after the // conversion, but we need to know w, h, type // before the conversion - as it stands now // we update the texture twice... } //------------------------------------ void ofImage::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofImage::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.render(_x, _y, _w, _h); } } Node-path: graphics/ofImage.h Node-kind: file Node-action: change Text-content-length: 1268 Text-content-md5: 80373b7a448a76ece15b143c81664547 Content-length: 1268 #ifndef _OF_IMAGE_H_ #define _OF_IMAGE_H_ #include "ofConstants.h" #include "ofTexture.h" #define OF_IMAGE_GRAYSCALE 0x00 #define OF_IMAGE_COLOR 0x01 #define OF_IMAGE_COLOR_ALPHA 0x02 #define OF_IMAGE_UNDEFINED 0x03 //------------------------- // forward class declaration, something // we will need in order to compile "OF" as a lib // so that you don't need freeImage, quicktime, etc.. class freeImageBitmap; //------------------------- class ofImage { public : ofImage(); void loadImage(char * fileName); void saveImage(char * fileName); void allocate(int w, int h, int type); unsigned char * getPixels(); // up to you to get this right void setImageType(int type); void resize(int newWidth, int newHeight); void grabScreen(int x, int y, int w, int h); // grab pixels from opengl, using glreadpixels int type; // what type of image it is (as above) int w, h, bpp; // w,h, bits per pixel void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); private: void swapChannels(); void update(); freeImageBitmap * IMG; ofTexture tex; bool bUseTexture; }; #endif Node-path: graphics/ofTexture.cpp Node-kind: file Node-action: change Text-content-length: 3166 Text-content-md5: a119becfacb1e93796a12a9fc465e4d6 Content-length: 3166 #include "ofTexture.h" #include "ofUtils.h" // for nextPow2() //---------------------------------------------------------- ofTexture::ofTexture(){ texName = new unsigned int[1]; texName[0] = 0; } //---------------------------------------------------------- void ofTexture::clear(){ // try to free up the texture memory so we don't reallocate // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/deletetextures.html if (texName[0] != 0){ glDeleteTextures(1, texName); } } //---------------------------------------------------------- void ofTexture::setFormat(int w, int h, int internalGlDataType){ // can pass in anything (320x240) (10x5) // here we make it power of 2 for opengl (512x256), (16x8) tex_w = ofNextPow2(w); tex_h = ofNextPow2(h); tex_u = 1.0f; tex_t = 1.0f; // attempt to free the previous bound texture, if we can: clear(); // create the named texture: //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // not necessary, I think glGenTextures(1, texName); // could be more then one, but for now, just one glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texName[0]); glTexImage2D(GL_TEXTURE_2D, 0, internalGlDataType, tex_w, tex_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); // init to black... glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); } void ofTexture::loadData(unsigned char * data, int w, int h, int glDataType){ // can we allow for uploads bigger then texutre and // just take as much as the texture can? // // ie: // int uploadW = MIN(w, tex_w); // int uploadH = MIN(h, tex_h); // but with a "step" size of w? // check "glTexSubImage2D" if ( w > tex_w || h > tex_h) { printf("image data too big - bailing \n"); return; } //compute new tex co-ords based on the ratio of data's w, h to texture w,h; tex_t = (float)w / (float)tex_w; tex_u = (float)h / (float)tex_h; // update the texture image: glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texName[0]); glTexSubImage2D(GL_TEXTURE_2D,0,0,0,w,h,glDataType,GL_UNSIGNED_BYTE,data); glDisable(GL_TEXTURE_2D); } //================================================================================= void ofTexture::render(int x, int y, int w, int h){ glEnable(GL_TEXTURE_2D); // bind the texture glBindTexture( GL_TEXTURE_2D, texName[0] ); float px0 = x ; // up to you to get the aspect ratio right float py0 = y ; float px1 = x+w; float py1 = y+h; glBegin( GL_QUADS ); glTexCoord2f(0.0, 0.0); glVertex3f(px0, py0,0); glTexCoord2f(tex_t, 0.0); glVertex3f(px1, py0,0); glTexCoord2f(tex_t, tex_u); glVertex3f(px1, py1,0); glTexCoord2f(0.0, tex_u); glVertex3f(px0, py1,0); glEnd(); glDisable(GL_TEXTURE_2D); } Node-path: graphics/ofTexture.h Node-kind: file Node-action: change Text-content-length: 442 Text-content-md5: a96262351aa1489f8b939e5c0ffbbe0a Content-length: 442 #ifndef _IMAGE_TEXTURE_H_ #define _IMAGE_TEXTURE_H_ #include "ofConstants.h" class ofTexture { public : ofTexture(); void setFormat(int w, int h, int internalGlDataType); void clear(); void loadData(unsigned char * data, int w, int h, int glDataType); void render(int x, int y, int w, int h); float tex_t, tex_u; private: int tex_w, tex_h; unsigned int * texName; }; #endif Node-path: graphics/ofTrueTypeFont.cpp Node-kind: file Node-action: change Text-content-length: 11783 Text-content-md5: 0ba7e08dd7d66a6be137279dbd9236b7 Content-length: 11783 #include "ofTrueTypeFont.h" //-------------------------- #ifdef TARGET_WIN32 #include #include #include #include #include #endif #ifdef TARGET_OSX #include "ft2build.h" #include "freetype.h" #include "ftglyph.h" #include "ftoutln.h" #include "fttrigon.h" #endif //------------------------------------------------------------------ ofTrueTypeFont::ofTrueTypeFont(){ bLoadedOk = false; } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize){ // load anti-aliased, non-full character set: loadFont(filename, fontsize, true, false); } //------------------------------------------------------------------ void ofTrueTypeFont::ofTrueTypeFont::loadFont(const char *filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet){ bLoadedOk = false; bAntiAlised = _bAntiAliased; bFullCharacterSet = _bFullCharacterSet; //--------------- load the library and typeface FT_Library library; if (FT_Init_FreeType( &library )){ printf("PROBLEM WITH FT lib \n"); return; } FT_Face face; if (FT_New_Face( library, filename, 0, &face )) { return; } FT_Set_Char_Size( face,fontsize << 6,fontsize << 6,96,96); lineHeight = fontsize * 1.43f; //------------------------------------------------------ //kerning would be great to support: //printf("FT_HAS_KERNING ? %i \n", FT_HAS_KERNING(face)); //------------------------------------------------------ nCharacters = bFullCharacterSet ? 256 : 128 - NUM_CHARACTER_TO_START; //--------------- initialize character info and textures cps = new charProps[nCharacters]; texNames = new GLuint[nCharacters]; glGenTextures(nCharacters, texNames); //--------------------- load each char ----------------------- for (int i = 0 ; i < nCharacters; i++){ //------------------------------------------ anti aliased or not: if (bAntiAlised == true){ if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph %i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); } else { if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph%i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO); } //------------------------------------------ FT_Bitmap& bitmap= face->glyph->bitmap; // 1 pixel border around the glyph int border = 2; // prepare the texture: int width = ofNextPow2( bitmap.width + border); int height = ofNextPow2( bitmap.rows + border); // ------------------------- this is fixing a bug with small type // ------------------------- appearantly, opengl has trouble with // ------------------------- width or height textures of 1, so we // ------------------------- we just set it to 2... if (width == 1) width = 2; if (height == 1) height = 2; // ------------------------- // info about the character: cps[i].value = i; cps[i].height = face->glyph->bitmap_top; cps[i].width = face->glyph->bitmap.width; cps[i].setWidth = face->glyph->advance.x >> 6; cps[i].topExtent = face->glyph->bitmap.rows; cps[i].leftExtent = face->glyph->bitmap_left; // texture internals cps[i].tTex = (float)bitmap.width / (float)width; cps[i].vTex = (float)bitmap.rows / (float)height; cps[i].xOff = ((1.0+(float)bitmap.width) / (float)width) - cps[i].tTex; cps[i].yOff = ((1.0+(float)bitmap.rows) / (float)height) - cps[i].vTex; /* sanity check: printf("%i %i %i %i %i %i \n", cps[i].value , cps[i].height , cps[i].width , cps[i].setWidth , cps[i].topExtent , cps[i].leftExtent ); */ // Allocate Memory For The Texture Data. unsigned char* expanded_data = new unsigned char[ 2 * width * height]; //-------------------------------- clear data: for(int j=0; j =bitmap.width || j-1>=bitmap.rows) ? 0 : 255; expanded_data[2*(k+j*width)+1] = (k-1>=bitmap.width || j-1>=bitmap.rows) ? 0 : bitmap.buffer[k-1 + bitmap.width*(j-1)]; } } //----------------------------------- } else { //----------------------------------- // true type packs monochrome info in a // 1-bit format, hella funky // here we unpack it: unsigned char *src = bitmap.buffer; for(int j=0; j = nCharacters){ printf("Error : char (%i) not allocated -- line %d in %s\n", (c + NUM_CHARACTER_TO_START), __LINE__,__FILE__); return; } //----------------------- int cu = c; float height = cps[cu].height; float bwidth = cps[cu].width; float top = cps[cu].topExtent - cps[cu].height; float lextent = cps[cu].leftExtent; float t = cps[cu].tTex; float v = cps[cu].vTex; float xOff = cps[cu].xOff; float yOff = cps[cu].yOff; if (glIsTexture(texNames[cu])) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texNames[cu]); glNormal3f(0, 0, 1); glBegin(GL_QUADS); glTexCoord2d(xOff,yOff); glVertex2f(x + lextent, y + height); glTexCoord2d(xOff,v+yOff); glVertex2f(x + lextent, y-top); glTexCoord2d(t+xOff,v+yOff); glVertex2f(x + lextent + bwidth,y-top); glTexCoord2d(t+xOff,yOff); glVertex2f(x + + lextent + bwidth,y + height); glEnd(); glDisable(GL_TEXTURE_2D); } else { printf("Error : texture not bound for character -- line %d in %s\n", __LINE__,__FILE__); } } //----------------------------------------------------------- float ofTrueTypeFont::stringWidth(char *c) { float width = 0; int index = 0; float widthTemp = 0; bool bMultiLine = false; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { width = MAX(width, widthTemp); widthTemp = 0; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; widthTemp += cps[cy].width; } else { widthTemp += cps[cy].setWidth; } } index++; } width = MAX(width, widthTemp); return width; } //----------------------------------------------------------- float ofTrueTypeFont::stringHeight(char *c) { float height = 0; int index = 0; float maxHeight = 0; bool bFirstLineOfMultiLine = true; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { if (bFirstLineOfMultiLine == true){ bFirstLineOfMultiLine = false; height += maxHeight; } else { height += lineHeight; } maxHeight = 0; } else if (c[index] == ' ') { } else { float ht = cps[cy].height; if (ht > maxHeight) maxHeight = ht; } } index++; } height += maxHeight; return height; } //===================================================================== void ofTrueTypeFont::drawString(char *c, float x, float y) { if (!bLoadedOk){ printf("Error : font not allocated -- line %d in %s\n", __LINE__,__FILE__); return; }; // we need transparency to draw text, but we don't know // if that is set up in outside of this function // we "pushAttrib", turn on alpha and "popAttrib" // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushattrib.html // **** note **** // I have read that pushAttrib() is slow, if used often, // maybe there is a faster way to do this? // ie, check if blending is enabled, etc... // glIsEnabled().... glGet()... // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/get.html // ************** // (a) record the current "alpha state, blend func, etc" glPushAttrib(GL_COLOR_BUFFER_BIT); // (b) enable our regular ALPHA blending! glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); float startX = x; int index = 0; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { x = startX; int cy = (int)'M' - NUM_CHARACTER_TO_START; y -= lineHeight; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; x += cps[cy].width; } else { drawChar(cy, x, y); x += cps[cy].setWidth; } } index++; } // (c) return back to the way things were (with blending, blend func, etc) glPopAttrib(); } Node-path: graphics/ofTrueTypefont.h Node-kind: file Node-action: change Text-content-length: 1236 Text-content-md5: 458613937a8cc8f7518fc8e8140a01bf Content-length: 1236 #ifndef _OF_TTF_FONT_H_ #define _OF_TTF_FONT_H_ #include "ofConstants.h" //-------------------------------------------------- typedef struct { int value; int height; int width; int setWidth; int topExtent; int leftExtent; float tTex; float vTex; //0-1 pct of bitmap... float xOff; float yOff; } charProps; //-------------------------------------------------- #define NUM_CHARACTER_TO_START 33 // 0 - 32 are control characters, no graphics needed. class ofTrueTypeFont{ public: ofTrueTypeFont(); // -- default, non-full char set, anti aliased: void loadFont(const char *filename, int fontsize); void loadFont(const char *filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet); bool bLoadedOk; bool bAntiAlised; bool bFullCharacterSet; float getLineHeight(); void setLineHeight(float height); float stringWidth(char *s); float stringHeight(char *c); void drawString(char *c, float x, float y); int nCharacters; protected: float lineHeight; charProps * cps; // properties for each character GLuint * texNames; // textures for each character void drawChar(int c, float x, float y); int ofNextPow2 (int a); }; #endif Node-path: sound/ofAudio.cpp Node-kind: file Node-action: change Text-content-length: 3665 Text-content-md5: c1f169ad2848a16bfb9ab4b9aeb381e6 Content-length: 3665 #include "ofAudio.h" #include "rtAudio.h" //----------------------------------- static variables: static ofSimpleApp * OFSAptr; RtAudio * audio; int nInputChannels; int nOutputChannels; //----------------------------------- int receiveAudioBufferAndCallSimpleApp(char *buffer, int bufferSize, void *data); int receiveAudioBufferAndCallSimpleApp(char *buffer, int bufferSize, void *data){ // rtAudio uses a system by which the audio // can be of different formats // char, float, etc. // we choose float float * fPtr = (float *)buffer; // [zach] memset output to zero before output call // this is because of how rtAudio works: duplex w/ one callback // you need to cut in the middle. if the simpleApp // doesn't produce audio, we pass silence instead of duplex... if (nInputChannels > 0){ OFSAptr->processAudioInput(fPtr, bufferSize, nInputChannels); memset(fPtr, 0, bufferSize * nInputChannels * sizeof(float)); } if (nOutputChannels > 0) OFSAptr->processAudioOutput(fPtr, bufferSize, nOutputChannels); return 0; } //--------------------------------------------------------- void ofAudioSetup(int nOutputs, int nInputs, ofSimpleApp * OFSA){ ofAudioSetup(nOutputs, nInputs, OFSA, 44100, 256, 4); } //--------------------------------------------------------- void ofAudioSetup(int nOutputs, int nInputs, ofSimpleApp * OFSA, int sampleRate, int bufferSize, int nBuffers){ nInputChannels = nInputs; nOutputChannels = nOutputs; int device = 0; // default OFSAptr = OFSA; try { audio = new RtAudio(); audio->openStream( device, nOutputs, device, nInputs, RTAUDIO_FLOAT32, sampleRate, &bufferSize, nBuffers); } catch (RtError &error) { error.printMessage(); //std::exit(EXIT_FAILURE); // need case here } try { audio->setStreamCallback(&receiveAudioBufferAndCallSimpleApp, (void *)NULL); audio->startStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioStopStream(){ try { audio->stopStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioStartStream(){ try{ audio->startStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioEndStream(){ try { audio->stopStream(); audio->closeStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioEnumerateDevices(){ RtAudio *audioTemp = 0; try { audioTemp = new RtAudio(); } catch (RtError &error) { error.printMessage(); } int devices = audioTemp->getDeviceCount(); RtAudioDeviceInfo info; for (int i=1; i<=devices; i++) { try { info = audioTemp->getDeviceInfo(i); } catch (RtError &error) { error.printMessage(); break; } std::cout << "device = " << i << " (" << info.name << ")\n"; if (info.isDefault) std::cout << "***** default ***** \n"; std::cout << "maximum output channels = " << info.outputChannels << "\n"; std::cout << "maximum input channels = " << info.inputChannels << "\n"; std::cout << "-----------------------------------------\n"; } delete audioTemp; } /* try { // Stop and close the stream audio->stopStream(); audio->closeStream(); } catch (RtError &error) { error.printMessage(); } */ Node-path: utils/ofConstants.h Node-kind: file Node-action: change Text-content-length: 1682 Text-content-md5: bf4f40cb64e2f62b5d1795d784e7c352 Content-length: 1682 #ifndef OF_CONSTANTS #define OF_CONSTANTS //------------------------------- // pc or mac ? // soon: pc, mac or linux... #ifndef __APPLE_CC__ #define TARGET_WIN32 #else #define TARGET_OSX #endif //------------------------------- #ifdef TARGET_WIN32 #include #include "glut.h" #define __WINDOWS_DS__ #define __WINDOWS_MM__ #if (_MSC_VER) // microsoft visual studio #pragma warning(disable : 4996) // disable all deprecation warnings #pragma warning(disable : 4068) // unknown pragmas #pragma warning(disable : 4101) // unreferenced local variable #endif #endif #ifdef TARGET_OSX #define __MACOSX_CORE__ #include #endif #ifndef __MWERKS__ #define OF_EXIT_APP(val) exit(val); #else #define OF_EXIT_APP(val) std::exit(val); #endif // core: --------------------------- #include #include #include #include #include #ifndef PI #define PI 3.14159265358979323846 #endif #ifndef TWO_PI #define TWO_PI 6.28318530717958647693 #endif #ifndef M_TWO_PI #define M_TWO_PI 6.28318530717958647693 #endif #ifndef FOUR_PI #define FOUR_PI 12.56637061435917295385 #endif #ifndef HALF_PI #define HALF_PI 1.57079632679489661923 #endif #ifndef DEG_TO_RAD #define DEG_TO_RAD (PI/180.0) #endif #ifndef RAD_TO_DEG #define RAD_TO_DEG (180.0/PI) #endif #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #endif #ifndef ABS #define ABS(x) (((x) < 0) ? -(x) : (x)) #endif #define OF_FILLED 0x01 #define OF_OUTLINE 0x02 #define OF_WINDOW 0 #define OF_FULLSCREEN 1 #endif Node-path: utils/ofUtils.h Node-kind: file Node-action: change Text-content-length: 436 Text-content-md5: 9a4436aef7ba4b22aebfc07ad66cd7e2 Content-length: 436 #ifndef _OF_UTIL #define _OF_UTIL #include "ofConstants.h" float ofGetFps(void); int ofNextPow2( int input); float ofGetElapsedTimef(); int ofGetElapsedTimeMillis(); int ofGetMillis(); // should be different then above.. int ofGetSeconds(); int ofGetMinutes(); int ofGetHours(); void ofGetWindowSize( int * w, int * h); void ofScreenCapRaw(); void ofScreenCapRaw(int x, int y, int w, int h); #endif Node-path: video/ofQtVideoGrabber.cpp Node-kind: file Node-action: change Text-content-length: 7687 Text-content-md5: 56fb74d52dd6fcf0048d1836dbe578c0 Content-length: 7687 #include "ofQtVideoGrabber.h" //-------------------------------------------------------------------- Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon); Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon){ #pragma unused(theDialog, itemHit) Boolean handled = false; if ((theEvent->what == updateEvt) && ((WindowPtr) theEvent->message == (WindowPtr) refCon)) { BeginUpdate ((WindowPtr) refCon); EndUpdate ((WindowPtr) refCon); handled = true; } return (handled); } //-------------------------------------------------------------------- ofQtVideoGrabber::ofQtVideoGrabber(){ initializeQuicktime(); vgd = new videoGrabberData(); bVerbose = false; bSgGrabberInited = false; bUseTexture = true; } //-------------------------------------------------------------------- void ofQtVideoGrabber::setVerbose(bool bTalkToMe){ bVerbose = bTalkToMe; } //--------------------------------------------------------------------------- unsigned char * ofQtVideoGrabber::getPixels(){ return vgd->pixels; } //--------------------------------------------------------------------------- bool ofQtVideoGrabber::isFrameNew(){ if (bSgGrabberInited == true){ bool bNew = false; if (vgd->bHavePixelsChanged == true){ bNew = true; vgd->bHavePixelsChanged = false; } return bNew; } else { return false; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::grabFrame(){ if (bSgGrabberInited == true){ SGIdle(vgd->gSeqGrabber); // set the top pixel alpha = 0, so we can know if it // was a new frame or not.. // or else we will process way more than necessary // (ie opengl is running at 60fps +, capture at 30fps) if (vgd->offscreenGWorldPixels[0] != 0x00){ vgd->offscreenGWorldPixels[0] = 0x00; vgd->bHavePixelsChanged = true; convertPixels(vgd->offscreenGWorldPixels, vgd->pixels, vgd->w, vgd->h); if (bUseTexture){ tex.loadData(vgd->pixels, w, h, GL_RGB); } } } } //-------------------------------------------------------------------- void ofQtVideoGrabber::close(){ //thanks eloi! if (vgd->gSeqGrabber != 0L){ CloseComponent (vgd->gSeqGrabber); vgd->gSeqGrabber = 0L; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::videoSettings(void){ Rect curBounds, curVideoRect; ComponentResult err; // Get our current state err = SGGetChannelBounds (vgd->gVideoChannel, &curBounds); if (err != noErr){ printf("Error in SGGetChannelBounds \n"); return; } err = SGGetVideoRect (vgd->gVideoChannel, &curVideoRect); if (err != noErr){ printf("Error in SGGetVideoRect \n"); return; } // Pause err = SGPause (vgd->gSeqGrabber, true); if (err != noErr){ printf("Error in SGPause\n"); return; } #ifdef TARGET_OSX static SGModalFilterUPP gSeqGrabberModalFilterUPP = NewSGModalFilterUPP(SeqGrabberModalFilterUPP); ComponentResult result = SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, 0L, gSeqGrabberModalFilterUPP, nil); if (err != noErr){ printf("error in dialogue\n"); return; } #else SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, 0L, NULL, nil); #endif #ifdef TARGET_WIN32 SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); #endif SGPause (vgd->gSeqGrabber, false); } //-------------------------------------------------------------------- void ofQtVideoGrabber::initGrabber(int _w, int _h){ w = _w; h = _h; vgd->w = w; vgd->h = h; ComponentDescription theDesc; Component sgCompID = NULL; char name[256]; char info[256]; Handle componentName=NULL; Handle componentInfo=NULL; ComponentDescription info_description; componentName=NewHandle(sizeof(name)); componentInfo=NewHandle(sizeof(info)); if (bVerbose == true){ printf ("\n"); printf ("-------------------------------------\n"); printf ("attempting to set up ofQtVideoGrabber\n"); } vgd->gSeqGrabber = 0L; vgd->gVideoChannel = 0L; theDesc.componentType = SeqGrabComponentType; theDesc.componentSubType = 0L; theDesc.componentManufacturer = 0L; theDesc.componentFlags = 0L; theDesc.componentFlagsMask = 0L; sgCompID = FindNextComponent(sgCompID, &theDesc); while (sgCompID != 0){ GetComponentInfo(sgCompID,&info_description, componentName, componentInfo,nil); if (bVerbose == true){ printf("found a device to capture with \n"); printf("Type: %s\n", &info_description.componentType); printf("Manufacturer: %s\n", &info_description.componentManufacturer); printf("Name: %s\n", *componentName ? p2cstr((StringPtr)*componentName) : "-" ); printf("Name: %s\n", *componentInfo ? p2cstr((StringPtr)*componentInfo) : "-"); } vgd->gSeqGrabber = OpenComponent(sgCompID); sgCompID = FindNextComponent(sgCompID, &theDesc); } //-------------------------------------------- // setup the gworld and digitizing. OSStatus err; err = SGInitialize(vgd->gSeqGrabber); if (err != noErr){ printf("***** Error in SGInitialize (check cam drivers, vdig or winvidg)*****\n"); return; } MacSetRect(&(vgd->videoRect),0, 0, w, h); //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vgd->offscreenGWorldPixels = (unsigned char*)malloc(4 * w * h + 32); vgd->pixels = new unsigned char[w*h*3]; QTNewGWorldFromPtr (&vgd->videogworld, k32ARGBPixelFormat, &vgd->videoRect, NULL, NULL, 0, vgd->offscreenGWorldPixels, 4 * w); LockPixels(GetGWorldPixMap(vgd->videogworld)); SetGWorld (vgd->videogworld, NULL); err = SGSetGWorld(vgd->gSeqGrabber, vgd->videogworld, nil); if ( err != noErr ) goto bail; err = SGNewChannel(vgd->gSeqGrabber, VideoMediaType, &vgd->gVideoChannel); if ( err != noErr ) goto bail; err = SGSetDataRef(vgd->gSeqGrabber, 0, 0, seqGrabDontMakeMovie); if ( err != noErr ) goto bail; err = SGSetChannelUsage(vgd->gVideoChannel,seqGrabPreview); if ( err != noErr ) goto bail; err = SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); if ( err != noErr ) goto bail; if (SGSetFrameRate(vgd->gVideoChannel,30) != noErr) printf( "error setting 30 fps \n"); else{ if (bVerbose == true){ printf ("set to capture at 30 fps \n"); } } err = SGPrepare(vgd->gSeqGrabber, false, true); if ( err != noErr ) goto bail; err = SGStartPreview(vgd->gSeqGrabber); if ( err != noErr ) goto bail; if (bVerbose){ printf ("end setup ofQtVideoGrabber\n"); printf ("-------------------------------------\n"); printf ("\n"); } if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.setFormat(w,h,GL_RGB); memset(vgd->pixels, 0, w*h*3); tex.loadData(vgd->pixels, w, h, GL_RGB); } bSgGrabberInited = true; return; // good catch eloi/theo //--------------------- (bail) something's wrong ----- bail: if (bVerbose){ printf ("***** ofQtVideoGrabber error *****\n"); printf ("-------------------------------------\n"); printf ("\n"); } bSgGrabberInited = false; return; } //------------------------------------ void ofQtVideoGrabber::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofQtVideoGrabber::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.render(_x, _y, _w, _h); } } Node-path: video/ofQtVideoGrabber.h Node-kind: file Node-action: change Text-content-length: 2864 Text-content-md5: 6413ddf800e36107e820f7f55b43d533 Content-length: 2864 #ifndef _QT_VIDEO_GRABBER #define _QT_VIDEO_GRABBER #include "ofConstants.h" #include "ofQtUtils.h" #include "ofTexture.h" //----------------------------------------- // windows users check out winvdig: // // -[wvdig free]- // http://www.vdig.com/WinVDIG/ // but maybe older versions are better (at least w/ quicktime < 7.0) // try this one: (v 0.99) // www.vjshow.net/vart/WinVDIG_099.exe // uninstall instructions for winvdig in the winvdig forum // http://www.videoscript.com/forum/viewtopic.php?t=21 // // -[wvdig $]- // (also, www.abstractplane.com/products/vdig.jsp) // never tried... // 30 day demo available // // you will need a vdig to see video // try "hackTv" to test if you can use // quicktime to grab video // (pc) ftp://ftp.apple.com/developer/Quicktime/Windows_Tools/Programmers_Tools/Hack_TV/Hack_TV.zip // (mac) ftp://ftp.apple.com/developer/Quicktime/Tools/Programmers_Tools/Hack_TV.sit.hqx // // very good info here: // http://www.proce55ing.net/reference/libraries/video/ // (java stuff doesn't apply, but info on winvdig, vdig, etc) // // windows / direct show thoughts: // dShow capture via dsVideoLib coming soon ... // it's a c++ compiled lib, and tremendously difficult to work // in different c++ compilers. dope lib, but trouble with dev-c++... // look also at the reactable video input, useful? // wraps also v4l... // other cross platform video input options? // - opencv (cvAux?) //----------------------------------------- // todo: // -enumerate devices (ala wengo?) // -enumerate inputs // -allow input selection // -ntsc, pal format options... // -callback, via SGSetDataProc - couldn't get this to work yet // image decompress options ala mung... //--------------------------------------------- // this struct has all the info we need to grab pixels // typedef struct { unsigned char * offscreenGWorldPixels; // 32 bit: argb (qt k32ARGBPixelFormat) unsigned char * pixels; // 24 bit: rgb int w,h; bool bHavePixelsChanged; GWorldPtr videogworld; SeqGrabComponent gSeqGrabber; SGChannel gVideoChannel; Rect videoRect; } videoGrabberData; //--------------------------------------------- class ofQtVideoGrabber{ public : ofQtVideoGrabber(); bool isFrameNew(); void grabFrame(); void close(); void initGrabber(int w, int h); void initGrabber(int w, int h, bool bTexture); void videoSettings(); unsigned char * getPixels(); void setVerbose(bool bTalkToMe); void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); int w; int h; private: bool bSgGrabberInited; videoGrabberData * vgd; bool bVerbose; ofTexture tex; bool bUseTexture; }; #endif Node-path: video/ofQtVideoPlayer.cpp Node-kind: file Node-action: change Text-content-length: 9347 Text-content-md5: 9315b436a1c2a27109d2868212de6cea Content-length: 9347 #include "ofQtVideoPlayer.h" //-------------------------------------------------------------- bool createMovieFromPath(char * path, Movie * movie); bool createMovieFromPath(char * path, Movie * movie){ Boolean isdir = false; OSErr result = 0; FSSpec theFSSpec; FSRef fsref; short resRefNum = -1; short actualResId = DoTheRightThing; #ifdef TARGET_WIN32 result = NativePathNameToFSSpec (path, &theFSSpec, 0); if (result) { printf("NativePathNameToFSSpec failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } #endif #ifdef TARGET_OSX result = FSPathMakeRef((const UInt8*)path, &fsref, &isdir); if (result) { printf("FSPathMakeRef failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } result = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL); if (result) { printf("FSGetCatalogInfo failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } #endif result = OpenMovieFile (&theFSSpec, &resRefNum, 0); if (result) { printf("OpenMovieFile failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } result = NewMovieFromFile (movie, resRefNum, &actualResId, (unsigned char *) 0, 0, (Boolean *) 0); if (result) { printf("NewMovieFromFile failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } if (resRefNum != -1) CloseMovieFile (resRefNum); return true; } //-------------------------------------------------------------- OSErr DrawCompleteProc(Movie theMovie, long refCon); OSErr DrawCompleteProc(Movie theMovie, long refCon){ videoPlayerData * vd = (videoPlayerData *)refCon; convertPixels(vd->offscreenGWorldPixels, vd->pixels, vd->offscreenWidth, vd->offscreenHeight); vd->bHavePixelsChanged = true; // now if the pixels have changed AND we are // using a texture, let's update the texture if (vd->bUseTexture == true){ vd->tex->loadData(vd->pixels, vd->offscreenWidth, vd->offscreenHeight, GL_RGB); } return noErr; } //--------------------------------------------------------------------------- ofQtVideoPlayer::ofQtVideoPlayer (){ bLoadedMovie = false; w = 0; h = 0; vpd = new videoPlayerData(); vpd->moviePtr = NULL; vpd->offscreenWidth = 0; vpd->offscreenHeight = 0; bUseTexture = true; } //--------------------------------------------------------------------------- unsigned char * ofQtVideoPlayer::getPixels(){ return vpd->pixels; } //--------------------------------------------------------------------------- bool ofQtVideoPlayer::isFrameNew(){ if (bLoadedMovie == true){ bool bChanged = vpd->bHavePixelsChanged; if (vpd->bHavePixelsChanged == true) { vpd->bHavePixelsChanged = false; } return bChanged; } else { return false; } } //--------------------------------------------------------------------------- void ofQtVideoPlayer::idleMovie(){ // [zach] my question is how often to call this? // I don't want to call it too often, and up cpu usage // // shockingly,(or not) on a mac, it seems it's not even necessary to call it // the callback just works... // google " site:lists.apple.com MoviesTask windows mac // some code I've seen uses a thread to call this "JUCE" // maybe I could use ofElapsedTimeMillis() // or a system clock call (not glut call) // and make this less frequent if (bLoadedMovie == true){ MoviesTask(vpd->moviePtr,0); } } //--------------------------------------------------------------------------- void ofQtVideoPlayer::closeMovie(){ Movie moviePtr = vpd->moviePtr; DisposeMovie (vpd->moviePtr); #ifdef TARGET_WIN32 DisposeMovieDrawingCompleteUPP (myDrawCompleteProc); #endif ExitMovies (); } //--------------------------------------------------------------------------- bool ofQtVideoPlayer::loadMovie(char * name){ OSErr result = 0; short resRefNum = -1; bLoadedMovie = false; Rect bounds; //----------------- callback method MovieDrawingCompleteUPP myDrawCompleteProc; myDrawCompleteProc = NewMovieDrawingCompleteUPP (DrawCompleteProc); initializeQuicktime(); vpd->bHavePixelsChanged = false; Movie * moviePtr = &(vpd->moviePtr); createMovieFromPath(name, moviePtr); //----------------------------------movie box GetMovieBox(vpd->moviePtr, &(vpd->movieRect)); w = vpd->movieRect.right; h = vpd->movieRect.bottom; vpd->offscreenWidth = vpd->movieRect.right; vpd->offscreenHeight = vpd->movieRect.bottom; //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vpd->offscreenGWorldPixels = (unsigned char*)malloc(4 * w * h + 32); vpd->pixels = new unsigned char[w*h*3]; //---------------------------------- gworld allocation QTNewGWorldFromPtr (&(vpd->offscreenGWorld), k32ARGBPixelFormat, &(vpd->movieRect), NULL, NULL, 0, (vpd->offscreenGWorldPixels), 4 * w); LockPixels(GetGWorldPixMap(vpd->offscreenGWorld)); SetGWorld (vpd->offscreenGWorld, NULL); SetMovieGWorld (vpd->moviePtr, vpd->offscreenGWorld, nil); //----------------- callback method SetMovieDrawingCompleteProc (vpd->moviePtr, movieDrawingCallWhenChanged, myDrawCompleteProc, (long)vpd); //---------------------------------- reset themovie, get ready to roll GoToBeginningOfMovie(vpd->moviePtr); SetMovieActiveSegment(vpd->moviePtr, -1,-1); if (vpd->moviePtr == NULL){ return false; } SetMovieActive(vpd->moviePtr, true); StartMovie(vpd->moviePtr); //------------------ set the movie rate to default //------------------ and preroll, so the first frames come correct TimeValue timeNow; Fixed playRate; timeNow = GetMovieTime(vpd->moviePtr, 0); playRate =GetMoviePreferredRate(vpd->moviePtr); PrePrerollMovie(vpd->moviePtr, timeNow, playRate, 0, 0); PrerollMovie(vpd->moviePtr, timeNow, playRate); SetMovieRate(vpd->moviePtr, playRate); setLoopState(OF_QT_LOOP_NORMAL); bLoadedMovie = true; // get some pixels in there right away. MoviesTask(vpd->moviePtr,0); convertPixels(vpd->offscreenGWorldPixels, vpd->pixels, vpd->offscreenWidth, vpd->offscreenHeight); vpd->bUseTexture = bUseTexture; vpd->tex = &tex; if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.setFormat(w,h,GL_RGB); memset(vpd->pixels, 0, w*h*3); vpd->tex->loadData(vpd->pixels, vpd->offscreenWidth, vpd->offscreenHeight, GL_RGB); } return true; } //-------------------------------------------------------- void ofQtVideoPlayer::setVolume(int volume){ Movie moviePtr = vpd->moviePtr; SetMovieVolume(moviePtr, volume); } //-------------------------------------------------------- void ofQtVideoPlayer::setLoopState(int state){ Movie moviePtr = vpd->moviePtr; TimeBase myTimeBase; long myFlags = 0L; myTimeBase = GetMovieTimeBase(moviePtr); myFlags = GetTimeBaseFlags(myTimeBase); switch (state) { case OF_QT_LOOP_NORMAL: myFlags |= loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, hintsLoop, hintsLoop); SetMoviePlayHints(moviePtr, 0L, hintsPalindrome); break; case OF_QT_LOOP_PALINDROME: myFlags |= loopTimeBase; myFlags |= palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, hintsLoop, hintsLoop); SetMoviePlayHints(moviePtr, hintsPalindrome, hintsPalindrome); break; case OF_QT_LOOP_NONE: default: myFlags &= ~loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, 0L, hintsLoop | hintsPalindrome); break; } SetTimeBaseFlags(myTimeBase, myFlags); } //--------------------------------------------------------------------------- void ofQtVideoPlayer::setPosition(float pct){ TimeRecord tr; Movie moviePtr = vpd->moviePtr; tr.base = GetMovieTimeBase(moviePtr); long total = GetMovieDuration(moviePtr ); long newPos = (long)((float)total * pct); SetMovieTimeValue(moviePtr, newPos); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getDuration(){ Movie moviePtr = vpd->moviePtr; return GetMovieDuration (moviePtr) / (double) GetMovieTimeScale (moviePtr); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getPosition(){ Movie moviePtr = vpd->moviePtr; long total = GetMovieDuration(moviePtr); long current = GetMovieTime(moviePtr, nil); float pct = ((float)current/(float)total); return pct; } //--------------------------------------------------------------------------- void ofQtVideoPlayer::setSpeed(float _speed){ Movie moviePtr = vpd->moviePtr; speed = _speed; SetMovieRate(moviePtr, X2Fix(speed)); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getSpeed(){ return speed; } //------------------------------------ void ofQtVideoPlayer::setUseTexture(bool bUse){ bUseTexture = bUse; vpd->bUseTexture = bUseTexture; vpd->tex = &tex; } //------------------------------------ void ofQtVideoPlayer::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.render(_x, _y, _w, _h); } } Node-path: video/ofQtVideoPlayer.h Node-kind: file Node-action: change Text-content-length: 2849 Text-content-md5: 413a14060e8499ca8784d579c036456b Content-length: 2849 #ifndef _QT_VIDEO_PLAYER #define _QT_VIDEO_PLAYER #include "ofConstants.h" #include "ofQtUtils.h" #include "ofTexture.h" //------------------------------------------------- // (notes, links, etc) // // intersting technique employed here to get to RGB24 // from YUV2 - worthwhile? // paste.lisp.org/display/1051 //----------------------------- // http://viewcvs.osafoundation.org/chandler/trunk/internal/wx/src/msw/mediactrl.cpp?rev=6281&view=markup // http://developer.apple.com/documentation/QuickTime/INMAC/QT/iqMovieToolbox.34.htm // look for "QTURL_NewMovieFromURL", useful for loading URL based movies.. //------------------------------------------------- // // http://lists.apple.com/archives/QuickTime-API/2002/Feb/msg00118.html // //------------------------------------------------- // // note about callbacks: // // we use here a callback provided by quicktime to see if pixels have actually changed // the callback is "DrawCompleteProc" and int he quicktime code, // is defined as "static pascal OsErr ...." // in windows, I have dropped the pascal declaration as my compiler was // having trouble with that... necessary for mac? // // the alternative is to do what is done in qtVideoGrabber // set the alpha of the top pixel to 0x00 and every idle call // check to see if there are new pixels... #define OF_QT_LOOP_NONE 0x01 #define OF_QT_LOOP_PALINDROME 0x02 #define OF_QT_LOOP_NORMAL 0x03 //--------------------------------------------- // this struct has all the info we need to play 1 movie // kept in a struct, because the callback will // need to reference it... typedef struct { MovieController thePlayer; GWorldPtr offscreenGWorld; Movie moviePtr; Rect movieRect; unsigned char * offscreenGWorldPixels; // 32 bit: argb (qt k32ARGBPixelFormat) unsigned char * pixels; // 24 bit: rgb int offscreenWidth; int offscreenHeight; bool bHavePixelsChanged; ofTexture * tex; // a ptr to the texture we are utilizing bool bUseTexture; // are we using a texture } videoPlayerData; //--------------------------------------------- class ofQtVideoPlayer{ public: ofQtVideoPlayer (); void closeMovie(); bool loadMovie(char * name); void idleMovie(); int w, h; float speed; bool bLoadedMovie; bool isFrameNew(); unsigned char * getPixels(); float getPosition(); float getSpeed(); float getDuration(); void setPosition(float pct); void setVolume(int volume); void setLoopState(int state); void setSpeed(float speed); void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); private: //--------------------------- videoPlayerData * vpd; ofTexture tex; bool bUseTexture; }; #endif Revision-number: 20 Prop-content-length: 175 Content-length: 175 K 7 svn:log V 73 zach - lots of name / API modifications, in ofTexture and in ofSimple app K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-02-02T08:39:08.915318Z PROPS-END Node-path: app/ofAppGlutGlue.h Node-kind: file Node-action: change Text-content-length: 2158 Text-content-md5: 3de9eea0f39979da95984626a0fc579d Content-length: 2158 void display(void); void mouse_cb(int button, int state, int x, int y); void motion_cb(int x, int y); void passive_motion_cb(int x, int y); void idle_cb(void); void keyboard_cb(unsigned char key, int x, int y); void special_key_cb(int key, int x, int y) ; static int buttonInUse = 0; //-------------------------------- static float timeNow, timeThen, fps; static int nFrames; //------------------------------------------------------------ void display(void){ ofGetWindowSize( &width, &height ); height = height > 0 ? height : 1; // set viewport, clear the screen glViewport( 0, 0, width, height ); float * bgPtr = ofBgColorPtr(); glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); OFSAptr->draw(); glutSwapBuffers(); // -------------- fps calculation: timeNow = ofGetElapsedTimef(); if( (timeNow-timeThen) > 0.05f || nFrames == 0 ) { fps = (double)nFrames / (timeNow-timeThen); timeThen = timeNow; nFrames = 0; ofFrameRate = 0.9f * ofFrameRate + 0.1f * fps; } nFrames++; // -------------- } //------------------------------------------------------------ void mouse_cb(int button, int state, int x, int y) { if (state == GLUT_DOWN) { OFSAptr->mousePressed(x, height - y, button); } else if (state == GLUT_UP) { OFSAptr->mouseReleased(); } buttonInUse = button; } //------------------------------------------------------------ void motion_cb(int x, int y) { OFSAptr->mouseDragged(x, height - y, buttonInUse); } //------------------------------------------------------------ void passive_motion_cb(int x, int y) { OFSAptr->mouseMoved(x, height - y); } //------------------------------------------------------------ void idle_cb(void) { OFSAptr->update(); glutPostRedisplay(); } //------------------------------------------------------------ void keyboard_cb(unsigned char key, int x, int y) { OFSAptr->keyPressed((int)key); if (key == 27){ // "escape" OF_EXIT_APP(0); } } //------------------------------------------------------------ void special_key_cb(int key, int x, int y) { OFSAptr->keyPressed((int)key); } Node-path: app/ofAppRunner.cpp Node-kind: file Node-action: change Text-content-length: 1490 Text-content-md5: 9002821b499ae8d448c318c42f4bf91d Content-length: 1490 #include "ofAppRunner.h" //======================================================================== // static variables: static ofSimpleApp * OFSAptr; bool bMousePressed; bool bRightButton; int width, height; static float ofFrameRate; //======================================================================== // callbacks: #include "ofAppGlutGlue.h" //-------------------------------------- void ofSetupOpenGL(int w, int h, int screenMode){ int argc = 1; char *argv = "openframeworks"; char **vptr = &argv; glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA); glutInit(&argc, vptr); if (screenMode == OF_WINDOW) glutInitWindowSize(w, h); glutCreateWindow(""); if (screenMode == OF_FULLSCREEN) glutFullScreen(); } //-------------------------------------- void ofRunApp(ofSimpleApp * OFSA){ OFSAptr = OFSA; // window // callbacks glutMouseFunc(mouse_cb); glutMotionFunc(motion_cb); glutPassiveMotionFunc(passive_motion_cb); glutIdleFunc(idle_cb); glutDisplayFunc(display); glutKeyboardFunc(keyboard_cb); glutSpecialFunc(special_key_cb); OFSA->setup(); glutMainLoop(); } //-------------------------------------- float ofGetFrameRate(){ return ofFrameRate; } //-------------------------------------- void ofHideCursor(){ glutSetCursor(GLUT_CURSOR_NONE); } //-------------------------------------- void ofShowCursor(){ glutSetCursor(GLUT_CURSOR_RIGHT_ARROW); } Node-path: app/ofSimpleApp.h Node-kind: file Node-action: change Text-content-length: 664 Text-content-md5: ba368ee6e90efddf847542081a0a14f9 Content-length: 664 #ifndef _OF_SIMPLE_APP #define _OF_SIMPLE_APP #include "ofConstants.h" #include "ofUtils.h" class ofSimpleApp{ public: ofSimpleApp(){} virtual void setup(){} virtual void update(){} virtual void draw(){} virtual void keyPressed(int key ){} virtual void mouseMoved( int x, int y ){} virtual void mouseDragged( int x, int y, int button ){} virtual void mousePressed( int x, int y, int button ){} virtual void mouseReleased(){} virtual void audioReceived (float * input, int bufferSize, int nChannels) {} virtual void audioRequested (float * output, int bufferSize, int nChannels) {} }; #endif Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: change Text-content-length: 5560 Text-content-md5: ec52a187052e32de9734e3d26690699e Content-length: 5560 #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- void ofBackground(int r, int g, int b){ bgColor[0] = (float)r / (float)255.0f; bgColor[1] = (float)g / (float)255.0f; bgColor[2] = (float)b / (float)255.0f; bgColor[3] = 1.0f; } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } //---------------------------------------------------------- void ofEnableAlphaBlending(){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void ofDisableAlphaBlending(){ glDisable(GL_BLEND); } //-------------------------------------------------- void ofDrawBitmapString(char *string, float x, float y){ //--------------------------------------------------- // for now this is fixed to the 8_BY_13 glut character // http://pyopengl.sourceforge.net/documentation/manual/glutBitmapCharacter.3GLUT.html //--------------------------------------------------- char *c; int yOffset = 0; float fontSize = 8.0f; glRasterPos2f(x,y); for (c=string; *c != '\0'; c++) { if(*c == '\n') { yOffset -= (fontSize*1.4); glRasterPos2f(x,y + yOffset); } else if (((int)*c) > 32){ // < 32 = control characters - don't draw // solves a bug with control characters // getting drawn when they ought to not be glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c); } } } //---------------------------------------------------------- void ofSetupScreen(){ int w, h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } Node-path: graphics/ofGraphics.h Node-kind: file Node-action: change Text-content-length: 1117 Text-content-md5: 057874229af30a931ce18530657245c7 Content-length: 1117 #ifndef OF_GEOM #define OF_GEOM #include "ofConstants.h" #define CIRC_RESOLUTION 22 // 22 pts for a circle... // bg color float * ofBgColorPtr(); void ofBackground(int r, int g, int b); // geometry void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3); void ofCircle(float x,float y, float radius); void ofEllipse(float x, float y, float width, float height); void ofLine(float x1,float y1,float x2,float y2); void ofRect(float x1,float y1,float w, float h); void ofSetCircleResolution(int res); // if there 22 is a problem, you can change it here // drawing options void ofNoFill(); void ofFill(); // color options void ofSetColor(int r, int g, int b); // 0-255 void ofSetColor(int hexColor); // hex, like web 0xFF0033; // transparency void ofEnableAlphaBlending(); // this just turns on and off opengl blending, the common mode void ofDisableAlphaBlending(); // bitmapped type // ** note, this uses glDrawPixels and may be S L 0 W on some graphics cards void ofDrawBitmapString( char *string, float x, float y); // screen coordinate things... void ofSetupScreen(); #endif Node-path: graphics/ofImage.cpp Node-kind: file Node-action: change Text-content-length: 7527 Text-content-md5: c13bf1c4c08eec56c8b027562698f91a Content-length: 7527 #include "ofImage.h" #include "freeImage.h" static bool bFreeImageInited = false; //----------------------------------------- // class freeImageBitmap{ public: FIBITMAP * bmp; //----------------------- freeImageBitmap(){ bmp = NULL; } //----------------------- //swap my image out in a (hopefully) non-memory leakish way void swap(FIBITMAP *dst) { if(dst == NULL) return; if(bmp != NULL) FreeImage_Unload(bmp); bmp = dst; } //----------------------- void setSize(FREE_IMAGE_TYPE image_type, WORD width, WORD height, WORD bpp) { if(bmp == NULL) { FreeImage_Unload(bmp); } bmp = FreeImage_AllocateT(image_type, width, height, bpp); } //----------------------- bool isValid(){ return (bmp != NULL) ? true : false; } }; //---------------------------------------------------------- ofImage::ofImage(){ //----------------------- init free image if necessary if (!bFreeImageInited){ FreeImage_Initialise(); bFreeImageInited = true; } //----------------------- IMG = new freeImageBitmap(); w = h = bpp = 0; type = OF_IMAGE_UNDEFINED; bUseTexture = true; // the default is, yes, use a texture } //---------------------------------------------------------- void ofImage::grabScreen(int _x, int _y, int _w, int _h){ if (IMG->isValid()){ if (!(w == _w && h == _h)){ resize(_w, _h); } unsigned char * pixels = getPixels(); switch (bpp){ case 8: glReadPixels(_x, _y, _w, _h, GL_LUMINANCE,GL_UNSIGNED_BYTE, pixels); break; case 24: glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); break; case 32: glReadPixels(_x, _y, _w, _h, GL_RGBA,GL_UNSIGNED_BYTE, pixels); break; } } else { // assume that this is color.... IMG->setSize(FIT_BITMAP, _w, _h, 24); unsigned char * pixels = getPixels(); glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE,pixels); update(); } } //---------------------------------------------------------- void ofImage::allocate(int _w, int _h, int _type){ int newbpp; switch (_type){ case OF_IMAGE_GRAYSCALE: newbpp = 8; break; case OF_IMAGE_COLOR: newbpp = 24; break; case OF_IMAGE_COLOR_ALPHA: newbpp = 32; break; default: newbpp = 24; break; } IMG->setSize(FIT_BITMAP, _w, _h, newbpp); } //---------------------------------------------------------- void ofImage::update(){ w = FreeImage_GetWidth(IMG->bmp); h = FreeImage_GetHeight(IMG->bmp); bpp = FreeImage_GetBPP(IMG->bmp); switch (bpp){ case 8: type = OF_IMAGE_GRAYSCALE; break; case 24: type = OF_IMAGE_COLOR; break; case 32: type = OF_IMAGE_COLOR_ALPHA; break; default: // if we've got here, something is wrong, the image // is not 8bit, 24bit or 32bit, so let's at least // make it color: setImageType(OF_IMAGE_COLOR); break; } // if we are using a texture and the ofImage is upadate, // allocate (or reallocate) the texture and upload the data if (bUseTexture){ switch (type){ case OF_IMAGE_GRAYSCALE: tex.allocate(w,h,GL_LUMINANCE); tex.loadData(getPixels(), w, h, GL_LUMINANCE); break; case OF_IMAGE_COLOR: tex.allocate(w,h,GL_RGB); tex.loadData(getPixels(), w, h, GL_RGB); break; case OF_IMAGE_COLOR_ALPHA: tex.allocate(w,h,GL_RGBA); tex.loadData(getPixels(), w, h, GL_RGBA); break; } } } //---------------------------------------------------------- void ofImage::loadImage(char * fileName){ bool bLoaded = false; //----------------------------- find the format FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { if(IMG->isValid()) { FreeImage_Unload(IMG->bmp); } IMG->bmp = FreeImage_Load(fif, fileName, 0); bLoaded = true; if(!IMG->isValid()){ bLoaded = false; } } //----------------------------- if (bLoaded){ update(); //--------------- on windows, we need to change BGR to RGB // (also on intel macs? also with RGBA images?) #ifdef TARGET_WIN32 if (type == OF_IMAGE_COLOR){ swapChannels(); } #endif } else { w = h = bpp = 0; } } //---------------------------------------------------------- void ofImage::saveImage(char * fileName){ if (IMG->isValid()){ FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { FreeImage_Save(fif, IMG->bmp, fileName, 0); } } } //---------------------------------------------------------- unsigned char * ofImage::getPixels(){ // be careful! if (IMG->isValid()){ return (unsigned char *)FreeImage_GetBits(IMG->bmp); } else { return NULL; } } //---------------------------------------------------------- void ofImage::resize(int newWidth, int newHeight){ if (IMG->isValid()){ FIBITMAP * scaledBmp = FreeImage_Rescale(IMG->bmp, newWidth, newHeight, FILTER_BICUBIC); IMG->swap(scaledBmp); update(); } } //---------------------------------------------------------- void ofImage::setImageType(int newType){ if (IMG->isValid()){ switch (newType){ //------------------------------------ case OF_IMAGE_GRAYSCALE: if (type != OF_IMAGE_GRAYSCALE){ FIBITMAP * convertedBmp = FreeImage_ConvertToGreyscale(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; //------------------------------------ case OF_IMAGE_COLOR: if (type != OF_IMAGE_COLOR){ FIBITMAP * convertedBmp = FreeImage_ConvertTo24Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR; } break; //------------------------------------ case OF_IMAGE_COLOR_ALPHA: if (type != OF_IMAGE_COLOR_ALPHA){ FIBITMAP * convertedBmp = FreeImage_ConvertTo32Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; } update(); } } //------------------------------------ void ofImage::swapChannels(){ // this swaps the red and blue channel of an image // turning an bgr image to rgb and vice versa... // needed because of windows byte order... if (IMG->isValid() && type == OF_IMAGE_COLOR){ unsigned char * pixels = getPixels(); int nTotalPixels = w*h; unsigned char temp; // unoptimized for now... for (int i = 0; i < nTotalPixels; i++){ temp = pixels[i*3]; pixels[i*3] = pixels[i*3 + 2]; pixels[i*3 + 2] = temp; } } update(); // this is a redundant hack. please fix me // the thing is we need to update to texture, after the // conversion, but we need to know w, h, type // before the conversion - as it stands now // we update the texture twice... } //------------------------------------ void ofImage::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofImage::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } Node-path: graphics/ofTexture.cpp Node-kind: file Node-action: change Text-content-length: 3207 Text-content-md5: f351b4d01d935ab194d0107bd749ee93 Content-length: 3207 #include "ofTexture.h" #include "ofUtils.h" // for nextPow2() //---------------------------------------------------------- ofTexture::ofTexture(){ texName = new unsigned int[1]; texName[0] = 0; } //---------------------------------------------------------- void ofTexture::clear(){ // try to free up the texture memory so we don't reallocate // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/deletetextures.html if (texName[0] != 0){ glDeleteTextures(1, (GLuint *)texName); } } //---------------------------------------------------------- void ofTexture::allocate(int w, int h, int internalGlDataType){ // can pass in anything (320x240) (10x5) // here we make it power of 2 for opengl (512x256), (16x8) tex_w = ofNextPow2(w); tex_h = ofNextPow2(h); tex_u = 1.0f; tex_t = 1.0f; // attempt to free the previous bound texture, if we can: clear(); // create the named texture: //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // not necessary, I think glGenTextures(1, (GLuint *)texName); // could be more then one, but for now, just one glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); glTexImage2D(GL_TEXTURE_2D, 0, internalGlDataType, tex_w, tex_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); // init to black... glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); } void ofTexture::loadData(unsigned char * data, int w, int h, int glDataType){ // can we allow for uploads bigger then texutre and // just take as much as the texture can? // // ie: // int uploadW = MIN(w, tex_w); // int uploadH = MIN(h, tex_h); // but with a "step" size of w? // check "glTexSubImage2D" if ( w > tex_w || h > tex_h) { printf("image data too big - bailing \n"); return; } //compute new tex co-ords based on the ratio of data's w, h to texture w,h; tex_t = (float)w / (float)tex_w; tex_u = (float)h / (float)tex_h; // update the texture image: glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); glTexSubImage2D(GL_TEXTURE_2D,0,0,0,w,h,glDataType,GL_UNSIGNED_BYTE,data); glDisable(GL_TEXTURE_2D); } //================================================================================= void ofTexture::draw(int x, int y, int w, int h){ glEnable(GL_TEXTURE_2D); // bind the texture glBindTexture( GL_TEXTURE_2D, (GLuint)texName[0] ); float px0 = x ; // up to you to get the aspect ratio right float py0 = y ; float px1 = x+w; float py1 = y+h; glBegin( GL_QUADS ); glTexCoord2f(0.0, 0.0); glVertex3f(px0, py0,0); glTexCoord2f(tex_t, 0.0); glVertex3f(px1, py0,0); glTexCoord2f(tex_t, tex_u); glVertex3f(px1, py1,0); glTexCoord2f(0.0, tex_u); glVertex3f(px0, py1,0); glEnd(); glDisable(GL_TEXTURE_2D); } Node-path: graphics/ofTexture.h Node-kind: file Node-action: change Text-content-length: 439 Text-content-md5: d00e2581c70f8976dff038b0cf10fd21 Content-length: 439 #ifndef _IMAGE_TEXTURE_H_ #define _IMAGE_TEXTURE_H_ #include "ofConstants.h" class ofTexture { public : ofTexture(); void allocate(int w, int h, int internalGlDataType); void clear(); void loadData(unsigned char * data, int w, int h, int glDataType); void draw(int x, int y, int w, int h); float tex_t, tex_u; private: int tex_w, tex_h; unsigned int * texName; }; #endif Node-path: sound/ofAudio.cpp Node-kind: file Node-action: change Text-content-length: 3657 Text-content-md5: 4187b9de0032a04efcc6cffc8efe0c11 Content-length: 3657 #include "ofAudio.h" #include "rtAudio.h" //----------------------------------- static variables: static ofSimpleApp * OFSAptr; RtAudio * audio; int nInputChannels; int nOutputChannels; //----------------------------------- int receiveAudioBufferAndCallSimpleApp(char *buffer, int bufferSize, void *data); int receiveAudioBufferAndCallSimpleApp(char *buffer, int bufferSize, void *data){ // rtAudio uses a system by which the audio // can be of different formats // char, float, etc. // we choose float float * fPtr = (float *)buffer; // [zach] memset output to zero before output call // this is because of how rtAudio works: duplex w/ one callback // you need to cut in the middle. if the simpleApp // doesn't produce audio, we pass silence instead of duplex... if (nInputChannels > 0){ OFSAptr->audioReceived(fPtr, bufferSize, nInputChannels); memset(fPtr, 0, bufferSize * nInputChannels * sizeof(float)); } if (nOutputChannels > 0) OFSAptr->audioRequested(fPtr, bufferSize, nOutputChannels); return 0; } //--------------------------------------------------------- void ofAudioSetup(int nOutputs, int nInputs, ofSimpleApp * OFSA){ ofAudioSetup(nOutputs, nInputs, OFSA, 44100, 256, 4); } //--------------------------------------------------------- void ofAudioSetup(int nOutputs, int nInputs, ofSimpleApp * OFSA, int sampleRate, int bufferSize, int nBuffers){ nInputChannels = nInputs; nOutputChannels = nOutputs; int device = 0; // default OFSAptr = OFSA; try { audio = new RtAudio(); audio->openStream( device, nOutputs, device, nInputs, RTAUDIO_FLOAT32, sampleRate, &bufferSize, nBuffers); } catch (RtError &error) { error.printMessage(); //std::exit(EXIT_FAILURE); // need case here } try { audio->setStreamCallback(&receiveAudioBufferAndCallSimpleApp, (void *)NULL); audio->startStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioStopStream(){ try { audio->stopStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioStartStream(){ try{ audio->startStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioEndStream(){ try { audio->stopStream(); audio->closeStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioEnumerateDevices(){ RtAudio *audioTemp = 0; try { audioTemp = new RtAudio(); } catch (RtError &error) { error.printMessage(); } int devices = audioTemp->getDeviceCount(); RtAudioDeviceInfo info; for (int i=1; i<=devices; i++) { try { info = audioTemp->getDeviceInfo(i); } catch (RtError &error) { error.printMessage(); break; } std::cout << "device = " << i << " (" << info.name << ")\n"; if (info.isDefault) std::cout << "***** default ***** \n"; std::cout << "maximum output channels = " << info.outputChannels << "\n"; std::cout << "maximum input channels = " << info.inputChannels << "\n"; std::cout << "-----------------------------------------\n"; } delete audioTemp; } /* try { // Stop and close the stream audio->stopStream(); audio->closeStream(); } catch (RtError &error) { error.printMessage(); } */ Node-path: video/ofQtVideoGrabber.cpp Node-kind: file Node-action: change Text-content-length: 7674 Text-content-md5: 49883be1379749bf32bddbcab1a0e6c0 Content-length: 7674 #include "ofQtVideoGrabber.h" //-------------------------------------------------------------------- Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon); Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon){ #pragma unused(theDialog, itemHit) Boolean handled = false; if ((theEvent->what == updateEvt) && ((WindowPtr) theEvent->message == (WindowPtr) refCon)) { BeginUpdate ((WindowPtr) refCon); EndUpdate ((WindowPtr) refCon); handled = true; } return (handled); } //-------------------------------------------------------------------- ofQtVideoGrabber::ofQtVideoGrabber(){ initializeQuicktime(); vgd = new videoGrabberData(); bVerbose = false; bSgGrabberInited = false; bUseTexture = true; } //-------------------------------------------------------------------- void ofQtVideoGrabber::setVerbose(bool bTalkToMe){ bVerbose = bTalkToMe; } //--------------------------------------------------------------------------- unsigned char * ofQtVideoGrabber::getPixels(){ return vgd->pixels; } //--------------------------------------------------------------------------- bool ofQtVideoGrabber::isFrameNew(){ if (bSgGrabberInited == true){ bool bNew = false; if (vgd->bHavePixelsChanged == true){ bNew = true; vgd->bHavePixelsChanged = false; } return bNew; } else { return false; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::grabFrame(){ if (bSgGrabberInited == true){ SGIdle(vgd->gSeqGrabber); // set the top pixel alpha = 0, so we can know if it // was a new frame or not.. // or else we will process way more than necessary // (ie opengl is running at 60fps +, capture at 30fps) if (vgd->offscreenGWorldPixels[0] != 0x00){ vgd->offscreenGWorldPixels[0] = 0x00; vgd->bHavePixelsChanged = true; convertPixels(vgd->offscreenGWorldPixels, vgd->pixels, vgd->w, vgd->h); if (bUseTexture){ tex.loadData(vgd->pixels, vgd->w, vgd->h, GL_RGB); } } } } //-------------------------------------------------------------------- void ofQtVideoGrabber::close(){ //thanks eloi! if (vgd->gSeqGrabber != 0L){ CloseComponent (vgd->gSeqGrabber); vgd->gSeqGrabber = 0L; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::videoSettings(void){ Rect curBounds, curVideoRect; ComponentResult err; // Get our current state err = SGGetChannelBounds (vgd->gVideoChannel, &curBounds); if (err != noErr){ printf("Error in SGGetChannelBounds \n"); return; } err = SGGetVideoRect (vgd->gVideoChannel, &curVideoRect); if (err != noErr){ printf("Error in SGGetVideoRect \n"); return; } // Pause err = SGPause (vgd->gSeqGrabber, true); if (err != noErr){ printf("Error in SGPause\n"); return; } #ifdef TARGET_OSX static SGModalFilterUPP gSeqGrabberModalFilterUPP = NewSGModalFilterUPP(SeqGrabberModalFilterUPP); ComponentResult result = SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, 0L, gSeqGrabberModalFilterUPP, nil); if (err != noErr){ printf("error in dialogue\n"); return; } #else SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, 0L, NULL, nil); #endif #ifdef TARGET_WIN32 SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); #endif SGPause (vgd->gSeqGrabber, false); } //-------------------------------------------------------------------- void ofQtVideoGrabber::initGrabber(int w, int h){ vgd->w = w; vgd->h = h; ComponentDescription theDesc; Component sgCompID = NULL; char name[256]; char info[256]; Handle componentName=NULL; Handle componentInfo=NULL; ComponentDescription info_description; componentName=NewHandle(sizeof(name)); componentInfo=NewHandle(sizeof(info)); if (bVerbose == true){ printf ("\n"); printf ("-------------------------------------\n"); printf ("attempting to set up ofQtVideoGrabber\n"); } vgd->gSeqGrabber = 0L; vgd->gVideoChannel = 0L; theDesc.componentType = SeqGrabComponentType; theDesc.componentSubType = 0L; theDesc.componentManufacturer = 0L; theDesc.componentFlags = 0L; theDesc.componentFlagsMask = 0L; sgCompID = FindNextComponent(sgCompID, &theDesc); while (sgCompID != 0){ GetComponentInfo(sgCompID,&info_description, componentName, componentInfo,nil); if (bVerbose == true){ printf("found a device to capture with \n"); printf("Type: %s\n", &info_description.componentType); printf("Manufacturer: %s\n", &info_description.componentManufacturer); printf("Name: %s\n", *componentName ? p2cstr((StringPtr)*componentName) : "-" ); printf("Name: %s\n", *componentInfo ? p2cstr((StringPtr)*componentInfo) : "-"); } vgd->gSeqGrabber = OpenComponent(sgCompID); sgCompID = FindNextComponent(sgCompID, &theDesc); } //-------------------------------------------- // setup the gworld and digitizing. OSStatus err; err = SGInitialize(vgd->gSeqGrabber); if (err != noErr){ printf("***** Error in SGInitialize (check cam drivers, vdig or winvidg)*****\n"); return; } MacSetRect(&(vgd->videoRect),0, 0, w, h); //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vgd->offscreenGWorldPixels = (unsigned char*)malloc(4 * w * h + 32); vgd->pixels = new unsigned char[w*h*3]; QTNewGWorldFromPtr (&vgd->videogworld, k32ARGBPixelFormat, &vgd->videoRect, NULL, NULL, 0, vgd->offscreenGWorldPixels, 4 * w); LockPixels(GetGWorldPixMap(vgd->videogworld)); SetGWorld (vgd->videogworld, NULL); err = SGSetGWorld(vgd->gSeqGrabber, vgd->videogworld, nil); if ( err != noErr ) goto bail; err = SGNewChannel(vgd->gSeqGrabber, VideoMediaType, &vgd->gVideoChannel); if ( err != noErr ) goto bail; err = SGSetDataRef(vgd->gSeqGrabber, 0, 0, seqGrabDontMakeMovie); if ( err != noErr ) goto bail; err = SGSetChannelUsage(vgd->gVideoChannel,seqGrabPreview); if ( err != noErr ) goto bail; err = SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); if ( err != noErr ) goto bail; if (SGSetFrameRate(vgd->gVideoChannel,30) != noErr) printf( "error setting 30 fps \n"); else{ if (bVerbose == true){ printf ("set to capture at 30 fps \n"); } } err = SGPrepare(vgd->gSeqGrabber, false, true); if ( err != noErr ) goto bail; err = SGStartPreview(vgd->gSeqGrabber); if ( err != noErr ) goto bail; if (bVerbose){ printf ("end setup ofQtVideoGrabber\n"); printf ("-------------------------------------\n"); printf ("\n"); } if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.allocate(w,h,GL_RGB); memset(vgd->pixels, 0, w*h*3); tex.loadData(vgd->pixels, w, h, GL_RGB); } bSgGrabberInited = true; return; // good catch eloi/theo //--------------------- (bail) something's wrong ----- bail: if (bVerbose){ printf ("***** ofQtVideoGrabber error *****\n"); printf ("-------------------------------------\n"); printf ("\n"); } bSgGrabberInited = false; return; } //------------------------------------ void ofQtVideoGrabber::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofQtVideoGrabber::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } Node-path: video/ofQtVideoGrabber.h Node-kind: file Node-action: change Text-content-length: 2822 Text-content-md5: 2c3f6e55ca527cff6321340b021b3e6d Content-length: 2822 #ifndef _QT_VIDEO_GRABBER #define _QT_VIDEO_GRABBER #include "ofConstants.h" #include "ofQtUtils.h" #include "ofTexture.h" //----------------------------------------- // windows users check out winvdig: // // -[wvdig free]- // http://www.vdig.com/WinVDIG/ // but maybe older versions are better (at least w/ quicktime < 7.0) // try this one: (v 0.99) // www.vjshow.net/vart/WinVDIG_099.exe // uninstall instructions for winvdig in the winvdig forum // http://www.videoscript.com/forum/viewtopic.php?t=21 // // -[wvdig $]- // (also, www.abstractplane.com/products/vdig.jsp) // never tried... // 30 day demo available // // you will need a vdig to see video // try "hackTv" to test if you can use // quicktime to grab video // (pc) ftp://ftp.apple.com/developer/Quicktime/Windows_Tools/Programmers_Tools/Hack_TV/Hack_TV.zip // (mac) ftp://ftp.apple.com/developer/Quicktime/Tools/Programmers_Tools/Hack_TV.sit.hqx // // very good info here: // http://www.proce55ing.net/reference/libraries/video/ // (java stuff doesn't apply, but info on winvdig, vdig, etc) // // windows / direct show thoughts: // dShow capture via dsVideoLib coming soon ... // it's a c++ compiled lib, and tremendously difficult to work // in different c++ compilers. dope lib, but trouble with dev-c++... // look also at the reactable video input, useful? // wraps also v4l... // other cross platform video input options? // - opencv (cvAux?) //----------------------------------------- // todo: // -enumerate devices (ala wengo?) // -enumerate inputs // -allow input selection // -ntsc, pal format options... // -callback, via SGSetDataProc - couldn't get this to work yet // image decompress options ala mung... //--------------------------------------------- // this struct has all the info we need to grab pixels // typedef struct { unsigned char * offscreenGWorldPixels; // 32 bit: argb (qt k32ARGBPixelFormat) unsigned char * pixels; // 24 bit: rgb int w,h; bool bHavePixelsChanged; GWorldPtr videogworld; SeqGrabComponent gSeqGrabber; SGChannel gVideoChannel; Rect videoRect; } videoGrabberData; //--------------------------------------------- class ofQtVideoGrabber{ public : ofQtVideoGrabber(); bool isFrameNew(); void grabFrame(); void close(); void initGrabber(int w, int h); void initGrabber(int w, int h, bool bTexture); void videoSettings(); unsigned char * getPixels(); void setVerbose(bool bTalkToMe); void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); private: bool bSgGrabberInited; videoGrabberData * vgd; bool bVerbose; ofTexture tex; bool bUseTexture; }; #endif Node-path: video/ofQtVideoPlayer.cpp Node-kind: file Node-action: change Text-content-length: 9632 Text-content-md5: e94d0c898e5b24eeb01881b8d62ceb65 Content-length: 9632 #include "ofQtVideoPlayer.h" //-------------------------------------------------------------- bool createMovieFromPath(char * path, Movie * movie); bool createMovieFromPath(char * path, Movie * movie){ Boolean isdir = false; OSErr result = 0; FSSpec theFSSpec; FSRef fsref; short resRefNum = -1; short actualResId = DoTheRightThing; #ifdef TARGET_WIN32 result = NativePathNameToFSSpec (path, &theFSSpec, 0); if (result) { printf("NativePathNameToFSSpec failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } #endif #ifdef TARGET_OSX result = FSPathMakeRef((const UInt8*)path, &fsref, &isdir); if (result) { printf("FSPathMakeRef failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } result = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL); if (result) { printf("FSGetCatalogInfo failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } #endif result = OpenMovieFile (&theFSSpec, &resRefNum, 0); if (result) { printf("OpenMovieFile failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } result = NewMovieFromFile (movie, resRefNum, &actualResId, (unsigned char *) 0, 0, (Boolean *) 0); if (result) { printf("NewMovieFromFile failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } if (resRefNum != -1) CloseMovieFile (resRefNum); return true; } //-------------------------------------------------------------- OSErr DrawCompleteProc(Movie theMovie, long refCon); OSErr DrawCompleteProc(Movie theMovie, long refCon){ videoPlayerData * vd = (videoPlayerData *)refCon; convertPixels(vd->offscreenGWorldPixels, vd->pixels, vd->w, vd->h); vd->bHavePixelsChanged = true; // now if the pixels have changed AND we are // using a texture, let's update the texture if (vd->bUseTexture == true){ vd->tex->loadData(vd->pixels, vd->w, vd->h, GL_RGB); } return noErr; } //--------------------------------------------------------------------------- ofQtVideoPlayer::ofQtVideoPlayer (){ bLoadedMovie = false; width = 0; height = 0; vpd = new videoPlayerData(); vpd->moviePtr = NULL; vpd->w = 0; vpd->h = 0; bUseTexture = true; } //--------------------------------------------------------------------------- unsigned char * ofQtVideoPlayer::getPixels(){ return vpd->pixels; } //--------------------------------------------------------------------------- bool ofQtVideoPlayer::isFrameNew(){ if (bLoadedMovie == true){ bool bChanged = vpd->bHavePixelsChanged; if (vpd->bHavePixelsChanged == true) { vpd->bHavePixelsChanged = false; } return bChanged; } else { return false; } } //--------------------------------------------------------------------------- void ofQtVideoPlayer::idleMovie(){ // [zach] my question is how often to call this? // I don't want to call it too often, and up cpu usage // // shockingly,(or not) on a mac, it seems it's not even necessary to call it // the callback just works... // google " site:lists.apple.com MoviesTask windows mac // some code I've seen uses a thread to call this "JUCE" // maybe I could use ofElapsedTimeMillis() // or a system clock call (not glut call) // and make this less frequent if (bLoadedMovie == true){ MoviesTask(vpd->moviePtr,0); } } //--------------------------------------------------------------------------- void ofQtVideoPlayer::closeMovie(){ Movie moviePtr = vpd->moviePtr; DisposeMovie (vpd->moviePtr); #ifdef TARGET_WIN32 DisposeMovieDrawingCompleteUPP (myDrawCompleteProc); #endif ExitMovies (); } //--------------------------------------------------------------------------- bool ofQtVideoPlayer::loadMovie(char * name){ OSErr result = 0; short resRefNum = -1; bLoadedMovie = false; Rect bounds; //----------------- callback method MovieDrawingCompleteUPP myDrawCompleteProc; myDrawCompleteProc = NewMovieDrawingCompleteUPP (DrawCompleteProc); initializeQuicktime(); vpd->bHavePixelsChanged = false; Movie * moviePtr = &(vpd->moviePtr); createMovieFromPath(name, moviePtr); //----------------------------------movie box GetMovieBox(vpd->moviePtr, &(vpd->movieRect)); width = vpd->movieRect.right; height = vpd->movieRect.bottom; vpd->w = vpd->movieRect.right; vpd->h = vpd->movieRect.bottom; //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vpd->offscreenGWorldPixels = (unsigned char*)malloc(4 * width * height + 32); vpd->pixels = new unsigned char[width*height*3]; //---------------------------------- gworld allocation QTNewGWorldFromPtr (&(vpd->offscreenGWorld), k32ARGBPixelFormat, &(vpd->movieRect), NULL, NULL, 0, (vpd->offscreenGWorldPixels), 4 * width); LockPixels(GetGWorldPixMap(vpd->offscreenGWorld)); SetGWorld (vpd->offscreenGWorld, NULL); SetMovieGWorld (vpd->moviePtr, vpd->offscreenGWorld, nil); //----------------- callback method SetMovieDrawingCompleteProc (vpd->moviePtr, movieDrawingCallWhenChanged, myDrawCompleteProc, (long)vpd); //---------------------------------- reset themovie, get ready to roll GoToBeginningOfMovie(vpd->moviePtr); SetMovieActiveSegment(vpd->moviePtr, -1,-1); if (vpd->moviePtr == NULL){ return false; } SetMovieActive(vpd->moviePtr, true); StartMovie(vpd->moviePtr); //------------------ set the movie rate to default //------------------ and preroll, so the first frames come correct TimeValue timeNow; Fixed playRate; timeNow = GetMovieTime(vpd->moviePtr, 0); playRate =GetMoviePreferredRate(vpd->moviePtr); PrePrerollMovie(vpd->moviePtr, timeNow, playRate, 0, 0); PrerollMovie(vpd->moviePtr, timeNow, playRate); SetMovieRate(vpd->moviePtr, playRate); setLoopState(OF_QT_LOOP_NORMAL); bLoadedMovie = true; // get some pixels in there right away. MoviesTask(vpd->moviePtr,0); convertPixels(vpd->offscreenGWorldPixels, vpd->pixels, vpd->w, vpd->h); vpd->bUseTexture = bUseTexture; vpd->tex = &tex; if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.allocate(width,height,GL_RGB); memset(vpd->pixels, 0, width*height*3); vpd->tex->loadData(vpd->pixels, vpd->w, vpd->h, GL_RGB); } return true; } //-------------------------------------------------------- void ofQtVideoPlayer::setVolume(int volume){ Movie moviePtr = vpd->moviePtr; SetMovieVolume(moviePtr, volume); } //-------------------------------------------------------- void ofQtVideoPlayer::setLoopState(int state){ Movie moviePtr = vpd->moviePtr; TimeBase myTimeBase; long myFlags = 0L; myTimeBase = GetMovieTimeBase(moviePtr); myFlags = GetTimeBaseFlags(myTimeBase); switch (state) { case OF_QT_LOOP_NORMAL: myFlags |= loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, hintsLoop, hintsLoop); SetMoviePlayHints(moviePtr, 0L, hintsPalindrome); break; case OF_QT_LOOP_PALINDROME: myFlags |= loopTimeBase; myFlags |= palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, hintsLoop, hintsLoop); SetMoviePlayHints(moviePtr, hintsPalindrome, hintsPalindrome); break; case OF_QT_LOOP_NONE: default: myFlags &= ~loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, 0L, hintsLoop | hintsPalindrome); break; } SetTimeBaseFlags(myTimeBase, myFlags); } //--------------------------------------------------------------------------- void ofQtVideoPlayer::setPosition(float pct){ TimeRecord tr; Movie moviePtr = vpd->moviePtr; tr.base = GetMovieTimeBase(moviePtr); long total = GetMovieDuration(moviePtr ); long newPos = (long)((float)total * pct); SetMovieTimeValue(moviePtr, newPos); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getDuration(){ Movie moviePtr = vpd->moviePtr; return GetMovieDuration (moviePtr) / (double) GetMovieTimeScale (moviePtr); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getPosition(){ Movie moviePtr = vpd->moviePtr; long total = GetMovieDuration(moviePtr); long current = GetMovieTime(moviePtr, nil); float pct = ((float)current/(float)total); return pct; } //--------------------------------------------------------------------------- void ofQtVideoPlayer::setSpeed(float _speed){ Movie moviePtr = vpd->moviePtr; speed = _speed; SetMovieRate(moviePtr, X2Fix(speed)); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getSpeed(){ return speed; } //--------------------------------------------------------------------------- void ofQtVideoPlayer::setPause(bool bPause){ // there might be a more "quicktime-ish" way (or smarter way) // to do this for now, to pause, set the speed to zero, // on un-pause, set the speed to "speed" // (and hope that speed != 0...) if (bPause == true) setSpeed(0); else setSpeed(speed); } //------------------------------------ void ofQtVideoPlayer::setUseTexture(bool bUse){ bUseTexture = bUse; vpd->bUseTexture = bUseTexture; vpd->tex = &tex; } //------------------------------------ void ofQtVideoPlayer::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } Node-path: video/ofQtVideoPlayer.h Node-kind: file Node-action: change Text-content-length: 2868 Text-content-md5: f97d78442e746a38b0c619fe69ff69c9 Content-length: 2868 #ifndef _QT_VIDEO_PLAYER #define _QT_VIDEO_PLAYER #include "ofConstants.h" #include "ofQtUtils.h" #include "ofTexture.h" //------------------------------------------------- // (notes, links, etc) // // intersting technique employed here to get to RGB24 // from YUV2 - worthwhile? // paste.lisp.org/display/1051 //----------------------------- // http://viewcvs.osafoundation.org/chandler/trunk/internal/wx/src/msw/mediactrl.cpp?rev=6281&view=markup // http://developer.apple.com/documentation/QuickTime/INMAC/QT/iqMovieToolbox.34.htm // look for "QTURL_NewMovieFromURL", useful for loading URL based movies.. //------------------------------------------------- // // http://lists.apple.com/archives/QuickTime-API/2002/Feb/msg00118.html // //------------------------------------------------- // // note about callbacks: // // we use here a callback provided by quicktime to see if pixels have actually changed // the callback is "DrawCompleteProc" and int he quicktime code, // is defined as "static pascal OsErr ...." // in windows, I have dropped the pascal declaration as my compiler was // having trouble with that... necessary for mac? // // the alternative is to do what is done in qtVideoGrabber // set the alpha of the top pixel to 0x00 and every idle call // check to see if there are new pixels... #define OF_QT_LOOP_NONE 0x01 #define OF_QT_LOOP_PALINDROME 0x02 #define OF_QT_LOOP_NORMAL 0x03 //--------------------------------------------- // this struct has all the info we need to play 1 movie // kept in a struct, because the callback will // need to reference it... typedef struct { MovieController thePlayer; GWorldPtr offscreenGWorld; Movie moviePtr; Rect movieRect; unsigned char * offscreenGWorldPixels; // 32 bit: argb (qt k32ARGBPixelFormat) unsigned char * pixels; // 24 bit: rgb int w; int h; bool bHavePixelsChanged; ofTexture * tex; // a ptr to the texture we are utilizing bool bUseTexture; // are we using a texture } videoPlayerData; //--------------------------------------------- class ofQtVideoPlayer{ public: ofQtVideoPlayer (); void closeMovie(); bool loadMovie(char * name); void idleMovie(); int width, height; float speed; bool bLoadedMovie; bool isFrameNew(); unsigned char * getPixels(); float getPosition(); float getSpeed(); float getDuration(); void setPosition(float pct); void setVolume(int volume); void setLoopState(int state); void setSpeed(float speed); void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); void setPause(bool bPause); private: //--------------------------- videoPlayerData * vpd; ofTexture tex; bool bUseTexture; }; #endif Revision-number: 21 Prop-content-length: 215 Content-length: 215 K 7 svn:log V 112 zach - fixed ofImage: RGB/BGR issue with COLOR_ALPHA load image. ofGraphics -- small change to ofBitmappedType. K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-02-06T10:28:57.941989Z PROPS-END Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: change Text-content-length: 5567 Text-content-md5: 6e0e8d16fde5932cdcf26337e8a4c203 Content-length: 5567 #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- void ofBackground(int r, int g, int b){ bgColor[0] = (float)r / (float)255.0f; bgColor[1] = (float)g / (float)255.0f; bgColor[2] = (float)b / (float)255.0f; bgColor[3] = 1.0f; } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } //---------------------------------------------------------- void ofEnableAlphaBlending(){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void ofDisableAlphaBlending(){ glDisable(GL_BLEND); } //-------------------------------------------------- void ofDrawBitmapString(char *string, float x, float y){ //--------------------------------------------------- // for now this is fixed to the 8_BY_13 glut character // http://pyopengl.sourceforge.net/documentation/manual/glutBitmapCharacter.3GLUT.html //--------------------------------------------------- char *c; float yOffset = 0; float fontSize = 8.0f; glRasterPos2f(x,y); for (c=string; *c != '\0'; c++) { if(*c == '\n') { yOffset -= (fontSize*1.4); glRasterPos2f(x,y + (int)yOffset); } else if (((int)*c) > 32){ // < 32 = control characters - don't draw // solves a bug with control characters // getting drawn when they ought to not be glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c); } } } //---------------------------------------------------------- void ofSetupScreen(){ int w, h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } Node-path: graphics/ofImage.cpp Node-kind: file Node-action: change Text-content-length: 7792 Text-content-md5: a04139d240204309eb2c52501cec3fc2 Content-length: 7792 #include "ofImage.h" #include "freeImage.h" static bool bFreeImageInited = false; //----------------------------------------- // class freeImageBitmap{ public: FIBITMAP * bmp; //----------------------- freeImageBitmap(){ bmp = NULL; } //----------------------- //swap my image out in a (hopefully) non-memory leakish way void swap(FIBITMAP *dst) { if(dst == NULL) return; if(bmp != NULL) FreeImage_Unload(bmp); bmp = dst; } //----------------------- void setSize(FREE_IMAGE_TYPE image_type, WORD width, WORD height, WORD bpp) { if(bmp == NULL) { FreeImage_Unload(bmp); } bmp = FreeImage_AllocateT(image_type, width, height, bpp); } //----------------------- bool isValid(){ return (bmp != NULL) ? true : false; } }; //---------------------------------------------------------- ofImage::ofImage(){ //----------------------- init free image if necessary if (!bFreeImageInited){ FreeImage_Initialise(); bFreeImageInited = true; } //----------------------- IMG = new freeImageBitmap(); w = h = bpp = 0; type = OF_IMAGE_UNDEFINED; bUseTexture = true; // the default is, yes, use a texture } //---------------------------------------------------------- void ofImage::grabScreen(int _x, int _y, int _w, int _h){ if (IMG->isValid()){ if (!(w == _w && h == _h)){ resize(_w, _h); } unsigned char * pixels = getPixels(); switch (bpp){ case 8: glReadPixels(_x, _y, _w, _h, GL_LUMINANCE,GL_UNSIGNED_BYTE, pixels); break; case 24: glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); break; case 32: glReadPixels(_x, _y, _w, _h, GL_RGBA,GL_UNSIGNED_BYTE, pixels); break; } } else { // assume that this is color.... IMG->setSize(FIT_BITMAP, _w, _h, 24); unsigned char * pixels = getPixels(); glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE,pixels); update(); } } //---------------------------------------------------------- void ofImage::allocate(int _w, int _h, int _type){ int newbpp; switch (_type){ case OF_IMAGE_GRAYSCALE: newbpp = 8; break; case OF_IMAGE_COLOR: newbpp = 24; break; case OF_IMAGE_COLOR_ALPHA: newbpp = 32; break; default: newbpp = 24; break; } IMG->setSize(FIT_BITMAP, _w, _h, newbpp); } //---------------------------------------------------------- void ofImage::update(){ w = FreeImage_GetWidth(IMG->bmp); h = FreeImage_GetHeight(IMG->bmp); bpp = FreeImage_GetBPP(IMG->bmp); switch (bpp){ case 8: type = OF_IMAGE_GRAYSCALE; break; case 24: type = OF_IMAGE_COLOR; break; case 32: type = OF_IMAGE_COLOR_ALPHA; break; default: // if we've got here, something is wrong, the image // is not 8bit, 24bit or 32bit, so let's at least // make it color: setImageType(OF_IMAGE_COLOR); break; } // if we are using a texture and the ofImage is upadate, // allocate (or reallocate) the texture and upload the data if (bUseTexture){ switch (type){ case OF_IMAGE_GRAYSCALE: tex.allocate(w,h,GL_LUMINANCE); tex.loadData(getPixels(), w, h, GL_LUMINANCE); break; case OF_IMAGE_COLOR: tex.allocate(w,h,GL_RGB); tex.loadData(getPixels(), w, h, GL_RGB); break; case OF_IMAGE_COLOR_ALPHA: tex.allocate(w,h,GL_RGBA); tex.loadData(getPixels(), w, h, GL_RGBA); break; } } } //---------------------------------------------------------- void ofImage::loadImage(char * fileName){ bool bLoaded = false; //----------------------------- find the format FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { if(IMG->isValid()) { FreeImage_Unload(IMG->bmp); } IMG->bmp = FreeImage_Load(fif, fileName, 0); bLoaded = true; if(!IMG->isValid()){ bLoaded = false; } } //----------------------------- if (bLoaded){ update(); //--------------- on windows, we need to change BGR to RGB // (also on intel macs? also with RGBA images?) #ifdef TARGET_WIN32 if (type == OF_IMAGE_COLOR){ swapChannels(false); } else if (type == OF_IMAGE_COLOR_ALPHA){ swapChannels(true); } #endif } else { w = h = bpp = 0; } } //---------------------------------------------------------- void ofImage::saveImage(char * fileName){ if (IMG->isValid()){ FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { FreeImage_Save(fif, IMG->bmp, fileName, 0); } } } //---------------------------------------------------------- unsigned char * ofImage::getPixels(){ // be careful! if (IMG->isValid()){ return (unsigned char *)FreeImage_GetBits(IMG->bmp); } else { return NULL; } } //---------------------------------------------------------- void ofImage::resize(int newWidth, int newHeight){ if (IMG->isValid()){ FIBITMAP * scaledBmp = FreeImage_Rescale(IMG->bmp, newWidth, newHeight, FILTER_BICUBIC); IMG->swap(scaledBmp); update(); } } //---------------------------------------------------------- void ofImage::setImageType(int newType){ if (IMG->isValid()){ switch (newType){ //------------------------------------ case OF_IMAGE_GRAYSCALE: if (type != OF_IMAGE_GRAYSCALE){ FIBITMAP * convertedBmp = FreeImage_ConvertToGreyscale(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; //------------------------------------ case OF_IMAGE_COLOR: if (type != OF_IMAGE_COLOR){ FIBITMAP * convertedBmp = FreeImage_ConvertTo24Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR; } break; //------------------------------------ case OF_IMAGE_COLOR_ALPHA: if (type != OF_IMAGE_COLOR_ALPHA){ FIBITMAP * convertedBmp = FreeImage_ConvertTo32Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; } update(); } } //------------------------------------ void ofImage::swapChannels(bool bAlpha){ // this swaps the red and blue channel of an image // turning an bgr image to rgb and vice versa... // needed because of windows byte order... if (IMG->isValid()){ unsigned char * pixels = getPixels(); int nTotalPixels = w*h; unsigned char temp; // unoptimized for now... if (bAlpha == false){ for (int i = 0; i < nTotalPixels; i++){ temp = pixels[i*3]; pixels[i*3] = pixels[i*3 + 2]; pixels[i*3 + 2] = temp; } } else { for (int i = 0; i < nTotalPixels; i++){ temp = pixels[i*4]; pixels[i*4] = pixels[i*4 + 2]; pixels[i*4 + 2] = temp; } } } update(); // this is a redundant hack. please fix me // the thing is we need to update to texture, after the // conversion, but we need to know w, h, type // before the conversion - as it stands now // we update the texture twice... } //------------------------------------ void ofImage::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofImage::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } Node-path: graphics/ofImage.h Node-kind: file Node-action: change Text-content-length: 1279 Text-content-md5: 9a6cf285ed7fe822d93498d056a1c966 Content-length: 1279 #ifndef _OF_IMAGE_H_ #define _OF_IMAGE_H_ #include "ofConstants.h" #include "ofTexture.h" #define OF_IMAGE_GRAYSCALE 0x00 #define OF_IMAGE_COLOR 0x01 #define OF_IMAGE_COLOR_ALPHA 0x02 #define OF_IMAGE_UNDEFINED 0x03 //------------------------- // forward class declaration, something // we will need in order to compile "OF" as a lib // so that you don't need freeImage, quicktime, etc.. class freeImageBitmap; //------------------------- class ofImage { public : ofImage(); void loadImage(char * fileName); void saveImage(char * fileName); void allocate(int w, int h, int type); unsigned char * getPixels(); // up to you to get this right void setImageType(int type); void resize(int newWidth, int newHeight); void grabScreen(int x, int y, int w, int h); // grab pixels from opengl, using glreadpixels int type; // what type of image it is (as above) int w, h, bpp; // w,h, bits per pixel void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); private: void swapChannels(bool bAlpha); void update(); freeImageBitmap * IMG; ofTexture tex; bool bUseTexture; }; #endif Revision-number: 22 Prop-content-length: 168 Content-length: 168 K 7 svn:log V 66 // zach - small changes to get rid of dev-cpp warnings (EOF, etc). K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-02-09T21:35:51.387320Z PROPS-END Node-path: app/ofAppRunner.h Node-kind: file Node-action: change Text-content-length: 363 Text-content-md5: 014bb2be5c34b383c38721f54e6cbb52 Content-length: 363 #ifndef _OF_APP_RUNNER #define _OF_APP_RUNNER #include "ofConstants.h" #include "ofSimpleApp.h" #include "ofGraphics.h" #include "ofUtils.h" void ofSetupOpenGL(int w, int h, int screenMode); // sets up the opengl context! void ofRunApp(ofSimpleApp * OFSA); float ofGetFrameRate(); void ofHideCursor(); void ofShowCursor(); #endif Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: change Text-content-length: 5569 Text-content-md5: c30b661a95177a2715bd58335820c728 Content-length: 5569 #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- void ofBackground(int r, int g, int b){ bgColor[0] = (float)r / (float)255.0f; bgColor[1] = (float)g / (float)255.0f; bgColor[2] = (float)b / (float)255.0f; bgColor[3] = 1.0f; } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } //---------------------------------------------------------- void ofEnableAlphaBlending(){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void ofDisableAlphaBlending(){ glDisable(GL_BLEND); } //-------------------------------------------------- void ofDrawBitmapString(char *string, float x, float y){ //--------------------------------------------------- // for now this is fixed to the 8_BY_13 glut character // http://pyopengl.sourceforge.net/documentation/manual/glutBitmapCharacter.3GLUT.html //--------------------------------------------------- char *c; float yOffset = 0; float fontSize = 8.0f; glRasterPos2f(x,y); for (c=string; *c != '\0'; c++) { if(*c == '\n') { yOffset -= (fontSize*1.4); glRasterPos2f(x,y + (int)yOffset); } else if (((int)*c) > 32){ // < 32 = control characters - don't draw // solves a bug with control characters // getting drawn when they ought to not be glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c); } } } //---------------------------------------------------------- void ofSetupScreen(){ int w, h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } Node-path: graphics/ofTexture.cpp Node-kind: file Node-action: change Text-content-length: 3214 Text-content-md5: 3707ec4a63c416945085b14d85892bf7 Content-length: 3214 #include "ofTexture.h" #include "ofUtils.h" // for nextPow2() //---------------------------------------------------------- ofTexture::ofTexture(){ texName = new unsigned int[1]; texName[0] = 0; } //---------------------------------------------------------- void ofTexture::clear(){ // try to free up the texture memory so we don't reallocate // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/deletetextures.html if (texName[0] != 0){ glDeleteTextures(1, (GLuint *)texName); } } //---------------------------------------------------------- void ofTexture::allocate(int w, int h, int internalGlDataType){ // can pass in anything (320x240) (10x5) // here we make it power of 2 for opengl (512x256), (16x8) tex_w = ofNextPow2(w); tex_h = ofNextPow2(h); tex_u = 1.0f; tex_t = 1.0f; // attempt to free the previous bound texture, if we can: clear(); // create the named texture: //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // not necessary, I think glGenTextures(1, (GLuint *)texName); // could be more then one, but for now, just one glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); glTexImage2D(GL_TEXTURE_2D, 0, internalGlDataType, tex_w, tex_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); // init to black... glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); } void ofTexture::loadData(unsigned char * data, int w, int h, int glDataType){ // can we allow for uploads bigger then texutre and // just take as much as the texture can? // // ie: // int uploadW = MIN(w, tex_w); // int uploadH = MIN(h, tex_h); // but with a "step" size of w? // check "glTexSubImage2D" if ( w > tex_w || h > tex_h) { printf("image data too big - bailing \n"); return; } //compute new tex co-ords based on the ratio of data's w, h to texture w,h; tex_t = (float)w / (float)tex_w; tex_u = (float)h / (float)tex_h; // update the texture image: glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); glTexSubImage2D(GL_TEXTURE_2D,0,0,0,w,h,glDataType,GL_UNSIGNED_BYTE,data); glDisable(GL_TEXTURE_2D); } //================================================================================= void ofTexture::draw(float x, float y, float w, float h){ glEnable(GL_TEXTURE_2D); // bind the texture glBindTexture( GL_TEXTURE_2D, (GLuint)texName[0] ); float px0 = x ; // up to you to get the aspect ratio right float py0 = y ; float px1 = x+w; float py1 = y+h; glBegin( GL_QUADS ); glTexCoord2f(0.0, 0.0); glVertex3f(px0, py0,0); glTexCoord2f(tex_t, 0.0); glVertex3f(px1, py0,0); glTexCoord2f(tex_t, tex_u); glVertex3f(px1, py1,0); glTexCoord2f(0.0, tex_u); glVertex3f(px0, py1,0); glEnd(); glDisable(GL_TEXTURE_2D); } Node-path: graphics/ofTexture.h Node-kind: file Node-action: change Text-content-length: 447 Text-content-md5: c94b33c482bb2c608d84bfed870c8c56 Content-length: 447 #ifndef _IMAGE_TEXTURE_H_ #define _IMAGE_TEXTURE_H_ #include "ofConstants.h" class ofTexture { public : ofTexture(); void allocate(int w, int h, int internalGlDataType); void clear(); void loadData(unsigned char * data, int w, int h, int glDataType); void draw(float x, float y, float w, float h); float tex_t, tex_u; private: int tex_w, tex_h; unsigned int * texName; }; #endif Node-path: sound/ofAudio.cpp Node-kind: file Node-action: change Text-content-length: 3659 Text-content-md5: c692ecefc63e87c78b0ff340a5b641c6 Content-length: 3659 #include "ofAudio.h" #include "rtAudio.h" //----------------------------------- static variables: static ofSimpleApp * OFSAptr; RtAudio * audio; int nInputChannels; int nOutputChannels; //----------------------------------- int receiveAudioBufferAndCallSimpleApp(char *buffer, int bufferSize, void *data); int receiveAudioBufferAndCallSimpleApp(char *buffer, int bufferSize, void *data){ // rtAudio uses a system by which the audio // can be of different formats // char, float, etc. // we choose float float * fPtr = (float *)buffer; // [zach] memset output to zero before output call // this is because of how rtAudio works: duplex w/ one callback // you need to cut in the middle. if the simpleApp // doesn't produce audio, we pass silence instead of duplex... if (nInputChannels > 0){ OFSAptr->audioReceived(fPtr, bufferSize, nInputChannels); memset(fPtr, 0, bufferSize * nInputChannels * sizeof(float)); } if (nOutputChannels > 0) OFSAptr->audioRequested(fPtr, bufferSize, nOutputChannels); return 0; } //--------------------------------------------------------- void ofAudioSetup(int nOutputs, int nInputs, ofSimpleApp * OFSA){ ofAudioSetup(nOutputs, nInputs, OFSA, 44100, 256, 4); } //--------------------------------------------------------- void ofAudioSetup(int nOutputs, int nInputs, ofSimpleApp * OFSA, int sampleRate, int bufferSize, int nBuffers){ nInputChannels = nInputs; nOutputChannels = nOutputs; int device = 0; // default OFSAptr = OFSA; try { audio = new RtAudio(); audio->openStream( device, nOutputs, device, nInputs, RTAUDIO_FLOAT32, sampleRate, &bufferSize, nBuffers); } catch (RtError &error) { error.printMessage(); //std::exit(EXIT_FAILURE); // need case here } try { audio->setStreamCallback(&receiveAudioBufferAndCallSimpleApp, (void *)NULL); audio->startStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioStopStream(){ try { audio->stopStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioStartStream(){ try{ audio->startStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioEndStream(){ try { audio->stopStream(); audio->closeStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioEnumerateDevices(){ RtAudio *audioTemp = 0; try { audioTemp = new RtAudio(); } catch (RtError &error) { error.printMessage(); } int devices = audioTemp->getDeviceCount(); RtAudioDeviceInfo info; for (int i=1; i<=devices; i++) { try { info = audioTemp->getDeviceInfo(i); } catch (RtError &error) { error.printMessage(); break; } std::cout << "device = " << i << " (" << info.name << ")\n"; if (info.isDefault) std::cout << "***** default ***** \n"; std::cout << "maximum output channels = " << info.outputChannels << "\n"; std::cout << "maximum input channels = " << info.inputChannels << "\n"; std::cout << "-----------------------------------------\n"; } delete audioTemp; } /* try { // Stop and close the stream audio->stopStream(); audio->closeStream(); } catch (RtError &error) { error.printMessage(); } */ Node-path: video/ofQtVideoGrabber.cpp Node-kind: file Node-action: change Text-content-length: 7672 Text-content-md5: 5057af0163dc20c1a97f3c6b94800ac9 Content-length: 7672 #include "ofQtVideoGrabber.h" //-------------------------------------------------------------------- Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon); Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon){ #pragma unused(theDialog, itemHit) Boolean handled = false; if ((theEvent->what == updateEvt) && ((WindowPtr) theEvent->message == (WindowPtr) refCon)) { BeginUpdate ((WindowPtr) refCon); EndUpdate ((WindowPtr) refCon); handled = true; } return (handled); } //-------------------------------------------------------------------- ofQtVideoGrabber::ofQtVideoGrabber(){ initializeQuicktime(); vgd = new videoGrabberData(); bVerbose = false; bSgGrabberInited = false; bUseTexture = true; } //-------------------------------------------------------------------- void ofQtVideoGrabber::setVerbose(bool bTalkToMe){ bVerbose = bTalkToMe; } //--------------------------------------------------------------------------- unsigned char * ofQtVideoGrabber::getPixels(){ return vgd->pixels; } //--------------------------------------------------------------------------- bool ofQtVideoGrabber::isFrameNew(){ if (bSgGrabberInited == true){ bool bNew = false; if (vgd->bHavePixelsChanged == true){ bNew = true; vgd->bHavePixelsChanged = false; } return bNew; } else { return false; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::grabFrame(){ if (bSgGrabberInited == true){ SGIdle(vgd->gSeqGrabber); // set the top pixel alpha = 0, so we can know if it // was a new frame or not.. // or else we will process way more than necessary // (ie opengl is running at 60fps +, capture at 30fps) if (vgd->offscreenGWorldPixels[0] != 0x00){ vgd->offscreenGWorldPixels[0] = 0x00; vgd->bHavePixelsChanged = true; convertPixels(vgd->offscreenGWorldPixels, vgd->pixels, vgd->w, vgd->h); if (bUseTexture){ tex.loadData(vgd->pixels, vgd->w, vgd->h, GL_RGB); } } } } //-------------------------------------------------------------------- void ofQtVideoGrabber::close(){ //thanks eloi! if (vgd->gSeqGrabber != 0L){ CloseComponent (vgd->gSeqGrabber); vgd->gSeqGrabber = 0L; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::videoSettings(void){ Rect curBounds, curVideoRect; ComponentResult err; // Get our current state err = SGGetChannelBounds (vgd->gVideoChannel, &curBounds); if (err != noErr){ printf("Error in SGGetChannelBounds \n"); return; } err = SGGetVideoRect (vgd->gVideoChannel, &curVideoRect); if (err != noErr){ printf("Error in SGGetVideoRect \n"); return; } // Pause err = SGPause (vgd->gSeqGrabber, true); if (err != noErr){ printf("Error in SGPause\n"); return; } #ifdef TARGET_OSX static SGModalFilterUPP gSeqGrabberModalFilterUPP = NewSGModalFilterUPP(SeqGrabberModalFilterUPP); ComponentResult result = SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, 0L, gSeqGrabberModalFilterUPP, nil); if (err != noErr){ printf("error in dialogue\n"); return; } #else SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, 0L, NULL, 0); #endif #ifdef TARGET_WIN32 SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); #endif SGPause (vgd->gSeqGrabber, false); } //-------------------------------------------------------------------- void ofQtVideoGrabber::initGrabber(int w, int h){ vgd->w = w; vgd->h = h; ComponentDescription theDesc; Component sgCompID = NULL; char name[256]; char info[256]; Handle componentName=NULL; Handle componentInfo=NULL; ComponentDescription info_description; componentName=NewHandle(sizeof(name)); componentInfo=NewHandle(sizeof(info)); if (bVerbose == true){ printf ("\n"); printf ("-------------------------------------\n"); printf ("attempting to set up ofQtVideoGrabber\n"); } vgd->gSeqGrabber = 0L; vgd->gVideoChannel = 0L; theDesc.componentType = SeqGrabComponentType; theDesc.componentSubType = 0L; theDesc.componentManufacturer = 0L; theDesc.componentFlags = 0L; theDesc.componentFlagsMask = 0L; sgCompID = FindNextComponent(sgCompID, &theDesc); while (sgCompID != 0){ GetComponentInfo(sgCompID,&info_description, componentName, componentInfo,nil); if (bVerbose == true){ printf("found a device to capture with \n"); printf("Type: %s\n", &info_description.componentType); printf("Manufacturer: %s\n", &info_description.componentManufacturer); printf("Name: %s\n", *componentName ? p2cstr((StringPtr)*componentName) : "-" ); printf("Name: %s\n", *componentInfo ? p2cstr((StringPtr)*componentInfo) : "-"); } vgd->gSeqGrabber = OpenComponent(sgCompID); sgCompID = FindNextComponent(sgCompID, &theDesc); } //-------------------------------------------- // setup the gworld and digitizing. OSStatus err; err = SGInitialize(vgd->gSeqGrabber); if (err != noErr){ printf("***** Error in SGInitialize (check cam drivers, vdig or winvidg)*****\n"); return; } MacSetRect(&(vgd->videoRect),0, 0, w, h); //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vgd->offscreenGWorldPixels = (unsigned char*)malloc(4 * w * h + 32); vgd->pixels = new unsigned char[w*h*3]; QTNewGWorldFromPtr (&vgd->videogworld, k32ARGBPixelFormat, &vgd->videoRect, NULL, NULL, 0, vgd->offscreenGWorldPixels, 4 * w); LockPixels(GetGWorldPixMap(vgd->videogworld)); SetGWorld (vgd->videogworld, NULL); err = SGSetGWorld(vgd->gSeqGrabber, vgd->videogworld, nil); if ( err != noErr ) goto bail; err = SGNewChannel(vgd->gSeqGrabber, VideoMediaType, &vgd->gVideoChannel); if ( err != noErr ) goto bail; err = SGSetDataRef(vgd->gSeqGrabber, 0, 0, seqGrabDontMakeMovie); if ( err != noErr ) goto bail; err = SGSetChannelUsage(vgd->gVideoChannel,seqGrabPreview); if ( err != noErr ) goto bail; err = SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); if ( err != noErr ) goto bail; if (SGSetFrameRate(vgd->gVideoChannel,30) != noErr) printf( "error setting 30 fps \n"); else{ if (bVerbose == true){ printf ("set to capture at 30 fps \n"); } } err = SGPrepare(vgd->gSeqGrabber, false, true); if ( err != noErr ) goto bail; err = SGStartPreview(vgd->gSeqGrabber); if ( err != noErr ) goto bail; if (bVerbose){ printf ("end setup ofQtVideoGrabber\n"); printf ("-------------------------------------\n"); printf ("\n"); } if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.allocate(w,h,GL_RGB); memset(vgd->pixels, 0, w*h*3); tex.loadData(vgd->pixels, w, h, GL_RGB); } bSgGrabberInited = true; return; // good catch eloi/theo //--------------------- (bail) something's wrong ----- bail: if (bVerbose){ printf ("***** ofQtVideoGrabber error *****\n"); printf ("-------------------------------------\n"); printf ("\n"); } bSgGrabberInited = false; return; } //------------------------------------ void ofQtVideoGrabber::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofQtVideoGrabber::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } Node-path: video/ofQtVideoPlayer.h Node-kind: file Node-action: change Text-content-length: 2897 Text-content-md5: 1b39c09f70d3b609222c074e0dc9969f Content-length: 2897 #ifndef _QT_VIDEO_PLAYER #define _QT_VIDEO_PLAYER #include "ofConstants.h" #include "ofQtUtils.h" #include "ofTexture.h" //------------------------------------------------- // (notes, links, etc) // // intersting technique employed here to get to RGB24 // from YUV2 - worthwhile? // paste.lisp.org/display/1051 //----------------------------- // http://viewcvs.osafoundation.org/chandler/trunk/internal/wx/src/msw/mediactrl.cpp?rev=6281&view=markup // http://developer.apple.com/documentation/QuickTime/INMAC/QT/iqMovieToolbox.34.htm // look for "QTURL_NewMovieFromURL", useful for loading URL based movies.. //------------------------------------------------- // // http://lists.apple.com/archives/QuickTime-API/2002/Feb/msg00118.html // //------------------------------------------------- // // note about callbacks: // // we use here a callback provided by quicktime to see if pixels have actually changed // the callback is "DrawCompleteProc" and int he quicktime code, // is defined as "static pascal OsErr ...." // in windows, I have dropped the pascal declaration as my compiler was // having trouble with that... necessary for mac? // // the alternative is to do what is done in qtVideoGrabber // set the alpha of the top pixel to 0x00 and every idle call // check to see if there are new pixels... #define OF_QT_LOOP_NONE 0x01 #define OF_QT_LOOP_PALINDROME 0x02 #define OF_QT_LOOP_NORMAL 0x03 //--------------------------------------------- // this struct has all the info we need to play 1 movie // kept in a struct, because the callback will // need to reference it... typedef struct { MovieController thePlayer; GWorldPtr offscreenGWorld; Movie moviePtr; Rect movieRect; unsigned char * offscreenGWorldPixels; // 32 bit: argb (qt k32ARGBPixelFormat) unsigned char * pixels; // 24 bit: rgb int w; int h; bool bHavePixelsChanged; ofTexture * tex; // a ptr to the texture we are utilizing bool bUseTexture; // are we using a texture } videoPlayerData; //--------------------------------------------- class ofQtVideoPlayer{ public: ofQtVideoPlayer (); void closeMovie(); bool loadMovie(char * name); void idleMovie(); // rename to updateMovie? int width, height; float speed; bool bLoadedMovie; bool isFrameNew(); unsigned char * getPixels(); float getPosition(); float getSpeed(); float getDuration(); void setPosition(float pct); void setVolume(int volume); void setLoopState(int state); void setSpeed(float speed); void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); void setPause(bool bPause); private: //--------------------------- videoPlayerData * vpd; ofTexture tex; bool bUseTexture; }; #endif Revision-number: 23 Prop-content-length: 200 Content-length: 200 K 7 svn:log V 98 zach - fixes for the glutFullScreen / visual studio bug. We go fullscreen on the first frame now. K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-02-27T10:58:30.762289Z PROPS-END Node-path: app/ofAppGlutGlue.h Node-kind: file Node-action: change Text-content-length: 2633 Text-content-md5: 15a6944e1e70d1ef6e68e4c24bfb28c1 Content-length: 2633 void display(void); void mouse_cb(int button, int state, int x, int y); void motion_cb(int x, int y); void passive_motion_cb(int x, int y); void idle_cb(void); void keyboard_cb(unsigned char key, int x, int y); void special_key_cb(int key, int x, int y) ; static int buttonInUse = 0; //-------------------------------- static float timeNow, timeThen, fps; static int nFrames; //------------------------------------------------------------ void display(void){ //-------------------------------- // when I had "glutFullScreen()" // in the initOpenGl, I was gettings a "heap" allocation error // when debugging via visual studio. putting it here, changes that. // maybe it's voodoo, or I am getting rid of the problem // by removing something unrelated, but everything seems // to work if I put fullscreen on the first frame of display. if (nFrames == 0 && windowMode == OF_FULLSCREEN) glutFullScreen(); ofGetWindowSize( &width, &height ); height = height > 0 ? height : 1; // set viewport, clear the screen glViewport( 0, 0, width, height ); float * bgPtr = ofBgColorPtr(); glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ofSetupScreen(); OFSAptr->draw(); glutSwapBuffers(); // -------------- fps calculation: timeNow = ofGetElapsedTimef(); if( (timeNow-timeThen) > 0.05f || nFrames == 0 ) { fps = (double)nFrames / (timeNow-timeThen); timeThen = timeNow; nFrames = 0; ofFrameRate = 0.9f * ofFrameRate + 0.1f * fps; } nFrames++; // -------------- } //------------------------------------------------------------ void mouse_cb(int button, int state, int x, int y) { if (state == GLUT_DOWN) { OFSAptr->mousePressed(x, height - y, button); } else if (state == GLUT_UP) { OFSAptr->mouseReleased(); } buttonInUse = button; } //------------------------------------------------------------ void motion_cb(int x, int y) { OFSAptr->mouseDragged(x, height - y, buttonInUse); } //------------------------------------------------------------ void passive_motion_cb(int x, int y) { OFSAptr->mouseMoved(x, height - y); } //------------------------------------------------------------ void idle_cb(void) { OFSAptr->update(); glutPostRedisplay(); } //------------------------------------------------------------ void keyboard_cb(unsigned char key, int x, int y) { OFSAptr->keyPressed((int)key); if (key == 27){ // "escape" OF_EXIT_APP(0); } } //------------------------------------------------------------ void special_key_cb(int key, int x, int y) { OFSAptr->keyPressed((int)key); } Node-path: app/ofAppRunner.cpp Node-kind: file Node-action: change Text-content-length: 1847 Text-content-md5: 4defda8d61c101866ab79fa44b5d8c22 Content-length: 1847 #include "ofAppRunner.h" //======================================================================== // static variables: static ofSimpleApp * OFSAptr; int windowMode; bool bMousePressed; bool bRightButton; int width, height; static float ofFrameRate; //======================================================================== // callbacks: #include "ofAppGlutGlue.h" //-------------------------------------- void ofSetupOpenGL(int w, int h, int screenMode){ int argc = 1; char *argv = "openframeworks"; char **vptr = &argv; glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA); glutInit(&argc, vptr); //if (screenMode == OF_WINDOW) glutInitWindowSize(w, h); glutCreateWindow(""); windowMode = screenMode; ofBackground(200,200,200); // default bg color ofSetColor(0xFFFFFF); // default draw color // used to be black, but // black + texture = black // so maybe grey bg // and "white" fg color // as default works the best... } //-------------------------------------- void ofRunApp(ofSimpleApp * OFSA){ OFSAptr = OFSA; //---------------------- // setup the callbacks glutMouseFunc(mouse_cb); glutMotionFunc(motion_cb); glutPassiveMotionFunc(passive_motion_cb); glutIdleFunc(idle_cb); glutDisplayFunc(display); glutKeyboardFunc(keyboard_cb); glutSpecialFunc(special_key_cb); //---------------------- OFSA->setup(); glutMainLoop(); } //-------------------------------------- float ofGetFrameRate(){ return ofFrameRate; } //-------------------------------------- void ofHideCursor(){ glutSetCursor(GLUT_CURSOR_NONE); } //-------------------------------------- void ofShowCursor(){ glutSetCursor(GLUT_CURSOR_RIGHT_ARROW); } Revision-number: 24 Prop-content-length: 218 Content-length: 218 K 7 svn:log V 115 zach - ofTexture border bug / put in the % offset for texel option. OfImage fixes for getting continuous pixels. K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-02-27T11:02:01.050888Z PROPS-END Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: change Text-content-length: 5943 Text-content-md5: cbb8864a715140a65fb4360bfefea900 Content-length: 5943 #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- void ofBackground(int r, int g, int b){ bgColor[0] = (float)r / (float)255.0f; bgColor[1] = (float)g / (float)255.0f; bgColor[2] = (float)b / (float)255.0f; bgColor[3] = 1.0f; } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b, int _a){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); float a = (float)_a / 255.0f; a = MAX(0,MIN(a,1.0f)); glColor4f(r,g,b,a); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } //---------------------------------------------------------- void ofEnableAlphaBlending(){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void ofDisableAlphaBlending(){ glDisable(GL_BLEND); } //-------------------------------------------------- void ofDrawBitmapString(char *string, float x, float y){ //--------------------------------------------------- // for now this is fixed to the 8_BY_13 glut character // http://pyopengl.sourceforge.net/documentation/manual/glutBitmapCharacter.3GLUT.html //--------------------------------------------------- char *c; float yOffset = 0; float fontSize = 8.0f; glRasterPos2f(x,y); for (c=string; *c != '\0'; c++) { if(*c == '\n') { yOffset -= (fontSize*1.7); glRasterPos2f(x,y + (int)yOffset); } else if (((int)*c) >= 32){ // < 32 = control characters - don't draw // solves a bug with control characters // getting drawn when they ought to not be glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c); } } } //---------------------------------------------------------- void ofSetupScreen(){ int w, h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } Node-path: graphics/ofGraphics.h Node-kind: file Node-action: change Text-content-length: 1171 Text-content-md5: b3ff3d279fe7634884e57e9603aeaf62 Content-length: 1171 #ifndef OF_GEOM #define OF_GEOM #include "ofConstants.h" #define CIRC_RESOLUTION 22 // 22 pts for a circle... // bg color float * ofBgColorPtr(); void ofBackground(int r, int g, int b); // geometry void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3); void ofCircle(float x,float y, float radius); void ofEllipse(float x, float y, float width, float height); void ofLine(float x1,float y1,float x2,float y2); void ofRect(float x1,float y1,float w, float h); void ofSetCircleResolution(int res); // if there 22 is a problem, you can change it here // drawing options void ofNoFill(); void ofFill(); // color options void ofSetColor(int r, int g, int b); // 0-255 void ofSetColor(int r, int g, int b, int a); // 0-255 void ofSetColor(int hexColor); // hex, like web 0xFF0033; // transparency void ofEnableAlphaBlending(); // this just turns on and off opengl blending, the common mode void ofDisableAlphaBlending(); // bitmapped type // ** note, this uses glDrawPixels and may be S L 0 W on some graphics cards void ofDrawBitmapString( char *string, float x, float y); // screen coordinate things... void ofSetupScreen(); #endif Node-path: graphics/ofImage.cpp Node-kind: file Node-action: change Text-content-length: 9112 Text-content-md5: 77c4bdd32b8884719b78ba218541935b Content-length: 9112 #include "ofImage.h" #include "freeImage.h" static bool bFreeImageInited = false; //----------------------------------------- // class freeImageBitmap{ public: FIBITMAP * bmp; // when OF users ask for pixels // we will get them contiguous memory // ie, non-aligned // see the pixel access chapter of the freeImage pdf // these pixel will also be RGB // on both platforms // bmp will be RGB / BGR depending // on the endianess of the platform. unsigned char * pixels; //----------------------- freeImageBitmap(){ bmp = NULL; } //----------------------- //swap my image out in a (hopefully) non-memory leakish way void swap(FIBITMAP *dst) { if(dst == NULL) return; if(bmp != NULL) FreeImage_Unload(bmp); bmp = dst; } //----------------------- void setSize(FREE_IMAGE_TYPE image_type, WORD width, WORD height, WORD bpp) { if(bmp == NULL) { FreeImage_Unload(bmp); } bmp = FreeImage_AllocateT(image_type, width, height, bpp); } //----------------------- bool isValid(){ return (bmp != NULL) ? true : false; } }; //---------------------------------------------------------- ofImage::ofImage(){ //----------------------- init free image if necessary if (!bFreeImageInited){ FreeImage_Initialise(); bFreeImageInited = true; } //----------------------- IMG = new freeImageBitmap(); width = height = bpp = 0; type = OF_IMAGE_UNDEFINED; bUseTexture = true; // the default is, yes, use a texture } //---------------------------------------------------------- void ofImage::grabScreen(int _x, int _y, int _w, int _h){ if (IMG->isValid()){ if (!(width == _w && height == _h)){ resize(_w, _h); } unsigned char * pixels = (unsigned char *)FreeImage_GetBits(IMG->bmp); switch (bpp){ case 8: glReadPixels(_x, _y, _w, _h, GL_LUMINANCE,GL_UNSIGNED_BYTE, pixels); break; case 24: #ifdef TARGET_WIN32 glReadPixels(_x, _y, _w, _h, GL_BGR_EXT,GL_UNSIGNED_BYTE, pixels); #else glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); #endif break; case 32: glReadPixels(_x, _y, _w, _h, GL_RGBA,GL_UNSIGNED_BYTE, pixels); break; } update(); } else { // assume that this is color.... IMG->setSize(FIT_BITMAP, _w, _h, 24); unsigned char * pixels = (unsigned char *)FreeImage_GetBits(IMG->bmp); #ifdef TARGET_WIN32 glReadPixels(_x, _y, _w, _h, GL_BGR_EXT,GL_UNSIGNED_BYTE, pixels); #else glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); #endif update(); } } //---------------------------------------------------------- void ofImage::allocate(int _w, int _h, int _type){ int newbpp; switch (_type){ case OF_IMAGE_GRAYSCALE: newbpp = 8; break; case OF_IMAGE_COLOR: newbpp = 24; break; case OF_IMAGE_COLOR_ALPHA: newbpp = 32; break; default: newbpp = 24; break; } IMG->setSize(FIT_BITMAP, _w, _h, newbpp); } //---------------------------------------------------------- void ofImage::update(){ width = FreeImage_GetWidth(IMG->bmp); height = FreeImage_GetHeight(IMG->bmp); bpp = FreeImage_GetBPP(IMG->bmp); switch (bpp){ case 8: type = OF_IMAGE_GRAYSCALE; break; case 24: type = OF_IMAGE_COLOR; break; case 32: type = OF_IMAGE_COLOR_ALPHA; break; default: // if we've got here, something is wrong, the image // is not 8bit, 24bit or 32bit, so let's at least // make it color: setImageType(OF_IMAGE_COLOR); break; } //---------------------------------- // now, since the "freeImage" memory is padded // (see freeImage392.pdf - "Pixel access functions") // lets get the data into contiguous memory - to make it easier // for folks to work with... delete IMG->pixels; // delete anything that might have existed int byteCount = bpp / 8; // bytes ber pixel (not bits per pixel) IMG->pixels = new unsigned char[width*height*byteCount]; //allocate that memory for the image (contiguously) FreeImage_ConvertToRawBits(IMG->pixels, IMG->bmp, width*byteCount, bpp, FI_RGBA_RED_MASK,FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE); // get bits #ifdef TARGET_WIN32 if (type == OF_IMAGE_COLOR) swapChannels(false); if (type == OF_IMAGE_COLOR_ALPHA) swapChannels(true); #endif //---------------------------------- // if we are using a texture and the ofImage is upadate, // allocate (or reallocate) the texture and upload the data // I will upload from the contguous memory, and use pixelStorei to // make sure opengl knows I am contiguous. if (bUseTexture){ switch (type){ case OF_IMAGE_GRAYSCALE: tex.allocate(width,height,GL_LUMINANCE); tex.loadData(IMG->pixels, width,height, GL_LUMINANCE); break; case OF_IMAGE_COLOR: tex.allocate(width,height,GL_RGB); tex.loadData(IMG->pixels, width,height, GL_RGB); break; case OF_IMAGE_COLOR_ALPHA: tex.allocate(width,height,GL_RGBA); tex.loadData(IMG->pixels, width,height, GL_RGBA); break; } } } //---------------------------------------------------------- void ofImage::loadImage(char * fileName){ bool bLoaded = false; //----------------------------- find the format FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { if(IMG->isValid()) { FreeImage_Unload(IMG->bmp); } IMG->bmp = FreeImage_Load(fif, fileName, 0); bLoaded = true; if(!IMG->isValid()){ bLoaded = false; } } //----------------------------- if (bLoaded){ update(); } else { width = height = bpp = 0; } } //---------------------------------------------------------- void ofImage::saveImage(char * fileName){ if (IMG->isValid()){ FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { FreeImage_Save(fif, IMG->bmp, fileName, 0); } } } //---------------------------------------------------------- unsigned char * ofImage::getPixels(){ // be careful! might not be allocated. you need to check for null... if (IMG->isValid()){ return (unsigned char *)IMG->pixels; } else { return NULL; } } //---------------------------------------------------------- void ofImage::resize(int newWidth, int newHeight){ if (IMG->isValid()){ FIBITMAP * scaledBmp = FreeImage_Rescale(IMG->bmp, newWidth, newHeight, FILTER_BICUBIC); IMG->swap(scaledBmp); update(); } } //---------------------------------------------------------- void ofImage::setImageType(int newType){ if (IMG->isValid()){ switch (newType){ //------------------------------------ case OF_IMAGE_GRAYSCALE: if (type != OF_IMAGE_GRAYSCALE){ FIBITMAP * convertedBmp = FreeImage_ConvertToGreyscale(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; //------------------------------------ case OF_IMAGE_COLOR: if (type != OF_IMAGE_COLOR){ FIBITMAP * convertedBmp = FreeImage_ConvertTo24Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR; } break; //------------------------------------ case OF_IMAGE_COLOR_ALPHA: if (type != OF_IMAGE_COLOR_ALPHA){ FIBITMAP * convertedBmp = FreeImage_ConvertTo32Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR_ALPHA; } break; } update(); } } //------------------------------------ void ofImage::swapChannels(bool bAlpha){ // this swaps the red and blue channel of an image // turning an bgr image to rgb and vice versa... // needed because of windows byte order... if (IMG->isValid()){ unsigned char * pixels = IMG->pixels; unsigned char temp; int totalPixels = width*height; // unoptimized for now... if (bAlpha == false){ for (int i = 0; i < totalPixels; i++){ temp = pixels[i*3 + 2]; pixels[i*3 + 2] = pixels[i*3]; pixels[i*3] = temp; } } else { for (int i = 0; i < totalPixels; i++){ temp = pixels[i*4]; pixels[i*4] = pixels[i*4 + 2]; pixels[i*4 + 2] = temp; } } } } //------------------------------------ void ofImage::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofImage::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } //------------------------------------ void ofImage::draw(float x, float y){ draw(x,y,width,height); } Node-path: graphics/ofImage.h Node-kind: file Node-action: change Text-content-length: 1334 Text-content-md5: e418a8d8f6ff6d5a7ec1fb8bb7caa8b4 Content-length: 1334 #ifndef _OF_IMAGE_H_ #define _OF_IMAGE_H_ #include "ofConstants.h" #include "ofTexture.h" #define OF_IMAGE_GRAYSCALE 0x00 #define OF_IMAGE_COLOR 0x01 #define OF_IMAGE_COLOR_ALPHA 0x02 #define OF_IMAGE_UNDEFINED 0x03 //------------------------- // forward class declaration, something // we will need in order to compile "OF" as a lib // so that you don't need freeImage, quicktime, etc.. class freeImageBitmap; //------------------------- class ofImage { public : ofImage(); void loadImage(char * fileName); void saveImage(char * fileName); void allocate(int w, int h, int type); unsigned char * getPixels(); // up to you to get this right void setImageType(int type); void resize(int newWidth, int newHeight); void grabScreen(int x, int y, int w, int h); // grab pixels from opengl, using glreadpixels int type; // what type of image it is (as above) int width, height, bpp; // w,h, bits per pixel void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); void draw(float x, float y); private: void swapChannels(bool bAlpha); void update(); freeImageBitmap * IMG; ofTexture tex; bool bUseTexture; }; #endif Node-path: graphics/ofTexture.cpp Node-kind: file Node-action: change Text-content-length: 4909 Text-content-md5: ca12ac1bef1995415f334ed3341621e5 Content-length: 4909 #include "ofTexture.h" #include "ofUtils.h" // for nextPow2() //---------------------------------------------------------- ofTexture::ofTexture(){ texName = new unsigned int[1]; texName[0] = 0; } //---------------------------------------------------------- void ofTexture::clear(){ // try to free up the texture memory so we don't reallocate // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/deletetextures.html if (texName[0] != 0){ glDeleteTextures(1, (GLuint *)texName); } } //---------------------------------------------------------- void ofTexture::allocate(int w, int h, int internalGlDataType){ // can pass in anything (320x240) (10x5) // here we make it power of 2 for opengl (512x256), (16x8) tex_w = ofNextPow2(w); tex_h = ofNextPow2(h); tex_u = 1.0f; tex_t = 1.0f; // attempt to free the previous bound texture, if we can: clear(); glGenTextures(1, (GLuint *)texName); // could be more then one, but for now, just one glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); // upload 0 or white pixels.... glTexImage2D(GL_TEXTURE_2D, 0, internalGlDataType, tex_w, tex_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); // init to black... glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); } void ofTexture::loadData(unsigned char * data, int w, int h, int glDataType){ // can we allow for uploads bigger then texture and // just take as much as the texture can? // // ie: // int uploadW = MIN(w, tex_w); // int uploadH = MIN(h, tex_h); // but with a "step" size of w? // check "glTexSubImage2D" if ( w > tex_w || h > tex_h) { printf("image data too big - bailing \n"); return; } //compute new tex co-ords based on the ratio of data's w, h to texture w,h; tex_t = (float)(w) / (float)tex_w; tex_u = (float)(h) / (float)tex_h; // ok this is an ultra annoying bug : // opengl texels and linear filtering - // when we have a sub-image, and we scale it // we can clamp the border pixels to the border, // but the borders of the sub image get mixed with // neighboring pixels... // grr... // // the best solution would be to pad out the image // being uploaded with 2 pixels on all sides, and // recompute tex_t coordinates.. // another option is a gl_arb non pow 2 textures... // the current hack is to alter the tex_t, tex_u calcs, but // that makes the image slightly off... // this is currently being done in draw... // // we need a good solution for this.. // // http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014770#000001 // http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014770#000001 //------------------------ likely, we are uploading continuous data int prevAlignment; glGetIntegerv(GL_UNPACK_ALIGNMENT, &prevAlignment); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // update the texture image: glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); glTexSubImage2D(GL_TEXTURE_2D,0,0,0,w,h,glDataType,GL_UNSIGNED_BYTE,data); glDisable(GL_TEXTURE_2D); //------------------------ back to normal. glPixelStorei(GL_UNPACK_ALIGNMENT, prevAlignment); } //================================================================================= void ofTexture::draw(float x, float y, float w, float h){ glEnable(GL_TEXTURE_2D); // bind the texture glBindTexture( GL_TEXTURE_2D, (GLuint)texName[0] ); float px0 = x ; // up to you to get the aspect ratio right float py0 = y ; float px1 = x+w; float py1 = y+h; // ------------------------------------------------- // complete hack to remove border artifacts. // slightly, slightly alters an image, scaling... // to remove the border. // we need a better solution for this, but // to constantly add a 2 pixel border on all uploaded images // is insane.. float offsetw = 1.0f/(tex_w*2.0f); float offseth = 1.0f/(tex_h*2.0f); // ------------------------------------------------- float tx0 = 0+offsetw; float ty0 = 0+offseth; float tx1 = tex_t - offsetw; float ty1 = tex_u - offseth; glBegin( GL_QUADS ); glTexCoord2f(tx0,ty0); glVertex3f(px0, py0,0); glTexCoord2f(tx1,ty0); glVertex3f(px1, py0,0); glTexCoord2f(tx1,ty1); glVertex3f(px1, py1,0); glTexCoord2f(tx0,ty1); glVertex3f(px0, py1,0); glEnd(); glDisable(GL_TEXTURE_2D); } Node-path: graphics/ofTexture.h Node-kind: file Node-action: change Text-content-length: 478 Text-content-md5: 3780e329a3965aacdc179316610d9e6c Content-length: 478 #ifndef _IMAGE_TEXTURE_H_ #define _IMAGE_TEXTURE_H_ #include "ofConstants.h" class ofTexture { public : ofTexture(); void allocate(int w, int h, int internalGlDataType); void clear(); void loadData(unsigned char * data, int w, int h, int glDataType); void draw(float x, float y, float w, float h); float tex_t, tex_u; private: float offset_x, offset_y; int tex_w, tex_h; unsigned int * texName; }; #endif Node-path: graphics/ofTrueTypeFont.cpp Node-kind: file Node-action: change Text-content-length: 11891 Text-content-md5: 9480bcf10afe96464a3376c0bb40e71f Content-length: 11891 #include "ofTrueTypeFont.h" //-------------------------- #ifdef TARGET_WIN32 #include #include #include #include #include #endif #ifdef TARGET_OSX #include "ft2build.h" #include "freetype.h" #include "ftglyph.h" #include "ftoutln.h" #include "fttrigon.h" #endif //------------------------------------------------------------------ ofTrueTypeFont::ofTrueTypeFont(){ bLoadedOk = false; } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize){ // load anti-aliased, non-full character set: loadFont(filename, fontsize, true, false); } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet){ bLoadedOk = false; bAntiAlised = _bAntiAliased; bFullCharacterSet = _bFullCharacterSet; //--------------- load the library and typeface FT_Library library; if (FT_Init_FreeType( &library )){ printf("PROBLEM WITH FT lib \n"); return; } FT_Face face; if (FT_New_Face( library, filename, 0, &face )) { return; } FT_Set_Char_Size( face,fontsize << 6,fontsize << 6,96,96); lineHeight = fontsize * 1.43f; //------------------------------------------------------ //kerning would be great to support: //printf("FT_HAS_KERNING ? %i \n", FT_HAS_KERNING(face)); //------------------------------------------------------ nCharacters = bFullCharacterSet ? 256 : 128 - NUM_CHARACTER_TO_START; //--------------- initialize character info and textures cps = new charProps[nCharacters]; texNames = new GLuint[nCharacters]; glGenTextures(nCharacters, texNames); //--------------------- load each char ----------------------- for (int i = 0 ; i < nCharacters; i++){ //------------------------------------------ anti aliased or not: if (bAntiAlised == true){ if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph %i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); } else { if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph%i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO); } //------------------------------------------ FT_Bitmap& bitmap= face->glyph->bitmap; // 1 pixel border around the glyph int border = 2; // prepare the texture: int width = ofNextPow2( bitmap.width + border); int height = ofNextPow2( bitmap.rows + border); // ------------------------- this is fixing a bug with small type // ------------------------- appearantly, opengl has trouble with // ------------------------- width or height textures of 1, so we // ------------------------- we just set it to 2... if (width == 1) width = 2; if (height == 1) height = 2; // ------------------------- // info about the character: cps[i].value = i; cps[i].height = face->glyph->bitmap_top; cps[i].width = face->glyph->bitmap.width; cps[i].setWidth = face->glyph->advance.x >> 6; cps[i].topExtent = face->glyph->bitmap.rows; cps[i].leftExtent = face->glyph->bitmap_left; // texture internals cps[i].tTex = (float)bitmap.width / (float)width; cps[i].vTex = (float)bitmap.rows / (float)height; cps[i].xOff = ((1.0+(float)bitmap.width) / (float)width) - cps[i].tTex; cps[i].yOff = ((1.0+(float)bitmap.rows) / (float)height) - cps[i].vTex; /* sanity check: printf("%i %i %i %i %i %i \n", cps[i].value , cps[i].height , cps[i].width , cps[i].setWidth , cps[i].topExtent , cps[i].leftExtent ); */ // Allocate Memory For The Texture Data. unsigned char* expanded_data = new unsigned char[ 2 * width * height]; //-------------------------------- clear data: for(int j=0; j =bitmap.width || j-1>=bitmap.rows) ? 0 : 255; expanded_data[2*(k+j*width)+1] = (k-1>=bitmap.width || j-1>=bitmap.rows) ? 0 : bitmap.buffer[k-1 + bitmap.width*(j-1)]; } } //----------------------------------- } else { //----------------------------------- // true type packs monochrome info in a // 1-bit format, hella funky // here we unpack it: unsigned char *src = bitmap.buffer; for(int j=0; j = nCharacters){ //printf("Error : char (%i) not allocated -- line %d in %s\n", (c + NUM_CHARACTER_TO_START), __LINE__,__FILE__); return; } //----------------------- int cu = c; float height = cps[cu].height; float bwidth = cps[cu].width; float top = cps[cu].topExtent - cps[cu].height; float lextent = cps[cu].leftExtent; float t = cps[cu].tTex; float v = cps[cu].vTex; float xOff = cps[cu].xOff; float yOff = cps[cu].yOff; if (glIsTexture(texNames[cu])) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texNames[cu]); glNormal3f(0, 0, 1); glBegin(GL_QUADS); glTexCoord2d(xOff,yOff); glVertex2f(x + lextent, y + height); glTexCoord2d(xOff,v+yOff); glVertex2f(x + lextent, y-top); glTexCoord2d(t+xOff,v+yOff); glVertex2f(x + lextent + bwidth,y-top); glTexCoord2d(t+xOff,yOff); glVertex2f(x + + lextent + bwidth,y + height); glEnd(); glDisable(GL_TEXTURE_2D); } else { //let's add verbosity levels somewhere... //this error, for example, is kind of annoying to see //all the time: //printf("Warning : texture not bound for character -- line %d in %s\n", __LINE__,__FILE__); } } //----------------------------------------------------------- float ofTrueTypeFont::stringWidth(char *c) { float width = 0; int index = 0; float widthTemp = 0; bool bMultiLine = false; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { width = MAX(width, widthTemp); widthTemp = 0; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; widthTemp += cps[cy].width; } else { widthTemp += cps[cy].setWidth; } } index++; } width = MAX(width, widthTemp); return width; } //----------------------------------------------------------- float ofTrueTypeFont::stringHeight(char *c) { float height = 0; int index = 0; float maxHeight = 0; bool bFirstLineOfMultiLine = true; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { if (bFirstLineOfMultiLine == true){ bFirstLineOfMultiLine = false; height += maxHeight; } else { height += lineHeight; } maxHeight = 0; } else if (c[index] == ' ') { } else { float ht = cps[cy].height; if (ht > maxHeight) maxHeight = ht; } } index++; } height += maxHeight; return height; } //===================================================================== void ofTrueTypeFont::drawString(char *c, float x, float y) { if (!bLoadedOk){ printf("Error : font not allocated -- line %d in %s\n", __LINE__,__FILE__); return; }; // we need transparency to draw text, but we don't know // if that is set up in outside of this function // we "pushAttrib", turn on alpha and "popAttrib" // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushattrib.html // **** note **** // I have read that pushAttrib() is slow, if used often, // maybe there is a faster way to do this? // ie, check if blending is enabled, etc... // glIsEnabled().... glGet()... // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/get.html // ************** // (a) record the current "alpha state, blend func, etc" glPushAttrib(GL_COLOR_BUFFER_BIT); // (b) enable our regular ALPHA blending! glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); float startX = x; int index = 0; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { x = startX; int cy = (int)'M' - NUM_CHARACTER_TO_START; y -= lineHeight; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; x += cps[cy].width; } else { drawChar(cy, x, y); x += cps[cy].setWidth; } } index++; } // (c) return back to the way things were (with blending, blend func, etc) glPopAttrib(); } Revision-number: 25 Prop-content-length: 192 Content-length: 192 K 7 svn:log V 90 zach - visual studio warnings, getting rid of. Added new width / height access functions. K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-02-27T11:02:31.556902Z PROPS-END Node-path: utils/ofConstants.h Node-kind: file Node-action: change Text-content-length: 1833 Text-content-md5: b5a400a43162935604413ffb1b2e3508 Content-length: 1833 #ifndef OF_CONSTANTS #define OF_CONSTANTS //------------------------------- // pc or mac ? // soon: pc, mac or linux... #ifndef __APPLE_CC__ #define TARGET_WIN32 #else #define TARGET_OSX #endif //------------------------------- #ifdef TARGET_WIN32 #include #include "glut.h" #define __WINDOWS_DS__ #define __WINDOWS_MM__ #if (_MSC_VER) // microsoft visual studio #pragma warning(disable : 4996) // disable all deprecation warnings #pragma warning(disable : 4068) // unknown pragmas #pragma warning(disable : 4101) // unreferenced local variable #pragma warning(disable : 4312) // type cast conversion (in qt vp) #pragma warning(disable : 4311) // type cast pointer truncation (qt vp) #endif #endif #ifdef TARGET_OSX #define __MACOSX_CORE__ #include #endif #ifndef __MWERKS__ #define OF_EXIT_APP(val) exit(val); #else #define OF_EXIT_APP(val) std::exit(val); #endif // core: --------------------------- #include #include #include #include #include #ifndef PI #define PI 3.14159265358979323846 #endif #ifndef TWO_PI #define TWO_PI 6.28318530717958647693 #endif #ifndef M_TWO_PI #define M_TWO_PI 6.28318530717958647693 #endif #ifndef FOUR_PI #define FOUR_PI 12.56637061435917295385 #endif #ifndef HALF_PI #define HALF_PI 1.57079632679489661923 #endif #ifndef DEG_TO_RAD #define DEG_TO_RAD (PI/180.0) #endif #ifndef RAD_TO_DEG #define RAD_TO_DEG (180.0/PI) #endif #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #endif #ifndef ABS #define ABS(x) (((x) < 0) ? -(x) : (x)) #endif #define OF_FILLED 0x01 #define OF_OUTLINE 0x02 #define OF_WINDOW 0 #define OF_FULLSCREEN 1 #endif Node-path: utils/ofUtils.cpp Node-kind: file Node-action: change Text-content-length: 3654 Text-content-md5: 8e70bfa9530d3940218dc31087443e7e Content-length: 3654 #include "ofUtils.h" //-------------------------------------------------- int ofNextPow2 ( int a ){ // from nehe.gamedev.net lesson 43 int rval=1; while(rval sw) width = sw-x; if (height+y > sh) height = sh-y; char *ScreenImageBuffer = (char*)malloc(width*height*3); char *flippedScreenImageBuffer = (char*)malloc(width*height*3); char fileName[255]; sprintf(fileName, "screen_grab__%ix%i__%0.4i.raw", width, height, frameNum++); FILE* OutputFile = fopen(fileName, "wb"); glReadPixels(x,y,width,height,GL_RGB,GL_UNSIGNED_BYTE,ScreenImageBuffer); // need to flip image for (int i = 0; i < height; i++) { memcpy(flippedScreenImageBuffer+(sizeof(char)*i*width*3), ScreenImageBuffer+(sizeof(char)*(height-i)*width*3), sizeof(char)*width*3); } fwrite(flippedScreenImageBuffer,width*height*3,1,OutputFile); fclose(OutputFile); free(ScreenImageBuffer); free(flippedScreenImageBuffer); } //-------------------------------------- int ofGetElapsedTimeMillis(){ return (int)(glutGet(GLUT_ELAPSED_TIME)); } //-------------------------------------- float ofGetElapsedTimef(){ return (float)(glutGet(GLUT_ELAPSED_TIME))/1000.0f; } //-------------------------------------- int ofGetMillis(){ // this is a hack now... should be based on system time // time_t is not in millisecond resolution. what to replace this with? // for not millis is elapsed milliseconds, not clock millis... return (int)(glutGet(GLUT_ELAPSED_TIME) % 1000); // http://man.he.net/man2/gettimeofday } //-------------------------------------------------- int ofGetSeconds(){ time_t curr; tm local; time(&curr); local =*(localtime(&curr)); return local.tm_sec; } //-------------------------------------------------- int ofGetMinutes(){ time_t curr; tm local; time(&curr); local =*(localtime(&curr)); return local.tm_min; } //-------------------------------------------------- int ofGetHours(){ time_t curr; tm local; time(&curr); local =*(localtime(&curr)); return local.tm_hour; } Node-path: utils/ofUtils.h Node-kind: file Node-action: change Text-content-length: 477 Text-content-md5: 9edbee7806549c7abbccef5ce19a114f Content-length: 477 #ifndef _OF_UTIL #define _OF_UTIL #include "ofConstants.h" float ofGetFps(void); int ofNextPow2( int input); float ofGetElapsedTimef(); int ofGetElapsedTimeMillis(); int ofGetMillis(); // should be different then above.. int ofGetSeconds(); int ofGetMinutes(); int ofGetHours(); void ofGetWindowSize( int * w, int * h); int ofGetWidth(); int ofGetHeight(); void ofScreenCapRaw(); void ofScreenCapRaw(int x, int y, int w, int h); #endif Revision-number: 26 Prop-content-length: 174 Content-length: 174 K 7 svn:log V 72 zach - added another drawing option that is simpler (just x,y w/out w,h) K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-02-27T11:03:49.935996Z PROPS-END Node-path: video/ofQtVideoGrabber.cpp Node-kind: file Node-action: change Text-content-length: 7820 Text-content-md5: acfdaba0313daba55f26aad0fe2846fc Content-length: 7820 #include "ofQtVideoGrabber.h" //-------------------------------------------------------------------- Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon); Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon){ #pragma unused(theDialog, itemHit) Boolean handled = false; if ((theEvent->what == updateEvt) && ((WindowPtr) theEvent->message == (WindowPtr) refCon)) { BeginUpdate ((WindowPtr) refCon); EndUpdate ((WindowPtr) refCon); handled = true; } return (handled); } //-------------------------------------------------------------------- ofQtVideoGrabber::ofQtVideoGrabber(){ initializeQuicktime(); vgd = new videoGrabberData(); bVerbose = false; bSgGrabberInited = false; bUseTexture = true; } //-------------------------------------------------------------------- void ofQtVideoGrabber::setVerbose(bool bTalkToMe){ bVerbose = bTalkToMe; } //--------------------------------------------------------------------------- unsigned char * ofQtVideoGrabber::getPixels(){ return vgd->pixels; } //--------------------------------------------------------------------------- bool ofQtVideoGrabber::isFrameNew(){ if (bSgGrabberInited == true){ bool bNew = false; if (vgd->bHavePixelsChanged == true){ bNew = true; vgd->bHavePixelsChanged = false; } return bNew; } else { return false; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::grabFrame(){ if (bSgGrabberInited == true){ SGIdle(vgd->gSeqGrabber); // set the top pixel alpha = 0, so we can know if it // was a new frame or not.. // or else we will process way more than necessary // (ie opengl is running at 60fps +, capture at 30fps) if (vgd->offscreenGWorldPixels[0] != 0x00){ vgd->offscreenGWorldPixels[0] = 0x00; vgd->bHavePixelsChanged = true; convertPixels(vgd->offscreenGWorldPixels, vgd->pixels, vgd->w, vgd->h); if (bUseTexture){ tex.loadData(vgd->pixels, vgd->w, vgd->h, GL_RGB); } } } } //-------------------------------------------------------------------- void ofQtVideoGrabber::close(){ //thanks eloi! if (vgd->gSeqGrabber != 0L){ CloseComponent (vgd->gSeqGrabber); vgd->gSeqGrabber = 0L; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::videoSettings(void){ Rect curBounds, curVideoRect; ComponentResult err; // Get our current state err = SGGetChannelBounds (vgd->gVideoChannel, &curBounds); if (err != noErr){ printf("Error in SGGetChannelBounds \n"); return; } err = SGGetVideoRect (vgd->gVideoChannel, &curVideoRect); if (err != noErr){ printf("Error in SGGetVideoRect \n"); return; } // Pause err = SGPause (vgd->gSeqGrabber, true); if (err != noErr){ printf("Error in SGPause\n"); return; } #ifdef TARGET_OSX static SGModalFilterUPP gSeqGrabberModalFilterUPP = NewSGModalFilterUPP(SeqGrabberModalFilterUPP); ComponentResult result = SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, 0L, gSeqGrabberModalFilterUPP, nil); if (err != noErr){ printf("error in dialogue\n"); return; } #else SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, 0L, NULL, 0); #endif #ifdef TARGET_WIN32 SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); #endif SGPause (vgd->gSeqGrabber, false); } //-------------------------------------------------------------------- void ofQtVideoGrabber::initGrabber(int w, int h){ vgd->w = w; vgd->h = h; ComponentDescription theDesc; Component sgCompID = NULL; char name[256]; char info[256]; Handle componentName=NULL; Handle componentInfo=NULL; ComponentDescription info_description; componentName=NewHandle(sizeof(name)); componentInfo=NewHandle(sizeof(info)); if (bVerbose == true){ printf ("\n"); printf ("-------------------------------------\n"); printf ("attempting to set up ofQtVideoGrabber\n"); } vgd->gSeqGrabber = 0L; vgd->gVideoChannel = 0L; theDesc.componentType = SeqGrabComponentType; theDesc.componentSubType = 0L; theDesc.componentManufacturer = 0L; theDesc.componentFlags = 0L; theDesc.componentFlagsMask = 0L; sgCompID = FindNextComponent(sgCompID, &theDesc); while (sgCompID != 0){ GetComponentInfo(sgCompID,&info_description, componentName, componentInfo,nil); if (bVerbose == true){ printf("found a device to capture with \n"); printf("Type: %s\n", &info_description.componentType); printf("Manufacturer: %s\n", &info_description.componentManufacturer); printf("Name: %s\n", *componentName ? p2cstr((StringPtr)*componentName) : "-" ); printf("Name: %s\n", *componentInfo ? p2cstr((StringPtr)*componentInfo) : "-"); } vgd->gSeqGrabber = OpenComponent(sgCompID); sgCompID = FindNextComponent(sgCompID, &theDesc); } //-------------------------------------------- // setup the gworld and digitizing. OSStatus err; err = SGInitialize(vgd->gSeqGrabber); if (err != noErr){ printf("***** Error in SGInitialize (check cam drivers, vdig or winvidg)*****\n"); return; } MacSetRect(&(vgd->videoRect),0, 0, w, h); width = w; height = h; //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vgd->offscreenGWorldPixels = (unsigned char*)malloc(4 * w * h + 32); vgd->pixels = new unsigned char[w*h*3]; QTNewGWorldFromPtr (&vgd->videogworld, k32ARGBPixelFormat, &vgd->videoRect, NULL, NULL, 0, vgd->offscreenGWorldPixels, 4 * w); LockPixels(GetGWorldPixMap(vgd->videogworld)); SetGWorld (vgd->videogworld, NULL); err = SGSetGWorld(vgd->gSeqGrabber, vgd->videogworld, nil); if ( err != noErr ) goto bail; err = SGNewChannel(vgd->gSeqGrabber, VideoMediaType, &vgd->gVideoChannel); if ( err != noErr ) goto bail; err = SGSetDataRef(vgd->gSeqGrabber, 0, 0, seqGrabDontMakeMovie); if ( err != noErr ) goto bail; err = SGSetChannelUsage(vgd->gVideoChannel,seqGrabPreview); if ( err != noErr ) goto bail; err = SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); if ( err != noErr ) goto bail; if (SGSetFrameRate(vgd->gVideoChannel,30) != noErr) printf( "error setting 30 fps \n"); else{ if (bVerbose == true){ printf ("set to capture at 30 fps \n"); } } err = SGPrepare(vgd->gSeqGrabber, false, true); if ( err != noErr ) goto bail; err = SGStartPreview(vgd->gSeqGrabber); if ( err != noErr ) goto bail; if (bVerbose){ printf ("end setup ofQtVideoGrabber\n"); printf ("-------------------------------------\n"); printf ("\n"); } if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.allocate(w,h,GL_RGB); memset(vgd->pixels, 0, w*h*3); tex.loadData(vgd->pixels, w, h, GL_RGB); } bSgGrabberInited = true; return; // good catch eloi/theo //--------------------- (bail) something's wrong ----- bail: if (bVerbose){ printf ("***** ofQtVideoGrabber error *****\n"); printf ("-------------------------------------\n"); printf ("\n"); } bSgGrabberInited = false; return; } //------------------------------------ void ofQtVideoGrabber::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofQtVideoGrabber::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } //------------------------------------ void ofQtVideoGrabber::draw(float _x, float _y){ draw(_x, _y, width, height); } Node-path: video/ofQtVideoGrabber.h Node-kind: file Node-action: change Text-content-length: 2881 Text-content-md5: 1621a97ab54aec1bcad6faffc720feb0 Content-length: 2881 #ifndef _QT_VIDEO_GRABBER #define _QT_VIDEO_GRABBER #include "ofConstants.h" #include "ofQtUtils.h" #include "ofTexture.h" //----------------------------------------- // windows users check out winvdig: // // -[wvdig free]- // http://www.vdig.com/WinVDIG/ // but maybe older versions are better (at least w/ quicktime < 7.0) // try this one: (v 0.99) // www.vjshow.net/vart/WinVDIG_099.exe // uninstall instructions for winvdig in the winvdig forum // http://www.videoscript.com/forum/viewtopic.php?t=21 // // -[wvdig $]- // (also, www.abstractplane.com/products/vdig.jsp) // never tried... // 30 day demo available // // you will need a vdig to see video // try "hackTv" to test if you can use // quicktime to grab video // (pc) ftp://ftp.apple.com/developer/Quicktime/Windows_Tools/Programmers_Tools/Hack_TV/Hack_TV.zip // (mac) ftp://ftp.apple.com/developer/Quicktime/Tools/Programmers_Tools/Hack_TV.sit.hqx // // very good info here: // http://www.proce55ing.net/reference/libraries/video/ // (java stuff doesn't apply, but info on winvdig, vdig, etc) // // windows / direct show thoughts: // dShow capture via dsVideoLib coming soon ... // it's a c++ compiled lib, and tremendously difficult to work // in different c++ compilers. dope lib, but trouble with dev-c++... // look also at the reactable video input, useful? // wraps also v4l... // other cross platform video input options? // - opencv (cvAux?) //----------------------------------------- // todo: // -enumerate devices (ala wengo?) // -enumerate inputs // -allow input selection // -ntsc, pal format options... // -callback, via SGSetDataProc - couldn't get this to work yet // image decompress options ala mung... //--------------------------------------------- // this struct has all the info we need to grab pixels // typedef struct { unsigned char * offscreenGWorldPixels; // 32 bit: argb (qt k32ARGBPixelFormat) unsigned char * pixels; // 24 bit: rgb int w,h; bool bHavePixelsChanged; GWorldPtr videogworld; SeqGrabComponent gSeqGrabber; SGChannel gVideoChannel; Rect videoRect; } videoGrabberData; //--------------------------------------------- class ofQtVideoGrabber{ public : ofQtVideoGrabber(); bool isFrameNew(); void grabFrame(); void close(); void initGrabber(int w, int h); void initGrabber(int w, int h, bool bTexture); void videoSettings(); unsigned char * getPixels(); void setVerbose(bool bTalkToMe); void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); void draw(float x, float y); int width, height; private: bool bSgGrabberInited; videoGrabberData * vgd; bool bVerbose; ofTexture tex; bool bUseTexture; }; #endif Node-path: video/ofQtVideoPlayer.cpp Node-kind: file Node-action: change Text-content-length: 9755 Text-content-md5: 7268a62b94fe8eaa1f59181d9c9ebd49 Content-length: 9755 #include "ofQtVideoPlayer.h" //-------------------------------------------------------------- bool createMovieFromPath(char * path, Movie * movie); bool createMovieFromPath(char * path, Movie * movie){ Boolean isdir = false; OSErr result = 0; FSSpec theFSSpec; FSRef fsref; short resRefNum = -1; short actualResId = DoTheRightThing; #ifdef TARGET_WIN32 result = NativePathNameToFSSpec (path, &theFSSpec, 0); if (result) { printf("NativePathNameToFSSpec failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } #endif #ifdef TARGET_OSX result = FSPathMakeRef((const UInt8*)path, &fsref, &isdir); if (result) { printf("FSPathMakeRef failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } result = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL); if (result) { printf("FSGetCatalogInfo failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } #endif result = OpenMovieFile (&theFSSpec, &resRefNum, 0); if (result) { printf("OpenMovieFile failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } result = NewMovieFromFile (movie, resRefNum, &actualResId, (unsigned char *) 0, 0, (Boolean *) 0); if (result) { printf("NewMovieFromFile failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } if (resRefNum != -1) CloseMovieFile (resRefNum); return true; } //-------------------------------------------------------------- OSErr DrawCompleteProc(Movie theMovie, long refCon); OSErr DrawCompleteProc(Movie theMovie, long refCon){ videoPlayerData * vd = (videoPlayerData *)refCon; convertPixels(vd->offscreenGWorldPixels, vd->pixels, vd->w, vd->h); vd->bHavePixelsChanged = true; // now if the pixels have changed AND we are // using a texture, let's update the texture if (vd->bUseTexture == true){ vd->tex->loadData(vd->pixels, vd->w, vd->h, GL_RGB); } return noErr; } //--------------------------------------------------------------------------- ofQtVideoPlayer::ofQtVideoPlayer (){ bLoadedMovie = false; width = 0; height = 0; vpd = new videoPlayerData(); vpd->moviePtr = NULL; vpd->w = 0; vpd->h = 0; bUseTexture = true; } //--------------------------------------------------------------------------- unsigned char * ofQtVideoPlayer::getPixels(){ return vpd->pixels; } //--------------------------------------------------------------------------- bool ofQtVideoPlayer::isFrameNew(){ if (bLoadedMovie == true){ bool bChanged = vpd->bHavePixelsChanged; if (vpd->bHavePixelsChanged == true) { vpd->bHavePixelsChanged = false; } return bChanged; } else { return false; } } //--------------------------------------------------------------------------- void ofQtVideoPlayer::idleMovie(){ // [zach] my question is how often to call this? // I don't want to call it too often, and up cpu usage // // shockingly,(or not) on a mac, it seems it's not even necessary to call it // the callback just works... // google " site:lists.apple.com MoviesTask windows mac // some code I've seen uses a thread to call this "JUCE" // maybe I could use ofElapsedTimeMillis() // or a system clock call (not glut call) // and make this less frequent if (bLoadedMovie == true){ MoviesTask(vpd->moviePtr,0); } } //--------------------------------------------------------------------------- void ofQtVideoPlayer::closeMovie(){ Movie moviePtr = vpd->moviePtr; DisposeMovie (vpd->moviePtr); #ifdef TARGET_WIN32 DisposeMovieDrawingCompleteUPP (myDrawCompleteProc); #endif ExitMovies (); } //--------------------------------------------------------------------------- bool ofQtVideoPlayer::loadMovie(char * name){ OSErr result = 0; short resRefNum = -1; bLoadedMovie = false; Rect bounds; //----------------- callback method MovieDrawingCompleteUPP myDrawCompleteProc; myDrawCompleteProc = NewMovieDrawingCompleteUPP (DrawCompleteProc); initializeQuicktime(); vpd->bHavePixelsChanged = false; Movie * moviePtr = &(vpd->moviePtr); createMovieFromPath(name, moviePtr); //----------------------------------movie box GetMovieBox(vpd->moviePtr, &(vpd->movieRect)); width = vpd->movieRect.right; height = vpd->movieRect.bottom; vpd->w = vpd->movieRect.right; vpd->h = vpd->movieRect.bottom; //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vpd->offscreenGWorldPixels = (unsigned char*)malloc(4 * width * height + 32); vpd->pixels = new unsigned char[width*height*3]; //---------------------------------- gworld allocation QTNewGWorldFromPtr (&(vpd->offscreenGWorld), k32ARGBPixelFormat, &(vpd->movieRect), NULL, NULL, 0, (vpd->offscreenGWorldPixels), 4 * width); LockPixels(GetGWorldPixMap(vpd->offscreenGWorld)); SetGWorld (vpd->offscreenGWorld, NULL); SetMovieGWorld (vpd->moviePtr, vpd->offscreenGWorld, nil); //----------------- callback method SetMovieDrawingCompleteProc (vpd->moviePtr, movieDrawingCallWhenChanged, myDrawCompleteProc, (long)vpd); //---------------------------------- reset themovie, get ready to roll GoToBeginningOfMovie(vpd->moviePtr); SetMovieActiveSegment(vpd->moviePtr, -1,-1); if (vpd->moviePtr == NULL){ return false; } SetMovieActive(vpd->moviePtr, true); StartMovie(vpd->moviePtr); //------------------ set the movie rate to default //------------------ and preroll, so the first frames come correct TimeValue timeNow; Fixed playRate; timeNow = GetMovieTime(vpd->moviePtr, 0); playRate =GetMoviePreferredRate(vpd->moviePtr); PrePrerollMovie(vpd->moviePtr, timeNow, playRate, 0, 0); PrerollMovie(vpd->moviePtr, timeNow, playRate); SetMovieRate(vpd->moviePtr, playRate); setLoopState(OF_QT_LOOP_NORMAL); bLoadedMovie = true; // get some pixels in there right away. MoviesTask(vpd->moviePtr,0); convertPixels(vpd->offscreenGWorldPixels, vpd->pixels, vpd->w, vpd->h); vpd->bUseTexture = bUseTexture; vpd->tex = &tex; if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.allocate(width,height,GL_RGB); memset(vpd->pixels, 0, width*height*3); vpd->tex->loadData(vpd->pixels, vpd->w, vpd->h, GL_RGB); } return true; } //-------------------------------------------------------- void ofQtVideoPlayer::setVolume(int volume){ Movie moviePtr = vpd->moviePtr; SetMovieVolume(moviePtr, volume); } //-------------------------------------------------------- void ofQtVideoPlayer::setLoopState(int state){ Movie moviePtr = vpd->moviePtr; TimeBase myTimeBase; long myFlags = 0L; myTimeBase = GetMovieTimeBase(moviePtr); myFlags = GetTimeBaseFlags(myTimeBase); switch (state) { case OF_QT_LOOP_NORMAL: myFlags |= loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, hintsLoop, hintsLoop); SetMoviePlayHints(moviePtr, 0L, hintsPalindrome); break; case OF_QT_LOOP_PALINDROME: myFlags |= loopTimeBase; myFlags |= palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, hintsLoop, hintsLoop); SetMoviePlayHints(moviePtr, hintsPalindrome, hintsPalindrome); break; case OF_QT_LOOP_NONE: default: myFlags &= ~loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, 0L, hintsLoop | hintsPalindrome); break; } SetTimeBaseFlags(myTimeBase, myFlags); } //--------------------------------------------------------------------------- void ofQtVideoPlayer::setPosition(float pct){ TimeRecord tr; Movie moviePtr = vpd->moviePtr; tr.base = GetMovieTimeBase(moviePtr); long total = GetMovieDuration(moviePtr ); long newPos = (long)((float)total * pct); SetMovieTimeValue(moviePtr, newPos); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getDuration(){ Movie moviePtr = vpd->moviePtr; return GetMovieDuration (moviePtr) / (double) GetMovieTimeScale (moviePtr); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getPosition(){ Movie moviePtr = vpd->moviePtr; long total = GetMovieDuration(moviePtr); long current = GetMovieTime(moviePtr, nil); float pct = ((float)current/(float)total); return pct; } //--------------------------------------------------------------------------- void ofQtVideoPlayer::setSpeed(float _speed){ Movie moviePtr = vpd->moviePtr; speed = _speed; SetMovieRate(moviePtr, X2Fix(speed)); } //--------------------------------------------------------------------------- float ofQtVideoPlayer::getSpeed(){ return speed; } //--------------------------------------------------------------------------- void ofQtVideoPlayer::setPaused(bool bPause){ // there might be a more "quicktime-ish" way (or smarter way) // to do this for now, to pause, set the speed to zero, // on un-pause, set the speed to "speed" // (and hope that speed != 0...) if (bPause == true) setSpeed(0); else setSpeed(speed); } //------------------------------------ void ofQtVideoPlayer::setUseTexture(bool bUse){ bUseTexture = bUse; vpd->bUseTexture = bUseTexture; vpd->tex = &tex; } //------------------------------------ void ofQtVideoPlayer::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } //------------------------------------ void ofQtVideoPlayer::draw(float _x, float _y){ draw(_x, _y, width, height); } Node-path: video/ofQtVideoPlayer.h Node-kind: file Node-action: change Text-content-length: 2934 Text-content-md5: b4dbd175833eddaa9a641106e2e58fac Content-length: 2934 #ifndef _QT_VIDEO_PLAYER #define _QT_VIDEO_PLAYER #include "ofConstants.h" #include "ofQtUtils.h" #include "ofTexture.h" //------------------------------------------------- // (notes, links, etc) // // intersting technique employed here to get to RGB24 // from YUV2 - worthwhile? // paste.lisp.org/display/1051 //----------------------------- // http://viewcvs.osafoundation.org/chandler/trunk/internal/wx/src/msw/mediactrl.cpp?rev=6281&view=markup // http://developer.apple.com/documentation/QuickTime/INMAC/QT/iqMovieToolbox.34.htm // look for "QTURL_NewMovieFromURL", useful for loading URL based movies.. //------------------------------------------------- // // http://lists.apple.com/archives/QuickTime-API/2002/Feb/msg00118.html // //------------------------------------------------- // // note about callbacks: // // we use here a callback provided by quicktime to see if pixels have actually changed // the callback is "DrawCompleteProc" and int he quicktime code, // is defined as "static pascal OsErr ...." // in windows, I have dropped the pascal declaration as my compiler was // having trouble with that... necessary for mac? // // the alternative is to do what is done in qtVideoGrabber // set the alpha of the top pixel to 0x00 and every idle call // check to see if there are new pixels... #define OF_QT_LOOP_NONE 0x01 #define OF_QT_LOOP_PALINDROME 0x02 #define OF_QT_LOOP_NORMAL 0x03 //--------------------------------------------- // this struct has all the info we need to play 1 movie // kept in a struct, because the callback will // need to reference it... typedef struct { MovieController thePlayer; GWorldPtr offscreenGWorld; Movie moviePtr; Rect movieRect; unsigned char * offscreenGWorldPixels; // 32 bit: argb (qt k32ARGBPixelFormat) unsigned char * pixels; // 24 bit: rgb int w; int h; bool bHavePixelsChanged; ofTexture * tex; // a ptr to the texture we are utilizing bool bUseTexture; // are we using a texture } videoPlayerData; //--------------------------------------------- class ofQtVideoPlayer{ public: ofQtVideoPlayer (); void closeMovie(); bool loadMovie(char * name); void idleMovie(); // rename to updateMovie? int width, height; float speed; bool bLoadedMovie; bool isFrameNew(); unsigned char * getPixels(); float getPosition(); float getSpeed(); float getDuration(); void setPosition(float pct); void setVolume(int volume); void setLoopState(int state); void setSpeed(float speed); void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); void draw(float x, float y); void setPaused(bool bPause); private: //--------------------------- videoPlayerData * vpd; ofTexture tex; bool bUseTexture; }; #endif Revision-number: 27 Prop-content-length: 309 Content-length: 309 K 7 svn:log V 206 zach - changes to ofTexture and ofImage to deal with visual studio issues. texNames is now allocated non-dynamically, and a flag is added to the ofImage class so that we know if pixels have been allocated. K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-01T13:57:44.871976Z PROPS-END Node-path: graphics/ofImage.cpp Node-kind: file Node-action: change Text-content-length: 9220 Text-content-md5: fceb7704f33dca8e6b78eb1a01035d7e Content-length: 9220 #include "ofImage.h" #include "freeImage.h" static bool bFreeImageInited = false; //----------------------------------------- // class freeImageBitmap{ public: FIBITMAP * bmp; // when OF users ask for pixels // we will get them contiguous memory // ie, non-aligned // see the pixel access chapter of the freeImage pdf // these pixel will also be RGB // on both platforms // bmp will be RGB / BGR depending // on the endianess of the platform. unsigned char * pixels; //----------------------- freeImageBitmap(){ bmp = NULL; } //----------------------- //swap my image out in a (hopefully) non-memory leakish way void swap(FIBITMAP *dst) { if(dst == NULL) return; if(bmp != NULL) FreeImage_Unload(bmp); bmp = dst; } //----------------------- void setSize(FREE_IMAGE_TYPE image_type, WORD width, WORD height, WORD bpp) { if(bmp == NULL) { FreeImage_Unload(bmp); } bmp = FreeImage_AllocateT(image_type, width, height, bpp); } //----------------------- bool isValid(){ return (bmp != NULL) ? true : false; } }; //---------------------------------------------------------- ofImage::ofImage(){ //----------------------- init free image if necessary if (!bFreeImageInited){ FreeImage_Initialise(); bFreeImageInited = true; } //----------------------- IMG = new freeImageBitmap(); width = height = bpp = 0; type = OF_IMAGE_UNDEFINED; bUseTexture = true; // the default is, yes, use a texture bAllocatedPixels = false; } //---------------------------------------------------------- void ofImage::grabScreen(int _x, int _y, int _w, int _h){ if (IMG->isValid()){ if (!(width == _w && height == _h)){ resize(_w, _h); } unsigned char * pixels = (unsigned char *)FreeImage_GetBits(IMG->bmp); switch (bpp){ case 8: glReadPixels(_x, _y, _w, _h, GL_LUMINANCE,GL_UNSIGNED_BYTE, pixels); break; case 24: #ifdef TARGET_WIN32 glReadPixels(_x, _y, _w, _h, GL_BGR_EXT,GL_UNSIGNED_BYTE, pixels); #else glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); #endif break; case 32: glReadPixels(_x, _y, _w, _h, GL_RGBA,GL_UNSIGNED_BYTE, pixels); break; } update(); } else { // assume that this is color.... IMG->setSize(FIT_BITMAP, _w, _h, 24); unsigned char * pixels = (unsigned char *)FreeImage_GetBits(IMG->bmp); #ifdef TARGET_WIN32 glReadPixels(_x, _y, _w, _h, GL_BGR_EXT,GL_UNSIGNED_BYTE, pixels); #else glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); #endif update(); } } //---------------------------------------------------------- void ofImage::allocate(int _w, int _h, int _type){ int newbpp; switch (_type){ case OF_IMAGE_GRAYSCALE: newbpp = 8; break; case OF_IMAGE_COLOR: newbpp = 24; break; case OF_IMAGE_COLOR_ALPHA: newbpp = 32; break; default: newbpp = 24; break; } IMG->setSize(FIT_BITMAP, _w, _h, newbpp); } //---------------------------------------------------------- void ofImage::update(){ width = FreeImage_GetWidth(IMG->bmp); height = FreeImage_GetHeight(IMG->bmp); bpp = FreeImage_GetBPP(IMG->bmp); switch (bpp){ case 8: type = OF_IMAGE_GRAYSCALE; break; case 24: type = OF_IMAGE_COLOR; break; case 32: type = OF_IMAGE_COLOR_ALPHA; break; default: // if we've got here, something is wrong, the image // is not 8bit, 24bit or 32bit, so let's at least // make it color: setImageType(OF_IMAGE_COLOR); break; } //---------------------------------- // now, since the "freeImage" memory is padded // (see freeImage392.pdf - "Pixel access functions") // lets get the data into contiguous memory - to make it easier // for folks to work with... if (IMG->pixels != NULL && bAllocatedPixels == true) delete IMG->pixels; // delete anything that might have existed int byteCount = bpp / 8; // bytes ber pixel (not bits per pixel) IMG->pixels = new unsigned char[width*height*byteCount]; //allocate that memory for the image (contiguously) bAllocatedPixels = true; FreeImage_ConvertToRawBits(IMG->pixels, IMG->bmp, width*byteCount, bpp, FI_RGBA_RED_MASK,FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE); // get bits #ifdef TARGET_WIN32 if (type == OF_IMAGE_COLOR) swapChannels(false); if (type == OF_IMAGE_COLOR_ALPHA) swapChannels(true); #endif //---------------------------------- // if we are using a texture and the ofImage is upadate, // allocate (or reallocate) the texture and upload the data // I will upload from the contguous memory, and use pixelStorei to // make sure opengl knows I am contiguous. if (bUseTexture){ switch (type){ case OF_IMAGE_GRAYSCALE: tex.allocate(width,height,GL_LUMINANCE); tex.loadData(IMG->pixels, width,height, GL_LUMINANCE); break; case OF_IMAGE_COLOR: tex.allocate(width,height,GL_RGB); tex.loadData(IMG->pixels, width,height, GL_RGB); break; case OF_IMAGE_COLOR_ALPHA: tex.allocate(width,height,GL_RGBA); tex.loadData(IMG->pixels, width,height, GL_RGBA); break; } } } //---------------------------------------------------------- void ofImage::loadImage(char * fileName){ bool bLoaded = false; //----------------------------- find the format FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { if(IMG->isValid()) { FreeImage_Unload(IMG->bmp); } IMG->bmp = FreeImage_Load(fif, fileName, 0); bLoaded = true; if(!IMG->isValid()){ bLoaded = false; } } //----------------------------- if (bLoaded){ update(); } else { width = height = bpp = 0; } } //---------------------------------------------------------- void ofImage::saveImage(char * fileName){ if (IMG->isValid()){ FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { FreeImage_Save(fif, IMG->bmp, fileName, 0); } } } //---------------------------------------------------------- unsigned char * ofImage::getPixels(){ // be careful! might not be allocated. you need to check for null... if (IMG->isValid()){ return (unsigned char *)IMG->pixels; } else { return NULL; } } //---------------------------------------------------------- void ofImage::resize(int newWidth, int newHeight){ if (IMG->isValid()){ FIBITMAP * scaledBmp = FreeImage_Rescale(IMG->bmp, newWidth, newHeight, FILTER_BICUBIC); IMG->swap(scaledBmp); update(); } } //---------------------------------------------------------- void ofImage::setImageType(int newType){ if (IMG->isValid()){ switch (newType){ //------------------------------------ case OF_IMAGE_GRAYSCALE: if (type != OF_IMAGE_GRAYSCALE){ FIBITMAP * convertedBmp = FreeImage_ConvertToGreyscale(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; //------------------------------------ case OF_IMAGE_COLOR: if (type != OF_IMAGE_COLOR){ FIBITMAP * convertedBmp = FreeImage_ConvertTo24Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR; } break; //------------------------------------ case OF_IMAGE_COLOR_ALPHA: if (type != OF_IMAGE_COLOR_ALPHA){ FIBITMAP * convertedBmp = FreeImage_ConvertTo32Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR_ALPHA; } break; } update(); } } //------------------------------------ void ofImage::swapChannels(bool bAlpha){ // this swaps the red and blue channel of an image // turning an bgr image to rgb and vice versa... // needed because of windows byte order... if (IMG->isValid()){ unsigned char * pixels = IMG->pixels; unsigned char temp; int totalPixels = width*height; // unoptimized for now... if (bAlpha == false){ for (int i = 0; i < totalPixels; i++){ temp = pixels[i*3 + 2]; pixels[i*3 + 2] = pixels[i*3]; pixels[i*3] = temp; } } else { for (int i = 0; i < totalPixels; i++){ temp = pixels[i*4]; pixels[i*4] = pixels[i*4 + 2]; pixels[i*4 + 2] = temp; } } } } //------------------------------------ void ofImage::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofImage::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } //------------------------------------ void ofImage::draw(float x, float y){ draw(x,y,width,height); } Node-path: graphics/ofImage.h Node-kind: file Node-action: change Text-content-length: 1363 Text-content-md5: 8d21a193fda718634f36dc10382201d8 Content-length: 1363 #ifndef _OF_IMAGE_H_ #define _OF_IMAGE_H_ #include "ofConstants.h" #include "ofTexture.h" #define OF_IMAGE_GRAYSCALE 0x00 #define OF_IMAGE_COLOR 0x01 #define OF_IMAGE_COLOR_ALPHA 0x02 #define OF_IMAGE_UNDEFINED 0x03 //------------------------- // forward class declaration, something // we will need in order to compile "OF" as a lib // so that you don't need freeImage, quicktime, etc.. class freeImageBitmap; //------------------------- class ofImage { public : ofImage(); void loadImage(char * fileName); void saveImage(char * fileName); void allocate(int w, int h, int type); unsigned char * getPixels(); // up to you to get this right void setImageType(int type); void resize(int newWidth, int newHeight); void grabScreen(int x, int y, int w, int h); // grab pixels from opengl, using glreadpixels int type; // what type of image it is (as above) int width, height, bpp; // w,h, bits per pixel void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); void draw(float x, float y); private: void swapChannels(bool bAlpha); void update(); freeImageBitmap * IMG; ofTexture tex; bool bUseTexture; bool bAllocatedPixels; }; #endif Node-path: graphics/ofTexture.cpp Node-kind: file Node-action: change Text-content-length: 4876 Text-content-md5: 4dc61f540cff179fb9963ab641b6c436 Content-length: 4876 #include "ofTexture.h" #include "ofUtils.h" // for nextPow2() //---------------------------------------------------------- ofTexture::ofTexture(){ texName[0] = 0; } //---------------------------------------------------------- void ofTexture::clear(){ // try to free up the texture memory so we don't reallocate // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/deletetextures.html if (texName[0] != 0){ glDeleteTextures(1, (GLuint *)texName); } } //---------------------------------------------------------- void ofTexture::allocate(int w, int h, int internalGlDataType){ // can pass in anything (320x240) (10x5) // here we make it power of 2 for opengl (512x256), (16x8) tex_w = ofNextPow2(w); tex_h = ofNextPow2(h); tex_u = 1.0f; tex_t = 1.0f; // attempt to free the previous bound texture, if we can: clear(); glGenTextures(1, (GLuint *)texName); // could be more then one, but for now, just one glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); // upload 0 or white pixels.... glTexImage2D(GL_TEXTURE_2D, 0, internalGlDataType, tex_w, tex_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); // init to black... glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); } void ofTexture::loadData(unsigned char * data, int w, int h, int glDataType){ // can we allow for uploads bigger then texture and // just take as much as the texture can? // // ie: // int uploadW = MIN(w, tex_w); // int uploadH = MIN(h, tex_h); // but with a "step" size of w? // check "glTexSubImage2D" if ( w > tex_w || h > tex_h) { printf("image data too big - bailing \n"); return; } //compute new tex co-ords based on the ratio of data's w, h to texture w,h; tex_t = (float)(w) / (float)tex_w; tex_u = (float)(h) / (float)tex_h; // ok this is an ultra annoying bug : // opengl texels and linear filtering - // when we have a sub-image, and we scale it // we can clamp the border pixels to the border, // but the borders of the sub image get mixed with // neighboring pixels... // grr... // // the best solution would be to pad out the image // being uploaded with 2 pixels on all sides, and // recompute tex_t coordinates.. // another option is a gl_arb non pow 2 textures... // the current hack is to alter the tex_t, tex_u calcs, but // that makes the image slightly off... // this is currently being done in draw... // // we need a good solution for this.. // // http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014770#000001 // http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014770#000001 //------------------------ likely, we are uploading continuous data int prevAlignment; glGetIntegerv(GL_UNPACK_ALIGNMENT, &prevAlignment); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // update the texture image: glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); glTexSubImage2D(GL_TEXTURE_2D,0,0,0,w,h,glDataType,GL_UNSIGNED_BYTE,data); glDisable(GL_TEXTURE_2D); //------------------------ back to normal. glPixelStorei(GL_UNPACK_ALIGNMENT, prevAlignment); } //================================================================================= void ofTexture::draw(float x, float y, float w, float h){ glEnable(GL_TEXTURE_2D); // bind the texture glBindTexture( GL_TEXTURE_2D, (GLuint)texName[0] ); float px0 = x ; // up to you to get the aspect ratio right float py0 = y ; float px1 = x+w; float py1 = y+h; // ------------------------------------------------- // complete hack to remove border artifacts. // slightly, slightly alters an image, scaling... // to remove the border. // we need a better solution for this, but // to constantly add a 2 pixel border on all uploaded images // is insane.. float offsetw = 1.0f/(tex_w*2.0f); float offseth = 1.0f/(tex_h*2.0f); // ------------------------------------------------- float tx0 = 0+offsetw; float ty0 = 0+offseth; float tx1 = tex_t - offsetw; float ty1 = tex_u - offseth; glBegin( GL_QUADS ); glTexCoord2f(tx0,ty0); glVertex3f(px0, py0,0); glTexCoord2f(tx1,ty0); glVertex3f(px1, py0,0); glTexCoord2f(tx1,ty1); glVertex3f(px1, py1,0); glTexCoord2f(tx0,ty1); glVertex3f(px0, py1,0); glEnd(); glDisable(GL_TEXTURE_2D); } Node-path: graphics/ofTexture.h Node-kind: file Node-action: change Text-content-length: 536 Text-content-md5: 3559e73f5734143a7f0973ca6a35b6fe Content-length: 536 #ifndef _IMAGE_TEXTURE_H_ #define _IMAGE_TEXTURE_H_ #include "ofConstants.h" class ofTexture { public : ofTexture(); void allocate(int w, int h, int internalGlDataType); void clear(); void loadData(unsigned char * data, int w, int h, int glDataType); void draw(float x, float y, float w, float h); float tex_t, tex_u; private: float offset_x, offset_y; int tex_w, tex_h; unsigned int texName[1]; // vs not happy with dynamic allocation of this... }; #endif Revision-number: 28 Prop-content-length: 248 Content-length: 248 K 7 svn:log V 145 zach - fixes to ofImage for the intel / RGB-BGR issue (added endian target flags), and the bug where 256 color gifs were assumed to be grayscale. K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-06T12:50:10.442899Z PROPS-END Node-path: graphics/ofImage.cpp Node-kind: file Node-action: change Text-content-length: 9547 Text-content-md5: cb950a83dc3b9270c6b4cfbfae689d69 Content-length: 9547 #include "ofImage.h" #include "freeImage.h" static bool bFreeImageInited = false; //----------------------------------------- // class freeImageBitmap{ public: FIBITMAP * bmp; // when OF users ask for pixels // we will get them contiguous memory // ie, non-aligned // see the pixel access chapter of the freeImage pdf // these pixel will also be RGB // on both platforms // bmp will be RGB / BGR depending // on the endianess of the platform. unsigned char * pixels; //----------------------- freeImageBitmap(){ bmp = NULL; } //----------------------- //swap my image out in a (hopefully) non-memory leakish way void swap(FIBITMAP *dst) { if(dst == NULL) return; if(bmp != NULL) FreeImage_Unload(bmp); bmp = dst; } //----------------------- void setSize(FREE_IMAGE_TYPE image_type, WORD width, WORD height, WORD bpp) { if(bmp == NULL) { FreeImage_Unload(bmp); } bmp = FreeImage_AllocateT(image_type, width, height, bpp); } //----------------------- bool isValid(){ return (bmp != NULL) ? true : false; } }; //---------------------------------------------------------- ofImage::ofImage(){ //----------------------- init free image if necessary if (!bFreeImageInited){ FreeImage_Initialise(); bFreeImageInited = true; } //----------------------- IMG = new freeImageBitmap(); width = height = bpp = 0; type = OF_IMAGE_UNDEFINED; bUseTexture = true; // the default is, yes, use a texture bAllocatedPixels = false; } //---------------------------------------------------------- void ofImage::grabScreen(int _x, int _y, int _w, int _h){ if (IMG->isValid()){ if (!(width == _w && height == _h)){ resize(_w, _h); } unsigned char * pixels = (unsigned char *)FreeImage_GetBits(IMG->bmp); switch (bpp){ case 8: glReadPixels(_x, _y, _w, _h, GL_LUMINANCE,GL_UNSIGNED_BYTE, pixels); break; case 24: #ifdef TARGET_LITTLE_ENDIAN glReadPixels(_x, _y, _w, _h, GL_BGR_EXT,GL_UNSIGNED_BYTE, pixels); #else glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); #endif break; case 32: glReadPixels(_x, _y, _w, _h, GL_RGBA,GL_UNSIGNED_BYTE, pixels); break; } update(); } else { // assume that this is color.... IMG->setSize(FIT_BITMAP, _w, _h, 24); unsigned char * pixels = (unsigned char *)FreeImage_GetBits(IMG->bmp); #ifdef TARGET_LITTLE_ENDIAN glReadPixels(_x, _y, _w, _h, GL_BGR_EXT,GL_UNSIGNED_BYTE, pixels); #else glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); #endif update(); } } //---------------------------------------------------------- void ofImage::allocate(int _w, int _h, int _type){ int newbpp; switch (_type){ case OF_IMAGE_GRAYSCALE: newbpp = 8; break; case OF_IMAGE_COLOR: newbpp = 24; break; case OF_IMAGE_COLOR_ALPHA: newbpp = 32; break; default: newbpp = 24; break; } IMG->setSize(FIT_BITMAP, _w, _h, newbpp); } //---------------------------------------------------------- void ofImage::update(){ width = FreeImage_GetWidth(IMG->bmp); height = FreeImage_GetHeight(IMG->bmp); bpp = FreeImage_GetBPP(IMG->bmp); // this is check to see if it's a gif bool bNoPallette = (FreeImage_GetColorType(IMG->bmp) != FIC_PALETTE); switch (bpp){ case 8: if (bNoPallette) { //!bUsesPallette){ type = OF_IMAGE_GRAYSCALE; } else { // convert to RGB - // this is a gif (or other) with 256 colors, not b&w. setImageType(OF_IMAGE_COLOR); } break; case 24: type = OF_IMAGE_COLOR; break; case 32: type = OF_IMAGE_COLOR_ALPHA; break; default: // if we've got here, something is wrong, the image // is not 8bit, 24bit or 32bit, so let's at least // make it color: setImageType(OF_IMAGE_COLOR); break; } //---------------------------------- // now, since the "freeImage" memory is padded // (see freeImage392.pdf - "Pixel access functions") // lets get the data into contiguous memory - to make it easier // for folks to work with... if (IMG->pixels != NULL && bAllocatedPixels == true) delete IMG->pixels; // delete anything that might have existed int byteCount = bpp / 8; // bytes ber pixel (not bits per pixel) IMG->pixels = new unsigned char[width*height*byteCount]; //allocate that memory for the image (contiguously) bAllocatedPixels = true; FreeImage_ConvertToRawBits(IMG->pixels, IMG->bmp, width*byteCount, bpp, FI_RGBA_RED_MASK,FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE); // get bits #ifdef TARGET_LITTLE_ENDIAN if (type == OF_IMAGE_COLOR) swapChannels(false); if (type == OF_IMAGE_COLOR_ALPHA) swapChannels(true); #endif //---------------------------------- // if we are using a texture and the ofImage is upadate, // allocate (or reallocate) the texture and upload the data // I will upload from the contguous memory, and use pixelStorei to // make sure opengl knows I am contiguous. if (bUseTexture){ switch (type){ case OF_IMAGE_GRAYSCALE: tex.allocate(width,height,GL_LUMINANCE); tex.loadData(IMG->pixels, width,height, GL_LUMINANCE); break; case OF_IMAGE_COLOR: tex.allocate(width,height,GL_RGB); tex.loadData(IMG->pixels, width,height, GL_RGB); break; case OF_IMAGE_COLOR_ALPHA: tex.allocate(width,height,GL_RGBA); tex.loadData(IMG->pixels, width,height, GL_RGBA); break; } } } //---------------------------------------------------------- void ofImage::loadImage(char * fileName){ bool bLoaded = false; //----------------------------- find the format FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { if(IMG->isValid()) { FreeImage_Unload(IMG->bmp); } IMG->bmp = FreeImage_Load(fif, fileName, 0); bLoaded = true; if(!IMG->isValid()){ bLoaded = false; } } //----------------------------- if (bLoaded){ update(); } else { width = height = bpp = 0; } } //---------------------------------------------------------- void ofImage::saveImage(char * fileName){ if (IMG->isValid()){ FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { FreeImage_Save(fif, IMG->bmp, fileName, 0); } } } //---------------------------------------------------------- unsigned char * ofImage::getPixels(){ // be careful! might not be allocated. you need to check for null... if (IMG->isValid()){ return (unsigned char *)IMG->pixels; } else { return NULL; } } //---------------------------------------------------------- void ofImage::resize(int newWidth, int newHeight){ if (IMG->isValid()){ FIBITMAP * scaledBmp = FreeImage_Rescale(IMG->bmp, newWidth, newHeight, FILTER_BICUBIC); IMG->swap(scaledBmp); update(); } } //---------------------------------------------------------- void ofImage::setImageType(int newType){ if (IMG->isValid()){ switch (newType){ //------------------------------------ case OF_IMAGE_GRAYSCALE: if (type != OF_IMAGE_GRAYSCALE){ FIBITMAP * convertedBmp = FreeImage_ConvertToGreyscale(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; //------------------------------------ case OF_IMAGE_COLOR: if (type != OF_IMAGE_COLOR){ FIBITMAP * convertedBmp = FreeImage_ConvertTo24Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR; } break; //------------------------------------ case OF_IMAGE_COLOR_ALPHA: if (type != OF_IMAGE_COLOR_ALPHA){ FIBITMAP * convertedBmp = FreeImage_ConvertTo32Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR_ALPHA; } break; } update(); } } //------------------------------------ void ofImage::swapChannels(bool bAlpha){ // this swaps the red and blue channel of an image // turning an bgr image to rgb and vice versa... // needed because of windows byte order... if (IMG->isValid()){ unsigned char * pixels = IMG->pixels; unsigned char temp; int totalPixels = width*height; // unoptimized for now... if (bAlpha == false){ for (int i = 0; i < totalPixels; i++){ temp = pixels[i*3 + 2]; pixels[i*3 + 2] = pixels[i*3]; pixels[i*3] = temp; } } else { for (int i = 0; i < totalPixels; i++){ temp = pixels[i*4]; pixels[i*4] = pixels[i*4 + 2]; pixels[i*4 + 2] = temp; } } } } //------------------------------------ void ofImage::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofImage::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } //------------------------------------ void ofImage::draw(float x, float y){ draw(x,y,width,height); } Revision-number: 29 Prop-content-length: 199 Content-length: 199 K 7 svn:log V 97 zach - add endian flags for intel macs, and BGR_EXT definition for dev-c++ and eclipse compilers. K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-06T12:51:04.829286Z PROPS-END Node-path: utils/ofConstants.h Node-kind: file Node-action: change Text-content-length: 2084 Text-content-md5: 16be603858b94bdd808a02eac6b192fb Content-length: 2084 #ifndef OF_CONSTANTS #define OF_CONSTANTS //------------------------------- // pc or mac ? // soon: pc, mac or linux... #ifndef __APPLE_CC__ #define TARGET_WIN32 #else #define TARGET_OSX #endif //------------------------------- #ifdef TARGET_WIN32 #include #include "glut.h" #define __WINDOWS_DS__ #define __WINDOWS_MM__ #if (_MSC_VER) // microsoft visual studio #pragma warning(disable : 4996) // disable all deprecation warnings #pragma warning(disable : 4068) // unknown pragmas #pragma warning(disable : 4101) // unreferenced local variable #pragma warning(disable : 4312) // type cast conversion (in qt vp) #pragma warning(disable : 4311) // type cast pointer truncation (qt vp) #endif #define TARGET_LITTLE_ENDIAN; // intel cpu // some gl.h files, like dev-c++, are old - this is pretty universal #ifndef GL_BGR_EXT #define GL_BGR_EXT 0x80E0 #endif #endif #ifdef TARGET_OSX #define __MACOSX_CORE__ #include #if defined(__i386__) #define TARGET_LITTLE_ENDIAN; // intel cpu #endif #endif #ifndef __MWERKS__ #define OF_EXIT_APP(val) exit(val); #else #define OF_EXIT_APP(val) std::exit(val); #endif // core: --------------------------- #include #include #include #include #include #ifndef PI #define PI 3.14159265358979323846 #endif #ifndef TWO_PI #define TWO_PI 6.28318530717958647693 #endif #ifndef M_TWO_PI #define M_TWO_PI 6.28318530717958647693 #endif #ifndef FOUR_PI #define FOUR_PI 12.56637061435917295385 #endif #ifndef HALF_PI #define HALF_PI 1.57079632679489661923 #endif #ifndef DEG_TO_RAD #define DEG_TO_RAD (PI/180.0) #endif #ifndef RAD_TO_DEG #define RAD_TO_DEG (180.0/PI) #endif #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #endif #ifndef ABS #define ABS(x) (((x) < 0) ? -(x) : (x)) #endif #define OF_FILLED 0x01 #define OF_OUTLINE 0x02 #define OF_WINDOW 0 #define OF_FULLSCREEN 1 #endif Revision-number: 30 Prop-content-length: 174 Content-length: 174 K 7 svn:log V 72 Theo - added GLint fix for mac and also setShowDialog option to VG class K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-07T00:42:18.790341Z PROPS-END Node-path: graphics/ofTexture.cpp Node-kind: file Node-action: change Text-content-length: 4878 Text-content-md5: 34affb036c73cdbc3a7ff17b91021dc1 Content-length: 4878 #include "ofTexture.h" #include "ofUtils.h" // for nextPow2() //---------------------------------------------------------- ofTexture::ofTexture(){ texName[0] = 0; } //---------------------------------------------------------- void ofTexture::clear(){ // try to free up the texture memory so we don't reallocate // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/deletetextures.html if (texName[0] != 0){ glDeleteTextures(1, (GLuint *)texName); } } //---------------------------------------------------------- void ofTexture::allocate(int w, int h, int internalGlDataType){ // can pass in anything (320x240) (10x5) // here we make it power of 2 for opengl (512x256), (16x8) tex_w = ofNextPow2(w); tex_h = ofNextPow2(h); tex_u = 1.0f; tex_t = 1.0f; // attempt to free the previous bound texture, if we can: clear(); glGenTextures(1, (GLuint *)texName); // could be more then one, but for now, just one glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); // upload 0 or white pixels.... glTexImage2D(GL_TEXTURE_2D, 0, internalGlDataType, tex_w, tex_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); // init to black... glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); } void ofTexture::loadData(unsigned char * data, int w, int h, int glDataType){ // can we allow for uploads bigger then texture and // just take as much as the texture can? // // ie: // int uploadW = MIN(w, tex_w); // int uploadH = MIN(h, tex_h); // but with a "step" size of w? // check "glTexSubImage2D" if ( w > tex_w || h > tex_h) { printf("image data too big - bailing \n"); return; } //compute new tex co-ords based on the ratio of data's w, h to texture w,h; tex_t = (float)(w) / (float)tex_w; tex_u = (float)(h) / (float)tex_h; // ok this is an ultra annoying bug : // opengl texels and linear filtering - // when we have a sub-image, and we scale it // we can clamp the border pixels to the border, // but the borders of the sub image get mixed with // neighboring pixels... // grr... // // the best solution would be to pad out the image // being uploaded with 2 pixels on all sides, and // recompute tex_t coordinates.. // another option is a gl_arb non pow 2 textures... // the current hack is to alter the tex_t, tex_u calcs, but // that makes the image slightly off... // this is currently being done in draw... // // we need a good solution for this.. // // http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014770#000001 // http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014770#000001 //------------------------ likely, we are uploading continuous data GLint prevAlignment; glGetIntegerv(GL_UNPACK_ALIGNMENT, &prevAlignment); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // update the texture image: glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); glTexSubImage2D(GL_TEXTURE_2D,0,0,0,w,h,glDataType,GL_UNSIGNED_BYTE,data); glDisable(GL_TEXTURE_2D); //------------------------ back to normal. glPixelStorei(GL_UNPACK_ALIGNMENT, prevAlignment); } //================================================================================= void ofTexture::draw(float x, float y, float w, float h){ glEnable(GL_TEXTURE_2D); // bind the texture glBindTexture( GL_TEXTURE_2D, (GLuint)texName[0] ); float px0 = x ; // up to you to get the aspect ratio right float py0 = y ; float px1 = x+w; float py1 = y+h; // ------------------------------------------------- // complete hack to remove border artifacts. // slightly, slightly alters an image, scaling... // to remove the border. // we need a better solution for this, but // to constantly add a 2 pixel border on all uploaded images // is insane.. float offsetw = 1.0f/(tex_w*2.0f); float offseth = 1.0f/(tex_h*2.0f); // ------------------------------------------------- float tx0 = 0+offsetw; float ty0 = 0+offseth; float tx1 = tex_t - offsetw; float ty1 = tex_u - offseth; glBegin( GL_QUADS ); glTexCoord2f(tx0,ty0); glVertex3f(px0, py0,0); glTexCoord2f(tx1,ty0); glVertex3f(px1, py0,0); glTexCoord2f(tx1,ty1); glVertex3f(px1, py1,0); glTexCoord2f(tx0,ty1); glVertex3f(px0, py1,0); glEnd(); glDisable(GL_TEXTURE_2D); } Node-path: video/ofQtVideoGrabber.cpp Node-kind: file Node-action: change Text-content-length: 8067 Text-content-md5: 888b3a8e74da59c86babbeed49950715 Content-length: 8067 #include "ofQtVideoGrabber.h" //-------------------------------------------------------------------- Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon); Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon){ #pragma unused(theDialog, itemHit) Boolean handled = false; if ((theEvent->what == updateEvt) && ((WindowPtr) theEvent->message == (WindowPtr) refCon)) { BeginUpdate ((WindowPtr) refCon); EndUpdate ((WindowPtr) refCon); handled = true; } return (handled); } //-------------------------------------------------------------------- ofQtVideoGrabber::ofQtVideoGrabber(){ initializeQuicktime(); vgd = new videoGrabberData(); bVerbose = false; bSgGrabberInited = false; bUseTexture = true; bShowDialog = false; } //-------------------------------------------------------------------- void ofQtVideoGrabber::setVerbose(bool bTalkToMe){ bVerbose = bTalkToMe; } //-------------------------------------------------------------------- void ofQtVideoGrabber::setShowDialog(bool bTalkToMe){ bShowDialog = bTalkToMe; } //--------------------------------------------------------------------------- unsigned char * ofQtVideoGrabber::getPixels(){ return vgd->pixels; } //--------------------------------------------------------------------------- bool ofQtVideoGrabber::isFrameNew(){ if (bSgGrabberInited == true){ bool bNew = false; if (vgd->bHavePixelsChanged == true){ bNew = true; vgd->bHavePixelsChanged = false; } return bNew; } else { return false; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::grabFrame(){ if (bSgGrabberInited == true){ SGIdle(vgd->gSeqGrabber); // set the top pixel alpha = 0, so we can know if it // was a new frame or not.. // or else we will process way more than necessary // (ie opengl is running at 60fps +, capture at 30fps) if (vgd->offscreenGWorldPixels[0] != 0x00){ vgd->offscreenGWorldPixels[0] = 0x00; vgd->bHavePixelsChanged = true; convertPixels(vgd->offscreenGWorldPixels, vgd->pixels, vgd->w, vgd->h); if (bUseTexture){ tex.loadData(vgd->pixels, vgd->w, vgd->h, GL_RGB); } } } } //-------------------------------------------------------------------- void ofQtVideoGrabber::close(){ //thanks eloi! if (vgd->gSeqGrabber != 0L){ CloseComponent (vgd->gSeqGrabber); vgd->gSeqGrabber = 0L; } } //-------------------------------------------------------------------- void ofQtVideoGrabber::videoSettings(void){ Rect curBounds, curVideoRect; ComponentResult err; // Get our current state err = SGGetChannelBounds (vgd->gVideoChannel, &curBounds); if (err != noErr){ printf("Error in SGGetChannelBounds \n"); return; } err = SGGetVideoRect (vgd->gVideoChannel, &curVideoRect); if (err != noErr){ printf("Error in SGGetVideoRect \n"); return; } // Pause err = SGPause (vgd->gSeqGrabber, true); if (err != noErr){ printf("Error in SGPause\n"); return; } #ifdef TARGET_OSX static SGModalFilterUPP gSeqGrabberModalFilterUPP = NewSGModalFilterUPP(SeqGrabberModalFilterUPP); ComponentResult result = SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, seqGrabSettingsPreviewOnly, gSeqGrabberModalFilterUPP, nil); if (err != noErr){ printf("error in dialogue\n"); return; } #else SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, seqGrabSettingsPreviewOnly, NULL, 0); #endif SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); SGPause (vgd->gSeqGrabber, false); } //-------------------------------------------------------------------- void ofQtVideoGrabber::initGrabber(int w, int h){ vgd->w = w; vgd->h = h; ComponentDescription theDesc; Component sgCompID = NULL; char name[256]; char info[256]; Handle componentName=NULL; Handle componentInfo=NULL; ComponentDescription info_description; componentName=NewHandle(sizeof(name)); componentInfo=NewHandle(sizeof(info)); if (bVerbose == true){ printf ("\n"); printf ("-------------------------------------\n"); printf ("attempting to set up ofQtVideoGrabber\n"); } vgd->gSeqGrabber = 0L; vgd->gVideoChannel = 0L; theDesc.componentType = SeqGrabComponentType; theDesc.componentSubType = 0L; theDesc.componentManufacturer = 0L; theDesc.componentFlags = 0L; theDesc.componentFlagsMask = 0L; sgCompID = FindNextComponent(sgCompID, &theDesc); while (sgCompID != 0){ GetComponentInfo(sgCompID,&info_description, componentName, componentInfo,nil); if (bVerbose == true){ printf("found a device to capture with \n"); printf("Type: %s\n", &info_description.componentType); printf("Manufacturer: %s\n", &info_description.componentManufacturer); printf("Name: %s\n", *componentName ? p2cstr((StringPtr)*componentName) : "-" ); printf("Name: %s\n", *componentInfo ? p2cstr((StringPtr)*componentInfo) : "-"); } vgd->gSeqGrabber = OpenComponent(sgCompID); sgCompID = FindNextComponent(sgCompID, &theDesc); } //-------------------------------------------- // setup the gworld and digitizing. OSStatus err; err = SGInitialize(vgd->gSeqGrabber); if (err != noErr){ printf("***** Error in SGInitialize (check cam drivers, vdig or winvidg)*****\n"); return; } MacSetRect(&(vgd->videoRect),0, 0, w, h); width = w; height = h; //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vgd->offscreenGWorldPixels = (unsigned char*)malloc(4 * w * h + 32); vgd->pixels = new unsigned char[w*h*3]; QTNewGWorldFromPtr (&vgd->videogworld, k32ARGBPixelFormat, &vgd->videoRect, NULL, NULL, 0, vgd->offscreenGWorldPixels, 4 * w); LockPixels(GetGWorldPixMap(vgd->videogworld)); SetGWorld (vgd->videogworld, NULL); err = SGSetGWorld(vgd->gSeqGrabber, vgd->videogworld, nil); if ( err != noErr ) goto bail; err = SGNewChannel(vgd->gSeqGrabber, VideoMediaType, &vgd->gVideoChannel); if ( err != noErr ) goto bail; //err = SGSetDataRef(vgd->gSeqGrabber, 0, 0, seqGrabDontMakeMovie); //if ( err != noErr ) goto bail; err = SGSetChannelUsage(vgd->gVideoChannel,seqGrabPreview); if ( err != noErr ) goto bail; err = SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); if ( err != noErr ) goto bail; if (SGSetFrameRate(vgd->gVideoChannel,30) != noErr) printf( "error setting 30 fps \n"); else{ if (bVerbose == true){ printf ("set to capture at 30 fps \n"); } } err = SGPrepare(vgd->gSeqGrabber, true, false); //theo swapped so preview is true and capture is false if ( err != noErr ) goto bail; err = SGStartPreview(vgd->gSeqGrabber); if ( err != noErr ) goto bail; if (bVerbose){ printf ("end setup ofQtVideoGrabber\n"); printf ("-------------------------------------\n"); printf ("\n"); } if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.allocate(w,h,GL_RGB); memset(vgd->pixels, 0, w*h*3); tex.loadData(vgd->pixels, w, h, GL_RGB); } if(bShowDialog)videoSettings(); bSgGrabberInited = true; return; // good catch eloi/theo //--------------------- (bail) something's wrong ----- bail: if (bVerbose){ printf ("***** ofQtVideoGrabber error *****\n"); printf ("-------------------------------------\n"); printf ("\n"); } bSgGrabberInited = false; return; } //------------------------------------ void ofQtVideoGrabber::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofQtVideoGrabber::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } //------------------------------------ void ofQtVideoGrabber::draw(float _x, float _y){ draw(_x, _y, width, height); } Node-path: video/ofQtVideoGrabber.h Node-kind: file Node-action: change Text-content-length: 2947 Text-content-md5: 769793b6a295cc74d7249674278ae7a9 Content-length: 2947 #ifndef _QT_VIDEO_GRABBER #define _QT_VIDEO_GRABBER #include "ofConstants.h" #include "ofQtUtils.h" #include "ofTexture.h" //----------------------------------------- // windows users check out winvdig: // // -[wvdig free]- // http://www.vdig.com/WinVDIG/ // but maybe older versions are better (at least w/ quicktime < 7.0) // try this one: (v 0.99) // www.vjshow.net/vart/WinVDIG_099.exe // uninstall instructions for winvdig in the winvdig forum // http://www.videoscript.com/forum/viewtopic.php?t=21 // // -[wvdig $]- // (also, www.abstractplane.com/products/vdig.jsp) // never tried... // 30 day demo available // // you will need a vdig to see video // try "hackTv" to test if you can use // quicktime to grab video // (pc) ftp://ftp.apple.com/developer/Quicktime/Windows_Tools/Programmers_Tools/Hack_TV/Hack_TV.zip // (mac) ftp://ftp.apple.com/developer/Quicktime/Tools/Programmers_Tools/Hack_TV.sit.hqx // // very good info here: // http://www.proce55ing.net/reference/libraries/video/ // (java stuff doesn't apply, but info on winvdig, vdig, etc) // // windows / direct show thoughts: // dShow capture via dsVideoLib coming soon ... // it's a c++ compiled lib, and tremendously difficult to work // in different c++ compilers. dope lib, but trouble with dev-c++... // look also at the reactable video input, useful? // wraps also v4l... // other cross platform video input options? // - opencv (cvAux?) //----------------------------------------- // todo: // -enumerate devices (ala wengo?) // -enumerate inputs // -allow input selection // -ntsc, pal format options... // -callback, via SGSetDataProc - couldn't get this to work yet // image decompress options ala mung... //--------------------------------------------- // this struct has all the info we need to grab pixels // typedef struct { unsigned char * offscreenGWorldPixels; // 32 bit: argb (qt k32ARGBPixelFormat) unsigned char * pixels; // 24 bit: rgb int w,h; bool bHavePixelsChanged; GWorldPtr videogworld; SeqGrabComponent gSeqGrabber; SGChannel gVideoChannel; Rect videoRect; } videoGrabberData; //--------------------------------------------- class ofQtVideoGrabber{ public : ofQtVideoGrabber(); bool isFrameNew(); void grabFrame(); void close(); void initGrabber(int w, int h); void initGrabber(int w, int h, bool bTexture); void videoSettings(); unsigned char * getPixels(); void setVerbose(bool bTalkToMe); void setShowDialog(bool bTalkToMe); void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); void draw(float x, float y); int width, height; private: bool bSgGrabberInited; videoGrabberData * vgd; bool bVerbose; bool bShowDialog; ofTexture tex; bool bUseTexture; }; #endif Revision-number: 31 Prop-content-length: 133 Content-length: 133 K 7 svn:log V 31 changes for video / dshow added K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-26T15:57:53.305899Z PROPS-END Node-path: video/ofVideoGrabber.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 12796 Text-content-md5: 1738298fab7e53b8ff41c344924261e8 Content-length: 12806 PROPS-END #include "ofVideoGrabber.h" //-------------------------------------------------------------------- ofVideoGrabber::ofVideoGrabber(){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- initializeQuicktime(); vgd = new videoGrabberData(); vgd->bSgInited = false; //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW //--------------------------------- bVerbose = false; bFrameNew = false; //--------------------------------- #endif //--------------------------------- // common bVerbose = false; bSgGrabberInited = false; bUseTexture = true; bChooseDevice = false; deviceID = 0; width = 320; height = 240; } //-------------------------------------------------------------------- void ofVideoGrabber::listDevices(){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- initGrabbingComponent(vgd, true); // if necessary, start the sg object if (!vgd->bSgInited){ printf("error in list devices, couldn't allocate grabbing component\n"); return; } printf("-------------------------------------\n"); SGDeviceList deviceList; SGGetChannelDeviceList (vgd->gVideoChannel, sgDeviceListIncludeInputs, &deviceList); unsigned char pascalName[64]; if(true) { printf("listing available capture devices\n"); for(int i = 0 ; i < (*deviceList)->count ; ++i) { SGDeviceName nameRec; nameRec = (*deviceList)->entry[i]; memcpy(pascalName, (*deviceList)->entry[i].name, sizeof(char) * 64); if(nameRec.flags != sgDeviceNameFlagDeviceUnavailable) printf("device[%i] %s \n", i, p2cstr(pascalName) ); else printf("(unavailable) device[%i] %s \n", i, p2cstr(pascalName) ); } } printf("-------------------------------------\n"); //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW //--------------------------------- printf("---\n"); VI.listDevices(); printf("---\n"); //--------------------------------- #endif //--------------------------------- } //-------------------------------------------------------------------- void ofVideoGrabber::setVerbose(bool bTalkToMe){ bVerbose = bTalkToMe; } //-------------------------------------------------------------------- void ofVideoGrabber::setDeviceID(int _deviceID){ deviceID = _deviceID; bChooseDevice = true; } //--------------------------------------------------------------------------- unsigned char * ofVideoGrabber::getPixels(){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- return vgd->pixels; //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW //--------------------------------- return pixels; //--------------------------------- #endif //--------------------------------- } //--------------------------------------------------------------------------- bool ofVideoGrabber::isFrameNew(){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- if (bSgGrabberInited == true){ bool bNew = false; if (vgd->bHavePixelsChanged == true){ bNew = true; vgd->bHavePixelsChanged = false; } return bNew; } else { return false; } //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW //--------------------------------- if (bFrameNew == true){ bFrameNew = false; return true; } else { return false; } //--------------------------------- #endif //--------------------------------- } //-------------------------------------------------------------------- void ofVideoGrabber::grabFrame(){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- if (bSgGrabberInited == true){ SGIdle(vgd->gSeqGrabber); // set the top pixel alpha = 0, so we can know if it // was a new frame or not.. // or else we will process way more than necessary // (ie opengl is running at 60fps +, capture at 30fps) if (vgd->offscreenGWorldPixels[0] != 0x00){ vgd->offscreenGWorldPixels[0] = 0x00; vgd->bHavePixelsChanged = true; convertPixels(vgd->offscreenGWorldPixels, vgd->pixels, vgd->w, vgd->h); if (bUseTexture){ tex.loadData(vgd->pixels, vgd->w, vgd->h, GL_RGB); } } } //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW //--------------------------------- if (bSgGrabberInited == true){ if (VI.isFrameNew(device)){ bFrameNew = true; memcpy(pixels, VI.getPixels(device), width*height*3); if (bUseTexture){ tex.loadData(pixels, width, height, GL_RGB); } } } //--------------------------------- #endif //--------------------------------- } //-------------------------------------------------------------------- void ofVideoGrabber::close(){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //thanks eloi! if (vgd->gSeqGrabber != 0L){ CloseComponent (vgd->gSeqGrabber); vgd->gSeqGrabber = 0L; } #endif } //-------------------------------------------------------------------- void ofVideoGrabber::videoSettings(void){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- Rect curBounds, curVideoRect; ComponentResult err; // Get our current state err = SGGetChannelBounds (vgd->gVideoChannel, &curBounds); if (err != noErr){ printf("Error in SGGetChannelBounds \n"); return; } err = SGGetVideoRect (vgd->gVideoChannel, &curVideoRect); if (err != noErr){ printf("Error in SGGetVideoRect \n"); return; } // Pause err = SGPause (vgd->gSeqGrabber, true); if (err != noErr){ printf("Error in SGPause\n"); return; } #ifdef TARGET_OSX static SGModalFilterUPP gSeqGrabberModalFilterUPP = NewSGModalFilterUPP(SeqGrabberModalFilterUPP); ComponentResult result = SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, seqGrabSettingsPreviewOnly, gSeqGrabberModalFilterUPP, nil); if (err != noErr){ printf("error in dialogue\n"); return; } #else SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, seqGrabSettingsPreviewOnly, NULL, 0); #endif SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); SGPause (vgd->gSeqGrabber, false); //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW //--------------------------------- if (bSgGrabberInited == true) VI.showSettingsWindow(device); //--------------------------------- #endif //--------------------------------- } //-------------------------------------------------------------------- void ofVideoGrabber::initGrabber(int w, int h){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- vgd->w = w; vgd->h = h; OSStatus err; initGrabbingComponent(vgd, true); if (!vgd->bSgInited){ printf("error in init grabber, couldn't allocate grabbing component\n"); return; } MacSetRect(&(vgd->videoRect),0, 0, w, h); width = w; height = h; //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vgd->offscreenGWorldPixels = (unsigned char*)malloc(4 * w * h + 32); vgd->pixels = new unsigned char[w*h*3]; QTNewGWorldFromPtr (&vgd->videogworld, k32ARGBPixelFormat, &vgd->videoRect, NULL, NULL, 0, vgd->offscreenGWorldPixels, 4 * w); LockPixels(GetGWorldPixMap(vgd->videogworld)); SetGWorld (vgd->videogworld, NULL); SGSetGWorld(vgd->gSeqGrabber, vgd->videogworld, nil); //---------------------------------- choose a specific device to setup if(bChooseDevice) { //Generate a device list and enumerate //all devices availble to the channel SGDeviceList deviceList; SGGetChannelDeviceList (vgd->gVideoChannel, sgDeviceListIncludeInputs, &deviceList); unsigned char pascalName[64]; //List all available devices if(bVerbose) { printf("listing available capture devices\n"); for(int i = 0 ; i < (*deviceList)->count ; ++i){ memcpy(pascalName, (*deviceList)->entry[i].name, sizeof(char) * 64); printf("device[%i] %s \n", i, p2cstr(pascalName) ); } } //check that the device requested exists if(deviceID+1 <= (*deviceList)->count) { SGDeviceName nameRec; nameRec = (*deviceList)->entry[deviceID]; if(nameRec.flags != sgDeviceNameFlagDeviceUnavailable) { unsigned char camStr[255]; memcpy(camStr, (*deviceList)->entry[deviceID].name, sizeof(char) * 64); memcpy(pascalName, (*deviceList)->entry[deviceID].name, sizeof(char) * 64); p2cstr(camStr); if(bVerbose)printf("attempting to setup device[%i] (%s) \n", deviceID, camStr); memcpy(pascalName, (*deviceList)->entry[deviceID].name, sizeof(char) * 64); err = SGSetChannelDevice(vgd->gVideoChannel, pascalName); if ( err != noErr ) { printf("***** Error in SGSetChannelDevice - setting device[%i] %s *****\n", deviceID, pascalName); goto bail; } } else { printf("device[%i] in use - using next default device\n", deviceID); } } else printf("device[%i] unavailable - using next default device\n", deviceID); } err = SGSetChannelUsage(vgd->gVideoChannel,seqGrabPreview); if ( err != noErr ) goto bail; err = SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); if ( err != noErr ) goto bail; err = SGPrepare(vgd->gSeqGrabber, true, false); //theo swapped so preview is true and capture is false if ( err != noErr ) goto bail; err = SGStartPreview(vgd->gSeqGrabber); if ( err != noErr ) goto bail; if (bVerbose){ printf ("end setup ofVideoGrabber\n"); printf ("-------------------------------------\n"); printf ("\n"); } if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.allocate(w,h,GL_RGB); memset(vgd->pixels, 0, w*h*3); tex.loadData(vgd->pixels, w, h, GL_RGB); } bSgGrabberInited = true; return; // good catch eloi/theo //--------------------- (bail) something's wrong ----- bail: if (bVerbose){ printf ("***** ofVideoGrabber error *****\n"); printf ("-------------------------------------\n"); printf ("\n"); } bSgGrabberInited = false; return; //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW //--------------------------------- if (bChooseDevice){ device = deviceID; printf("choosing %i \n", deviceID); } else { device = 0; } //device = 0; bool bOk = VI.setupDevice(device, w, h); if (bOk == true){ bSgGrabberInited = true; width = VI.getWidth(device); height = VI.getHeight(device); pixels = new unsigned char[width * height * 3]; if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.allocate(width,height,GL_RGB); memset(pixels, 0, width*height*3); tex.loadData(pixels, width, height, GL_RGB); } } else { printf("error allocating a video device \nplease check your camera with AMCAP or other software\n"); } //--------------------------------- #endif //--------------------------------- } //------------------------------------ void ofVideoGrabber::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofVideoGrabber::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } //------------------------------------ void ofVideoGrabber::draw(float _x, float _y){ draw(_x, _y, width, height); } Node-path: video/ofVideoGrabber.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1386 Text-content-md5: 977c8b613c8af09b628f61528ecfd5f1 Content-length: 1396 PROPS-END #ifndef _OF_VIDEO_GRABBER #define _OF_VIDEO_GRABBER #include "ofConstants.h" #include "ofTexture.h" #ifdef OF_VIDEO_CAPTURE_QUICKTIME #include "ofQtUtils.h" #endif #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW #include "videoInput.h" #endif // todo: // -callback, via SGSetDataProc - couldn't get this to work yet // image decompress options ala mung... class ofVideoGrabber{ public : ofVideoGrabber(); void listDevices(); bool isFrameNew(); void grabFrame(); void close(); void initGrabber(int w, int h); void initGrabber(int w, int h, bool bTexture); void videoSettings(); unsigned char * getPixels(); void setVerbose(bool bTalkToMe); void setDeviceID(int _deviceID); void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); void draw(float x, float y); int width, height; private: bool bChooseDevice; int deviceID; bool bUseTexture; ofTexture tex; bool bVerbose; bool bSgGrabberInited; //--------------------------------- quicktime #ifdef OF_VIDEO_CAPTURE_QUICKTIME videoGrabberData * vgd; #endif //--------------------------------- directshow #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW int device; unsigned char * pixels; bool bFrameNew; videoInput VI; #endif }; #endif Node-path: video/ofVideoPlayer.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 9717 Text-content-md5: 93b0e3ec551fcbbce1cc8b58c47d3461 Content-length: 9727 PROPS-END #include "ofVideoPlayer.h" //-------------------------------------------------------------- bool createMovieFromPath(char * path, Movie * movie); bool createMovieFromPath(char * path, Movie * movie){ Boolean isdir = false; OSErr result = 0; FSSpec theFSSpec; FSRef fsref; short resRefNum = -1; short actualResId = DoTheRightThing; #ifdef TARGET_WIN32 result = NativePathNameToFSSpec (path, &theFSSpec, 0); if (result) { printf("NativePathNameToFSSpec failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } #endif #ifdef TARGET_OSX result = FSPathMakeRef((const UInt8*)path, &fsref, &isdir); if (result) { printf("FSPathMakeRef failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } result = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL); if (result) { printf("FSGetCatalogInfo failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } #endif result = OpenMovieFile (&theFSSpec, &resRefNum, 0); if (result) { printf("OpenMovieFile failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } result = NewMovieFromFile (movie, resRefNum, &actualResId, (unsigned char *) 0, 0, (Boolean *) 0); if (result) { printf("NewMovieFromFile failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } if (resRefNum != -1) CloseMovieFile (resRefNum); return true; } //-------------------------------------------------------------- OSErr DrawCompleteProc(Movie theMovie, long refCon); OSErr DrawCompleteProc(Movie theMovie, long refCon){ videoPlayerData * vd = (videoPlayerData *)refCon; convertPixels(vd->offscreenGWorldPixels, vd->pixels, vd->w, vd->h); vd->bHavePixelsChanged = true; // now if the pixels have changed AND we are // using a texture, let's update the texture if (vd->bUseTexture == true){ vd->tex->loadData(vd->pixels, vd->w, vd->h, GL_RGB); } return noErr; } //--------------------------------------------------------------------------- ofVideoPlayer::ofVideoPlayer (){ bLoadedMovie = false; width = 0; height = 0; vpd = new videoPlayerData(); vpd->moviePtr = NULL; vpd->w = 0; vpd->h = 0; bUseTexture = true; } //--------------------------------------------------------------------------- unsigned char * ofVideoPlayer::getPixels(){ return vpd->pixels; } //--------------------------------------------------------------------------- bool ofVideoPlayer::isFrameNew(){ if (bLoadedMovie == true){ bool bChanged = vpd->bHavePixelsChanged; if (vpd->bHavePixelsChanged == true) { vpd->bHavePixelsChanged = false; } return bChanged; } else { return false; } } //--------------------------------------------------------------------------- void ofVideoPlayer::idleMovie(){ // [zach] my question is how often to call this? // I don't want to call it too often, and up cpu usage // // shockingly,(or not) on a mac, it seems it's not even necessary to call it // the callback just works... // google " site:lists.apple.com MoviesTask windows mac // some code I've seen uses a thread to call this "JUCE" // maybe I could use ofElapsedTimeMillis() // or a system clock call (not glut call) // and make this less frequent if (bLoadedMovie == true){ MoviesTask(vpd->moviePtr,0); } } //--------------------------------------------------------------------------- void ofVideoPlayer::closeMovie(){ Movie moviePtr = vpd->moviePtr; DisposeMovie (vpd->moviePtr); #ifdef TARGET_WIN32 DisposeMovieDrawingCompleteUPP (myDrawCompleteProc); #endif ExitMovies (); } //--------------------------------------------------------------------------- bool ofVideoPlayer::loadMovie(char * name){ OSErr result = 0; short resRefNum = -1; bLoadedMovie = false; Rect bounds; //----------------- callback method MovieDrawingCompleteUPP myDrawCompleteProc; myDrawCompleteProc = NewMovieDrawingCompleteUPP (DrawCompleteProc); initializeQuicktime(); vpd->bHavePixelsChanged = false; Movie * moviePtr = &(vpd->moviePtr); createMovieFromPath(name, moviePtr); //----------------------------------movie box GetMovieBox(vpd->moviePtr, &(vpd->movieRect)); width = vpd->movieRect.right; height = vpd->movieRect.bottom; vpd->w = vpd->movieRect.right; vpd->h = vpd->movieRect.bottom; //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vpd->offscreenGWorldPixels = (unsigned char*)malloc(4 * width * height + 32); vpd->pixels = new unsigned char[width*height*3]; //---------------------------------- gworld allocation QTNewGWorldFromPtr (&(vpd->offscreenGWorld), k32ARGBPixelFormat, &(vpd->movieRect), NULL, NULL, 0, (vpd->offscreenGWorldPixels), 4 * width); LockPixels(GetGWorldPixMap(vpd->offscreenGWorld)); SetGWorld (vpd->offscreenGWorld, NULL); SetMovieGWorld (vpd->moviePtr, vpd->offscreenGWorld, nil); //----------------- callback method SetMovieDrawingCompleteProc (vpd->moviePtr, movieDrawingCallWhenChanged, myDrawCompleteProc, (long)vpd); //---------------------------------- reset themovie, get ready to roll GoToBeginningOfMovie(vpd->moviePtr); SetMovieActiveSegment(vpd->moviePtr, -1,-1); if (vpd->moviePtr == NULL){ return false; } SetMovieActive(vpd->moviePtr, true); StartMovie(vpd->moviePtr); //------------------ set the movie rate to default //------------------ and preroll, so the first frames come correct TimeValue timeNow; Fixed playRate; timeNow = GetMovieTime(vpd->moviePtr, 0); playRate =GetMoviePreferredRate(vpd->moviePtr); PrePrerollMovie(vpd->moviePtr, timeNow, playRate, 0, 0); PrerollMovie(vpd->moviePtr, timeNow, playRate); SetMovieRate(vpd->moviePtr, playRate); setLoopState(OF_QT_LOOP_NORMAL); bLoadedMovie = true; // get some pixels in there right away. MoviesTask(vpd->moviePtr,0); convertPixels(vpd->offscreenGWorldPixels, vpd->pixels, vpd->w, vpd->h); vpd->bUseTexture = bUseTexture; vpd->tex = &tex; if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.allocate(width,height,GL_RGB); memset(vpd->pixels, 0, width*height*3); vpd->tex->loadData(vpd->pixels, vpd->w, vpd->h, GL_RGB); } return true; } //-------------------------------------------------------- void ofVideoPlayer::setVolume(int volume){ Movie moviePtr = vpd->moviePtr; SetMovieVolume(moviePtr, volume); } //-------------------------------------------------------- void ofVideoPlayer::setLoopState(int state){ Movie moviePtr = vpd->moviePtr; TimeBase myTimeBase; long myFlags = 0L; myTimeBase = GetMovieTimeBase(moviePtr); myFlags = GetTimeBaseFlags(myTimeBase); switch (state) { case OF_QT_LOOP_NORMAL: myFlags |= loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, hintsLoop, hintsLoop); SetMoviePlayHints(moviePtr, 0L, hintsPalindrome); break; case OF_QT_LOOP_PALINDROME: myFlags |= loopTimeBase; myFlags |= palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, hintsLoop, hintsLoop); SetMoviePlayHints(moviePtr, hintsPalindrome, hintsPalindrome); break; case OF_QT_LOOP_NONE: default: myFlags &= ~loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, 0L, hintsLoop | hintsPalindrome); break; } SetTimeBaseFlags(myTimeBase, myFlags); } //--------------------------------------------------------------------------- void ofVideoPlayer::setPosition(float pct){ TimeRecord tr; Movie moviePtr = vpd->moviePtr; tr.base = GetMovieTimeBase(moviePtr); long total = GetMovieDuration(moviePtr ); long newPos = (long)((float)total * pct); SetMovieTimeValue(moviePtr, newPos); } //--------------------------------------------------------------------------- float ofVideoPlayer::getDuration(){ Movie moviePtr = vpd->moviePtr; return GetMovieDuration (moviePtr) / (double) GetMovieTimeScale (moviePtr); } //--------------------------------------------------------------------------- float ofVideoPlayer::getPosition(){ Movie moviePtr = vpd->moviePtr; long total = GetMovieDuration(moviePtr); long current = GetMovieTime(moviePtr, nil); float pct = ((float)current/(float)total); return pct; } //--------------------------------------------------------------------------- void ofVideoPlayer::setSpeed(float _speed){ Movie moviePtr = vpd->moviePtr; speed = _speed; SetMovieRate(moviePtr, X2Fix(speed)); } //--------------------------------------------------------------------------- float ofVideoPlayer::getSpeed(){ return speed; } //--------------------------------------------------------------------------- void ofVideoPlayer::setPaused(bool bPause){ // there might be a more "quicktime-ish" way (or smarter way) // to do this for now, to pause, set the speed to zero, // on un-pause, set the speed to "speed" // (and hope that speed != 0...) if (bPause == true) setSpeed(0); else setSpeed(speed); } //------------------------------------ void ofVideoPlayer::setUseTexture(bool bUse){ bUseTexture = bUse; vpd->bUseTexture = bUseTexture; vpd->tex = &tex; } //------------------------------------ void ofVideoPlayer::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } //------------------------------------ void ofVideoPlayer::draw(float _x, float _y){ draw(_x, _y, width, height); } Node-path: video/ofVideoPlayer.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2930 Text-content-md5: 2593f518e6997c241855a9788cb880fc Content-length: 2940 PROPS-END #ifndef _OF_VIDEO_PLAYER #define _OF_VIDEO_PLAYER #include "ofConstants.h" #include "ofQtUtils.h" #include "ofTexture.h" //------------------------------------------------- // (notes, links, etc) // // intersting technique employed here to get to RGB24 // from YUV2 - worthwhile? // paste.lisp.org/display/1051 //----------------------------- // http://viewcvs.osafoundation.org/chandler/trunk/internal/wx/src/msw/mediactrl.cpp?rev=6281&view=markup // http://developer.apple.com/documentation/QuickTime/INMAC/QT/iqMovieToolbox.34.htm // look for "QTURL_NewMovieFromURL", useful for loading URL based movies.. //------------------------------------------------- // // http://lists.apple.com/archives/QuickTime-API/2002/Feb/msg00118.html // //------------------------------------------------- // // note about callbacks: // // we use here a callback provided by quicktime to see if pixels have actually changed // the callback is "DrawCompleteProc" and int he quicktime code, // is defined as "static pascal OsErr ...." // in windows, I have dropped the pascal declaration as my compiler was // having trouble with that... necessary for mac? // // the alternative is to do what is done in qtVideoGrabber // set the alpha of the top pixel to 0x00 and every idle call // check to see if there are new pixels... #define OF_QT_LOOP_NONE 0x01 #define OF_QT_LOOP_PALINDROME 0x02 #define OF_QT_LOOP_NORMAL 0x03 //--------------------------------------------- // this struct has all the info we need to play 1 movie // kept in a struct, because the callback will // need to reference it... typedef struct { MovieController thePlayer; GWorldPtr offscreenGWorld; Movie moviePtr; Rect movieRect; unsigned char * offscreenGWorldPixels; // 32 bit: argb (qt k32ARGBPixelFormat) unsigned char * pixels; // 24 bit: rgb int w; int h; bool bHavePixelsChanged; ofTexture * tex; // a ptr to the texture we are utilizing bool bUseTexture; // are we using a texture } videoPlayerData; //--------------------------------------------- class ofVideoPlayer{ public: ofVideoPlayer (); void closeMovie(); bool loadMovie(char * name); void idleMovie(); // rename to updateMovie? int width, height; float speed; bool bLoadedMovie; bool isFrameNew(); unsigned char * getPixels(); float getPosition(); float getSpeed(); float getDuration(); void setPosition(float pct); void setVolume(int volume); void setLoopState(int state); void setSpeed(float speed); void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); void draw(float x, float y); void setPaused(bool bPause); private: //--------------------------- videoPlayerData * vpd; ofTexture tex; bool bUseTexture; }; #endif Revision-number: 32 Prop-content-length: 138 Content-length: 138 K 7 svn:log V 36 zach -- fmod added via ofSoundPlayer K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-26T15:58:39.418624Z PROPS-END Node-path: sound/ofFmodUtils.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1979 Text-content-md5: 0a2a4e8775729a1415be9160b44e8f5a Content-length: 1989 PROPS-END #include "ofFmodUtils.h" static bool bFmodInitialized = false; // dsp callback? // interesting? // http://66.102.9.104/search?q=cache:LM47mq8hytwJ:www.cleeker.com/doxygen/audioengine__fmod_8cpp-source.html+FSOUND_Sample_Load+cpp&hl=en&ct=clnk&cd=18&client=firefox-a // ---------------------------------------------------------------------------- void initializeFmod(){ // linux users: // an example of setting up fmod for different audio systems // is in this code: // http://66.102.9.104/search?q=cache:LM47mq8hytwJ:www.cleeker.com/doxygen/audioengine__fmod_8cpp-source.html+FSOUND_Sample_Load+cpp&hl=en&ct=clnk&cd=18&client=firefox-a if (bFmodInitialized == false){ if (FSOUND_GetVersion() < FMOD_VERSION){ printf("Error : You are using the wrong DLL version! You should be using FMOD %.02f\n", FMOD_VERSION); return; } FSOUND_Init( 44100, 32, 0 ); //FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND); // Direct Sound //FSOUND_SetDriver(0); //FSOUND_SetMixer(FSOUND_MIXER_AUTODETECT); bFmodInitialized = true; } } void closeFmod(){ FSOUND_Close(); } /* // ---------------------------------------------------------------------------- void ofSampleSoundSystem::useSpectrum( const bool useSpectrum ){ FSOUND_DSP_SetActive( FSOUND_DSP_GetFFTUnit( ), useSpectrum ); } // ---------------------------------------------------------------------------- void ofSampleSoundSystem::getSpectrum( float *bufferToFill, const int numberOfBars ){ const float *spectrum = FSOUND_DSP_GetSpectrum( ); const float freqPerBand = 512.0f / ( (float) numberOfBars ); for ( int i = 0; i < numberOfBars; ++i ) { int offset = (int) ( ( (float) i ) * freqPerBand ); float spectrumValue = spectrum[ offset ] * 64.0f; if ( spectrumValue > 1.0f ) { spectrumValue = 1.0f; } bufferToFill[ i ] = spectrumValue; } } */ Node-path: sound/ofFmodUtils.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 323 Text-content-md5: f3b385aa6fc71c25273f5c69e8e6422a Content-length: 333 PROPS-END #ifndef _OF_FMOD_UTILS #define _OF_FMOD_UTILS #include "ofConstants.h" #include "fmod.h" // these are handled be the soundPlayer object // users shouldn't have to touch them: void initializeFmod(); // initilize fmod, if it's not already on void closeFmod(); // close fmod, if it's on; #endif Node-path: sound/ofSoundPlayer.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 6220 Text-content-md5: bdc4756d05517faa7a0619e6d19ed83d Content-length: 6230 PROPS-END #include "ofSoundPlayer.h" // these are global functions, that affect every sound / channel: // ------------------------------------------------------------ // ------------------------------------------------------------ bool bUseSpectrum = false; float fftValues[512]; // max # bands is 512 //-------------------- void ofSoundStopAll(){ FSOUND_StopSound(FSOUND_ALL); } //-------------------- void ofSoundSetVolume(float vol){ FSOUND_SetVolume(FSOUND_ALL, (int)(vol*255.0f)); } //-------------------- void ofSoundSetUseSpectrum(bool use){ bUseSpectrum = use; FSOUND_DSP_SetActive( FSOUND_DSP_GetFFTUnit( ), bUseSpectrum); } //-------------------- float * ofSoundGetSpectrum(int nBands){ // ------------------------------------ // [note] this code snippet comes from: // http://qepsilon.org/doc/snd__main_8cpp-source.html // via gamedev.net forum // ------------------------------------ if (nBands > 512){ printf("error in ofSoundGetSpectrum, the maximum number of bands is 512 - you asked for %i\nwe will return 512\n", nBands); nBands = 512; } // now, get the spectrum and // place it into fftValues array with the nBands requested // for returning: float *spectrum = FSOUND_DSP_GetSpectrum( ); int ctr = 0; int FreqPerBand = 448 / nBands; for (int i = 0; i < nBands; i++){ fftValues[i] = 0.0f; for (int j = 0; j < FreqPerBand; j++){ fftValues[i] += spectrum[ctr++]; } fftValues[i] = fftValues[i] / 1.5f; if (fftValues[i] > 1.0f){ fftValues[i] = 1.0f; } } return fftValues; } // ------------------------------------------------------------ // ------------------------------------------------------------ // now, the individual sound player: //------------------------------------------------------------ ofSoundPlayer::ofSoundPlayer(){ bLoop = false; bLoadedOk = false; channel = -1; pan = 0.5f; volume = 1.0f; internalFreq = 44100; speed = 1; bPaused = false; } //------------------------------------------------------------ void ofSoundPlayer::loadSound(char * fileName){ // fmod uses IO posix internally, might have trouble // with unicode paths... // says this code: // http://66.102.9.104/search?q=cache:LM47mq8hytwJ:www.cleeker.com/doxygen/audioengine__fmod_8cpp-source.html+FSOUND_Sample_Load+cpp&hl=en&ct=clnk&cd=18&client=firefox-a // for now we use FMODs way, but we could switch if // there are problems: // [1] init fmod, if necessary initializeFmod(); // [2] try to unload any previously loaded sounds // & prevent user-created memory leaks // if they call "loadSound" repeatedly, for example unloadSound(); // [3] load sound samp = FSOUND_Sample_Load(FSOUND_UNMANAGED, fileName, FSOUND_NORMAL, 0, 0); if (!samp){ bLoadedOk = false; } else { bLoadedOk = true; length = FSOUND_Sample_GetLength(samp); } } //------------------------------------------------------------ void ofSoundPlayer::unloadSound(){ if (bLoadedOk){ stop(); // try to stop the sound FSOUND_Sample_Free(samp); // & free the sample } } //------------------------------------------------------------ bool ofSoundPlayer::getIsPlaying(){ if (channel == -1 || !bLoadedOk) return false; return FSOUND_IsPlaying(channel); } //------------------------------------------------------------ void ofSoundPlayer::setVolume(float vol){ if (getIsPlaying() == true){ FSOUND_SetVolume(channel, (int)(vol*255.0f)); volume = vol; } } //------------------------------------------------------------ void ofSoundPlayer::setPosition(float pct){ if (getIsPlaying() == true){ int sampleToBeAt = (int)(length * pct); FSOUND_SetCurrentPosition(channel, sampleToBeAt); } } //------------------------------------------------------------ float ofSoundPlayer::getPosition(){ if (getIsPlaying() == true){ int sampleImAt; sampleImAt = (int)FSOUND_GetCurrentPosition(channel); float pct = 0.0f; if (length > 0){ pct = sampleImAt / (float)length; } return pct; } else { return 0; } } //------------------------------------------------------------ void ofSoundPlayer::setPan(float p){ if (getIsPlaying() == true){ FSOUND_SetPan(channel, (int)(p*255.0f)); pan = p; } } //------------------------------------------------------------ void ofSoundPlayer::setPaused(bool bP){ if (getIsPlaying() == true){ FSOUND_SetPaused(channel, bP); bPaused = bP; } } //------------------------------------------------------------ void ofSoundPlayer::setSpeed(float spd){ FSOUND_SetFrequency(channel, internalFreq * spd); speed = spd; } //------------------------------------------------------------ void ofSoundPlayer::setLoop(bool bLp){ FSOUND_SetLoopMode(channel, (bLp == true) ? FSOUND_LOOP_NORMAL : FSOUND_LOOP_OFF); bLoop = bLp; } // ---------------------------------------------------------------------------- void ofSoundPlayer::setMultiplay(bool bMp){ bMultiplay = bMp; // be careful with this... } // ---------------------------------------------------------------------------- void ofSoundPlayer::play(){ // if it's a looping sound, we should try to kill it, no? // or else people will have orphan channels that are looping if (bLoop == true){ FSOUND_StopSound(channel); } // if the sound is not set to multiplay, then stop the current, // before we start another if (!bMultiplay){ FSOUND_StopSound(channel); } channel = FSOUND_PlaySound(FSOUND_FREE, samp); internalFreq = FSOUND_GetFrequency(channel); FSOUND_SetVolume(channel, (int)(volume*255.0f)); FSOUND_SetPan(channel, (int)(pan*255.0f)); FSOUND_SetPaused(channel, bPaused); FSOUND_SetFrequency(channel, internalFreq * speed); FSOUND_SetLoopMode(channel, (bLoop == true) ? FSOUND_LOOP_NORMAL : FSOUND_LOOP_OFF); } // ---------------------------------------------------------------------------- void ofSoundPlayer::stop(){ FSOUND_StopSound(channel); } Node-path: sound/ofSoundPlayer.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1549 Text-content-md5: b1fb7cadf69732e7e575c9a67bed1f8e Content-length: 1559 PROPS-END #ifndef _OF_SAMPLE_SOUND #define _OF_SAMPLE_SOUND #include "fmod.h" #include "ofFmodUtils.h" // TO DO : // --------------------------- // -fft via fmod, as in the last time... // -close fmod if it's up // -streaming (long mp3s, urls, etc) // -loadSoundForStreaming(char * fileName); // --------------------------- // ---------------------------------------------------------------------------- SOUND SYSTEM FMOD // --------------------- global functions: void ofSoundStopAll(); void ofSoundSetVolume(float vol); void ofSoundSetUseSpectrum(bool use); float * ofSoundGetSpectrum(int nBands); // max 512... // --------------------- player functions: class ofSoundPlayer{ public: ofSoundPlayer(); void loadSound(char * fileName); void unloadSound(); void play(); void stop(); void setVolume(float vol); void setPan(float vol); void setSpeed(float vol); void setPaused(bool bP); void setLoop(bool bLp); void setMultiplay(bool bMp); void setPosition(float pct); // 0 = start, 1 = end; float getPosition(); bool getIsPlaying(); bool bMultiplay; bool bLoop; bool bLoadedOk; bool bPaused; int channel; // in Fmod, what channel am I playing on? float pan; // 0 - 1 float volume; // 0 - 1 float internalFreq; // 44100 ? float speed; // -n to n, 1 = normal, -1 backwards int length; // in samples; FSOUND_SAMPLE * samp; }; #endif // _OF_SAMPLE_SOUND Revision-number: 33 Prop-content-length: 127 Content-length: 127 K 7 svn:log V 25 // zach - renamed ofAudio K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-26T15:59:12.447874Z PROPS-END Node-path: sound/ofAudio.cpp Node-action: delete Node-path: sound/ofAudio.h Node-action: delete Revision-number: 34 Prop-content-length: 144 Content-length: 144 K 7 svn:log V 42 // zach - renamed ofAudio to ofAudioStream K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-26T15:59:56.734736Z PROPS-END Node-path: sound/ofAudioStream.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 3614 Text-content-md5: cf31c27bbb7cf7c502d0d115d06dbd34 Content-length: 3624 PROPS-END #include "ofAudioStream.h" #include "rtAudio.h" //----------------------------------- static variables: static ofSimpleApp * OFSAptr; RtAudio * audio; int nInputChannels; int nOutputChannels; int receiveAudioBufferAndCallSimpleApp(char *buffer, int bufferSize, void *data); //------------------------------------------------------------------------------ int receiveAudioBufferAndCallSimpleApp(char *buffer, int bufferSize, void *data){ // rtAudio uses a system by which the audio // can be of different formats // char, float, etc. // we choose float float * fPtr = (float *)buffer; // [zach] memset output to zero before output call // this is because of how rtAudio works: duplex w/ one callback // you need to cut in the middle. if the simpleApp // doesn't produce audio, we pass silence instead of duplex... if (nInputChannels > 0){ OFSAptr->audioReceived(fPtr, bufferSize, nInputChannels); memset(fPtr, 0, bufferSize * nInputChannels * sizeof(float)); } if (nOutputChannels > 0) OFSAptr->audioRequested(fPtr, bufferSize, nOutputChannels); return 0; } //--------------------------------------------------------- void ofAudioStreamSetup(int nOutputs, int nInputs, ofSimpleApp * OFSA){ ofAudioStreamSetup(nOutputs, nInputs, OFSA, 44100, 256, 4); } //--------------------------------------------------------- void ofAudioStreamSetup(int nOutputs, int nInputs, ofSimpleApp * OFSA, int sampleRate, int bufferSize, int nBuffers){ nInputChannels = nInputs; nOutputChannels = nOutputs; int device = 0; // default OFSAptr = OFSA; bufferSize = ofNextPow2(bufferSize); // must be pow2 try { audio = new RtAudio(); audio->openStream( device, nOutputs, device, nInputs, RTAUDIO_FLOAT32, sampleRate, &bufferSize, nBuffers); } catch (RtError &error) { error.printMessage(); //std::exit(EXIT_FAILURE); // need case here } try { audio->setStreamCallback(&receiveAudioBufferAndCallSimpleApp, (void *)NULL); audio->startStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioStreamStop(){ try { audio->stopStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioStreamStart(){ try{ audio->startStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioStreamEnd(){ try { audio->stopStream(); audio->closeStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofAudioStreamListDevices(){ RtAudio *audioTemp = 0; try { audioTemp = new RtAudio(); } catch (RtError &error) { error.printMessage(); } int devices = audioTemp->getDeviceCount(); RtAudioDeviceInfo info; for (int i=1; i<=devices; i++) { try { info = audioTemp->getDeviceInfo(i); } catch (RtError &error) { error.printMessage(); break; } std::cout << "device = " << i << " (" << info.name << ")\n"; if (info.isDefault) std::cout << "----* default ----* \n"; std::cout << "maximum output channels = " << info.outputChannels << "\n"; std::cout << "maximum input channels = " << info.inputChannels << "\n"; std::cout << "-----------------------------------------\n"; } delete audioTemp; } Node-path: sound/ofAudioStream.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 481 Text-content-md5: f4e36e09cc52ff3ecba46b67556bb31c Content-length: 491 PROPS-END #ifndef _OF_AUDIO #define _OF_AUDIO // to do: // fft -- coming very soon #include "ofMain.h" #include "ofSimpleApp.h" void ofAudioStreamSetup(int nOutputChannels, int nInputChannels, ofSimpleApp * OFSA); void ofAudioStreamSetup(int nOutputChannels, int nInputChannels, ofSimpleApp * OFSA, int sampleRate, int bufferSize, int nBuffers); void ofAudioStreamStop(); void ofAudioStreamStart(); void ofAudioStreamEnd(); void ofAudioStreamListDevices(); #endif Revision-number: 35 Prop-content-length: 181 Content-length: 181 K 7 svn:log V 79 // zach - renamed ofVideo classes to reflect the addition of dshow / videoInput K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-26T16:00:43.121301Z PROPS-END Node-path: video/ofQtVideoGrabber.h Node-action: delete Node-path: video/ofQtVideoPlayer.cpp Node-action: delete Node-path: video/ofQtVideoPlayer.h Node-action: delete Node-path: video/ofQtVideoGrabber.cpp Node-action: delete Revision-number: 36 Prop-content-length: 128 Content-length: 128 K 7 svn:log V 26 // zach - various cleanups K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-26T16:01:19.997817Z PROPS-END Node-path: utils/ofMath.cpp Node-kind: file Node-action: change Text-content-length: 1178 Text-content-md5: eb0b5ded56b0ca5566ffa979a49a156b Content-length: 1178 #include "ofMath.h" //-------------------------------------------------- int ofNextPow2(int a){ // from nehe.gamedev.net lesson 43 int rval=1; while(rval 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ // use smoothness, if requested: if (bSmoothHinted){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // draw: glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted){ glPopAttrib(); } } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted){ glPopAttrib(); } } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted){ glPopAttrib(); } } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ // use smoothness, if requested: if (bSmoothHinted){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // draw: glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted){ glPopAttrib(); } } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ // use smoothness, if requested: if (bSmoothHinted){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // draw: glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted){ glPopAttrib(); } } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b, int _a){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); float a = (float)_a / 255.0f; a = MAX(0,MIN(a,1.0f)); glColor4f(r,g,b,a); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } //---------------------------------------------------------- void ofEnableAlphaBlending(){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void ofDisableAlphaBlending(){ glDisable(GL_BLEND); } //---------------------------------------------------------- void ofEnableSmoothing(){ // please see: // http://www.opengl.org/resources/faq/technical/rasterization.htm bSmoothHinted = true; } //---------------------------------------------------------- void ofDisableSmoothing(){ bSmoothHinted = false; } //-------------------------------------------------- void ofDrawBitmapString(char *string, float x, float y){ //--------------------------------------------------- // for now this is fixed to the 8_BY_13 glut character // http://pyopengl.sourceforge.net/documentation/manual/glutBitmapCharacter.3GLUT.html //--------------------------------------------------- char *c; float yOffset = 0; float fontSize = 8.0f; glRasterPos2f(x,y); for (c=string; *c != '\0'; c++) { if(*c == '\n') { yOffset -= (fontSize*1.7); glRasterPos2f(x,y + (int)yOffset); } else if (((int)*c) >= 32){ // < 32 = control characters - don't draw // solves a bug with control characters // getting drawn when they ought to not be glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c); } } } //---------------------------------------------------------- void ofSetupScreen(){ int w, h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } Node-path: graphics/ofGraphics.h Node-kind: file Node-action: change Text-content-length: 1376 Text-content-md5: 480dd2dc5411c34e633405afdd82d959 Content-length: 1376 #ifndef OF_GEOM #define OF_GEOM #include "ofConstants.h" #define CIRC_RESOLUTION 22 // 22 pts for a circle... // bg color float * ofBgColorPtr(); void ofBackground(int r, int g, int b); // origin bool, since people are asking to change to top left // put in now as a means to test changes needed bool ofbOriginBottomLeft(); // geometry void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3); void ofCircle(float x,float y, float radius); void ofEllipse(float x, float y, float width, float height); void ofLine(float x1,float y1,float x2,float y2); void ofRect(float x1,float y1,float w, float h); void ofSetCircleResolution(int res); // if there 22 is a problem, you can change it here // drawing options void ofNoFill(); void ofFill(); // color options void ofSetColor(int r, int g, int b); // 0-255 void ofSetColor(int r, int g, int b, int a); // 0-255 void ofSetColor(int hexColor); // hex, like web 0xFF0033; // transparency void ofEnableAlphaBlending(); // this just turns on and off opengl blending, the common mode void ofDisableAlphaBlending(); // smooth void ofEnableSmoothing(); void ofDisableSmoothing(); // bitmapped type // ** note, this uses glDrawPixels and may be S L 0 W on some graphics cards void ofDrawBitmapString( char *string, float x, float y); // screen coordinate things... void ofSetupScreen(); #endif Revision-number: 38 Prop-content-length: 158 Content-length: 158 K 7 svn:log V 56 // zach - added grab from screen, and draw with just x,y K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-26T16:02:50.369229Z PROPS-END Node-path: graphics/ofTexture.cpp Node-kind: file Node-action: change Text-content-length: 5471 Text-content-md5: 5238f1dbc1c79d32472c23898237fe04 Content-length: 5471 #include "ofTexture.h" #include "ofUtils.h" // for nextPow2() //---------------------------------------------------------- ofTexture::ofTexture(){ texName[0] = 0; } //---------------------------------------------------------- void ofTexture::clear(){ // try to free up the texture memory so we don't reallocate // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/deletetextures.html if (texName[0] != 0){ glDeleteTextures(1, (GLuint *)texName); } width = 0; height = 0; } //---------------------------------------------------------- void ofTexture::allocate(int w, int h, int internalGlDataType){ // can pass in anything (320x240) (10x5) // here we make it power of 2 for opengl (512x256), (16x8) tex_w = ofNextPow2(w); tex_h = ofNextPow2(h); tex_u = 1.0f; tex_t = 1.0f; // attempt to free the previous bound texture, if we can: clear(); glGenTextures(1, (GLuint *)texName); // could be more then one, but for now, just one glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); // upload 0 or white pixels.... glTexImage2D(GL_TEXTURE_2D, 0, internalGlDataType, tex_w, tex_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); // init to black... glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); width = w; height = h; } //---------------------------------------------------------- void ofTexture::loadData(unsigned char * data, int w, int h, int glDataType){ // can we allow for uploads bigger then texture and // just take as much as the texture can? // // ie: // int uploadW = MIN(w, tex_w); // int uploadH = MIN(h, tex_h); // but with a "step" size of w? // check "glTexSubImage2D" if ( w > tex_w || h > tex_h) { printf("image data too big for allocated texture. not uploading... \n"); return; } width = w; height = h; //compute new tex co-ords based on the ratio of data's w, h to texture w,h; tex_t = (float)(w) / (float)tex_w; tex_u = (float)(h) / (float)tex_h; // ok this is an ultra annoying bug : // opengl texels and linear filtering - // when we have a sub-image, and we scale it // we can clamp the border pixels to the border, // but the borders of the sub image get mixed with // neighboring pixels... // grr... // // the best solution would be to pad out the image // being uploaded with 2 pixels on all sides, and // recompute tex_t coordinates.. // another option is a gl_arb non pow 2 textures... // the current hack is to alter the tex_t, tex_u calcs, but // that makes the image slightly off... // this is currently being done in draw... // // we need a good solution for this.. // // http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014770#000001 // http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014770#000001 //------------------------ likely, we are uploading continuous data GLint prevAlignment; glGetIntegerv(GL_UNPACK_ALIGNMENT, &prevAlignment); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // update the texture image: glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); glTexSubImage2D(GL_TEXTURE_2D,0,0,0,w,h,glDataType,GL_UNSIGNED_BYTE,data); glDisable(GL_TEXTURE_2D); //------------------------ back to normal. glPixelStorei(GL_UNPACK_ALIGNMENT, prevAlignment); } //---------------------------------------------------------- void ofTexture::loadScreenData(int x, int y, int w, int h){ glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); glCopyTexSubImage2D(GL_TEXTURE_2D, 0,0,0,x,y,w,h); glDisable(GL_TEXTURE_2D); } //---------------------------------------------------------- void ofTexture::draw(float x, float y, float w, float h){ glEnable(GL_TEXTURE_2D); // bind the texture glBindTexture( GL_TEXTURE_2D, (GLuint)texName[0] ); float px0 = x ; // up to you to get the aspect ratio right float py0 = y ; float px1 = x+w; float py1 = y+h; // ------------------------------------------------- // complete hack to remove border artifacts. // slightly, slightly alters an image, scaling... // to remove the border. // we need a better solution for this, but // to constantly add a 2 pixel border on all uploaded images // is insane.. float offsetw = 1.0f/(tex_w*2.0f); float offseth = 1.0f/(tex_h*2.0f); // ------------------------------------------------- float tx0 = 0+offsetw; float ty0 = 0+offseth; float tx1 = tex_t - offsetw; float ty1 = tex_u - offseth; glBegin( GL_QUADS ); glTexCoord2f(tx0,ty0); glVertex3f(px0, py0,0); glTexCoord2f(tx1,ty0); glVertex3f(px1, py0,0); glTexCoord2f(tx1,ty1); glVertex3f(px1, py1,0); glTexCoord2f(tx0,ty1); glVertex3f(px0, py1,0); glEnd(); glDisable(GL_TEXTURE_2D); } //---------------------------------------------------------- void ofTexture::draw(float x, float y){ draw(x,y,width, height); } Node-path: graphics/ofTexture.h Node-kind: file Node-action: change Text-content-length: 649 Text-content-md5: f988b99cce9e3ee06362982536f79c66 Content-length: 649 #ifndef _IMAGE_TEXTURE_H_ #define _IMAGE_TEXTURE_H_ #include "ofConstants.h" class ofTexture { public : ofTexture(); void allocate(int w, int h, int internalGlDataType); void clear(); void loadData(unsigned char * data, int w, int h, int glDataType); void loadScreenData(int x, int y, int w, int h); void draw(float x, float y, float w, float h); void draw(float x, float y); float tex_t, tex_u; int width, height; // private: float offset_x, offset_y; int tex_w, tex_h; unsigned int texName[1]; // vs not happy with dynamic allocation of this... }; #endif Revision-number: 39 Prop-content-length: 168 Content-length: 168 K 7 svn:log V 66 // zach - start of attempts to fix (0,0) to top left via a boolean K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-26T16:03:53.027606Z PROPS-END Node-path: graphics/ofTrueTypeFont.cpp Node-kind: file Node-action: change Text-content-length: 12269 Text-content-md5: 2edbdff2c836210f29e3b9fe0139dba0 Content-length: 12269 #include "ofTrueTypeFont.h" //-------------------------- #ifdef TARGET_WIN32 #include #include #include #include #include #endif #ifdef TARGET_OSX #include "ft2build.h" #include "freetype.h" #include "ftglyph.h" #include "ftoutln.h" #include "fttrigon.h" #endif //------------------------------------------------------------------ ofTrueTypeFont::ofTrueTypeFont(){ bLoadedOk = false; } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize){ // load anti-aliased, non-full character set: loadFont(filename, fontsize, true, false); } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet){ bLoadedOk = false; bAntiAlised = _bAntiAliased; bFullCharacterSet = _bFullCharacterSet; //--------------- load the library and typeface FT_Library library; if (FT_Init_FreeType( &library )){ printf("PROBLEM WITH FT lib \n"); return; } FT_Face face; if (FT_New_Face( library, filename, 0, &face )) { return; } FT_Set_Char_Size( face,fontsize << 6,fontsize << 6,96,96); lineHeight = fontsize * 1.43f; //------------------------------------------------------ //kerning would be great to support: //printf("FT_HAS_KERNING ? %i \n", FT_HAS_KERNING(face)); //------------------------------------------------------ nCharacters = bFullCharacterSet ? 256 : 128 - NUM_CHARACTER_TO_START; //--------------- initialize character info and textures cps = new charProps[nCharacters]; texNames = new GLuint[nCharacters]; glGenTextures(nCharacters, texNames); //--------------------- load each char ----------------------- for (int i = 0 ; i < nCharacters; i++){ //------------------------------------------ anti aliased or not: if (bAntiAlised == true){ if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph %i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); } else { if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph%i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO); } //------------------------------------------ FT_Bitmap& bitmap= face->glyph->bitmap; // 1 pixel border around the glyph int border = 2; // prepare the texture: int width = ofNextPow2( bitmap.width + border); int height = ofNextPow2( bitmap.rows + border); // ------------------------- this is fixing a bug with small type // ------------------------- appearantly, opengl has trouble with // ------------------------- width or height textures of 1, so we // ------------------------- we just set it to 2... if (width == 1) width = 2; if (height == 1) height = 2; // ------------------------- // info about the character: cps[i].value = i; cps[i].height = face->glyph->bitmap_top; cps[i].width = face->glyph->bitmap.width; cps[i].setWidth = face->glyph->advance.x >> 6; cps[i].topExtent = face->glyph->bitmap.rows; cps[i].leftExtent = face->glyph->bitmap_left; // texture internals cps[i].tTex = (float)bitmap.width / (float)width; cps[i].vTex = (float)bitmap.rows / (float)height; cps[i].xOff = ((1.0+(float)bitmap.width) / (float)width) - cps[i].tTex; cps[i].yOff = ((1.0+(float)bitmap.rows) / (float)height) - cps[i].vTex; /* sanity check: printf("%i %i %i %i %i %i \n", cps[i].value , cps[i].height , cps[i].width , cps[i].setWidth , cps[i].topExtent , cps[i].leftExtent ); */ // Allocate Memory For The Texture Data. unsigned char* expanded_data = new unsigned char[ 2 * width * height]; //-------------------------------- clear data: for(int j=0; j =bitmap.width || j-1>=bitmap.rows) ? 0 : 255; expanded_data[2*(k+j*width)+1] = (k-1>=bitmap.width || j-1>=bitmap.rows) ? 0 : bitmap.buffer[k-1 + bitmap.width*(j-1)]; } } //----------------------------------- } else { //----------------------------------- // true type packs monochrome info in a // 1-bit format, hella funky // here we unpack it: unsigned char *src = bitmap.buffer; for(int j=0; j = nCharacters){ //printf("Error : char (%i) not allocated -- line %d in %s\n", (c + NUM_CHARACTER_TO_START), __LINE__,__FILE__); return; } //----------------------- int cu = c; float height = cps[cu].height; float bwidth = cps[cu].width; float top = cps[cu].topExtent - cps[cu].height; float lextent = cps[cu].leftExtent; float t = cps[cu].tTex; float v = cps[cu].vTex; float xOff = cps[cu].xOff; float yOff = cps[cu].yOff; if (glIsTexture(texNames[cu])) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texNames[cu]); glNormal3f(0, 0, 1); if (ofbOriginBottomLeft()){ glBegin(GL_QUADS); glTexCoord2d(xOff,yOff); glVertex2f(x + lextent, y + height); glTexCoord2d(xOff,v+yOff); glVertex2f(x + lextent, y-top); glTexCoord2d(t+xOff,v+yOff); glVertex2f(x + lextent + bwidth,y-top); glTexCoord2d(t+xOff,yOff); glVertex2f(x + + lextent + bwidth,y + height); glEnd(); } else { glBegin(GL_QUADS); glTexCoord2d(xOff,v+yOff); glVertex2f(x + lextent, y + height); glTexCoord2d(xOff,yOff); glVertex2f(x + lextent, y-top); glTexCoord2d(t+xOff,yOff); glVertex2f(x + lextent + bwidth,y-top); glTexCoord2d(t+xOff,v+yOff); glVertex2f(x + + lextent + bwidth,y + height); glEnd(); } glDisable(GL_TEXTURE_2D); } else { //let's add verbosity levels somewhere... //this error, for example, is kind of annoying to see //all the time: //printf("Warning : texture not bound for character -- line %d in %s\n", __LINE__,__FILE__); } } //----------------------------------------------------------- float ofTrueTypeFont::stringWidth(char *c) { float width = 0; int index = 0; float widthTemp = 0; bool bMultiLine = false; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { width = MAX(width, widthTemp); widthTemp = 0; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; widthTemp += cps[cy].width; } else { widthTemp += cps[cy].setWidth; } } index++; } width = MAX(width, widthTemp); return width; } //----------------------------------------------------------- float ofTrueTypeFont::stringHeight(char *c) { float height = 0; int index = 0; float maxHeight = 0; bool bFirstLineOfMultiLine = true; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { if (bFirstLineOfMultiLine == true){ bFirstLineOfMultiLine = false; height += maxHeight; } else { height += lineHeight; } maxHeight = 0; } else if (c[index] == ' ') { } else { float ht = cps[cy].height; if (ht > maxHeight) maxHeight = ht; } } index++; } height += maxHeight; return height; } //===================================================================== void ofTrueTypeFont::drawString(char *c, float x, float y) { if (!bLoadedOk){ printf("Error : font not allocated -- line %d in %s\n", __LINE__,__FILE__); return; }; // we need transparency to draw text, but we don't know // if that is set up in outside of this function // we "pushAttrib", turn on alpha and "popAttrib" // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushattrib.html // **** note **** // I have read that pushAttrib() is slow, if used often, // maybe there is a faster way to do this? // ie, check if blending is enabled, etc... // glIsEnabled().... glGet()... // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/get.html // ************** // (a) record the current "alpha state, blend func, etc" glPushAttrib(GL_COLOR_BUFFER_BIT); // (b) enable our regular ALPHA blending! glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); float startX = x; int index = 0; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { x = startX; int cy = (int)'M' - NUM_CHARACTER_TO_START; y -= lineHeight; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; x += cps[cy].width; } else { drawChar(cy, x, y); x += cps[cy].setWidth; } } index++; } // (c) return back to the way things were (with blending, blend func, etc) glPopAttrib(); } Node-path: graphics/ofTrueTypefont.h Node-kind: file Node-action: change Text-content-length: 1260 Text-content-md5: 7f28a33e97bb8cb76c3da704066b2166 Content-length: 1260 #ifndef _OF_TTF_FONT_H_ #define _OF_TTF_FONT_H_ #include "ofConstants.h" #include "ofGraphics.h" //-------------------------------------------------- typedef struct { int value; int height; int width; int setWidth; int topExtent; int leftExtent; float tTex; float vTex; //0-1 pct of bitmap... float xOff; float yOff; } charProps; //-------------------------------------------------- #define NUM_CHARACTER_TO_START 33 // 0 - 32 are control characters, no graphics needed. class ofTrueTypeFont{ public: ofTrueTypeFont(); // -- default, non-full char set, anti aliased: void loadFont(const char *filename, int fontsize); void loadFont(const char *filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet); bool bLoadedOk; bool bAntiAlised; bool bFullCharacterSet; float getLineHeight(); void setLineHeight(float height); float stringWidth(char *s); float stringHeight(char *c); void drawString(char *c, float x, float y); int nCharacters; protected: float lineHeight; charProps * cps; // properties for each character GLuint * texNames; // textures for each character void drawChar(int c, float x, float y); int ofNextPow2 (int a); }; #endif Revision-number: 40 Prop-content-length: 142 Content-length: 142 K 7 svn:log V 40 //zach - fixes for direct show addition. K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-26T16:04:27.635354Z PROPS-END Node-path: video/ofQtUtils.cpp Node-kind: file Node-action: change Text-content-length: 4036 Text-content-md5: 814dc86f4b6732282aa779f0bc8f21c2 Content-length: 4036 #include "ofQtUtils.h" static bool bQuicktimeInitialized = true; //---------------------------------------- void initializeQuicktime(){ if (bQuicktimeInitialized == true){ //---------------------------------- // do we have quicktime installed at all? // http://www.apple.com/quicktime/download/win.html // can gestalt help with versions, or is that only after init? long myAttrs; OSErr myErr = noErr; #ifdef TARGET_WIN32 myErr = InitializeQTML(0); if (myErr != noErr){ printf("----------------------------------------------------- \n"); printf("sorry, there is a problem with quicktime starting up \nplease check!"); OF_EXIT_APP(0); } #endif myErr = EnterMovies (); if (myErr != noErr){ printf("----------------------------------------------------- \n"); printf("sorry, there is a problem with quicktime starting up \nplease check!"); OF_EXIT_APP(0); } bQuicktimeInitialized = false; } } //---------------------------------------- void convertPixels(unsigned char * gWorldPixels, unsigned char * rgbPixels, int w, int h){ // ok for macs? // ok for intel macs? int * rgbaPtr = (int *) gWorldPixels; pix24 * rgbPtr = (pix24 *) rgbPixels; int totalPixelCount = w * h; unsigned char * rgbaStart; // putting in the boolean, so we can work on // 0,0 in top right... // bool bFlipVertically = true; bool bFlipVertically = ofbOriginBottomLeft(); // ------------------------------------------- // we flip vertically because the 0,0 position in OF // is the bottom left (not top left, like processing) // since the 0,0 of a picture is top left // if we upload and drawf the data as is // it will be upside-down.... // ------------------------------------------- if (!bFlipVertically){ //----- argb->rgb for (int i = 0; i < h; i++){ pix24 * rgbPtr = (pix24 *) rgbPixels + ((i) * w); for (int j = 0; j < w; j++){ rgbaStart = (unsigned char *)rgbaPtr; memcpy (rgbPtr, rgbaStart+1, sizeof(pix24)); rgbPtr++; rgbaPtr++; } } } else { //----- flip while argb->rgb for (int i = 0; i < h; i++){ pix24 * rgbPtr = (pix24 *) rgbPixels + ((h-i-1) * w); for (int j = 0; j < w; j++){ rgbaStart = (unsigned char *)rgbaPtr; memcpy (rgbPtr, rgbaStart+1, sizeof(pix24)); rgbPtr++; rgbaPtr++; } } } } //---------------------------------------- // osx needs this for modal dialogs. Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon){ #pragma unused(theDialog, itemHit) Boolean handled = false; if ((theEvent->what == updateEvt) && ((WindowPtr) theEvent->message == (WindowPtr) refCon)) { BeginUpdate ((WindowPtr) refCon); EndUpdate ((WindowPtr) refCon); handled = true; } return (handled); } //---------------------------------------- void initGrabbingComponent(videoGrabberData * vgd, bool bVerbose) { if (vgd->bSgInited == true) return; // don't do this twice OSErr err = noErr; vgd->gSeqGrabber = OpenDefaultComponent(SeqGrabComponentType, 0); err = GetMoviesError (); if (vgd->gSeqGrabber == NULL || err) { printf("error: can't get default sequence grabber component"); return; } err = SGInitialize(vgd->gSeqGrabber); if (err != noErr) { printf("error: can't initialize sequence grabber component"); return; } err = SGSetDataRef(vgd->gSeqGrabber, 0, 0, seqGrabDontMakeMovie); if (err != noErr) { printf("error: can't set the destination data reference"); return; } // windows crashes w/ out gworld, make a dummy for now... // this took a long time to figure out. err = SGSetGWorld(vgd->gSeqGrabber, 0, 0); if (err != noErr) { printf("error: setting up the gworld"); return; } err = SGNewChannel(vgd->gSeqGrabber, VideoMediaType, &(vgd->gVideoChannel)); if (err != noErr) { printf("error: creating a channel. Check if you have any qt capable cameras attached\n"); return; } vgd->bSgInited = true; } Node-path: video/ofQtUtils.h Node-kind: file Node-action: change Text-content-length: 1457 Text-content-md5: 6bca85b71a6c3b4e9014b16d60e318f7 Content-length: 1457 #ifndef _QT_UTILS #define _QT_UTILS #include "ofConstants.h" #include "ofGraphics.h" #if TARGET_OS_MAC #include #include #include #else #include #include #include #include #endif //-------------------------- helpful for rgba->rgb conversion typedef struct{ unsigned char r; unsigned char g; unsigned char b; } pix24; //-------------------------- for the video grabber typedef struct { unsigned char * offscreenGWorldPixels; // 32 bit: argb (qt k32ARGBPixelFormat) unsigned char * pixels; // 24 bit: rgb int w,h; bool bHavePixelsChanged; GWorldPtr videogworld; SeqGrabComponent gSeqGrabber; SGChannel gVideoChannel; Rect videoRect; bool bSgInited; } videoGrabberData; //--------------------------------------------- //ofQtVideoGrabber static vars static ComponentDescription theDesc; static Component sgCompID; //---------------------------------------- void initializeQuicktime(); void convertPixels(unsigned char * gWorldPixels, unsigned char * rgbPixels, int w, int h); Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon); void initGrabbingComponent(videoGrabberData * vgd, bool bVerbose); #endif Revision-number: 41 Prop-content-length: 146 Content-length: 146 K 7 svn:log V 44 // zach - dshow and high res timer additions K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-26T16:05:06.006477Z PROPS-END Node-path: utils/ofConstants.h Node-kind: file Node-action: change Text-content-length: 3125 Text-content-md5: 0f08ede76f78040957a21ea0ef0f1a32 Content-length: 3125 #ifndef OF_CONSTANTS #define OF_CONSTANTS //------------------------------- // pc or mac ? // soon: pc, mac or linux... #ifndef __APPLE_CC__ #define TARGET_WIN32 #else #define TARGET_OSX #endif //------------------------------- #ifdef TARGET_WIN32 #include #include "glut.h" #define __WINDOWS_DS__ #define __WINDOWS_MM__ #if (_MSC_VER) // microsoft visual studio #pragma warning(disable : 4996) // disable all deprecation warnings #pragma warning(disable : 4068) // unknown pragmas #pragma warning(disable : 4101) // unreferenced local variable #pragma warning(disable : 4312) // type cast conversion (in qt vp) #pragma warning(disable : 4311) // type cast pointer truncation (qt vp) #endif #define TARGET_LITTLE_ENDIAN; // intel cpu // some gl.h files, like dev-c++, are old - this is pretty universal #ifndef GL_BGR_EXT #define GL_BGR_EXT 0x80E0 // #define WIN32_HIGH_RES_TIMING // note: this is experimental! // uncomment to turn this on (only for windows machines) // if you want to try setting the timer to be high resolution // this could make camera grabbing and other low level // operations quicker, but you must quit the app normally, // ie, using "esc", rather than killing the process or closing // the console window in order to set the timer resolution back // to normal (since the high res timer might give the OS // problems) // info: http://www.geisswerks.com/ryan/FAQS/timing.html #endif #endif #ifdef TARGET_OSX #define __MACOSX_CORE__ #include #if defined(__i386__) #define TARGET_LITTLE_ENDIAN; // intel cpu #endif #endif #ifndef __MWERKS__ #define OF_EXIT_APP(val) exit(val); #else #define OF_EXIT_APP(val) std::exit(val); #endif // comment out this line, if you'd like to use the // quicktime capture interface on windows // if not, we default to videoInput library for // direct show capture, which is quite #define OF_SWITCH_TO_DSHOW_FOR_WIN_VIDCAP #ifdef OF_SWITCH_TO_DSHOW_FOR_WIN_VIDCAP #ifdef TARGET_OSX #define OF_VIDEO_CAPTURE_QUICKTIME #else #define OF_VIDEO_CAPTURE_DIRECTSHOW #endif #else // all quicktime, all the time #define OF_VIDEO_CAPTURE_QUICKTIME #endif // core: --------------------------- #include #include #include #include #include #ifndef PI #define PI 3.14159265358979323846 #endif #ifndef TWO_PI #define TWO_PI 6.28318530717958647693 #endif #ifndef M_TWO_PI #define M_TWO_PI 6.28318530717958647693 #endif #ifndef FOUR_PI #define FOUR_PI 12.56637061435917295385 #endif #ifndef HALF_PI #define HALF_PI 1.57079632679489661923 #endif #ifndef DEG_TO_RAD #define DEG_TO_RAD (PI/180.0) #endif #ifndef RAD_TO_DEG #define RAD_TO_DEG (180.0/PI) #endif #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #endif #ifndef ABS #define ABS(x) (((x) < 0) ? -(x) : (x)) #endif #define OF_FILLED 0x01 #define OF_OUTLINE 0x02 #define OF_WINDOW 0 #define OF_FULLSCREEN 1 #endif Revision-number: 42 Prop-content-length: 215 Content-length: 215 K 7 svn:log V 112 // zach - ofSetFrameRate, atExit, seedRandom call added. glut glue also has 0,0 top left via boolean additions. K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-26T16:06:40.151117Z PROPS-END Node-path: app/ofAppGlutGlue.h Node-kind: file Node-action: change Text-content-length: 3491 Text-content-md5: 8db465c75f6259d0ed8b4b9eba075f0a Content-length: 3491 void display(void); void mouse_cb(int button, int state, int x, int y); void motion_cb(int x, int y); void passive_motion_cb(int x, int y); void idle_cb(void); void keyboard_cb(unsigned char key, int x, int y); void special_key_cb(int key, int x, int y) ; static int buttonInUse = 0; //-------------------------------- static float timeNow, timeThen, fps; static int nFrames; static bool bFrameRateSet; int millisForFrame; int prevMillis; int diffMillis; //------------------------------------------------------------ void display(void){ //-------------------------------- // when I had "glutFullScreen()" // in the initOpenGl, I was gettings a "heap" allocation error // when debugging via visual studio. putting it here, changes that. // maybe it's voodoo, or I am getting rid of the problem // by removing something unrelated, but everything seems // to work if I put fullscreen on the first frame of display. if (nFrames == 0 && windowMode == OF_FULLSCREEN) glutFullScreen(); width = ofGetWidth(); height = ofGetHeight(); height = height > 0 ? height : 1; // set viewport, clear the screen glViewport( 0, 0, width, height ); float * bgPtr = ofBgColorPtr(); glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ofSetupScreen(); if (!ofbOriginBottomLeft()){ glScalef(1, -1, 1); // invert Y axis so increasing Y goes down. glTranslatef(0, -height, 0); // shift origin up to upper-left corner. } OFSAptr->draw(); glutSwapBuffers(); // -------------- fps calculation: timeNow = ofGetElapsedTimef(); if( (timeNow-timeThen) > 0.05f || nFrames == 0 ) { fps = (double)nFrames / (timeNow-timeThen); timeThen = timeNow; nFrames = 0; ofFrameRate = 0.9f * ofFrameRate + 0.1f * fps; } nFrames++; // -------------- } //------------------------------------------------------------ void mouse_cb(int button, int state, int x, int y) { if (!ofbOriginBottomLeft()){ y = ofGetHeight() - y; } if (state == GLUT_DOWN) { OFSAptr->mousePressed(x, height - y, button); } else if (state == GLUT_UP) { OFSAptr->mouseReleased(); } buttonInUse = button; } //------------------------------------------------------------ void motion_cb(int x, int y) { if (!ofbOriginBottomLeft()){ y = ofGetHeight() - y; } OFSAptr->mouseDragged(x, height - y, buttonInUse); } //------------------------------------------------------------ void passive_motion_cb(int x, int y) { if (!ofbOriginBottomLeft()){ y = ofGetHeight() - y; } OFSAptr->mouseMoved(x, height - y); } //------------------------------------------------------------ void idle_cb(void) { if (nFrames != 0 && bFrameRateSet == true){ diffMillis = ofGetElapsedTimeMillis() - prevMillis; if (diffMillis > millisForFrame){ ; // we do nothing, we are already slower than target frame } else { int waitMillis = millisForFrame - diffMillis; Sleep(waitMillis); // this is where the mac sleep // usecs is needed. } } OFSAptr->update(); glutPostRedisplay(); prevMillis = ofGetElapsedTimeMillis(); } //------------------------------------------------------------ void keyboard_cb(unsigned char key, int x, int y) { OFSAptr->keyPressed((int)key); if (key == 27){ // "escape" OF_EXIT_APP(0); } } //------------------------------------------------------------ void special_key_cb(int key, int x, int y) { OFSAptr->keyPressed((int)key); } Node-path: app/ofAppRunner.cpp Node-kind: file Node-action: change Text-content-length: 3321 Text-content-md5: 50e3b174cdd453c78cdbe0d0307000ee Content-length: 3321 #include "ofAppRunner.h" //======================================================================== // static variables: static ofSimpleApp * OFSAptr; int windowMode; bool bMousePressed; bool bRightButton; int width, height; static float ofFrameRate; //======================================================================== // callbacks: #include "ofAppGlutGlue.h" //-------------------------------------- void ofSetupOpenGL(int w, int h, int screenMode){ int argc = 1; char *argv = "openframeworks"; char **vptr = &argv; glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA); glutInit(&argc, vptr); //if (screenMode == OF_WINDOW) glutInitWindowSize(w, h); glutCreateWindow(""); windowMode = screenMode; ofBackground(200,200,200); // default bg color ofSetColor(0xFFFFFF); // default draw color // used to be black, but // black + texture = black // so maybe grey bg // and "white" fg color // as default works the best... } //----------------------- gets called when the app exits // currently looking at who to turn off // at the end of the application void ofExitCallback(); void ofExitCallback(){ // who to kill off ? // -- fmod // -- quicktime // -- freeImage // anyone else? #ifdef WIN32_HIGH_RES_TIMING timeEndPeriod(1); #endif delete OFSAptr; } //-------------------------------------- void ofRunApp(ofSimpleApp * OFSA){ OFSAptr = OFSA; atexit(ofExitCallback); #ifdef WIN32_HIGH_RES_TIMING timeBeginPeriod(1); // ! experimental, sets high res time // you need to call timeEndPeriod. // if you quit the app other than "esc" // (ie, close the console, kill the process, etc) // at exit wont get called, and the time will // remain high res, that could mess things // up on your system. // info here:http://www.geisswerks.com/ryan/FAQS/timing.html #endif bFrameRateSet = false; //---------------------- // setup the callbacks glutMouseFunc(mouse_cb); glutMotionFunc(motion_cb); glutPassiveMotionFunc(passive_motion_cb); glutIdleFunc(idle_cb); glutDisplayFunc(display); glutKeyboardFunc(keyboard_cb); glutSpecialFunc(special_key_cb); //---------------------- ofSeedRandom(); // seed the random generator // (users can seed it to a value in setup // if they want it fixed); OFSA->setup(); glutMainLoop(); } //-------------------------------------- float ofGetFrameRate(){ return ofFrameRate; } //-------------------------------------- void ofSetFrameRate(int targetRate){ // given this FPS, what is the amount of millis per frame // that should elapse? // --- > f / s if (targetRate == 0){ bFrameRateSet = false; return; } bFrameRateSet = true; float durationOfFrame = 1.0f / (float)targetRate; millisForFrame = (int)(1000.0f * durationOfFrame); } //-------------------------------------- void ofHideCursor(){ glutSetCursor(GLUT_CURSOR_NONE); } //-------------------------------------- void ofShowCursor(){ glutSetCursor(GLUT_CURSOR_RIGHT_ARROW); } Node-path: app/ofAppRunner.h Node-kind: file Node-action: change Text-content-length: 424 Text-content-md5: b3bf5d564e87b7589e9b588853f7fa85 Content-length: 424 #ifndef _OF_APP_RUNNER #define _OF_APP_RUNNER #include "ofConstants.h" #include "ofSimpleApp.h" #include "ofGraphics.h" #include "ofMath.h" #include "ofUtils.h" void ofSetupOpenGL(int w, int h, int screenMode); // sets up the opengl context! void ofRunApp(ofSimpleApp * OFSA); float ofGetFrameRate(); void ofSetFrameRate(int targetRate); void ofHideCursor(); void ofShowCursor(); #endif Revision-number: 43 Prop-content-length: 101 Content-length: 101 K 7 svn:log V 0 K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-26T16:07:15.176743Z PROPS-END Node-path: app/ofSimpleApp.h Node-kind: file Node-action: change Text-content-length: 662 Text-content-md5: d1832020ea408dc54d3856f2427287e2 Content-length: 662 #ifndef _OF_SIMPLE_APP #define _OF_SIMPLE_APP #include "ofConstants.h" #include "ofUtils.h" class ofSimpleApp{ public: ofSimpleApp(){} virtual void setup(){} virtual void update(){} virtual void draw(){} virtual void keyPressed(int key ){} virtual void mouseMoved( int x, int y ){} virtual void mouseDragged( int x, int y, int button ){} virtual void mousePressed( int x, int y, int button ){} virtual void mouseReleased(){} virtual void audioReceived (float * input, int bufferSize, int nChannels) {} virtual void audioRequested (float * output, int bufferSize, int nChannels) {} }; #endif Node-path: ofMain.h Node-kind: file Node-action: change Text-content-length: 562 Text-content-md5: 5cb5256525f3968e655a65fea91965f0 Content-length: 562 #ifndef OF_MAIN_H #define OF_MAIN_H //-------------------------- // utils #include "ofConstants.h" #include "ofMath.h" #include "ofUtils.h" //-------------------------- // graphics #include "ofTexture.h" #include "ofTrueTypeFont.h" #include "ofGraphics.h" #include "ofImage.h" //-------------------------- // app #include "ofSimpleApp.h" #include "ofAppRunner.h" //-------------------------- // audio #include "ofAudioStream.h" #include "ofSoundPlayer.h" //-------------------------- // video #include "ofVideoGrabber.h" #include "ofVideoPlayer.h" #endif Revision-number: 44 Prop-content-length: 242 Content-length: 242 K 7 svn:log V 139 Theo: Type in flipped mode now works. Moved flipping code to ofSetupScreen. Added usleep for ofSetFrameRate. Some changes in ofConstants.h. K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-28T13:48:29.264130Z PROPS-END Node-path: app/ofAppGlutGlue.h Node-kind: file Node-action: change Text-content-length: 3578 Text-content-md5: 810dfb2992cf71904f3851fb5b9991c1 Content-length: 3578 void display(void); void mouse_cb(int button, int state, int x, int y); void motion_cb(int x, int y); void passive_motion_cb(int x, int y); void idle_cb(void); void keyboard_cb(unsigned char key, int x, int y); void special_key_cb(int key, int x, int y) ; static int buttonInUse = 0; //-------------------------------- static float timeNow, timeThen, fps; static int nFrames; static bool bFrameRateSet; int millisForFrame; int prevMillis; int diffMillis; //------------------------------------------------------------ void display(void){ //-------------------------------- // when I had "glutFullScreen()" // in the initOpenGl, I was gettings a "heap" allocation error // when debugging via visual studio. putting it here, changes that. // maybe it's voodoo, or I am getting rid of the problem // by removing something unrelated, but everything seems // to work if I put fullscreen on the first frame of display. if (nFrames == 0 && windowMode == OF_FULLSCREEN) glutFullScreen(); width = ofGetWidth(); height = ofGetHeight(); height = height > 0 ? height : 1; // set viewport, clear the screen glViewport( 0, 0, width, height ); float * bgPtr = ofBgColorPtr(); glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ofSetupScreen(); if (!ofbOriginBottomLeft()){ glScalef(1, -1, 1); // invert Y axis so increasing Y goes down. glTranslatef(0, -height, 0); // shift origin up to upper-left corner. } OFSAptr->draw(); glutSwapBuffers(); // -------------- fps calculation: timeNow = ofGetElapsedTimef(); if( (timeNow-timeThen) > 0.05f || nFrames == 0 ) { fps = (double)nFrames / (timeNow-timeThen); timeThen = timeNow; nFrames = 0; ofFrameRate = 0.9f * ofFrameRate + 0.1f * fps; } nFrames++; // -------------- } //------------------------------------------------------------ void mouse_cb(int button, int state, int x, int y) { if (!ofbOriginBottomLeft()){ y = ofGetHeight() - y; } if (state == GLUT_DOWN) { OFSAptr->mousePressed(x, height - y, button); } else if (state == GLUT_UP) { OFSAptr->mouseReleased(); } buttonInUse = button; } //------------------------------------------------------------ void motion_cb(int x, int y) { if (!ofbOriginBottomLeft()){ y = ofGetHeight() - y; } OFSAptr->mouseDragged(x, height - y, buttonInUse); } //------------------------------------------------------------ void passive_motion_cb(int x, int y) { if (!ofbOriginBottomLeft()){ y = ofGetHeight() - y; } OFSAptr->mouseMoved(x, height - y); } //------------------------------------------------------------ void idle_cb(void) { if (nFrames != 0 && bFrameRateSet == true){ diffMillis = ofGetElapsedTimeMillis() - prevMillis; if (diffMillis > millisForFrame){ ; // we do nothing, we are already slower than target frame } else { int waitMillis = millisForFrame - diffMillis; #ifdef TARGET_WIN32 Sleep(waitMillis); //windows sleep in milliseconds #else usleep(waitMillis * 1000); //mac sleep in microseconds - cooler :) #endif } } OFSAptr->update(); glutPostRedisplay(); prevMillis = ofGetElapsedTimeMillis(); } //------------------------------------------------------------ void keyboard_cb(unsigned char key, int x, int y) { OFSAptr->keyPressed((int)key); if (key == 27){ // "escape" OF_EXIT_APP(0); } } //------------------------------------------------------------ void special_key_cb(int key, int x, int y) { OFSAptr->keyPressed((int)key); } Node-path: app/ofAppRunner.cpp Node-kind: file Node-action: change Text-content-length: 3323 Text-content-md5: 4a5267fef3717faa0d302d87e6a6275d Content-length: 3323 #include "ofAppRunner.h" //======================================================================== // static variables: static ofSimpleApp * OFSAptr; int windowMode; bool bMousePressed; bool bRightButton; int width, height; static float ofFrameRate; //======================================================================== // callbacks: #include "ofAppGlutGlue.h" //-------------------------------------- void ofSetupOpenGL(int w, int h, int screenMode){ int argc = 1; char *argv = "openframeworks"; char **vptr = &argv; glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA); glutInit(&argc, vptr); //if (screenMode == OF_WINDOW) glutInitWindowSize(w, h); glutCreateWindow(""); windowMode = screenMode; ofBackground(200,200,200); // default bg color ofSetColor(0xFFFFFF); // default draw color // used to be black, but // black + texture = black // so maybe grey bg // and "white" fg color // as default works the best... } //----------------------- gets called when the app exits // currently looking at who to turn off // at the end of the application void ofExitCallback(); void ofExitCallback(){ // who to kill off ? // -- fmod // -- quicktime // -- freeImage // anyone else? #ifdef WIN32_HIGH_RES_TIMING timeEndPeriod(1); #endif //delete OFSAptr; } //-------------------------------------- void ofRunApp(ofSimpleApp * OFSA){ OFSAptr = OFSA; atexit(ofExitCallback); #ifdef WIN32_HIGH_RES_TIMING timeBeginPeriod(1); // ! experimental, sets high res time // you need to call timeEndPeriod. // if you quit the app other than "esc" // (ie, close the console, kill the process, etc) // at exit wont get called, and the time will // remain high res, that could mess things // up on your system. // info here:http://www.geisswerks.com/ryan/FAQS/timing.html #endif bFrameRateSet = false; //---------------------- // setup the callbacks glutMouseFunc(mouse_cb); glutMotionFunc(motion_cb); glutPassiveMotionFunc(passive_motion_cb); glutIdleFunc(idle_cb); glutDisplayFunc(display); glutKeyboardFunc(keyboard_cb); glutSpecialFunc(special_key_cb); //---------------------- ofSeedRandom(); // seed the random generator // (users can seed it to a value in setup // if they want it fixed); OFSA->setup(); glutMainLoop(); } //-------------------------------------- float ofGetFrameRate(){ return ofFrameRate; } //-------------------------------------- void ofSetFrameRate(int targetRate){ // given this FPS, what is the amount of millis per frame // that should elapse? // --- > f / s if (targetRate == 0){ bFrameRateSet = false; return; } bFrameRateSet = true; float durationOfFrame = 1.0f / (float)targetRate; millisForFrame = (int)(1000.0f * durationOfFrame); } //-------------------------------------- void ofHideCursor(){ glutSetCursor(GLUT_CURSOR_NONE); } //-------------------------------------- void ofShowCursor(){ glutSetCursor(GLUT_CURSOR_RIGHT_ARROW); } Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: change Text-content-length: 8975 Text-content-md5: cf5726e742d77c3bd01d697ce17d1b77 Content-length: 8975 #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); bool bSmoothHinted = false; //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- bool ofbOriginBottomLeft(){ return true; // because people are asking for it! // currently, the following works in 0,0 top left // -- ofVideoGrabber (quicktime) // -- ofVideoPlayer // -- ofGraphics, regular opengl drawing // -- ofTexture (unchanged, assume that the input is flipped: 0,0 top left) // the following doesn't work: // -- ofTrueTypeFont ** // -- ofImage // -- ofVideoGraber (dshow) // ** this is hardest to fix, because of the // asscent and descent issues. } //---------------------------------------------------------- void ofBackground(int r, int g, int b){ bgColor[0] = (float)r / (float)255.0f; bgColor[1] = (float)g / (float)255.0f; bgColor[2] = (float)b / (float)255.0f; bgColor[3] = 1.0f; } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ // use smoothness, if requested: if (bSmoothHinted){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // draw: glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted){ glPopAttrib(); } } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted){ glPopAttrib(); } } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted){ glPopAttrib(); } } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ // use smoothness, if requested: if (bSmoothHinted){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // draw: glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted){ glPopAttrib(); } } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ // use smoothness, if requested: if (bSmoothHinted){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // draw: glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted){ glPopAttrib(); } } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b, int _a){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); float a = (float)_a / 255.0f; a = MAX(0,MIN(a,1.0f)); glColor4f(r,g,b,a); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } //---------------------------------------------------------- void ofEnableAlphaBlending(){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void ofDisableAlphaBlending(){ glDisable(GL_BLEND); } //---------------------------------------------------------- void ofEnableSmoothing(){ // please see: // http://www.opengl.org/resources/faq/technical/rasterization.htm bSmoothHinted = true; } //---------------------------------------------------------- void ofDisableSmoothing(){ bSmoothHinted = false; } //-------------------------------------------------- void ofDrawBitmapString(char *string, float x, float y){ //--------------------------------------------------- // for now this is fixed to the 8_BY_13 glut character // http://pyopengl.sourceforge.net/documentation/manual/glutBitmapCharacter.3GLUT.html //--------------------------------------------------- char *c; float yOffset = 0; float fontSize = 8.0f; glRasterPos2f(x,y); for (c=string; *c != '\0'; c++) { if(*c == '\n') { yOffset -= (fontSize*1.7); glRasterPos2f(x,y + (int)yOffset); } else if (((int)*c) >= 32){ // < 32 = control characters - don't draw // solves a bug with control characters // getting drawn when they ought to not be glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c); } } } //---------------------------------------------------------- void ofSetupScreen(){ int w, h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (!ofbOriginBottomLeft()){ glScalef(1, -1, 1); // invert Y axis so increasing Y goes down. glTranslatef(0, -h, 0); // shift origin up to upper-left corner. } } Node-path: graphics/ofTrueTypeFont.cpp Node-kind: file Node-action: change Text-content-length: 12430 Text-content-md5: 411623e9e62b025cd71a1fdda26315b8 Content-length: 12430 #include "ofTrueTypeFont.h" //-------------------------- #ifdef TARGET_WIN32 #include #include #include #include #include #endif #ifdef TARGET_OSX #include "ft2build.h" #include "freetype.h" #include "ftglyph.h" #include "ftoutln.h" #include "fttrigon.h" #endif //------------------------------------------------------------------ ofTrueTypeFont::ofTrueTypeFont(){ bLoadedOk = false; } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize){ // load anti-aliased, non-full character set: loadFont(filename, fontsize, true, false); } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet){ bLoadedOk = false; bAntiAlised = _bAntiAliased; bFullCharacterSet = _bFullCharacterSet; fontSize = fontsize; //--------------- load the library and typeface FT_Library library; if (FT_Init_FreeType( &library )){ printf("PROBLEM WITH FT lib \n"); return; } FT_Face face; if (FT_New_Face( library, filename, 0, &face )) { return; } FT_Set_Char_Size( face,fontsize << 6,fontsize << 6,96,96); lineHeight = fontsize * 1.43f; //------------------------------------------------------ //kerning would be great to support: //printf("FT_HAS_KERNING ? %i \n", FT_HAS_KERNING(face)); //------------------------------------------------------ nCharacters = bFullCharacterSet ? 256 : 128 - NUM_CHARACTER_TO_START; //--------------- initialize character info and textures cps = new charProps[nCharacters]; texNames = new GLuint[nCharacters]; glGenTextures(nCharacters, texNames); //--------------------- load each char ----------------------- for (int i = 0 ; i < nCharacters; i++){ //------------------------------------------ anti aliased or not: if (bAntiAlised == true){ if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph %i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); } else { if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph%i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO); } //------------------------------------------ FT_Bitmap& bitmap= face->glyph->bitmap; // 1 pixel border around the glyph int border = 2; // prepare the texture: int width = ofNextPow2( bitmap.width + border); int height = ofNextPow2( bitmap.rows + border); // ------------------------- this is fixing a bug with small type // ------------------------- appearantly, opengl has trouble with // ------------------------- width or height textures of 1, so we // ------------------------- we just set it to 2... if (width == 1) width = 2; if (height == 1) height = 2; // ------------------------- // info about the character: cps[i].value = i; cps[i].height = face->glyph->bitmap_top; cps[i].width = face->glyph->bitmap.width; cps[i].setWidth = face->glyph->advance.x >> 6; cps[i].topExtent = face->glyph->bitmap.rows; cps[i].leftExtent = face->glyph->bitmap_left; // texture internals cps[i].tTex = (float)bitmap.width / (float)width; cps[i].vTex = (float)bitmap.rows / (float)height; cps[i].xOff = ((1.0+(float)bitmap.width) / (float)width) - cps[i].tTex; cps[i].yOff = ((1.0+(float)bitmap.rows) / (float)height) - cps[i].vTex; /* sanity check: printf("%i %i %i %i %i %i \n", cps[i].value , cps[i].height , cps[i].width , cps[i].setWidth , cps[i].topExtent , cps[i].leftExtent ); */ // Allocate Memory For The Texture Data. unsigned char* expanded_data = new unsigned char[ 2 * width * height]; //-------------------------------- clear data: for(int j=0; j =bitmap.width || j-1>=bitmap.rows) ? 0 : 255; expanded_data[2*(k+j*width)+1] = (k-1>=bitmap.width || j-1>=bitmap.rows) ? 0 : bitmap.buffer[k-1 + bitmap.width*(j-1)]; } } //----------------------------------- } else { //----------------------------------- // true type packs monochrome info in a // 1-bit format, hella funky // here we unpack it: unsigned char *src = bitmap.buffer; for(int j=0; j = nCharacters){ //printf("Error : char (%i) not allocated -- line %d in %s\n", (c + NUM_CHARACTER_TO_START), __LINE__,__FILE__); return; } //----------------------- int cu = c; float height = cps[cu].height; float bwidth = cps[cu].width; float top = cps[cu].topExtent - cps[cu].height; float lextent = cps[cu].leftExtent; float t = cps[cu].tTex; float v = cps[cu].vTex; float xOff = cps[cu].xOff; float yOff = cps[cu].yOff; //this is for topLeftDrawing only float corr = ( (fontSize - height) + top) - fontSize; if (glIsTexture(texNames[cu])) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texNames[cu]); glNormal3f(0, 0, 1); if (ofbOriginBottomLeft()){ glBegin(GL_QUADS); glTexCoord2d(xOff,yOff); glVertex2f(x + lextent, y + height); glTexCoord2d(xOff,v+yOff); glVertex2f(x + lextent, y-top); glTexCoord2d(t+xOff,v+yOff); glVertex2f(x + lextent + bwidth, y-top); glTexCoord2d(t+xOff,yOff); glVertex2f(x + lextent + bwidth, y + height); glEnd(); } else { glBegin(GL_QUADS); glTexCoord2d(t+xOff,v+yOff); glVertex2f(x + lextent + bwidth, y + height + corr); glTexCoord2d(t+xOff,yOff); glVertex2f(x + lextent + bwidth, (y-top) + corr); glTexCoord2d(xOff,yOff); glVertex2f(x + lextent, (y-top) + corr); glTexCoord2d(xOff,v+yOff); glVertex2f(x + lextent, y + height + corr); glEnd(); } glDisable(GL_TEXTURE_2D); } else { //let's add verbosity levels somewhere... //this error, for example, is kind of annoying to see //all the time: //printf("Warning : texture not bound for character -- line %d in %s\n", __LINE__,__FILE__); } } //----------------------------------------------------------- float ofTrueTypeFont::stringWidth(char *c) { float width = 0; int index = 0; float widthTemp = 0; bool bMultiLine = false; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { width = MAX(width, widthTemp); widthTemp = 0; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; widthTemp += cps[cy].width; } else { widthTemp += cps[cy].setWidth; } } index++; } width = MAX(width, widthTemp); return width; } //----------------------------------------------------------- float ofTrueTypeFont::stringHeight(char *c) { float height = 0; int index = 0; float maxHeight = 0; bool bFirstLineOfMultiLine = true; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { if (bFirstLineOfMultiLine == true){ bFirstLineOfMultiLine = false; height += maxHeight; } else { height += lineHeight; } maxHeight = 0; } else if (c[index] == ' ') { } else { float ht = cps[cy].height; if (ht > maxHeight) maxHeight = ht; } } index++; } height += maxHeight; return height; } //===================================================================== void ofTrueTypeFont::drawString(char *c, float x, float y) { if (!bLoadedOk){ printf("Error : font not allocated -- line %d in %s\n", __LINE__,__FILE__); return; }; // we need transparency to draw text, but we don't know // if that is set up in outside of this function // we "pushAttrib", turn on alpha and "popAttrib" // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushattrib.html // **** note **** // I have read that pushAttrib() is slow, if used often, // maybe there is a faster way to do this? // ie, check if blending is enabled, etc... // glIsEnabled().... glGet()... // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/get.html // ************** // (a) record the current "alpha state, blend func, etc" glPushAttrib(GL_COLOR_BUFFER_BIT); // (b) enable our regular ALPHA blending! glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); float startX = x; int index = 0; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { x = startX; int cy = (int)'M' - NUM_CHARACTER_TO_START; y -= lineHeight; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; x += cps[cy].width; } else { drawChar(cy, x, y); x += cps[cy].setWidth; } } index++; } // (c) return back to the way things were (with blending, blend func, etc) glPopAttrib(); } Node-path: graphics/ofTrueTypefont.h Node-kind: file Node-action: change Text-content-length: 1277 Text-content-md5: 9c4c745a6253640a0135bb6c054dad15 Content-length: 1277 #ifndef _OF_TTF_FONT_H_ #define _OF_TTF_FONT_H_ #include "ofConstants.h" #include "ofGraphics.h" //-------------------------------------------------- typedef struct { int value; int height; int width; int setWidth; int topExtent; int leftExtent; float tTex; float vTex; //0-1 pct of bitmap... float xOff; float yOff; } charProps; //-------------------------------------------------- #define NUM_CHARACTER_TO_START 33 // 0 - 32 are control characters, no graphics needed. class ofTrueTypeFont{ public: ofTrueTypeFont(); // -- default, non-full char set, anti aliased: void loadFont(const char *filename, int fontsize); void loadFont(const char *filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet); bool bLoadedOk; bool bAntiAlised; bool bFullCharacterSet; float getLineHeight(); void setLineHeight(float height); float stringWidth(char *s); float stringHeight(char *c); void drawString(char *c, float x, float y); int nCharacters; protected: float lineHeight; charProps * cps; // properties for each character GLuint * texNames; // textures for each character int fontSize; void drawChar(int c, float x, float y); int ofNextPow2 (int a); }; #endif Node-path: utils/ofConstants.h Node-kind: file Node-action: change Text-content-length: 3156 Text-content-md5: 005ca8a7b077a89a2f9a4f5b1fca1128 Content-length: 3156 #ifndef OF_CONSTANTS #define OF_CONSTANTS //------------------------------- // pc or mac ? // soon: pc, mac or linux... #ifndef __APPLE_CC__ #define TARGET_WIN32 #else #define TARGET_OSX #endif //------------------------------- #ifdef TARGET_WIN32 #include #include "glut.h" #define __WINDOWS_DS__ #define __WINDOWS_MM__ #if (_MSC_VER) // microsoft visual studio #pragma warning(disable : 4996) // disable all deprecation warnings #pragma warning(disable : 4068) // unknown pragmas #pragma warning(disable : 4101) // unreferenced local variable #pragma warning(disable : 4312) // type cast conversion (in qt vp) #pragma warning(disable : 4311) // type cast pointer truncation (qt vp) #endif #define TARGET_LITTLE_ENDIAN; // intel cpu // some gl.h files, like dev-c++, are old - this is pretty universal #ifndef GL_BGR_EXT #define GL_BGR_EXT 0x80E0 // #define WIN32_HIGH_RES_TIMING // note: this is experimental! // uncomment to turn this on (only for windows machines) // if you want to try setting the timer to be high resolution // this could make camera grabbing and other low level // operations quicker, but you must quit the app normally, // ie, using "esc", rather than killing the process or closing // the console window in order to set the timer resolution back // to normal (since the high res timer might give the OS // problems) // info: http://www.geisswerks.com/ryan/FAQS/timing.html #endif #endif #ifdef TARGET_OSX #define __MACOSX_CORE__ #include #include #if defined(__LITTLE_ENDIAN__) #define TARGET_LITTLE_ENDIAN; // intel cpu #endif #endif #ifndef __MWERKS__ #define OF_EXIT_APP(val) exit(val); #else #define OF_EXIT_APP(val) std::exit(val); #endif // comment out this line, if you'd like to use the // quicktime capture interface on windows // if not, we default to videoInput library for // direct show capture, which is quite #define OF_SWITCH_TO_DSHOW_FOR_WIN_VIDCAP #ifdef OF_SWITCH_TO_DSHOW_FOR_WIN_VIDCAP #ifdef TARGET_OSX #define OF_VIDEO_CAPTURE_QUICKTIME #else #define OF_VIDEO_CAPTURE_DIRECTSHOW #endif #else // all quicktime, all the time #define OF_VIDEO_CAPTURE_QUICKTIME #endif // core: --------------------------- #include #include #include #include #include #ifndef PI #define PI 3.14159265358979323846 #endif #ifndef TWO_PI #define TWO_PI 6.28318530717958647693 #endif #ifndef M_TWO_PI #define M_TWO_PI 6.28318530717958647693 #endif #ifndef FOUR_PI #define FOUR_PI 12.56637061435917295385 #endif #ifndef HALF_PI #define HALF_PI 1.57079632679489661923 #endif #ifndef DEG_TO_RAD #define DEG_TO_RAD (PI/180.0) #endif #ifndef RAD_TO_DEG #define RAD_TO_DEG (180.0/PI) #endif #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #endif #ifndef ABS #define ABS(x) (((x) < 0) ? -(x) : (x)) #endif #define OF_FILLED 0x01 #define OF_OUTLINE 0x02 #define OF_WINDOW 0 #define OF_FULLSCREEN 1 #endif Revision-number: 45 Prop-content-length: 139 Content-length: 139 K 7 svn:log V 37 // zach fixes for 0,0 origin requests K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-30T11:24:23.018444Z PROPS-END Node-path: graphics/ofImage.cpp Node-kind: file Node-action: change Text-content-length: 10194 Text-content-md5: f857f3d668926c91cc39f2a395bf2500 Content-length: 10194 #include "ofImage.h" #include "freeImage.h" static bool bFreeImageInited = false; //----------------------------------------- // class freeImageBitmap{ public: FIBITMAP * bmp; // when OF users ask for pixels // we will get them contiguous memory // ie, non-aligned // see the pixel access chapter of the freeImage pdf // these pixel will also be RGB // on both platforms // bmp will be RGB / BGR depending // on the endianess of the platform. unsigned char * pixels; //----------------------- freeImageBitmap(){ bmp = NULL; } //----------------------- //swap my image out in a (hopefully) non-memory leakish way void swap(FIBITMAP *dst) { if(dst == NULL) return; if(bmp != NULL) FreeImage_Unload(bmp); bmp = dst; } //----------------------- void setSize(FREE_IMAGE_TYPE image_type, WORD width, WORD height, WORD bpp) { if(bmp == NULL) { FreeImage_Unload(bmp); } bmp = FreeImage_AllocateT(image_type, width, height, bpp); } //----------------------- bool isValid(){ return (bmp != NULL) ? true : false; } }; //---------------------------------------------------------- ofImage::ofImage(){ //----------------------- init free image if necessary if (!bFreeImageInited){ FreeImage_Initialise(); bFreeImageInited = true; } //----------------------- IMG = new freeImageBitmap(); width = height = bpp = 0; type = OF_IMAGE_UNDEFINED; bUseTexture = true; // the default is, yes, use a texture bAllocatedPixels = false; } //---------------------------------------------------------- void ofImage::grabScreen(int _x, int _y, int _w, int _h){ if (IMG->isValid()){ // flip y if origin is top: if (!ofbOriginBottomLeft()){ float height = ofGetHeight(); _y = height - _y; _y -= _h; // top, bottom issues } if (!(width == _w && height == _h)){ resize(_w, _h); } unsigned char * pixels = (unsigned char *)FreeImage_GetBits(IMG->bmp); switch (bpp){ case 8: glReadPixels(_x, _y, _w, _h, GL_LUMINANCE,GL_UNSIGNED_BYTE, pixels); break; case 24: #ifdef TARGET_LITTLE_ENDIAN glReadPixels(_x, _y, _w, _h, GL_BGR_EXT,GL_UNSIGNED_BYTE, pixels); #else glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); #endif break; case 32: glReadPixels(_x, _y, _w, _h, GL_RGBA,GL_UNSIGNED_BYTE, pixels); break; } // we will need to flip images // if the 0,0 position is in the top left: if (!ofbOriginBottomLeft()){ FreeImage_FlipVertical(IMG->bmp); } update(); } else { // assume that this is color.... IMG->setSize(FIT_BITMAP, _w, _h, 24); unsigned char * pixels = (unsigned char *)FreeImage_GetBits(IMG->bmp); #ifdef TARGET_LITTLE_ENDIAN glReadPixels(_x, _y, _w, _h, GL_BGR_EXT,GL_UNSIGNED_BYTE, pixels); #else glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); #endif // we will need to flip images // if the 0,0 position is in the top left: if (!ofbOriginBottomLeft()){ FreeImage_FlipVertical(IMG->bmp); } update(); } } //---------------------------------------------------------- void ofImage::allocate(int _w, int _h, int _type){ int newbpp; switch (_type){ case OF_IMAGE_GRAYSCALE: newbpp = 8; break; case OF_IMAGE_COLOR: newbpp = 24; break; case OF_IMAGE_COLOR_ALPHA: newbpp = 32; break; default: newbpp = 24; break; } IMG->setSize(FIT_BITMAP, _w, _h, newbpp); } //---------------------------------------------------------- void ofImage::update(){ width = FreeImage_GetWidth(IMG->bmp); height = FreeImage_GetHeight(IMG->bmp); bpp = FreeImage_GetBPP(IMG->bmp); // this is check to see if it's a gif bool bNoPallette = (FreeImage_GetColorType(IMG->bmp) != FIC_PALETTE); switch (bpp){ case 8: if (bNoPallette) { //!bUsesPallette){ type = OF_IMAGE_GRAYSCALE; } else { // convert to RGB - // this is a gif (or other) with 256 colors, not b&w. setImageType(OF_IMAGE_COLOR); } break; case 24: type = OF_IMAGE_COLOR; break; case 32: type = OF_IMAGE_COLOR_ALPHA; break; default: // if we've got here, something is wrong, the image // is not 8bit, 24bit or 32bit, so let's at least // make it color: setImageType(OF_IMAGE_COLOR); break; } //---------------------------------- // now, since the "freeImage" memory is padded // (see freeImage392.pdf - "Pixel access functions") // lets get the data into contiguous memory - to make it easier // for folks to work with... if (IMG->pixels != NULL && bAllocatedPixels == true) delete IMG->pixels; // delete anything that might have existed int byteCount = bpp / 8; // bytes ber pixel (not bits per pixel) IMG->pixels = new unsigned char[width*height*byteCount]; //allocate that memory for the image (contiguously) bAllocatedPixels = true; FreeImage_ConvertToRawBits(IMG->pixels, IMG->bmp, width*byteCount, bpp, FI_RGBA_RED_MASK,FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE); // get bits #ifdef TARGET_LITTLE_ENDIAN if (type == OF_IMAGE_COLOR) swapChannels(false); if (type == OF_IMAGE_COLOR_ALPHA) swapChannels(true); #endif //---------------------------------- // if we are using a texture and the ofImage is upadate, // allocate (or reallocate) the texture and upload the data // I will upload from the contguous memory, and use pixelStorei to // make sure opengl knows I am contiguous. if (bUseTexture){ switch (type){ case OF_IMAGE_GRAYSCALE: tex.allocate(width,height,GL_LUMINANCE); tex.loadData(IMG->pixels, width,height, GL_LUMINANCE); break; case OF_IMAGE_COLOR: tex.allocate(width,height,GL_RGB); tex.loadData(IMG->pixels, width,height, GL_RGB); break; case OF_IMAGE_COLOR_ALPHA: tex.allocate(width,height,GL_RGBA); tex.loadData(IMG->pixels, width,height, GL_RGBA); break; } } } //---------------------------------------------------------- void ofImage::loadImage(char * fileName){ bool bLoaded = false; //----------------------------- find the format FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { if(IMG->isValid()) { FreeImage_Unload(IMG->bmp); } IMG->bmp = FreeImage_Load(fif, fileName, 0); bLoaded = true; if(!IMG->isValid()){ bLoaded = false; } } //----------------------------- if (bLoaded){ // we will need to flip images // if the 0,0 position is in the top left: if (!ofbOriginBottomLeft()){ FreeImage_FlipVertical(IMG->bmp); } update(); } else { width = height = bpp = 0; } } //---------------------------------------------------------- void ofImage::saveImage(char * fileName){ if (IMG->isValid()){ FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { FreeImage_Save(fif, IMG->bmp, fileName, 0); } } } //---------------------------------------------------------- unsigned char * ofImage::getPixels(){ // be careful! might not be allocated. you need to check for null... if (IMG->isValid()){ return (unsigned char *)IMG->pixels; } else { return NULL; } } //---------------------------------------------------------- void ofImage::resize(int newWidth, int newHeight){ if (IMG->isValid()){ FIBITMAP * scaledBmp = FreeImage_Rescale(IMG->bmp, newWidth, newHeight, FILTER_BICUBIC); IMG->swap(scaledBmp); update(); } } //---------------------------------------------------------- void ofImage::setImageType(int newType){ if (IMG->isValid()){ switch (newType){ //------------------------------------ case OF_IMAGE_GRAYSCALE: if (type != OF_IMAGE_GRAYSCALE){ FIBITMAP * convertedBmp = FreeImage_ConvertToGreyscale(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; //------------------------------------ case OF_IMAGE_COLOR: if (type != OF_IMAGE_COLOR){ FIBITMAP * convertedBmp = FreeImage_ConvertTo24Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR; } break; //------------------------------------ case OF_IMAGE_COLOR_ALPHA: if (type != OF_IMAGE_COLOR_ALPHA){ FIBITMAP * convertedBmp = FreeImage_ConvertTo32Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR_ALPHA; } break; } update(); } } //------------------------------------ void ofImage::swapChannels(bool bAlpha){ // this swaps the red and blue channel of an image // turning an bgr image to rgb and vice versa... // needed because of windows byte order... if (IMG->isValid()){ unsigned char * pixels = IMG->pixels; unsigned char temp; int totalPixels = width*height; // unoptimized for now... if (bAlpha == false){ for (int i = 0; i < totalPixels; i++){ temp = pixels[i*3 + 2]; pixels[i*3 + 2] = pixels[i*3]; pixels[i*3] = temp; } } else { for (int i = 0; i < totalPixels; i++){ temp = pixels[i*4]; pixels[i*4] = pixels[i*4 + 2]; pixels[i*4 + 2] = temp; } } } } //------------------------------------ void ofImage::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofImage::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } //------------------------------------ void ofImage::draw(float x, float y){ draw(x,y,width,height); } Node-path: graphics/ofImage.h Node-kind: file Node-action: change Text-content-length: 1410 Text-content-md5: 9950337e46234995088416082f3b2176 Content-length: 1410 #ifndef _OF_IMAGE_H_ #define _OF_IMAGE_H_ #include "ofConstants.h" #include "ofTexture.h" #include "ofGraphics.h" #include "ofUtils.h" #define OF_IMAGE_GRAYSCALE 0x00 #define OF_IMAGE_COLOR 0x01 #define OF_IMAGE_COLOR_ALPHA 0x02 #define OF_IMAGE_UNDEFINED 0x03 //------------------------- // forward class declaration, something // we will need in order to compile "OF" as a lib // so that you don't need freeImage, quicktime, etc.. class freeImageBitmap; //------------------------- class ofImage { public : ofImage(); void loadImage(char * fileName); void saveImage(char * fileName); void allocate(int w, int h, int type); unsigned char * getPixels(); // up to you to get this right void setImageType(int type); void resize(int newWidth, int newHeight); void grabScreen(int x, int y, int w, int h); // grab pixels from opengl, using glreadpixels int type; // what type of image it is (as above) int width, height, bpp; // w,h, bits per pixel void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); void draw(float x, float y); private: void swapChannels(bool bAlpha); void update(); freeImageBitmap * IMG; ofTexture tex; bool bUseTexture; bool bAllocatedPixels; }; #endif Revision-number: 46 Prop-content-length: 127 Content-length: 127 K 7 svn:log V 25 // zach - fixes pause bug K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-30T11:25:28.418424Z PROPS-END Node-path: video/ofVideoPlayer.cpp Node-kind: file Node-action: change Text-content-length: 9764 Text-content-md5: 24e13821049d6cc7faa474e676d0a9cf Content-length: 9764 #include "ofVideoPlayer.h" //-------------------------------------------------------------- bool createMovieFromPath(char * path, Movie * movie); bool createMovieFromPath(char * path, Movie * movie){ Boolean isdir = false; OSErr result = 0; FSSpec theFSSpec; FSRef fsref; short resRefNum = -1; short actualResId = DoTheRightThing; #ifdef TARGET_WIN32 result = NativePathNameToFSSpec (path, &theFSSpec, 0); if (result) { printf("NativePathNameToFSSpec failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } #endif #ifdef TARGET_OSX result = FSPathMakeRef((const UInt8*)path, &fsref, &isdir); if (result) { printf("FSPathMakeRef failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } result = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL); if (result) { printf("FSGetCatalogInfo failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } #endif result = OpenMovieFile (&theFSSpec, &resRefNum, 0); if (result) { printf("OpenMovieFile failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } result = NewMovieFromFile (movie, resRefNum, &actualResId, (unsigned char *) 0, 0, (Boolean *) 0); if (result) { printf("NewMovieFromFile failed %d\n", result); printf("ERROR LOADINGmovie \n"); return false; } if (resRefNum != -1) CloseMovieFile (resRefNum); return true; } //-------------------------------------------------------------- OSErr DrawCompleteProc(Movie theMovie, long refCon); OSErr DrawCompleteProc(Movie theMovie, long refCon){ videoPlayerData * vd = (videoPlayerData *)refCon; convertPixels(vd->offscreenGWorldPixels, vd->pixels, vd->w, vd->h); vd->bHavePixelsChanged = true; // now if the pixels have changed AND we are // using a texture, let's update the texture if (vd->bUseTexture == true){ vd->tex->loadData(vd->pixels, vd->w, vd->h, GL_RGB); } return noErr; } //--------------------------------------------------------------------------- ofVideoPlayer::ofVideoPlayer (){ bLoadedMovie = false; width = 0; height = 0; vpd = new videoPlayerData(); vpd->moviePtr = NULL; vpd->w = 0; vpd->h = 0; bUseTexture = true; } //--------------------------------------------------------------------------- unsigned char * ofVideoPlayer::getPixels(){ return vpd->pixels; } //--------------------------------------------------------------------------- bool ofVideoPlayer::isFrameNew(){ if (bLoadedMovie == true){ bool bChanged = vpd->bHavePixelsChanged; if (vpd->bHavePixelsChanged == true) { vpd->bHavePixelsChanged = false; } return bChanged; } else { return false; } } //--------------------------------------------------------------------------- void ofVideoPlayer::idleMovie(){ // [zach] my question is how often to call this? // I don't want to call it too often, and up cpu usage // // shockingly,(or not) on a mac, it seems it's not even necessary to call it // the callback just works... // google " site:lists.apple.com MoviesTask windows mac // some code I've seen uses a thread to call this "JUCE" // maybe I could use ofElapsedTimeMillis() // or a system clock call (not glut call) // and make this less frequent if (bLoadedMovie == true){ MoviesTask(vpd->moviePtr,0); } } //--------------------------------------------------------------------------- void ofVideoPlayer::closeMovie(){ Movie moviePtr = vpd->moviePtr; DisposeMovie (vpd->moviePtr); #ifdef TARGET_WIN32 DisposeMovieDrawingCompleteUPP (myDrawCompleteProc); #endif ExitMovies (); } //--------------------------------------------------------------------------- bool ofVideoPlayer::loadMovie(char * name){ OSErr result = 0; short resRefNum = -1; bLoadedMovie = false; Rect bounds; //----------------- callback method MovieDrawingCompleteUPP myDrawCompleteProc; myDrawCompleteProc = NewMovieDrawingCompleteUPP (DrawCompleteProc); initializeQuicktime(); vpd->bHavePixelsChanged = false; Movie * moviePtr = &(vpd->moviePtr); createMovieFromPath(name, moviePtr); //----------------------------------movie box GetMovieBox(vpd->moviePtr, &(vpd->movieRect)); width = vpd->movieRect.right; height = vpd->movieRect.bottom; vpd->w = vpd->movieRect.right; vpd->h = vpd->movieRect.bottom; //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vpd->offscreenGWorldPixels = (unsigned char*)malloc(4 * width * height + 32); vpd->pixels = new unsigned char[width*height*3]; //---------------------------------- gworld allocation QTNewGWorldFromPtr (&(vpd->offscreenGWorld), k32ARGBPixelFormat, &(vpd->movieRect), NULL, NULL, 0, (vpd->offscreenGWorldPixels), 4 * width); LockPixels(GetGWorldPixMap(vpd->offscreenGWorld)); SetGWorld (vpd->offscreenGWorld, NULL); SetMovieGWorld (vpd->moviePtr, vpd->offscreenGWorld, nil); //----------------- callback method SetMovieDrawingCompleteProc (vpd->moviePtr, movieDrawingCallWhenChanged, myDrawCompleteProc, (long)vpd); //---------------------------------- reset themovie, get ready to roll GoToBeginningOfMovie(vpd->moviePtr); SetMovieActiveSegment(vpd->moviePtr, -1,-1); if (vpd->moviePtr == NULL){ return false; } SetMovieActive(vpd->moviePtr, true); StartMovie(vpd->moviePtr); //------------------ set the movie rate to default //------------------ and preroll, so the first frames come correct TimeValue timeNow; Fixed playRate; timeNow = GetMovieTime(vpd->moviePtr, 0); playRate =GetMoviePreferredRate(vpd->moviePtr); PrePrerollMovie(vpd->moviePtr, timeNow, playRate, 0, 0); PrerollMovie(vpd->moviePtr, timeNow, playRate); SetMovieRate(vpd->moviePtr, playRate); setLoopState(OF_QT_LOOP_NORMAL); bLoadedMovie = true; // get some pixels in there right away. MoviesTask(vpd->moviePtr,0); convertPixels(vpd->offscreenGWorldPixels, vpd->pixels, vpd->w, vpd->h); vpd->bUseTexture = bUseTexture; vpd->tex = &tex; if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.allocate(width,height,GL_RGB); memset(vpd->pixels, 0, width*height*3); vpd->tex->loadData(vpd->pixels, vpd->w, vpd->h, GL_RGB); } return true; } //-------------------------------------------------------- void ofVideoPlayer::setVolume(int volume){ Movie moviePtr = vpd->moviePtr; SetMovieVolume(moviePtr, volume); } //-------------------------------------------------------- void ofVideoPlayer::setLoopState(int state){ Movie moviePtr = vpd->moviePtr; TimeBase myTimeBase; long myFlags = 0L; myTimeBase = GetMovieTimeBase(moviePtr); myFlags = GetTimeBaseFlags(myTimeBase); switch (state) { case OF_QT_LOOP_NORMAL: myFlags |= loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, hintsLoop, hintsLoop); SetMoviePlayHints(moviePtr, 0L, hintsPalindrome); break; case OF_QT_LOOP_PALINDROME: myFlags |= loopTimeBase; myFlags |= palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, hintsLoop, hintsLoop); SetMoviePlayHints(moviePtr, hintsPalindrome, hintsPalindrome); break; case OF_QT_LOOP_NONE: default: myFlags &= ~loopTimeBase; myFlags &= ~palindromeLoopTimeBase; SetMoviePlayHints(moviePtr, 0L, hintsLoop | hintsPalindrome); break; } SetTimeBaseFlags(myTimeBase, myFlags); } //--------------------------------------------------------------------------- void ofVideoPlayer::setPosition(float pct){ TimeRecord tr; Movie moviePtr = vpd->moviePtr; tr.base = GetMovieTimeBase(moviePtr); long total = GetMovieDuration(moviePtr ); long newPos = (long)((float)total * pct); SetMovieTimeValue(moviePtr, newPos); } //--------------------------------------------------------------------------- float ofVideoPlayer::getDuration(){ Movie moviePtr = vpd->moviePtr; return GetMovieDuration (moviePtr) / (double) GetMovieTimeScale (moviePtr); } //--------------------------------------------------------------------------- float ofVideoPlayer::getPosition(){ Movie moviePtr = vpd->moviePtr; long total = GetMovieDuration(moviePtr); long current = GetMovieTime(moviePtr, nil); float pct = ((float)current/(float)total); return pct; } //--------------------------------------------------------------------------- void ofVideoPlayer::setSpeed(float _speed){ Movie moviePtr = vpd->moviePtr; speed = _speed; SetMovieRate(moviePtr, X2Fix(speed)); } //--------------------------------------------------------------------------- float ofVideoPlayer::getSpeed(){ return speed; } //--------------------------------------------------------------------------- void ofVideoPlayer::setPaused(bool bPause){ // there might be a more "quicktime-ish" way (or smarter way) // to do this for now, to pause, just set the movie's speed to zero, // on un-pause, set the movie's speed to "speed" // (and hope that speed != 0...) if (bPause == true) SetMovieRate(vpd->moviePtr, X2Fix(0)); else setSpeed(speed); } //------------------------------------ void ofVideoPlayer::setUseTexture(bool bUse){ bUseTexture = bUse; vpd->bUseTexture = bUseTexture; vpd->tex = &tex; } //------------------------------------ void ofVideoPlayer::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } //------------------------------------ void ofVideoPlayer::draw(float _x, float _y){ draw(_x, _y, width, height); } Revision-number: 47 Prop-content-length: 125 Content-length: 125 K 7 svn:log V 23 // fixes for 0,0 origin K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-30T11:27:45.524276Z PROPS-END Node-path: app/ofAppGlutGlue.h Node-kind: file Node-action: change Text-content-length: 3389 Text-content-md5: abd828b6acbd519ea1cd5549e4e9f32a Content-length: 3389 void display(void); void mouse_cb(int button, int state, int x, int y); void motion_cb(int x, int y); void passive_motion_cb(int x, int y); void idle_cb(void); void keyboard_cb(unsigned char key, int x, int y); void special_key_cb(int key, int x, int y) ; static int buttonInUse = 0; //-------------------------------- static float timeNow, timeThen, fps; static int nFrames; static bool bFrameRateSet; int millisForFrame; int prevMillis; int diffMillis; //------------------------------------------------------------ void display(void){ //-------------------------------- // when I had "glutFullScreen()" // in the initOpenGl, I was gettings a "heap" allocation error // when debugging via visual studio. putting it here, changes that. // maybe it's voodoo, or I am getting rid of the problem // by removing something unrelated, but everything seems // to work if I put fullscreen on the first frame of display. if (nFrames == 0 && windowMode == OF_FULLSCREEN) glutFullScreen(); width = ofGetWidth(); height = ofGetHeight(); height = height > 0 ? height : 1; // set viewport, clear the screen glViewport( 0, 0, width, height ); float * bgPtr = ofBgColorPtr(); glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ofSetupScreen(); OFSAptr->draw(); glutSwapBuffers(); // -------------- fps calculation: timeNow = ofGetElapsedTimef(); if( (timeNow-timeThen) > 0.05f || nFrames == 0 ) { fps = (double)nFrames / (timeNow-timeThen); timeThen = timeNow; nFrames = 0; ofFrameRate = 0.9f * ofFrameRate + 0.1f * fps; } nFrames++; // -------------- } //------------------------------------------------------------ void mouse_cb(int button, int state, int x, int y) { if (!ofbOriginBottomLeft()){ y = ofGetHeight() - y; } if (state == GLUT_DOWN) { OFSAptr->mousePressed(x, height - y, button); } else if (state == GLUT_UP) { OFSAptr->mouseReleased(); } buttonInUse = button; } //------------------------------------------------------------ void motion_cb(int x, int y) { if (!ofbOriginBottomLeft()){ y = ofGetHeight() - y; } OFSAptr->mouseDragged(x, height - y, buttonInUse); } //------------------------------------------------------------ void passive_motion_cb(int x, int y) { if (!ofbOriginBottomLeft()){ y = ofGetHeight() - y; } OFSAptr->mouseMoved(x, height - y); } //------------------------------------------------------------ void idle_cb(void) { if (nFrames != 0 && bFrameRateSet == true){ diffMillis = ofGetElapsedTimeMillis() - prevMillis; if (diffMillis > millisForFrame){ ; // we do nothing, we are already slower than target frame } else { int waitMillis = millisForFrame - diffMillis; #ifdef TARGET_WIN32 Sleep(waitMillis); //windows sleep in milliseconds #else usleep(waitMillis * 1000); //mac sleep in microseconds - cooler :) #endif } } OFSAptr->update(); glutPostRedisplay(); prevMillis = ofGetElapsedTimeMillis(); } //------------------------------------------------------------ void keyboard_cb(unsigned char key, int x, int y) { OFSAptr->keyPressed((int)key); if (key == 27){ // "escape" OF_EXIT_APP(0); } } //------------------------------------------------------------ void special_key_cb(int key, int x, int y) { OFSAptr->keyPressed((int)key); } Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: change Text-content-length: 8989 Text-content-md5: de80b90837f299de26ebb84f4f9dc6ef Content-length: 8989 #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); bool bSmoothHinted = false; //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- bool ofbOriginBottomLeft(){ return true; // because people are certainly asking for it! // currently, the following works in 0,0 top left // -- ofVideoGrabber (quicktime) // -- ofVideoPlayer // -- ofGraphics, regular opengl drawing // -- ofTexture (unchanged, assume that the input is flipped: 0,0 top left) // -- ofImage // -- ofTrueTypeFont (mostly) // the following doesn't work: // -- ofVideoGraber (dshow) -- pixels need to be flipped // -- ofTrueTypeFont -- string height } //---------------------------------------------------------- void ofBackground(int r, int g, int b){ bgColor[0] = (float)r / (float)255.0f; bgColor[1] = (float)g / (float)255.0f; bgColor[2] = (float)b / (float)255.0f; bgColor[3] = 1.0f; } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ // use smoothness, if requested: if (bSmoothHinted){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // draw: glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted){ glPopAttrib(); } } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted){ glPopAttrib(); } } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted){ glPopAttrib(); } } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ // use smoothness, if requested: if (bSmoothHinted){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // draw: glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted){ glPopAttrib(); } } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ // use smoothness, if requested: if (bSmoothHinted){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // draw: glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted){ glPopAttrib(); } } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b, int _a){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); float a = (float)_a / 255.0f; a = MAX(0,MIN(a,1.0f)); glColor4f(r,g,b,a); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } //---------------------------------------------------------- void ofEnableAlphaBlending(){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void ofDisableAlphaBlending(){ glDisable(GL_BLEND); } //---------------------------------------------------------- void ofEnableSmoothing(){ // please see: // http://www.opengl.org/resources/faq/technical/rasterization.htm bSmoothHinted = true; } //---------------------------------------------------------- void ofDisableSmoothing(){ bSmoothHinted = false; } //-------------------------------------------------- void ofDrawBitmapString(char *string, float x, float y){ //--------------------------------------------------- // for now this is fixed to the 8_BY_13 glut character // http://pyopengl.sourceforge.net/documentation/manual/glutBitmapCharacter.3GLUT.html //--------------------------------------------------- char *c; float yOffset = 0; float fontSize = 8.0f; glRasterPos2f(x,y); for (c=string; *c != '\0'; c++) { if(*c == '\n') { yOffset -= (fontSize*1.7); glRasterPos2f(x,y + (int)yOffset); } else if (((int)*c) >= 32){ // < 32 = control characters - don't draw // solves a bug with control characters // getting drawn when they ought to not be glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c); } } } //---------------------------------------------------------- void ofSetupScreen(){ int w, h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (!ofbOriginBottomLeft()){ glScalef(1, -1, 1); // invert Y axis so increasing Y goes down. glTranslatef(0, -h, 0); // shift origin up to upper-left corner. } } Revision-number: 48 Prop-content-length: 189 Content-length: 189 K 7 svn:log V 87 Theo: added startBlending endBlending to ofGraphics, fixed a \n issue with flipped type K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-03-30T15:54:06.458944Z PROPS-END Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: change Text-content-length: 8193 Text-content-md5: 46973e573eb4086b902791aceda677f7 Content-length: 8193 #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); bool bSmoothHinted = false; //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- bool ofbOriginBottomLeft(){ return true; // because people are certainly asking for it! // currently, the following works in 0,0 top left // -- ofVideoGrabber (quicktime) // -- ofVideoPlayer // -- ofGraphics, regular opengl drawing // -- ofTexture (unchanged, assume that the input is flipped: 0,0 top left) // -- ofImage // -- ofTrueTypeFont (mostly) // the following doesn't work: // -- ofVideoGraber (dshow) -- pixels need to be flipped // -- ofTrueTypeFont -- string height } //---------------------------------------------------------- void ofBackground(int r, int g, int b){ bgColor[0] = (float)r / (float)255.0f; bgColor[1] = (float)g / (float)255.0f; bgColor[2] = (float)b / (float)255.0f; bgColor[3] = 1.0f; } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void startSmoothing(){ if(drawMode == OF_FILLED) return; //No point trying to smooth polygons glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void endSmoothing(){ if(drawMode == OF_FILLED) return; //Smoothing was never started glPopAttrib(); } //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ // use smoothness, if requested: if (bSmoothHinted) startSmoothing(); // draw: glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted) endSmoothing(); } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted) startSmoothing(); // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted) endSmoothing(); } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted) startSmoothing(); // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted) endSmoothing(); } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ // use smoothness, if requested: if (bSmoothHinted) startSmoothing(); // draw: glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted){ glPopAttrib(); } } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ // use smoothness, if requested: if (bSmoothHinted) startSmoothing(); // draw: glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); // use smoothness, if requested: if (bSmoothHinted) startSmoothing(); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b, int _a){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); float a = (float)_a / 255.0f; a = MAX(0,MIN(a,1.0f)); glColor4f(r,g,b,a); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } //---------------------------------------------------------- void ofEnableAlphaBlending(){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void ofDisableAlphaBlending(){ glDisable(GL_BLEND); } //---------------------------------------------------------- void ofEnableSmoothing(){ // please see: // http://www.opengl.org/resources/faq/technical/rasterization.htm bSmoothHinted = true; } //---------------------------------------------------------- void ofDisableSmoothing(){ bSmoothHinted = false; } //-------------------------------------------------- void ofDrawBitmapString(char *string, float x, float y){ //--------------------------------------------------- // for now this is fixed to the 8_BY_13 glut character // http://pyopengl.sourceforge.net/documentation/manual/glutBitmapCharacter.3GLUT.html //--------------------------------------------------- char *c; float yOffset = 0; float fontSize = 8.0f; glRasterPos2f(x,y); for (c=string; *c != '\0'; c++) { if(*c == '\n') { yOffset -= (fontSize*1.7); glRasterPos2f(x,y + (int)yOffset); } else if (((int)*c) >= 32){ // < 32 = control characters - don't draw // solves a bug with control characters // getting drawn when they ought to not be glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c); } } } //---------------------------------------------------------- void ofSetupScreen(){ int w, h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (!ofbOriginBottomLeft()){ glScalef(1, -1, 1); // invert Y axis so increasing Y goes down. glTranslatef(0, -h, 0); // shift origin up to upper-left corner. } } Node-path: graphics/ofTrueTypeFont.cpp Node-kind: file Node-action: change Text-content-length: 12484 Text-content-md5: a7e328760ed6ab37861d22c07513d4ef Content-length: 12484 #include "ofTrueTypeFont.h" //-------------------------- #ifdef TARGET_WIN32 #include #include #include #include #include #endif #ifdef TARGET_OSX #include "ft2build.h" #include "freetype.h" #include "ftglyph.h" #include "ftoutln.h" #include "fttrigon.h" #endif //------------------------------------------------------------------ ofTrueTypeFont::ofTrueTypeFont(){ bLoadedOk = false; } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize){ // load anti-aliased, non-full character set: loadFont(filename, fontsize, true, false); } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet){ bLoadedOk = false; bAntiAlised = _bAntiAliased; bFullCharacterSet = _bFullCharacterSet; fontSize = fontsize; //--------------- load the library and typeface FT_Library library; if (FT_Init_FreeType( &library )){ printf("PROBLEM WITH FT lib \n"); return; } FT_Face face; if (FT_New_Face( library, filename, 0, &face )) { return; } FT_Set_Char_Size( face,fontsize << 6,fontsize << 6,96,96); lineHeight = fontsize * 1.43f; //------------------------------------------------------ //kerning would be great to support: //printf("FT_HAS_KERNING ? %i \n", FT_HAS_KERNING(face)); //------------------------------------------------------ nCharacters = bFullCharacterSet ? 256 : 128 - NUM_CHARACTER_TO_START; //--------------- initialize character info and textures cps = new charProps[nCharacters]; texNames = new GLuint[nCharacters]; glGenTextures(nCharacters, texNames); //--------------------- load each char ----------------------- for (int i = 0 ; i < nCharacters; i++){ //------------------------------------------ anti aliased or not: if (bAntiAlised == true){ if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph %i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); } else { if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph%i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO); } //------------------------------------------ FT_Bitmap& bitmap= face->glyph->bitmap; // 1 pixel border around the glyph int border = 2; // prepare the texture: int width = ofNextPow2( bitmap.width + border); int height = ofNextPow2( bitmap.rows + border); // ------------------------- this is fixing a bug with small type // ------------------------- appearantly, opengl has trouble with // ------------------------- width or height textures of 1, so we // ------------------------- we just set it to 2... if (width == 1) width = 2; if (height == 1) height = 2; // ------------------------- // info about the character: cps[i].value = i; cps[i].height = face->glyph->bitmap_top; cps[i].width = face->glyph->bitmap.width; cps[i].setWidth = face->glyph->advance.x >> 6; cps[i].topExtent = face->glyph->bitmap.rows; cps[i].leftExtent = face->glyph->bitmap_left; // texture internals cps[i].tTex = (float)bitmap.width / (float)width; cps[i].vTex = (float)bitmap.rows / (float)height; cps[i].xOff = ((1.0+(float)bitmap.width) / (float)width) - cps[i].tTex; cps[i].yOff = ((1.0+(float)bitmap.rows) / (float)height) - cps[i].vTex; /* sanity check: printf("%i %i %i %i %i %i \n", cps[i].value , cps[i].height , cps[i].width , cps[i].setWidth , cps[i].topExtent , cps[i].leftExtent ); */ // Allocate Memory For The Texture Data. unsigned char* expanded_data = new unsigned char[ 2 * width * height]; //-------------------------------- clear data: for(int j=0; j =bitmap.width || j-1>=bitmap.rows) ? 0 : 255; expanded_data[2*(k+j*width)+1] = (k-1>=bitmap.width || j-1>=bitmap.rows) ? 0 : bitmap.buffer[k-1 + bitmap.width*(j-1)]; } } //----------------------------------- } else { //----------------------------------- // true type packs monochrome info in a // 1-bit format, hella funky // here we unpack it: unsigned char *src = bitmap.buffer; for(int j=0; j = nCharacters){ //printf("Error : char (%i) not allocated -- line %d in %s\n", (c + NUM_CHARACTER_TO_START), __LINE__,__FILE__); return; } //----------------------- int cu = c; float height = cps[cu].height; float bwidth = cps[cu].width; float top = cps[cu].topExtent - cps[cu].height; float lextent = cps[cu].leftExtent; float t = cps[cu].tTex; float v = cps[cu].vTex; float xOff = cps[cu].xOff; float yOff = cps[cu].yOff; //this is for topLeftDrawing only float corr = ( (fontSize - height) + top) - fontSize; if (glIsTexture(texNames[cu])) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texNames[cu]); glNormal3f(0, 0, 1); if (ofbOriginBottomLeft()){ glBegin(GL_QUADS); glTexCoord2d(xOff,yOff); glVertex2f(x + lextent, y + height); glTexCoord2d(xOff,v+yOff); glVertex2f(x + lextent, y-top); glTexCoord2d(t+xOff,v+yOff); glVertex2f(x + lextent + bwidth, y-top); glTexCoord2d(t+xOff,yOff); glVertex2f(x + lextent + bwidth, y + height); glEnd(); } else { glBegin(GL_QUADS); glTexCoord2d(t+xOff,v+yOff); glVertex2f(x + lextent + bwidth, y + height + corr); glTexCoord2d(t+xOff,yOff); glVertex2f(x + lextent + bwidth, (y-top) + corr); glTexCoord2d(xOff,yOff); glVertex2f(x + lextent, (y-top) + corr); glTexCoord2d(xOff,v+yOff); glVertex2f(x + lextent, y + height + corr); glEnd(); } glDisable(GL_TEXTURE_2D); } else { //let's add verbosity levels somewhere... //this error, for example, is kind of annoying to see //all the time: //printf("Warning : texture not bound for character -- line %d in %s\n", __LINE__,__FILE__); } } //----------------------------------------------------------- float ofTrueTypeFont::stringWidth(char *c) { float width = 0; int index = 0; float widthTemp = 0; bool bMultiLine = false; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { width = MAX(width, widthTemp); widthTemp = 0; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; widthTemp += cps[cy].width; } else { widthTemp += cps[cy].setWidth; } } index++; } width = MAX(width, widthTemp); return width; } //----------------------------------------------------------- float ofTrueTypeFont::stringHeight(char *c) { float height = 0; int index = 0; float maxHeight = 0; bool bFirstLineOfMultiLine = true; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { if (bFirstLineOfMultiLine == true){ bFirstLineOfMultiLine = false; height += maxHeight; } else { height += lineHeight; } maxHeight = 0; } else if (c[index] == ' ') { } else { float ht = cps[cy].height; if (ht > maxHeight) maxHeight = ht; } } index++; } height += maxHeight; return height; } //===================================================================== void ofTrueTypeFont::drawString(char *c, float x, float y) { if (!bLoadedOk){ printf("Error : font not allocated -- line %d in %s\n", __LINE__,__FILE__); return; }; // we need transparency to draw text, but we don't know // if that is set up in outside of this function // we "pushAttrib", turn on alpha and "popAttrib" // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushattrib.html // **** note **** // I have read that pushAttrib() is slow, if used often, // maybe there is a faster way to do this? // ie, check if blending is enabled, etc... // glIsEnabled().... glGet()... // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/get.html // ************** // (a) record the current "alpha state, blend func, etc" glPushAttrib(GL_COLOR_BUFFER_BIT); // (b) enable our regular ALPHA blending! glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); float startX = x; int index = 0; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { x = startX; int cy = (int)'M' - NUM_CHARACTER_TO_START; if(ofbOriginBottomLeft() ) y -= lineHeight; else y += lineHeight; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; x += cps[cy].width; } else { drawChar(cy, x, y); x += cps[cy].setWidth; } } index++; } // (c) return back to the way things were (with blending, blend func, etc) glPopAttrib(); } Revision-number: 49 Prop-content-length: 150 Content-length: 150 K 7 svn:log V 48 //zach - removed some extra ";"s in ofConstants K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-03T10:10:38.012599Z PROPS-END Node-path: utils/ofConstants.h Node-kind: file Node-action: change Text-content-length: 3128 Text-content-md5: 64ffcfabedb079999b85d0e472031945 Content-length: 3128 #ifndef OF_CONSTANTS #define OF_CONSTANTS //------------------------------- // pc or mac ? // soon: pc, mac or linux... #ifndef __APPLE_CC__ #define TARGET_WIN32 #else #define TARGET_OSX #endif //------------------------------- #ifdef TARGET_WIN32 #include #include "glut.h" #define __WINDOWS_DS__ #define __WINDOWS_MM__ #if (_MSC_VER) // microsoft visual studio #pragma warning(disable : 4996) // disable all deprecation warnings #pragma warning(disable : 4068) // unknown pragmas #pragma warning(disable : 4101) // unreferenced local variable #pragma warning(disable : 4312) // type cast conversion (in qt vp) #pragma warning(disable : 4311) // type cast pointer truncation (qt vp) #endif #define TARGET_LITTLE_ENDIAN // intel cpu // some gl.h files, like dev-c++, are old - this is pretty universal #ifndef GL_BGR_EXT #define GL_BGR_EXT 0x80E0 // #define WIN32_HIGH_RES_TIMING // note: this is experimental! // uncomment to turn this on (only for windows machines) // if you want to try setting the timer to be high resolution // this could make camera grabbing and other low level // operations quicker, but you must quit the app normally, // ie, using "esc", rather than killing the process or closing // the console window in order to set the timer resolution back // to normal (since the high res timer might give the OS // problems) // info: http://www.geisswerks.com/ryan/FAQS/timing.html #endif #endif #ifdef TARGET_OSX #define __MACOSX_CORE__ #include #include #if defined(__LITTLE_ENDIAN__) #define TARGET_LITTLE_ENDIAN // intel cpu #endif #endif #ifndef __MWERKS__ #define OF_EXIT_APP(val) exit(val); #else #define OF_EXIT_APP(val) std::exit(val); #endif // comment out this line, if you'd like to use the // quicktime capture interface on windows // if not, we default to videoInput library for // direct show capture, which is quite #define OF_SWITCH_TO_DSHOW_FOR_WIN_VIDCAP #ifdef OF_SWITCH_TO_DSHOW_FOR_WIN_VIDCAP #ifdef TARGET_OSX #define OF_VIDEO_CAPTURE_QUICKTIME #else #define OF_VIDEO_CAPTURE_DIRECTSHOW #endif #else // all quicktime, all the time #define OF_VIDEO_CAPTURE_QUICKTIME #endif // core: --------------------------- #include #include #include #include #include #ifndef PI #define PI 3.14159265358979323846 #endif #ifndef TWO_PI #define TWO_PI 6.28318530717958647693 #endif #ifndef M_TWO_PI #define M_TWO_PI 6.28318530717958647693 #endif #ifndef FOUR_PI #define FOUR_PI 12.56637061435917295385 #endif #ifndef HALF_PI #define HALF_PI 1.57079632679489661923 #endif #ifndef DEG_TO_RAD #define DEG_TO_RAD (PI/180.0) #endif #ifndef RAD_TO_DEG #define RAD_TO_DEG (180.0/PI) #endif #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #endif #ifndef ABS #define ABS(x) (((x) < 0) ? -(x) : (x)) #endif #define OF_FILLED 0x01 #define OF_OUTLINE 0x02 #define OF_WINDOW 0 #define OF_FULLSCREEN 1 #endif Revision-number: 50 Prop-content-length: 159 Content-length: 159 K 7 svn:log V 57 // zach - added ofSerial classes and communication folder K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-03T10:25:49.637020Z PROPS-END Node-path: communication Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: communication/ofSerial.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 4652 Text-content-md5: e2f4009cb6f2aca7a56d5fa8391d777b Content-length: 4662 PROPS-END #include "ofSerial.h" static bool bInited; #ifdef TARGET_WIN32 static HANDLE hComm; // the handle to the serial port pc #else static int fd; // the handle to the serial port mac #endif //---------------------------------------------------------------- void ofSerialInit (char * portName, int baud){ bInited = false; //--------------------------------------------- #ifdef TARGET_OSX //--------------------------------------------- struct termios toptions; printf("init_serialport: opening port %s @ %d bps\n", portName,baud); fd = open(portName, O_RDWR | O_NOCTTY | O_NDELAY); if(fd == -1) perror("open_port: unable to open port"); struct termios options; tcgetattr(fd,&options); switch(baud) { case 9600: cfsetispeed(&options,B9600); cfsetospeed(&options,B9600); break; case 19200: cfsetispeed(&options,B19200); cfsetospeed(&options,B19200); break; case 38400: cfsetispeed(&options,B38400); cfsetospeed(&options,B38400); break; default:cfsetispeed(&options,B9600); cfsetospeed(&options,B9600); break; } options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; tcsetattr(fd,TCSANOW,&options); bInited = true; printf("sucess in opening serial connection\n"); return; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- // open the serial port: // "COM4", etc... hComm=CreateFileA(portName,GENERIC_READ|GENERIC_WRITE,0,0, OPEN_EXISTING,0,0); if(hComm==INVALID_HANDLE_VALUE){ printf("error opening port %s\n please check to see if it's in use, or the right port\n", portName); return; } // now try the settings: COMMCONFIG cfg; DWORD cfgSize; char buf[80]; cfgSize=sizeof(cfg); GetCommConfig(hComm,&cfg,&cfgSize); int bps = baud; // Set baudrate and bits etc. // Note that BuildCommDCB() clears XON/XOFF and hardware control by default sprintf(buf,"baud=%d parity=N data=8 stop=1",bps); if(!BuildCommDCB(buf,&cfg.dcb)){ printf("Can't build comm dcb; %s",buf); } if(!SetCommState(hComm,&cfg.dcb)){ printf("Can't set comm state"); } printf(buf,"bps=%d, xio=%d/%d\n",cfg.dcb.BaudRate,cfg.dcb.fOutX,cfg.dcb.fInX); // Set communication timeouts (NT) COMMTIMEOUTS tOut; GetCommTimeouts(hComm,&tOut); // Make timeout so that: // - return immediately with buffered characters tOut.ReadIntervalTimeout=MAXDWORD; tOut.ReadTotalTimeoutMultiplier=0; tOut.ReadTotalTimeoutConstant=0; SetCommTimeouts(hComm,&tOut); bInited = true; //--------------------------------------------- #endif //--------------------------------------------- } //---------------------------------------------------------------- int ofSerialWrite (char * str){ if (!bInited){ printf("error: serial not inited\n"); return 0; } //--------------------------------------------- #ifdef TARGET_OSX //--------------------------------------------- int len = strlen(str); int numWritten = write(fd, str, len); printf("numWritten %i \n", numWritten); return numWritten; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- DWORD written; int len = strlen(str); if(!WriteFile(hComm,str,len,&written,0)){ printf("Can't write to com port"); return 0; } return (int)written; //--------------------------------------------- #endif //--------------------------------------------- } //---------------------------------------------------------------- int ofSerialRead (char * buffer, int length){ if (!bInited){ printf("error: serial not inited\n"); return 0; } //--------------------------------------------- #ifdef TARGET_OSX //--------------------------------------------- int nRead = read(fd,buffer,length); return nRead; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- DWORD nRead; if (!ReadFile(hComm,buffer,length,&nRead,0)){ printf("trouble reading from port"); return 0; } return nRead; //--------------------------------------------- #endif //--------------------------------------------- } Node-path: communication/ofSerial.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2134 Text-content-md5: 1ca749c634c661d37f46159d37de5282 Content-length: 2144 PROPS-END #ifndef OF_SERIAL_H #define OF_SERIAL_H #include "ofConstants.h" // this serial code contains small portions of the following code-examples: // --------------------------------------------------- // http://todbot.com/arduino/host/arduino-serial/arduino-serial.c // web.mac.com/miked13/iWeb/Arduino/Serial%20Write_files/main.cpp // www.racer.nl/docs/libraries/qlib/qserial.htm // --------------------------------------------------- // notes: // ---------------------------- // when callign ofSerialSetup("....") you need to pass in // the name of the com port the device is attached to // for example, on a mac, it might look like: // // ofSerialSetup("/dev/tty.usbserial-3B1", 9600) // // and on a mac, it might look like: // // ofSerialSetup("COM4", 9600) // // if you are using an arduino board, for example, // you should check what ports you device is on in the // arduino program // to do: // ---------------------------- // a) support multiple serial connections/ports // (currently supports only one) // b) support blocking / non-blocking // c) support numChars available type functions // ---------------------------- // (also useful, might be this serial example - worth checking out: // http://web.mit.edu/kvogt/Public/osrc/src/ // if has evolved ways of dealing with blocking // and non-blocking instances) // ---------------------------- #if TARGET_OS_MAC #include #include #include #else #include #include #include #include #endif #include /* Standard input/output definitions */ #include #include /* Standard types */ #include /* String function definitions */ #include /* UNIX standard function definitions */ #include /* File control definitions */ #include /* Error number definitions */ void ofSerialSetup (char * portName, int baud); int ofSerialWrite (char * str); int ofSerialRead (char * buffer, int length); #endif Revision-number: 51 Prop-content-length: 137 Content-length: 137 K 7 svn:log V 35 // just removed some extra comments K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-03T10:38:40.347082Z PROPS-END Node-path: sound/ofFmodUtils.cpp Node-kind: file Node-action: change Text-content-length: 1119 Text-content-md5: 57b9b13b4e4c9831bc41dc60c728224e Content-length: 1119 #include "ofFmodUtils.h" static bool bFmodInitialized = false; // dsp callback? // interesting? // http://66.102.9.104/search?q=cache:LM47mq8hytwJ:www.cleeker.com/doxygen/audioengine__fmod_8cpp-source.html+FSOUND_Sample_Load+cpp&hl=en&ct=clnk&cd=18&client=firefox-a // ---------------------------------------------------------------------------- void initializeFmod(){ // linux users: // an example of setting up fmod for different audio systems // is in this code: // http://66.102.9.104/search?q=cache:LM47mq8hytwJ:www.cleeker.com/doxygen/audioengine__fmod_8cpp-source.html+FSOUND_Sample_Load+cpp&hl=en&ct=clnk&cd=18&client=firefox-a if (bFmodInitialized == false){ if (FSOUND_GetVersion() < FMOD_VERSION){ printf("Error : You are using the wrong DLL version! You should be using FMOD %.02f\n", FMOD_VERSION); return; } FSOUND_Init( 44100, 32, 0 ); //FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND); // Direct Sound //FSOUND_SetDriver(0); //FSOUND_SetMixer(FSOUND_MIXER_AUTODETECT); bFmodInitialized = true; } } void closeFmod(){ FSOUND_Close(); } Revision-number: 52 Prop-content-length: 138 Content-length: 138 K 7 svn:log V 36 // added mouseX, mouseY as requested K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-04T14:57:24.343588Z PROPS-END Node-path: app/ofSimpleApp.h Node-kind: file Node-action: change Text-content-length: 711 Text-content-md5: 864129cf1ae4c1d3970acedc8ee13c30 Content-length: 711 #ifndef _OF_SIMPLE_APP #define _OF_SIMPLE_APP #include "ofConstants.h" #include "ofUtils.h" class ofSimpleApp{ public: ofSimpleApp(){} virtual void setup(){} virtual void update(){} virtual void draw(){} virtual void keyPressed(int key ){} virtual void mouseMoved( int x, int y ){} virtual void mouseDragged( int x, int y, int button ){} virtual void mousePressed( int x, int y, int button ){} virtual void mouseReleased(){} virtual void audioReceived (float * input, int bufferSize, int nChannels) {} virtual void audioRequested (float * output, int bufferSize, int nChannels) {} int mouseX, mouseY; // for processing heads }; #endif Revision-number: 53 Prop-content-length: 166 Content-length: 166 K 7 svn:log V 64 // zach - background auto-clear disable & rectMode setting added K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-04T14:58:47.641633Z PROPS-END Node-path: app/ofAppGlutGlue.h Node-kind: file Node-action: change Text-content-length: 4269 Text-content-md5: 344056964f72b1f25a515c128b923ddf Content-length: 4269 void display(void); void mouse_cb(int button, int state, int x, int y); void motion_cb(int x, int y); void passive_motion_cb(int x, int y); void idle_cb(void); void keyboard_cb(unsigned char key, int x, int y); void special_key_cb(int key, int x, int y) ; static int buttonInUse = 0; //-------------------------------- static float timeNow, timeThen, fps; static int nFramesForFPS; static int nFrameCount = 0; static bool bFrameRateSet; int millisForFrame; int prevMillis; int diffMillis; //------------------------------------------------------------ void display(void){ //-------------------------------- // when I had "glutFullScreen()" // in the initOpenGl, I was gettings a "heap" allocation error // when debugging via visual studio. putting it here, changes that. // maybe it's voodoo, or I am getting rid of the problem // by removing something unrelated, but everything seems // to work if I put fullscreen on the first frame of display. if (nFrameCount == 0 && windowMode == OF_FULLSCREEN) glutFullScreen(); width = ofGetWidth(); height = ofGetHeight(); height = height > 0 ? height : 1; // set viewport, clear the screen glViewport( 0, 0, width, height ); float * bgPtr = ofBgColorPtr(); bool bClearAuto = ofbClearBg(); // I don't know why, I need more than one frame at the start in fullscreen mode // also, // in non-fullscreen mode, windows/intel graphics, this bClearAuto just fails. // I seem to have 2 buffers, alot of flickering // and don't accumulate the way I expect. // with this line: if ((bClearAuto == true) || nFrameCount < 3){ // we do nFrameCount < 3, so that the buffers are cleared at the start of the app // or else we have video memory garbage to draw on to... if ((bClearAuto == true || windowMode == OF_WINDOW) || nFrameCount < 3){ glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } ofSetupScreen(); OFSAptr->draw(); glutSwapBuffers(); // -------------- fps calculation: timeNow = ofGetElapsedTimef(); if( (timeNow-timeThen) > 0.05f || nFramesForFPS == 0 ) { fps = (double)nFramesForFPS / (timeNow-timeThen); timeThen = timeNow; nFramesForFPS = 0; ofFrameRate = 0.9f * ofFrameRate + 0.1f * fps; } nFramesForFPS++; // -------------- nFrameCount++; // increase the overall frame count } //------------------------------------------------------------ void mouse_cb(int button, int state, int x, int y) { if (!ofbOriginBottomLeft()){ y = ofGetHeight() - y; } OFSAptr->mouseX = x; OFSAptr->mouseY = height - y; if (state == GLUT_DOWN) { OFSAptr->mousePressed(x, height - y, button); } else if (state == GLUT_UP) { OFSAptr->mouseReleased(); } buttonInUse = button; } //------------------------------------------------------------ void motion_cb(int x, int y) { if (!ofbOriginBottomLeft()){ y = ofGetHeight() - y; } OFSAptr->mouseX = x; OFSAptr->mouseY = height - y; OFSAptr->mouseDragged(x, height - y, buttonInUse); } //------------------------------------------------------------ void passive_motion_cb(int x, int y) { if (!ofbOriginBottomLeft()){ y = ofGetHeight() - y; } OFSAptr->mouseX = x; OFSAptr->mouseY = height - y; OFSAptr->mouseMoved(x, height - y); } //------------------------------------------------------------ void idle_cb(void) { if (nFrameCount != 0 && bFrameRateSet == true){ diffMillis = ofGetElapsedTimeMillis() - prevMillis; if (diffMillis > millisForFrame){ ; // we do nothing, we are already slower than target frame } else { int waitMillis = millisForFrame - diffMillis; #ifdef TARGET_WIN32 Sleep(waitMillis); //windows sleep in milliseconds #else usleep(waitMillis * 1000); //mac sleep in microseconds - cooler :) #endif } } OFSAptr->update(); glutPostRedisplay(); prevMillis = ofGetElapsedTimeMillis(); } //------------------------------------------------------------ void keyboard_cb(unsigned char key, int x, int y) { OFSAptr->keyPressed((int)key); if (key == 27){ // "escape" OF_EXIT_APP(0); } } //------------------------------------------------------------ void special_key_cb(int key, int x, int y) { OFSAptr->keyPressed((int)key); } Node-path: app/ofAppRunner.cpp Node-kind: file Node-action: change Text-content-length: 3327 Text-content-md5: 9d19276dea69da8a5de06b7f7afd3826 Content-length: 3327 #include "ofAppRunner.h" //======================================================================== // static variables: static ofSimpleApp * OFSAptr; int windowMode; bool bMousePressed; bool bRightButton; int width, height; static float ofFrameRate; //======================================================================== // callbacks: #include "ofAppGlutGlue.h" //-------------------------------------- void ofSetupOpenGL(int w, int h, int screenMode){ int argc = 1; char *argv = "openframeworks"; char **vptr = &argv; glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA); glutInit(&argc, vptr); //if (screenMode == OF_WINDOW) glutInitWindowSize(w, h); glutCreateWindow(""); windowMode = screenMode; ofBackground(200,200,200); // default bg color ofSetColor(0xFFFFFF); // default draw color // used to be black, but // black + texture = black // so maybe grey bg // and "white" fg color // as default works the best... } //----------------------- gets called when the app exits // currently looking at who to turn off // at the end of the application void ofExitCallback(); void ofExitCallback(){ // who to kill off ? // -- fmod // -- quicktime // -- freeImage // anyone else? #ifdef WIN32_HIGH_RES_TIMING timeEndPeriod(1); #endif //delete OFSAptr; } //-------------------------------------- void ofRunApp(ofSimpleApp * OFSA){ OFSAptr = OFSA; atexit(ofExitCallback); #ifdef WIN32_HIGH_RES_TIMING timeBeginPeriod(1); // ! experimental, sets high res time // you need to call timeEndPeriod. // if you quit the app other than "esc" // (ie, close the console, kill the process, etc) // at exit wont get called, and the time will // remain high res, that could mess things // up on your system. // info here:http://www.geisswerks.com/ryan/FAQS/timing.html #endif bFrameRateSet = false; //---------------------- // setup the callbacks glutMouseFunc(mouse_cb); glutMotionFunc(motion_cb); glutPassiveMotionFunc(passive_motion_cb); glutIdleFunc(idle_cb); glutDisplayFunc(display); glutKeyboardFunc(keyboard_cb); glutSpecialFunc(special_key_cb); //---------------------- ofSeedRandom(); // seed the random generator // (users can seed it to a value in setup // if they want it fixed); OFSA->setup(); glutMainLoop(); } //-------------------------------------- float ofGetFrameRate(){ return ofFrameRate; } //-------------------------------------- void ofSetFrameRate(int targetRate){ // given this FPS, what is the amount of millis per frame // that should elapse? // --- > f / s if (targetRate == 0){ bFrameRateSet = false; return; } bFrameRateSet = true; float durationOfFrame = 1.0f / (float)targetRate; millisForFrame = (int)(1000.0f * durationOfFrame); } //-------------------------------------- void ofHideCursor(){ glutSetCursor(GLUT_CURSOR_NONE); } //-------------------------------------- void ofShowCursor(){ glutSetCursor(GLUT_CURSOR_RIGHT_ARROW); } Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: change Text-content-length: 8981 Text-content-md5: a712cde8b777bfea5f91bb40b658399d Content-length: 8981 #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); bool bSmoothHinted = false; bool bBakgroundAuto = true; int cornerMode = OF_RECTMODE_CORNER; //---------------------------------------------------------- void ofSetRectMode(int mode){ if (mode == OF_RECTMODE_CORNER) cornerMode = OF_RECTMODE_CORNER; else if (mode == OF_RECTMODE_CENTER) cornerMode = OF_RECTMODE_CENTER; } //---------------------------------------------------------- int ofGetRectMode(){ return cornerMode; } //---------------------------------------------------------- void ofSetBackgroundAuto(bool bAuto){ bBakgroundAuto = bAuto; } //---------------------------------------------------------- bool ofbClearBg(){ return bBakgroundAuto; } //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- bool ofbOriginBottomLeft(){ return false; // because people are certainly asking for it! } //---------------------------------------------------------- void ofBackground(int r, int g, int b){ bgColor[0] = (float)r / (float)255.0f; bgColor[1] = (float)g / (float)255.0f; bgColor[2] = (float)b / (float)255.0f; bgColor[3] = 1.0f; // if we are in not-auto mode, then clear with a bg call... if (ofbClearBg() == false){ glClearColor(bgColor[0],bgColor[1],bgColor[2], bgColor[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void startSmoothing(){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void endSmoothing(){ glPopAttrib(); } //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_FILLED) startSmoothing(); // draw: glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_FILLED) endSmoothing(); } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_FILLED) startSmoothing(); // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_FILLED) endSmoothing(); } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_FILLED) startSmoothing(); // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_FILLED) endSmoothing(); } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_FILLED) startSmoothing(); // draw: glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_FILLED) endSmoothing(); } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_FILLED) startSmoothing(); if (cornerMode == OF_RECTMODE_CENTER){ glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x-w/2,y-h/2); glVertex2f(x+w/2,y-h/2); glVertex2f(x+w/2,y+h/2); glVertex2f(x-w/2,y+h/2); glEnd(); } else { glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); } // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_FILLED) startSmoothing(); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b, int _a){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); float a = (float)_a / 255.0f; a = MAX(0,MIN(a,1.0f)); glColor4f(r,g,b,a); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } //---------------------------------------------------------- void ofEnableAlphaBlending(){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void ofDisableAlphaBlending(){ glDisable(GL_BLEND); } //---------------------------------------------------------- void ofEnableSmoothing(){ // please see: // http://www.opengl.org/resources/faq/technical/rasterization.htm bSmoothHinted = true; } //---------------------------------------------------------- void ofDisableSmoothing(){ bSmoothHinted = false; } //-------------------------------------------------- void ofDrawBitmapString(char *string, float x, float y){ //--------------------------------------------------- // for now this is fixed to the 8_BY_13 glut character // http://pyopengl.sourceforge.net/documentation/manual/glutBitmapCharacter.3GLUT.html //--------------------------------------------------- char *c; float yOffset = 0; float fontSize = 8.0f; glRasterPos2f(x,y); for (c=string; *c != '\0'; c++) { if(*c == '\n') { yOffset -= (fontSize*1.7); glRasterPos2f(x,y + (int)yOffset); } else if (((int)*c) >= 32){ // < 32 = control characters - don't draw // solves a bug with control characters // getting drawn when they ought to not be glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c); } } } //---------------------------------------------------------- void ofSetupScreen(){ int w, h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (!ofbOriginBottomLeft()){ glScalef(1, -1, 1); // invert Y axis so increasing Y goes down. glTranslatef(0, -h, 0); // shift origin up to upper-left corner. } } Node-path: graphics/ofGraphics.h Node-kind: file Node-action: change Text-content-length: 1617 Text-content-md5: b22096b9c70c897561c3f66ba23f6aa2 Content-length: 1617 #ifndef OF_GEOM #define OF_GEOM #include "ofConstants.h" #define CIRC_RESOLUTION 22 // 22 pts for a circle... // bg color float * ofBgColorPtr(); void ofBackground(int r, int g, int b); // user's access to settings (bgAuto, corner mode): void ofSetBackgroundAuto(bool bManual); // default is true void ofSetRectMode(int mode); // set the mode, either to OF_RECTMODE_CORNER or OF_RECTMODE_CENTER // OF's access to settings (bgAuto, origin, corner mode): bool ofbOriginBottomLeft(); bool ofbClearBg(); int ofGetRectMode(); // default is OF_RECTMODE_CORNER // geometry void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3); void ofCircle(float x,float y, float radius); void ofEllipse(float x, float y, float width, float height); void ofLine(float x1,float y1,float x2,float y2); void ofRect(float x1,float y1,float w, float h); void ofSetCircleResolution(int res); // if there 22 is a problem, you can change it here // drawing options void ofNoFill(); void ofFill(); // color options void ofSetColor(int r, int g, int b); // 0-255 void ofSetColor(int r, int g, int b, int a); // 0-255 void ofSetColor(int hexColor); // hex, like web 0xFF0033; // transparency void ofEnableAlphaBlending(); // this just turns on and off opengl blending, the common mode void ofDisableAlphaBlending(); // smooth void ofEnableSmoothing(); void ofDisableSmoothing(); // bitmapped type // ** note, this uses glDrawPixels and may be S L 0 W on some graphics cards void ofDrawBitmapString( char *string, float x, float y); // screen coordinate things... void ofSetupScreen(); #endif Node-path: graphics/ofTexture.cpp Node-kind: file Node-action: change Text-content-length: 5631 Text-content-md5: b0a6484c117ec954b13c85a4b8fbba64 Content-length: 5631 #include "ofTexture.h" #include "ofUtils.h" // for nextPow2() //---------------------------------------------------------- ofTexture::ofTexture(){ texName[0] = 0; } //---------------------------------------------------------- void ofTexture::clear(){ // try to free up the texture memory so we don't reallocate // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/deletetextures.html if (texName[0] != 0){ glDeleteTextures(1, (GLuint *)texName); } width = 0; height = 0; } //---------------------------------------------------------- void ofTexture::allocate(int w, int h, int internalGlDataType){ // can pass in anything (320x240) (10x5) // here we make it power of 2 for opengl (512x256), (16x8) tex_w = ofNextPow2(w); tex_h = ofNextPow2(h); tex_u = 1.0f; tex_t = 1.0f; // attempt to free the previous bound texture, if we can: clear(); glGenTextures(1, (GLuint *)texName); // could be more then one, but for now, just one glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); // upload 0 or white pixels.... glTexImage2D(GL_TEXTURE_2D, 0, internalGlDataType, tex_w, tex_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); // init to black... glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); width = w; height = h; } //---------------------------------------------------------- void ofTexture::loadData(unsigned char * data, int w, int h, int glDataType){ // can we allow for uploads bigger then texture and // just take as much as the texture can? // // ie: // int uploadW = MIN(w, tex_w); // int uploadH = MIN(h, tex_h); // but with a "step" size of w? // check "glTexSubImage2D" if ( w > tex_w || h > tex_h) { printf("image data too big for allocated texture. not uploading... \n"); return; } width = w; height = h; //compute new tex co-ords based on the ratio of data's w, h to texture w,h; tex_t = (float)(w) / (float)tex_w; tex_u = (float)(h) / (float)tex_h; // ok this is an ultra annoying bug : // opengl texels and linear filtering - // when we have a sub-image, and we scale it // we can clamp the border pixels to the border, // but the borders of the sub image get mixed with // neighboring pixels... // grr... // // the best solution would be to pad out the image // being uploaded with 2 pixels on all sides, and // recompute tex_t coordinates.. // another option is a gl_arb non pow 2 textures... // the current hack is to alter the tex_t, tex_u calcs, but // that makes the image slightly off... // this is currently being done in draw... // // we need a good solution for this.. // // http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014770#000001 // http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014770#000001 //------------------------ likely, we are uploading continuous data GLint prevAlignment; glGetIntegerv(GL_UNPACK_ALIGNMENT, &prevAlignment); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // update the texture image: glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); glTexSubImage2D(GL_TEXTURE_2D,0,0,0,w,h,glDataType,GL_UNSIGNED_BYTE,data); glDisable(GL_TEXTURE_2D); //------------------------ back to normal. glPixelStorei(GL_UNPACK_ALIGNMENT, prevAlignment); } //---------------------------------------------------------- void ofTexture::loadScreenData(int x, int y, int w, int h){ glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); glCopyTexSubImage2D(GL_TEXTURE_2D, 0,0,0,x,y,w,h); glDisable(GL_TEXTURE_2D); } //---------------------------------------------------------- void ofTexture::draw(float x, float y, float w, float h){ glEnable(GL_TEXTURE_2D); // bind the texture glBindTexture( GL_TEXTURE_2D, (GLuint)texName[0] ); float px0 = x ; // up to you to get the aspect ratio right float py0 = y ; float px1 = x+w; float py1 = y+h; // for rect mode center, let's do this: if (ofGetRectMode() == OF_RECTMODE_CENTER){ px0 = x-w/2; py0 = y-h/2; px1 = x+w/2; py1 = y+h/2; } // ------------------------------------------------- // complete hack to remove border artifacts. // slightly, slightly alters an image, scaling... // to remove the border. // we need a better solution for this, but // to constantly add a 2 pixel border on all uploaded images // is insane.. float offsetw = 1.0f/(tex_w*2.0f); float offseth = 1.0f/(tex_h*2.0f); // ------------------------------------------------- float tx0 = 0+offsetw; float ty0 = 0+offseth; float tx1 = tex_t - offsetw; float ty1 = tex_u - offseth; glBegin( GL_QUADS ); glTexCoord2f(tx0,ty0); glVertex3f(px0, py0,0); glTexCoord2f(tx1,ty0); glVertex3f(px1, py0,0); glTexCoord2f(tx1,ty1); glVertex3f(px1, py1,0); glTexCoord2f(tx0,ty1); glVertex3f(px0, py1,0); glEnd(); glDisable(GL_TEXTURE_2D); } //---------------------------------------------------------- void ofTexture::draw(float x, float y){ draw(x,y,width, height); } Node-path: graphics/ofTexture.h Node-kind: file Node-action: change Text-content-length: 674 Text-content-md5: afc12c8d41c5374161c5c5b71d6d21da Content-length: 674 #ifndef _IMAGE_TEXTURE_H_ #define _IMAGE_TEXTURE_H_ #include "ofConstants.h" #include "ofGraphics.h" class ofTexture { public : ofTexture(); void allocate(int w, int h, int internalGlDataType); void clear(); void loadData(unsigned char * data, int w, int h, int glDataType); void loadScreenData(int x, int y, int w, int h); void draw(float x, float y, float w, float h); void draw(float x, float y); float tex_t, tex_u; int width, height; // private: float offset_x, offset_y; int tex_w, tex_h; unsigned int texName[1]; // vs not happy with dynamic allocation of this... }; #endif Node-path: utils/ofConstants.h Node-kind: file Node-action: change Text-content-length: 3194 Text-content-md5: bf400c6a79b4042134dde11417687e15 Content-length: 3194 #ifndef OF_CONSTANTS #define OF_CONSTANTS //------------------------------- // pc or mac ? // soon: pc, mac or linux... #ifndef __APPLE_CC__ #define TARGET_WIN32 #else #define TARGET_OSX #endif //------------------------------- #ifdef TARGET_WIN32 #include #include "glut.h" #define __WINDOWS_DS__ #define __WINDOWS_MM__ #if (_MSC_VER) // microsoft visual studio #pragma warning(disable : 4996) // disable all deprecation warnings #pragma warning(disable : 4068) // unknown pragmas #pragma warning(disable : 4101) // unreferenced local variable #pragma warning(disable : 4312) // type cast conversion (in qt vp) #pragma warning(disable : 4311) // type cast pointer truncation (qt vp) #endif #define TARGET_LITTLE_ENDIAN // intel cpu // some gl.h files, like dev-c++, are old - this is pretty universal #ifndef GL_BGR_EXT #define GL_BGR_EXT 0x80E0 // #define WIN32_HIGH_RES_TIMING // note: this is experimental! // uncomment to turn this on (only for windows machines) // if you want to try setting the timer to be high resolution // this could make camera grabbing and other low level // operations quicker, but you must quit the app normally, // ie, using "esc", rather than killing the process or closing // the console window in order to set the timer resolution back // to normal (since the high res timer might give the OS // problems) // info: http://www.geisswerks.com/ryan/FAQS/timing.html #endif #endif #ifdef TARGET_OSX #define __MACOSX_CORE__ #include #include #if defined(__LITTLE_ENDIAN__) #define TARGET_LITTLE_ENDIAN // intel cpu #endif #endif #ifndef __MWERKS__ #define OF_EXIT_APP(val) exit(val); #else #define OF_EXIT_APP(val) std::exit(val); #endif // comment out this line, if you'd like to use the // quicktime capture interface on windows // if not, we default to videoInput library for // direct show capture, which is quite #define OF_SWITCH_TO_DSHOW_FOR_WIN_VIDCAP #ifdef OF_SWITCH_TO_DSHOW_FOR_WIN_VIDCAP #ifdef TARGET_OSX #define OF_VIDEO_CAPTURE_QUICKTIME #else #define OF_VIDEO_CAPTURE_DIRECTSHOW #endif #else // all quicktime, all the time #define OF_VIDEO_CAPTURE_QUICKTIME #endif // core: --------------------------- #include #include #include #include #include #ifndef PI #define PI 3.14159265358979323846 #endif #ifndef TWO_PI #define TWO_PI 6.28318530717958647693 #endif #ifndef M_TWO_PI #define M_TWO_PI 6.28318530717958647693 #endif #ifndef FOUR_PI #define FOUR_PI 12.56637061435917295385 #endif #ifndef HALF_PI #define HALF_PI 1.57079632679489661923 #endif #ifndef DEG_TO_RAD #define DEG_TO_RAD (PI/180.0) #endif #ifndef RAD_TO_DEG #define RAD_TO_DEG (180.0/PI) #endif #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #endif #ifndef ABS #define ABS(x) (((x) < 0) ? -(x) : (x)) #endif #define OF_FILLED 0x01 #define OF_OUTLINE 0x02 #define OF_WINDOW 0 #define OF_FULLSCREEN 1 #define OF_RECTMODE_CORNER 0 #define OF_RECTMODE_CENTER 1 #endif Revision-number: 54 Prop-content-length: 144 Content-length: 144 K 7 svn:log V 42 // zach - fixes for warnings (int / float) K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-04T14:59:26.212281Z PROPS-END Node-path: graphics/ofImage.cpp Node-kind: file Node-action: change Text-content-length: 10192 Text-content-md5: fa4309dfe6f9a031d32fe547ed0b10c0 Content-length: 10192 #include "ofImage.h" #include "freeImage.h" static bool bFreeImageInited = false; //----------------------------------------- // class freeImageBitmap{ public: FIBITMAP * bmp; // when OF users ask for pixels // we will get them contiguous memory // ie, non-aligned // see the pixel access chapter of the freeImage pdf // these pixel will also be RGB // on both platforms // bmp will be RGB / BGR depending // on the endianess of the platform. unsigned char * pixels; //----------------------- freeImageBitmap(){ bmp = NULL; } //----------------------- //swap my image out in a (hopefully) non-memory leakish way void swap(FIBITMAP *dst) { if(dst == NULL) return; if(bmp != NULL) FreeImage_Unload(bmp); bmp = dst; } //----------------------- void setSize(FREE_IMAGE_TYPE image_type, WORD width, WORD height, WORD bpp) { if(bmp == NULL) { FreeImage_Unload(bmp); } bmp = FreeImage_AllocateT(image_type, width, height, bpp); } //----------------------- bool isValid(){ return (bmp != NULL) ? true : false; } }; //---------------------------------------------------------- ofImage::ofImage(){ //----------------------- init free image if necessary if (!bFreeImageInited){ FreeImage_Initialise(); bFreeImageInited = true; } //----------------------- IMG = new freeImageBitmap(); width = height = bpp = 0; type = OF_IMAGE_UNDEFINED; bUseTexture = true; // the default is, yes, use a texture bAllocatedPixels = false; } //---------------------------------------------------------- void ofImage::grabScreen(int _x, int _y, int _w, int _h){ if (IMG->isValid()){ // flip y if origin is top: if (!ofbOriginBottomLeft()){ int height = ofGetHeight(); _y = height - _y; _y -= _h; // top, bottom issues } if (!(width == _w && height == _h)){ resize(_w, _h); } unsigned char * pixels = (unsigned char *)FreeImage_GetBits(IMG->bmp); switch (bpp){ case 8: glReadPixels(_x, _y, _w, _h, GL_LUMINANCE,GL_UNSIGNED_BYTE, pixels); break; case 24: #ifdef TARGET_LITTLE_ENDIAN glReadPixels(_x, _y, _w, _h, GL_BGR_EXT,GL_UNSIGNED_BYTE, pixels); #else glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); #endif break; case 32: glReadPixels(_x, _y, _w, _h, GL_RGBA,GL_UNSIGNED_BYTE, pixels); break; } // we will need to flip images // if the 0,0 position is in the top left: if (!ofbOriginBottomLeft()){ FreeImage_FlipVertical(IMG->bmp); } update(); } else { // assume that this is color.... IMG->setSize(FIT_BITMAP, _w, _h, 24); unsigned char * pixels = (unsigned char *)FreeImage_GetBits(IMG->bmp); #ifdef TARGET_LITTLE_ENDIAN glReadPixels(_x, _y, _w, _h, GL_BGR_EXT,GL_UNSIGNED_BYTE, pixels); #else glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); #endif // we will need to flip images // if the 0,0 position is in the top left: if (!ofbOriginBottomLeft()){ FreeImage_FlipVertical(IMG->bmp); } update(); } } //---------------------------------------------------------- void ofImage::allocate(int _w, int _h, int _type){ int newbpp; switch (_type){ case OF_IMAGE_GRAYSCALE: newbpp = 8; break; case OF_IMAGE_COLOR: newbpp = 24; break; case OF_IMAGE_COLOR_ALPHA: newbpp = 32; break; default: newbpp = 24; break; } IMG->setSize(FIT_BITMAP, _w, _h, newbpp); } //---------------------------------------------------------- void ofImage::update(){ width = FreeImage_GetWidth(IMG->bmp); height = FreeImage_GetHeight(IMG->bmp); bpp = FreeImage_GetBPP(IMG->bmp); // this is check to see if it's a gif bool bNoPallette = (FreeImage_GetColorType(IMG->bmp) != FIC_PALETTE); switch (bpp){ case 8: if (bNoPallette) { //!bUsesPallette){ type = OF_IMAGE_GRAYSCALE; } else { // convert to RGB - // this is a gif (or other) with 256 colors, not b&w. setImageType(OF_IMAGE_COLOR); } break; case 24: type = OF_IMAGE_COLOR; break; case 32: type = OF_IMAGE_COLOR_ALPHA; break; default: // if we've got here, something is wrong, the image // is not 8bit, 24bit or 32bit, so let's at least // make it color: setImageType(OF_IMAGE_COLOR); break; } //---------------------------------- // now, since the "freeImage" memory is padded // (see freeImage392.pdf - "Pixel access functions") // lets get the data into contiguous memory - to make it easier // for folks to work with... if (IMG->pixels != NULL && bAllocatedPixels == true) delete IMG->pixels; // delete anything that might have existed int byteCount = bpp / 8; // bytes ber pixel (not bits per pixel) IMG->pixels = new unsigned char[width*height*byteCount]; //allocate that memory for the image (contiguously) bAllocatedPixels = true; FreeImage_ConvertToRawBits(IMG->pixels, IMG->bmp, width*byteCount, bpp, FI_RGBA_RED_MASK,FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE); // get bits #ifdef TARGET_LITTLE_ENDIAN if (type == OF_IMAGE_COLOR) swapChannels(false); if (type == OF_IMAGE_COLOR_ALPHA) swapChannels(true); #endif //---------------------------------- // if we are using a texture and the ofImage is upadate, // allocate (or reallocate) the texture and upload the data // I will upload from the contguous memory, and use pixelStorei to // make sure opengl knows I am contiguous. if (bUseTexture){ switch (type){ case OF_IMAGE_GRAYSCALE: tex.allocate(width,height,GL_LUMINANCE); tex.loadData(IMG->pixels, width,height, GL_LUMINANCE); break; case OF_IMAGE_COLOR: tex.allocate(width,height,GL_RGB); tex.loadData(IMG->pixels, width,height, GL_RGB); break; case OF_IMAGE_COLOR_ALPHA: tex.allocate(width,height,GL_RGBA); tex.loadData(IMG->pixels, width,height, GL_RGBA); break; } } } //---------------------------------------------------------- void ofImage::loadImage(char * fileName){ bool bLoaded = false; //----------------------------- find the format FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { if(IMG->isValid()) { FreeImage_Unload(IMG->bmp); } IMG->bmp = FreeImage_Load(fif, fileName, 0); bLoaded = true; if(!IMG->isValid()){ bLoaded = false; } } //----------------------------- if (bLoaded){ // we will need to flip images // if the 0,0 position is in the top left: if (!ofbOriginBottomLeft()){ FreeImage_FlipVertical(IMG->bmp); } update(); } else { width = height = bpp = 0; } } //---------------------------------------------------------- void ofImage::saveImage(char * fileName){ if (IMG->isValid()){ FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { FreeImage_Save(fif, IMG->bmp, fileName, 0); } } } //---------------------------------------------------------- unsigned char * ofImage::getPixels(){ // be careful! might not be allocated. you need to check for null... if (IMG->isValid()){ return (unsigned char *)IMG->pixels; } else { return NULL; } } //---------------------------------------------------------- void ofImage::resize(int newWidth, int newHeight){ if (IMG->isValid()){ FIBITMAP * scaledBmp = FreeImage_Rescale(IMG->bmp, newWidth, newHeight, FILTER_BICUBIC); IMG->swap(scaledBmp); update(); } } //---------------------------------------------------------- void ofImage::setImageType(int newType){ if (IMG->isValid()){ switch (newType){ //------------------------------------ case OF_IMAGE_GRAYSCALE: if (type != OF_IMAGE_GRAYSCALE){ FIBITMAP * convertedBmp = FreeImage_ConvertToGreyscale(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; //------------------------------------ case OF_IMAGE_COLOR: if (type != OF_IMAGE_COLOR){ FIBITMAP * convertedBmp = FreeImage_ConvertTo24Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR; } break; //------------------------------------ case OF_IMAGE_COLOR_ALPHA: if (type != OF_IMAGE_COLOR_ALPHA){ FIBITMAP * convertedBmp = FreeImage_ConvertTo32Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR_ALPHA; } break; } update(); } } //------------------------------------ void ofImage::swapChannels(bool bAlpha){ // this swaps the red and blue channel of an image // turning an bgr image to rgb and vice versa... // needed because of windows byte order... if (IMG->isValid()){ unsigned char * pixels = IMG->pixels; unsigned char temp; int totalPixels = width*height; // unoptimized for now... if (bAlpha == false){ for (int i = 0; i < totalPixels; i++){ temp = pixels[i*3 + 2]; pixels[i*3 + 2] = pixels[i*3]; pixels[i*3] = temp; } } else { for (int i = 0; i < totalPixels; i++){ temp = pixels[i*4]; pixels[i*4] = pixels[i*4 + 2]; pixels[i*4 + 2] = temp; } } } } //------------------------------------ void ofImage::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofImage::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } //------------------------------------ void ofImage::draw(float x, float y){ draw(x,y,width,height); } Revision-number: 55 Prop-content-length: 116 Content-length: 116 K 7 svn:log V 14 // 0,0 top fix K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-04T15:00:09.300867Z PROPS-END Node-path: video/ofVideoGrabber.cpp Node-kind: file Node-action: change Text-content-length: 13288 Text-content-md5: 1d7c37611c9a3f21888a1c58c51c6072 Content-length: 13288 #include "ofVideoGrabber.h" //-------------------------------------------------------------------- ofVideoGrabber::ofVideoGrabber(){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- initializeQuicktime(); vgd = new videoGrabberData(); vgd->bSgInited = false; //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW //--------------------------------- bVerbose = false; bFrameNew = false; //--------------------------------- #endif //--------------------------------- // common bVerbose = false; bSgGrabberInited = false; bUseTexture = true; bChooseDevice = false; deviceID = 0; width = 320; height = 240; } //-------------------------------------------------------------------- void ofVideoGrabber::listDevices(){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- initGrabbingComponent(vgd, true); // if necessary, start the sg object if (!vgd->bSgInited){ printf("error in list devices, couldn't allocate grabbing component\n"); return; } printf("-------------------------------------\n"); SGDeviceList deviceList; SGGetChannelDeviceList (vgd->gVideoChannel, sgDeviceListIncludeInputs, &deviceList); unsigned char pascalName[64]; if(true) { printf("listing available capture devices\n"); for(int i = 0 ; i < (*deviceList)->count ; ++i) { SGDeviceName nameRec; nameRec = (*deviceList)->entry[i]; memcpy(pascalName, (*deviceList)->entry[i].name, sizeof(char) * 64); if(nameRec.flags != sgDeviceNameFlagDeviceUnavailable) printf("device[%i] %s \n", i, p2cstr(pascalName) ); else printf("(unavailable) device[%i] %s \n", i, p2cstr(pascalName) ); } } printf("-------------------------------------\n"); //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW //--------------------------------- printf("---\n"); VI.listDevices(); printf("---\n"); //--------------------------------- #endif //--------------------------------- } //-------------------------------------------------------------------- void ofVideoGrabber::setVerbose(bool bTalkToMe){ bVerbose = bTalkToMe; } //-------------------------------------------------------------------- void ofVideoGrabber::setDeviceID(int _deviceID){ deviceID = _deviceID; bChooseDevice = true; } //--------------------------------------------------------------------------- unsigned char * ofVideoGrabber::getPixels(){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- return vgd->pixels; //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW //--------------------------------- return pixels; //--------------------------------- #endif //--------------------------------- } //--------------------------------------------------------------------------- bool ofVideoGrabber::isFrameNew(){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- if (bSgGrabberInited == true){ bool bNew = false; if (vgd->bHavePixelsChanged == true){ bNew = true; vgd->bHavePixelsChanged = false; } return bNew; } else { return false; } //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW //--------------------------------- if (bFrameNew == true){ bFrameNew = false; return true; } else { return false; } //--------------------------------- #endif //--------------------------------- } //-------------------------------------------------------------------- void ofVideoGrabber::grabFrame(){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- if (bSgGrabberInited == true){ SGIdle(vgd->gSeqGrabber); // set the top pixel alpha = 0, so we can know if it // was a new frame or not.. // or else we will process way more than necessary // (ie opengl is running at 60fps +, capture at 30fps) if (vgd->offscreenGWorldPixels[0] != 0x00){ vgd->offscreenGWorldPixels[0] = 0x00; vgd->bHavePixelsChanged = true; convertPixels(vgd->offscreenGWorldPixels, vgd->pixels, vgd->w, vgd->h); if (bUseTexture){ tex.loadData(vgd->pixels, vgd->w, vgd->h, GL_RGB); } } } //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW //--------------------------------- if (bSgGrabberInited == true){ if (VI.isFrameNew(device)){ bFrameNew = true; // VI.getPixels(device, true) // true = flip BGR to RGB // ok, if we are 0,0 top left, we need to flip this image: if (ofbOriginBottomLeft() == true){ // do nothing, just copy memcpy(pixels, VI.getPixels(device, true), width*height*3); } else { // else, let's flip! unsigned char * viPixels = VI.getPixels(device, true); int widthOfLine = width * 3; for (int i = 0; i < height; i++){ memcpy(pixels + (i * widthOfLine), viPixels + ((height - i - 1) * (widthOfLine)), widthOfLine); } } if (bUseTexture){ tex.loadData(pixels, width, height, GL_RGB); } } } //--------------------------------- #endif //--------------------------------- } //-------------------------------------------------------------------- void ofVideoGrabber::close(){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //thanks eloi! if (vgd->gSeqGrabber != 0L){ CloseComponent (vgd->gSeqGrabber); vgd->gSeqGrabber = 0L; } #endif } //-------------------------------------------------------------------- void ofVideoGrabber::videoSettings(void){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- Rect curBounds, curVideoRect; ComponentResult err; // Get our current state err = SGGetChannelBounds (vgd->gVideoChannel, &curBounds); if (err != noErr){ printf("Error in SGGetChannelBounds \n"); return; } err = SGGetVideoRect (vgd->gVideoChannel, &curVideoRect); if (err != noErr){ printf("Error in SGGetVideoRect \n"); return; } // Pause err = SGPause (vgd->gSeqGrabber, true); if (err != noErr){ printf("Error in SGPause\n"); return; } #ifdef TARGET_OSX static SGModalFilterUPP gSeqGrabberModalFilterUPP = NewSGModalFilterUPP(SeqGrabberModalFilterUPP); ComponentResult result = SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, seqGrabSettingsPreviewOnly, gSeqGrabberModalFilterUPP, nil); if (err != noErr){ printf("error in dialogue\n"); return; } #else SGSettingsDialog(vgd->gSeqGrabber, vgd->gVideoChannel, 0, nil, seqGrabSettingsPreviewOnly, NULL, 0); #endif SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); SGPause (vgd->gSeqGrabber, false); //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW //--------------------------------- if (bSgGrabberInited == true) VI.showSettingsWindow(device); //--------------------------------- #endif //--------------------------------- } //-------------------------------------------------------------------- void ofVideoGrabber::initGrabber(int w, int h){ //--------------------------------- #ifdef OF_VIDEO_CAPTURE_QUICKTIME //--------------------------------- vgd->w = w; vgd->h = h; OSStatus err; initGrabbingComponent(vgd, true); if (!vgd->bSgInited){ printf("error in init grabber, couldn't allocate grabbing component\n"); return; } MacSetRect(&(vgd->videoRect),0, 0, w, h); width = w; height = h; //---------------------------------- buffer allocation // Create a buffer big enough to hold the video data, // make sure the pointer is 32-byte aligned. // also the rgb image that people will grab vgd->offscreenGWorldPixels = (unsigned char*)malloc(4 * w * h + 32); vgd->pixels = new unsigned char[w*h*3]; QTNewGWorldFromPtr (&vgd->videogworld, k32ARGBPixelFormat, &vgd->videoRect, NULL, NULL, 0, vgd->offscreenGWorldPixels, 4 * w); LockPixels(GetGWorldPixMap(vgd->videogworld)); SetGWorld (vgd->videogworld, NULL); SGSetGWorld(vgd->gSeqGrabber, vgd->videogworld, nil); //---------------------------------- choose a specific device to setup if(bChooseDevice) { //Generate a device list and enumerate //all devices availble to the channel SGDeviceList deviceList; SGGetChannelDeviceList (vgd->gVideoChannel, sgDeviceListIncludeInputs, &deviceList); unsigned char pascalName[64]; //List all available devices if(bVerbose) { printf("listing available capture devices\n"); for(int i = 0 ; i < (*deviceList)->count ; ++i){ memcpy(pascalName, (*deviceList)->entry[i].name, sizeof(char) * 64); printf("device[%i] %s \n", i, p2cstr(pascalName) ); } } //check that the device requested exists if(deviceID+1 <= (*deviceList)->count) { SGDeviceName nameRec; nameRec = (*deviceList)->entry[deviceID]; if(nameRec.flags != sgDeviceNameFlagDeviceUnavailable) { unsigned char camStr[255]; memcpy(camStr, (*deviceList)->entry[deviceID].name, sizeof(char) * 64); memcpy(pascalName, (*deviceList)->entry[deviceID].name, sizeof(char) * 64); p2cstr(camStr); if(bVerbose)printf("attempting to setup device[%i] (%s) \n", deviceID, camStr); memcpy(pascalName, (*deviceList)->entry[deviceID].name, sizeof(char) * 64); err = SGSetChannelDevice(vgd->gVideoChannel, pascalName); if ( err != noErr ) { printf("***** Error in SGSetChannelDevice - setting device[%i] %s *****\n", deviceID, pascalName); goto bail; } } else { printf("device[%i] in use - using next default device\n", deviceID); } } else printf("device[%i] unavailable - using next default device\n", deviceID); } err = SGSetChannelUsage(vgd->gVideoChannel,seqGrabPreview); if ( err != noErr ) goto bail; err = SGSetChannelBounds(vgd->gVideoChannel, &vgd->videoRect); if ( err != noErr ) goto bail; err = SGPrepare(vgd->gSeqGrabber, true, false); //theo swapped so preview is true and capture is false if ( err != noErr ) goto bail; err = SGStartPreview(vgd->gSeqGrabber); if ( err != noErr ) goto bail; if (bVerbose){ printf ("end setup ofVideoGrabber\n"); printf ("-------------------------------------\n"); printf ("\n"); } if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.allocate(w,h,GL_RGB); memset(vgd->pixels, 0, w*h*3); tex.loadData(vgd->pixels, w, h, GL_RGB); } bSgGrabberInited = true; return; // good catch eloi/theo //--------------------- (bail) something's wrong ----- bail: if (bVerbose){ printf ("***** ofVideoGrabber error *****\n"); printf ("-------------------------------------\n"); printf ("\n"); } bSgGrabberInited = false; return; //--------------------------------- #endif //--------------------------------- //--------------------------------- #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW //--------------------------------- if (bChooseDevice){ device = deviceID; printf("choosing %i \n", deviceID); } else { device = 0; } //device = 0; bool bOk = VI.setupDevice(device, w, h); if (bOk == true){ bSgGrabberInited = true; width = VI.getWidth(device); height = VI.getHeight(device); pixels = new unsigned char[width * height * 3]; if (bUseTexture){ // create the texture, set the pixels to black and // upload them to the texture (so at least we see nothing black the callback) tex.allocate(width,height,GL_RGB); memset(pixels, 0, width*height*3); tex.loadData(pixels, width, height, GL_RGB); } } else { printf("error allocating a video device \nplease check your camera with AMCAP or other software\n"); } //--------------------------------- #endif //--------------------------------- } //------------------------------------ void ofVideoGrabber::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofVideoGrabber::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } //------------------------------------ void ofVideoGrabber::draw(float _x, float _y){ draw(_x, _y, width, height); } Node-path: video/ofVideoGrabber.h Node-kind: file Node-action: change Text-content-length: 1409 Text-content-md5: c0c413e114b039212012a58f0f930781 Content-length: 1409 #ifndef _OF_VIDEO_GRABBER #define _OF_VIDEO_GRABBER #include "ofConstants.h" #include "ofTexture.h" #include "ofGraphics.h" #ifdef OF_VIDEO_CAPTURE_QUICKTIME #include "ofQtUtils.h" #endif #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW #include "videoInput.h" #endif // todo: // -callback, via SGSetDataProc - couldn't get this to work yet // image decompress options ala mung... class ofVideoGrabber{ public : ofVideoGrabber(); void listDevices(); bool isFrameNew(); void grabFrame(); void close(); void initGrabber(int w, int h); void initGrabber(int w, int h, bool bTexture); void videoSettings(); unsigned char * getPixels(); void setVerbose(bool bTalkToMe); void setDeviceID(int _deviceID); void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); void draw(float x, float y); int width, height; private: bool bChooseDevice; int deviceID; bool bUseTexture; ofTexture tex; bool bVerbose; bool bSgGrabberInited; //--------------------------------- quicktime #ifdef OF_VIDEO_CAPTURE_QUICKTIME videoGrabberData * vgd; #endif //--------------------------------- directshow #ifdef OF_VIDEO_CAPTURE_DIRECTSHOW int device; unsigned char * pixels; bool bFrameNew; videoInput VI; #endif }; #endif Revision-number: 56 Prop-content-length: 129 Content-length: 129 K 7 svn:log V 27 // small fixes for warnings K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-04T15:01:04.823384Z PROPS-END Node-path: sound/ofFmodUtils.cpp Node-kind: file Node-action: change Text-content-length: 1126 Text-content-md5: 9432827f7a46364c69fc4407a439b6e6 Content-length: 1126 #include "ofFmodUtils.h" static bool bFmodInitialized = false; // dsp callback? // interesting? // http://66.102.9.104/search?q=cache:LM47mq8hytwJ:www.cleeker.com/doxygen/audioengine__fmod_8cpp-source.html+FSOUND_Sample_Load+cpp&hl=en&ct=clnk&cd=18&client=firefox-a // ---------------------------------------------------------------------------- void initializeFmod(){ // linux users: // an example of setting up fmod for different audio systems // is in this code: // http://66.102.9.104/search?q=cache:LM47mq8hytwJ:www.cleeker.com/doxygen/audioengine__fmod_8cpp-source.html+FSOUND_Sample_Load+cpp&hl=en&ct=clnk&cd=18&client=firefox-a if (bFmodInitialized == false){ if (FSOUND_GetVersion() < FMOD_VERSION){ printf("Error : You are using the wrong DLL version! You should be using FMOD %.02f\n", FMOD_VERSION); return; } FSOUND_Init( 44100, 32, 0 ); //FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND); // Direct Sound //FSOUND_SetDriver(0); //FSOUND_SetMixer(FSOUND_MIXER_AUTODETECT); bFmodInitialized = true; } } void closeFmod(){ FSOUND_Close(); } Node-path: sound/ofSoundPlayer.cpp Node-kind: file Node-action: change Text-content-length: 6234 Text-content-md5: 7c8185c622d348122c81d11c153a6b9b Content-length: 6234 #include "ofSoundPlayer.h" // these are global functions, that affect every sound / channel: // ------------------------------------------------------------ // ------------------------------------------------------------ bool bUseSpectrum = false; float fftValues[512]; // max # bands is 512 //-------------------- void ofSoundStopAll(){ FSOUND_StopSound(FSOUND_ALL); } //-------------------- void ofSoundSetVolume(float vol){ FSOUND_SetVolume(FSOUND_ALL, (int)(vol*255.0f)); } //-------------------- void ofSoundSetUseSpectrum(bool use){ bUseSpectrum = use; FSOUND_DSP_SetActive( FSOUND_DSP_GetFFTUnit( ), bUseSpectrum); } //-------------------- float * ofSoundGetSpectrum(int nBands){ // ------------------------------------ // [note] this code snippet comes from: // http://qepsilon.org/doc/snd__main_8cpp-source.html // via gamedev.net forum // ------------------------------------ if (nBands > 512){ printf("error in ofSoundGetSpectrum, the maximum number of bands is 512 - you asked for %i\nwe will return 512\n", nBands); nBands = 512; } // now, get the spectrum and // place it into fftValues array with the nBands requested // for returning: float *spectrum = FSOUND_DSP_GetSpectrum( ); int ctr = 0; int FreqPerBand = 448 / nBands; for (int i = 0; i < nBands; i++){ fftValues[i] = 0.0f; for (int j = 0; j < FreqPerBand; j++){ fftValues[i] += spectrum[ctr++]; } fftValues[i] = fftValues[i] / 1.5f; if (fftValues[i] > 1.0f){ fftValues[i] = 1.0f; } } return fftValues; } // ------------------------------------------------------------ // ------------------------------------------------------------ // now, the individual sound player: //------------------------------------------------------------ ofSoundPlayer::ofSoundPlayer(){ bLoop = false; bLoadedOk = false; channel = -1; pan = 0.5f; volume = 1.0f; internalFreq = 44100; speed = 1; bPaused = false; } //------------------------------------------------------------ void ofSoundPlayer::loadSound(char * fileName){ // fmod uses IO posix internally, might have trouble // with unicode paths... // says this code: // http://66.102.9.104/search?q=cache:LM47mq8hytwJ:www.cleeker.com/doxygen/audioengine__fmod_8cpp-source.html+FSOUND_Sample_Load+cpp&hl=en&ct=clnk&cd=18&client=firefox-a // for now we use FMODs way, but we could switch if // there are problems: // [1] init fmod, if necessary initializeFmod(); // [2] try to unload any previously loaded sounds // & prevent user-created memory leaks // if they call "loadSound" repeatedly, for example unloadSound(); // [3] load sound samp = FSOUND_Sample_Load(FSOUND_UNMANAGED, fileName, FSOUND_NORMAL, 0, 0); if (!samp){ bLoadedOk = false; } else { bLoadedOk = true; length = FSOUND_Sample_GetLength(samp); } } //------------------------------------------------------------ void ofSoundPlayer::unloadSound(){ if (bLoadedOk){ stop(); // try to stop the sound FSOUND_Sample_Free(samp); // & free the sample } } //------------------------------------------------------------ bool ofSoundPlayer::getIsPlaying(){ if (channel == -1 || !bLoadedOk) return false; return FSOUND_IsPlaying(channel); } //------------------------------------------------------------ void ofSoundPlayer::setVolume(float vol){ if (getIsPlaying() == true){ FSOUND_SetVolume(channel, (int)(vol*255.0f)); volume = vol; } } //------------------------------------------------------------ void ofSoundPlayer::setPosition(float pct){ if (getIsPlaying() == true){ int sampleToBeAt = (int)(length * pct); FSOUND_SetCurrentPosition(channel, sampleToBeAt); } } //------------------------------------------------------------ float ofSoundPlayer::getPosition(){ if (getIsPlaying() == true){ int sampleImAt; sampleImAt = (int)FSOUND_GetCurrentPosition(channel); float pct = 0.0f; if (length > 0){ pct = sampleImAt / (float)length; } return pct; } else { return 0; } } //------------------------------------------------------------ void ofSoundPlayer::setPan(float p){ if (getIsPlaying() == true){ FSOUND_SetPan(channel, (int)(p*255.0f)); pan = p; } } //------------------------------------------------------------ void ofSoundPlayer::setPaused(bool bP){ if (getIsPlaying() == true){ FSOUND_SetPaused(channel, bP); bPaused = bP; } } //------------------------------------------------------------ void ofSoundPlayer::setSpeed(float spd){ FSOUND_SetFrequency(channel, (int)(internalFreq * spd)); speed = spd; } //------------------------------------------------------------ void ofSoundPlayer::setLoop(bool bLp){ FSOUND_SetLoopMode(channel, (bLp == true) ? FSOUND_LOOP_NORMAL : FSOUND_LOOP_OFF); bLoop = bLp; } // ---------------------------------------------------------------------------- void ofSoundPlayer::setMultiplay(bool bMp){ bMultiplay = bMp; // be careful with this... } // ---------------------------------------------------------------------------- void ofSoundPlayer::play(){ // if it's a looping sound, we should try to kill it, no? // or else people will have orphan channels that are looping if (bLoop == true){ FSOUND_StopSound(channel); } // if the sound is not set to multiplay, then stop the current, // before we start another if (!bMultiplay){ FSOUND_StopSound(channel); } channel = FSOUND_PlaySound(FSOUND_FREE, samp); internalFreq = FSOUND_GetFrequency(channel); FSOUND_SetVolume(channel, (int)(volume*255.0f)); FSOUND_SetPan(channel, (int)(pan*255.0f)); FSOUND_SetPaused(channel, bPaused); FSOUND_SetFrequency(channel, (int)(internalFreq * speed)); FSOUND_SetLoopMode(channel, (bLoop == true) ? FSOUND_LOOP_NORMAL : FSOUND_LOOP_OFF); } // ---------------------------------------------------------------------------- void ofSoundPlayer::stop(){ FSOUND_StopSound(channel); } Revision-number: 57 Prop-content-length: 160 Content-length: 160 K 7 svn:log V 58 // zach - bug fixes for 0.02 release, glee & vertical sync K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-05T23:12:12.039967Z PROPS-END Node-path: app/ofAppGlutGlue.h Node-kind: file Node-action: change Text-content-length: 4263 Text-content-md5: 055fa7dfd916c859bc0657625fccefd0 Content-length: 4263 void display(void); void mouse_cb(int button, int state, int x, int y); void motion_cb(int x, int y); void passive_motion_cb(int x, int y); void idle_cb(void); void keyboard_cb(unsigned char key, int x, int y); void special_key_cb(int key, int x, int y) ; static int buttonInUse = 0; //-------------------------------- static float timeNow, timeThen, fps; static int nFramesForFPS; static int nFrameCount = 0; static bool bFrameRateSet; int millisForFrame; int prevMillis; int diffMillis; //------------------------------------------------------------ void display(void){ //-------------------------------- // when I had "glutFullScreen()" // in the initOpenGl, I was gettings a "heap" allocation error // when debugging via visual studio. putting it here, changes that. // maybe it's voodoo, or I am getting rid of the problem // by removing something unrelated, but everything seems // to work if I put fullscreen on the first frame of display. if (nFrameCount == 0 && windowMode == OF_FULLSCREEN) glutFullScreen(); width = ofGetWidth(); height = ofGetHeight(); height = height > 0 ? height : 1; // set viewport, clear the screen glViewport( 0, 0, width, height ); float * bgPtr = ofBgColorPtr(); bool bClearAuto = ofbClearBg(); // I don't know why, I need more than one frame at the start in fullscreen mode // also, in non-fullscreen mode, windows/intel graphics, this bClearAuto just fails. // I seem to have 2 buffers, alot of flickering // and don't accumulate the way I expect. // with this line: if ((bClearAuto == true) || nFrameCount < 3){ // we do nFrameCount < 3, so that the buffers are cleared at the start of the app // or else we have video memory garbage to draw on to... if ((bClearAuto == true || windowMode == OF_WINDOW) || nFrameCount < 3){ glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } ofSetupScreen(); OFSAptr->draw(); glutSwapBuffers(); // -------------- fps calculation: timeNow = ofGetElapsedTimef(); if( (timeNow-timeThen) > 0.05f || nFramesForFPS == 0 ) { fps = (double)nFramesForFPS / (timeNow-timeThen); timeThen = timeNow; nFramesForFPS = 0; ofFrameRate = 0.9f * ofFrameRate + 0.1f * fps; } nFramesForFPS++; // -------------- nFrameCount++; // increase the overall frame count } //------------------------------------------------------------ void mouse_cb(int button, int state, int x, int y) { if (!ofbOriginBottomLeft()){ y = ofGetHeight() - y; } OFSAptr->mouseX = x; OFSAptr->mouseY = height - y; if (state == GLUT_DOWN) { OFSAptr->mousePressed(x, height - y, button); } else if (state == GLUT_UP) { OFSAptr->mouseReleased(); } buttonInUse = button; } //------------------------------------------------------------ void motion_cb(int x, int y) { if (!ofbOriginBottomLeft()){ y = ofGetHeight() - y; } OFSAptr->mouseX = x; OFSAptr->mouseY = height - y; OFSAptr->mouseDragged(x, height - y, buttonInUse); } //------------------------------------------------------------ void passive_motion_cb(int x, int y) { if (!ofbOriginBottomLeft()){ y = ofGetHeight() - y; } OFSAptr->mouseX = x; OFSAptr->mouseY = height - y; OFSAptr->mouseMoved(x, height - y); } //------------------------------------------------------------ void idle_cb(void) { if (nFrameCount != 0 && bFrameRateSet == true){ diffMillis = ofGetElapsedTimeMillis() - prevMillis; if (diffMillis > millisForFrame){ ; // we do nothing, we are already slower than target frame } else { int waitMillis = millisForFrame - diffMillis; #ifdef TARGET_WIN32 Sleep(waitMillis); //windows sleep in milliseconds #else usleep(waitMillis * 1000); //mac sleep in microseconds - cooler :) #endif } } OFSAptr->update(); glutPostRedisplay(); prevMillis = ofGetElapsedTimeMillis(); } //------------------------------------------------------------ void keyboard_cb(unsigned char key, int x, int y) { OFSAptr->keyPressed((int)key); if (key == 27){ // "escape" OF_EXIT_APP(0); } } //------------------------------------------------------------ void special_key_cb(int key, int x, int y) { OFSAptr->keyPressed((int)key); } Node-path: app/ofAppRunner.cpp Node-kind: file Node-action: change Text-content-length: 4046 Text-content-md5: 5fcb8ff32ca46d9d273e02e2f197ed57 Content-length: 4046 #include "ofAppRunner.h" //======================================================================== // static variables: static ofSimpleApp * OFSAptr; int windowMode; bool bMousePressed; bool bRightButton; int width, height; static float ofFrameRate; //======================================================================== // callbacks: #include "ofAppGlutGlue.h" //-------------------------------------- void ofSetupOpenGL(int w, int h, int screenMode){ int argc = 1; char *argv = "openframeworks"; char **vptr = &argv; glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA); glutInit(&argc, vptr); //if (screenMode == OF_WINDOW) glutInitWindowSize(w, h); glutCreateWindow(""); windowMode = screenMode; ofBackground(200,200,200); // default bg color ofSetColor(0xFFFFFF); // default draw color // used to be black, but // black + texture = black // so maybe grey bg // and "white" fg color // as default works the best... } //----------------------- gets called when the app exits // currently looking at who to turn off // at the end of the application void ofExitCallback(); void ofExitCallback(){ // who to kill off ? // -- fmod // -- quicktime // -- freeImage // anyone else? #ifdef WIN32_HIGH_RES_TIMING timeEndPeriod(1); #endif //delete OFSAptr; } //-------------------------------------- void ofRunApp(ofSimpleApp * OFSA){ OFSAptr = OFSA; atexit(ofExitCallback); #ifdef WIN32_HIGH_RES_TIMING timeBeginPeriod(1); // ! experimental, sets high res time // you need to call timeEndPeriod. // if you quit the app other than "esc" // (ie, close the console, kill the process, etc) // at exit wont get called, and the time will // remain high res, that could mess things // up on your system. // info here:http://www.geisswerks.com/ryan/FAQS/timing.html #endif bFrameRateSet = false; //---------------------- // setup the callbacks glutMouseFunc(mouse_cb); glutMotionFunc(motion_cb); glutPassiveMotionFunc(passive_motion_cb); glutIdleFunc(idle_cb); glutDisplayFunc(display); glutKeyboardFunc(keyboard_cb); glutSpecialFunc(special_key_cb); //---------------------- ofSeedRandom(); // seed the random generator // (users can seed it to a value in setup // if they want it fixed); OFSA->setup(); glutMainLoop(); } //-------------------------------------- float ofGetFrameRate(){ return ofFrameRate; } //-------------------------------------- void ofSetFrameRate(int targetRate){ // given this FPS, what is the amount of millis per frame // that should elapse? // --- > f / s if (targetRate == 0){ bFrameRateSet = false; return; } bFrameRateSet = true; float durationOfFrame = 1.0f / (float)targetRate; millisForFrame = (int)(1000.0f * durationOfFrame); } //-------------------------------------- void ofHideCursor(){ glutSetCursor(GLUT_CURSOR_NONE); } //-------------------------------------- void ofShowCursor(){ glutSetCursor(GLUT_CURSOR_RIGHT_ARROW); } //-------------------------------------- void ofSetVerticalSync(bool bSync){ //---------------------------- #ifdef TARGET_WIN32 //---------------------------- if (bSync) { if (GLEE_WGL_EXT_swap_control) wglSwapIntervalEXT (1); } else { if (GLEE_WGL_EXT_swap_control) wglSwapIntervalEXT (0); } //---------------------------- #endif //---------------------------- //-------------------------------------- #ifdef TARGET_OSX //-------------------------------------- long sync = bSync == true ? 1 : 0; CGLSetParameter (CGLGetCurrentContext(), kCGLCPSwapInterval, &sync); //-------------------------------------- #endif //-------------------------------------- } Node-path: app/ofAppRunner.h Node-kind: file Node-action: change Text-content-length: 463 Text-content-md5: d2c18a26d25d0ca356d834b29902fb40 Content-length: 463 #ifndef _OF_APP_RUNNER #define _OF_APP_RUNNER #include "ofConstants.h" #include "ofSimpleApp.h" #include "ofGraphics.h" #include "ofMath.h" #include "ofUtils.h" void ofSetupOpenGL(int w, int h, int screenMode); // sets up the opengl context! void ofRunApp(ofSimpleApp * OFSA); float ofGetFrameRate(); void ofSetFrameRate(int targetRate); void ofHideCursor(); void ofShowCursor(); void ofSetVerticalSync(bool bSync); #endif Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: change Text-content-length: 9052 Text-content-md5: 09ca52b82d7615d0e53eb7f62e5c9faa Content-length: 9052 #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); bool bSmoothHinted = false; bool bBakgroundAuto = true; int cornerMode = OF_RECTMODE_CORNER; //---------------------------------------------------------- void ofSetRectMode(int mode){ if (mode == OF_RECTMODE_CORNER) cornerMode = OF_RECTMODE_CORNER; else if (mode == OF_RECTMODE_CENTER) cornerMode = OF_RECTMODE_CENTER; } //---------------------------------------------------------- int ofGetRectMode(){ return cornerMode; } //---------------------------------------------------------- void ofSetBackgroundAuto(bool bAuto){ bBakgroundAuto = bAuto; } //---------------------------------------------------------- bool ofbClearBg(){ return bBakgroundAuto; } //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- bool ofbOriginBottomLeft(){ return false; // because people are certainly asking for it! } //---------------------------------------------------------- void ofBackground(int r, int g, int b){ bgColor[0] = (float)r / (float)255.0f; bgColor[1] = (float)g / (float)255.0f; bgColor[2] = (float)b / (float)255.0f; bgColor[3] = 1.0f; // if we are in not-auto mode, then clear with a bg call... if (ofbClearBg() == false){ glClearColor(bgColor[0],bgColor[1],bgColor[2], bgColor[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void startSmoothing(){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void endSmoothing(){ glPopAttrib(); } //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); // draw: glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); // draw: glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); if (cornerMode == OF_RECTMODE_CENTER){ glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x-w/2,y-h/2); glVertex2f(x+w/2,y-h/2); glVertex2f(x+w/2,y+h/2); glVertex2f(x-w/2,y+h/2); glEnd(); } else { glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); } // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b, int _a){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); float a = (float)_a / 255.0f; a = MAX(0,MIN(a,1.0f)); glColor4f(r,g,b,a); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } //---------------------------------------------------------- void ofEnableAlphaBlending(){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void ofDisableAlphaBlending(){ glDisable(GL_BLEND); } //---------------------------------------------------------- void ofEnableSmoothing(){ // please see: // http://www.opengl.org/resources/faq/technical/rasterization.htm bSmoothHinted = true; } //---------------------------------------------------------- void ofDisableSmoothing(){ bSmoothHinted = false; } //-------------------------------------------------- void ofDrawBitmapString(char *string, float x, float y){ //--------------------------------------------------- // for now this is fixed to the 8_BY_13 glut character // http://pyopengl.sourceforge.net/documentation/manual/glutBitmapCharacter.3GLUT.html //--------------------------------------------------- char *c; float yOffset = 0; float fontSize = 8.0f; glRasterPos2f(x,y); bool bOrigin = ofbOriginBottomLeft(); for (c=string; *c != '\0'; c++) { if(*c == '\n') { yOffset += bOrigin ? -1 : 1 * (fontSize*1.7); glRasterPos2f(x,y + (int)yOffset); } else if (((int)*c) >= 32){ // < 32 = control characters - don't draw // solves a bug with control characters // getting drawn when they ought to not be glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c); } } } //---------------------------------------------------------- void ofSetupScreen(){ int w, h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (!ofbOriginBottomLeft()){ glScalef(1, -1, 1); // invert Y axis so increasing Y goes down. glTranslatef(0, -h, 0); // shift origin up to upper-left corner. } } Node-path: graphics/ofImage.cpp Node-kind: file Node-action: change Text-content-length: 10751 Text-content-md5: 0ec0e496cfd03ce7589735f35d7dcfe5 Content-length: 10751 #include "ofImage.h" #include "freeImage.h" static bool bFreeImageInited = false; //----------------------------------------- // class freeImageBitmap{ public: FIBITMAP * bmp; // when OF users ask for pixels // we will get them contiguous memory // ie, non-aligned // see the pixel access chapter of the freeImage pdf // these pixel will also be RGB // on both platforms // bmp will be RGB / BGR depending // on the endianess of the platform. unsigned char * pixels; //----------------------- freeImageBitmap(){ bmp = NULL; } //----------------------- //swap my image out in a (hopefully) non-memory leakish way void swap(FIBITMAP *dst) { if(dst == NULL) return; if(bmp != NULL) FreeImage_Unload(bmp); bmp = dst; } //----------------------- void setSize(FREE_IMAGE_TYPE image_type, WORD width, WORD height, WORD bpp) { if(bmp == NULL) { FreeImage_Unload(bmp); } bmp = FreeImage_AllocateT(image_type, width, height, bpp); } //----------------------- bool isValid(){ return (bmp != NULL) ? true : false; } }; //---------------------------------------------------------- ofImage::ofImage(){ //----------------------- init free image if necessary if (!bFreeImageInited){ FreeImage_Initialise(); bFreeImageInited = true; } //----------------------- IMG = new freeImageBitmap(); width = height = bpp = 0; type = OF_IMAGE_UNDEFINED; bUseTexture = true; // the default is, yes, use a texture bAllocatedPixels = false; } //---------------------------------------------------------- void ofImage::grabScreen(int _x, int _y, int _w, int _h){ if (IMG->isValid()){ // flip y if origin is top: if (!ofbOriginBottomLeft()){ int height = ofGetHeight(); _y = height - _y; _y -= _h; // top, bottom issues } if (!(width == _w && height == _h)){ resize(_w, _h); } unsigned char * pixels = (unsigned char *)FreeImage_GetBits(IMG->bmp); switch (bpp){ case 8: glReadPixels(_x, _y, _w, _h, GL_LUMINANCE,GL_UNSIGNED_BYTE, pixels); break; case 24: #ifdef TARGET_LITTLE_ENDIAN glReadPixels(_x, _y, _w, _h, GL_BGR_EXT,GL_UNSIGNED_BYTE, pixels); #else glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); #endif break; case 32: glReadPixels(_x, _y, _w, _h, GL_RGBA,GL_UNSIGNED_BYTE, pixels); break; } // we will need to flip images // if the 0,0 position is in the top left: if (!ofbOriginBottomLeft()){ FreeImage_FlipVertical(IMG->bmp); } update(); } else { // assume that this is color.... IMG->setSize(FIT_BITMAP, _w, _h, 24); unsigned char * pixels = (unsigned char *)FreeImage_GetBits(IMG->bmp); // flip y if origin is top: if (!ofbOriginBottomLeft()){ int height = ofGetHeight(); _y = height - _y; _y -= _h; // top, bottom issues } #ifdef TARGET_LITTLE_ENDIAN glReadPixels(_x, _y, _w, _h, GL_BGR_EXT,GL_UNSIGNED_BYTE, pixels); #else glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); #endif // we will need to flip images // if the 0,0 position is in the top left: if (!ofbOriginBottomLeft()){ FreeImage_FlipVertical(IMG->bmp); } update(); } } //---------------------------------------------------------- void ofImage::allocate(int _w, int _h, int _type){ int newbpp; switch (_type){ case OF_IMAGE_GRAYSCALE: newbpp = 8; break; case OF_IMAGE_COLOR: newbpp = 24; break; case OF_IMAGE_COLOR_ALPHA: newbpp = 32; break; default: newbpp = 24; break; } IMG->setSize(FIT_BITMAP, _w, _h, newbpp); } //---------------------------------------------------------- void ofImage::update(){ width = FreeImage_GetWidth(IMG->bmp); height = FreeImage_GetHeight(IMG->bmp); bpp = FreeImage_GetBPP(IMG->bmp); // this is check to see if it's a gif bool bNoPallette = (FreeImage_GetColorType(IMG->bmp) != FIC_PALETTE); switch (bpp){ case 8: if (bNoPallette) { //!bUsesPallette){ type = OF_IMAGE_GRAYSCALE; } else { // convert to RGB - // this is a gif (or other) with 256 colors, not b&w. setImageType(OF_IMAGE_COLOR); } break; case 24: type = OF_IMAGE_COLOR; break; case 32: type = OF_IMAGE_COLOR_ALPHA; break; default: // if we've got here, something is wrong, the image // is not 8bit, 24bit or 32bit, so let's at least // make it color: setImageType(OF_IMAGE_COLOR); break; } //---------------------------------- // now, since the "freeImage" memory is padded // (see freeImage392.pdf - "Pixel access functions") // lets get the data into contiguous memory - to make it easier // for folks to work with... if (IMG->pixels != NULL && bAllocatedPixels == true) delete IMG->pixels; // delete anything that might have existed int byteCount = bpp / 8; // bytes ber pixel (not bits per pixel) IMG->pixels = new unsigned char[width*height*byteCount]; //allocate that memory for the image (contiguously) bAllocatedPixels = true; FreeImage_ConvertToRawBits(IMG->pixels, IMG->bmp, width*byteCount, bpp, FI_RGBA_RED_MASK,FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE); // get bits #ifdef TARGET_LITTLE_ENDIAN if (type == OF_IMAGE_COLOR) swapChannels(false); if (type == OF_IMAGE_COLOR_ALPHA) swapChannels(true); #endif //---------------------------------- // if we are using a texture and the ofImage is upadate, // allocate (or reallocate) the texture and upload the data // I will upload from the contguous memory, and use pixelStorei to // make sure opengl knows I am contiguous. if (bUseTexture){ switch (type){ case OF_IMAGE_GRAYSCALE: tex.allocate(width,height,GL_LUMINANCE); tex.loadData(IMG->pixels, width,height, GL_LUMINANCE); break; case OF_IMAGE_COLOR: tex.allocate(width,height,GL_RGB); tex.loadData(IMG->pixels, width,height, GL_RGB); break; case OF_IMAGE_COLOR_ALPHA: tex.allocate(width,height,GL_RGBA); tex.loadData(IMG->pixels, width,height, GL_RGBA); break; } } } //---------------------------------------------------------- void ofImage::loadImage(char * fileName){ bool bLoaded = false; //----------------------------- find the format FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { if(IMG->isValid()) { FreeImage_Unload(IMG->bmp); } IMG->bmp = FreeImage_Load(fif, fileName, 0); bLoaded = true; if(!IMG->isValid()){ bLoaded = false; } } //----------------------------- if (bLoaded){ // we will need to flip images // if the 0,0 position is in the top left: if (!ofbOriginBottomLeft()){ FreeImage_FlipVertical(IMG->bmp); } update(); } else { width = height = bpp = 0; } } //---------------------------------------------------------- void ofImage::saveImage(char * fileName){ if (IMG->isValid()){ FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName, 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { // ok, if we are 0,0 top left, flip once, save and flip back // this is because the native format for freeImage is 0,0 lower left // there be a smarter way to do this (ie, just draw upside down) // as opposed to continually if (!ofbOriginBottomLeft()){ FreeImage_FlipVertical(IMG->bmp); } FreeImage_Save(fif, IMG->bmp, fileName, 0); if (!ofbOriginBottomLeft()){ FreeImage_FlipVertical(IMG->bmp); } } } } //---------------------------------------------------------- unsigned char * ofImage::getPixels(){ // be careful! might not be allocated. you need to check for null... if (IMG->isValid()){ return (unsigned char *)IMG->pixels; } else { return NULL; } } //---------------------------------------------------------- void ofImage::resize(int newWidth, int newHeight){ if (IMG->isValid()){ FIBITMAP * scaledBmp = FreeImage_Rescale(IMG->bmp, newWidth, newHeight, FILTER_BICUBIC); IMG->swap(scaledBmp); update(); } } //---------------------------------------------------------- void ofImage::setImageType(int newType){ if (IMG->isValid()){ switch (newType){ //------------------------------------ case OF_IMAGE_GRAYSCALE: if (type != OF_IMAGE_GRAYSCALE){ FIBITMAP * convertedBmp = FreeImage_ConvertToGreyscale(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; //------------------------------------ case OF_IMAGE_COLOR: if (type != OF_IMAGE_COLOR){ FIBITMAP * convertedBmp = FreeImage_ConvertTo24Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR; } break; //------------------------------------ case OF_IMAGE_COLOR_ALPHA: if (type != OF_IMAGE_COLOR_ALPHA){ FIBITMAP * convertedBmp = FreeImage_ConvertTo32Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR_ALPHA; } break; } update(); } } //------------------------------------ void ofImage::swapChannels(bool bAlpha){ // this swaps the red and blue channel of an image // turning an bgr image to rgb and vice versa... // needed because of windows byte order... if (IMG->isValid()){ unsigned char * pixels = IMG->pixels; unsigned char temp; int totalPixels = width*height; // unoptimized for now... if (bAlpha == false){ for (int i = 0; i < totalPixels; i++){ temp = pixels[i*3 + 2]; pixels[i*3 + 2] = pixels[i*3]; pixels[i*3] = temp; } } else { for (int i = 0; i < totalPixels; i++){ temp = pixels[i*4]; pixels[i*4] = pixels[i*4 + 2]; pixels[i*4 + 2] = temp; } } } } //------------------------------------ void ofImage::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofImage::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } //------------------------------------ void ofImage::draw(float x, float y){ draw(x,y,width,height); } Node-path: graphics/ofTexture.cpp Node-kind: file Node-action: change Text-content-length: 6274 Text-content-md5: a9c3cc36ac8d55437e2318de844547a2 Content-length: 6274 #include "ofTexture.h" #include "ofUtils.h" // for nextPow2() //---------------------------------------------------------- ofTexture::ofTexture(){ texName[0] = 0; bFlipTexture = false; } //---------------------------------------------------------- void ofTexture::clear(){ // try to free up the texture memory so we don't reallocate // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/deletetextures.html if (texName[0] != 0){ glDeleteTextures(1, (GLuint *)texName); } width = 0; height = 0; bFlipTexture = false; } //---------------------------------------------------------- void ofTexture::allocate(int w, int h, int internalGlDataType){ // can pass in anything (320x240) (10x5) // here we make it power of 2 for opengl (512x256), (16x8) tex_w = ofNextPow2(w); tex_h = ofNextPow2(h); tex_u = 1.0f; tex_t = 1.0f; // attempt to free the previous bound texture, if we can: clear(); glGenTextures(1, (GLuint *)texName); // could be more then one, but for now, just one glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); // upload 0 or white pixels.... glTexImage2D(GL_TEXTURE_2D, 0, internalGlDataType, tex_w, tex_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); // init to black... glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); width = w; height = h; bFlipTexture = false; } //---------------------------------------------------------- void ofTexture::loadData(unsigned char * data, int w, int h, int glDataType){ // can we allow for uploads bigger then texture and // just take as much as the texture can? // // ie: // int uploadW = MIN(w, tex_w); // int uploadH = MIN(h, tex_h); // but with a "step" size of w? // check "glTexSubImage2D" if ( w > tex_w || h > tex_h) { printf("image data too big for allocated texture. not uploading... \n"); return; } width = w; height = h; //compute new tex co-ords based on the ratio of data's w, h to texture w,h; tex_t = (float)(w) / (float)tex_w; tex_u = (float)(h) / (float)tex_h; // ok this is an ultra annoying bug : // opengl texels and linear filtering - // when we have a sub-image, and we scale it // we can clamp the border pixels to the border, // but the borders of the sub image get mixed with // neighboring pixels... // grr... // // the best solution would be to pad out the image // being uploaded with 2 pixels on all sides, and // recompute tex_t coordinates.. // another option is a gl_arb non pow 2 textures... // the current hack is to alter the tex_t, tex_u calcs, but // that makes the image slightly off... // this is currently being done in draw... // // we need a good solution for this.. // // http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014770#000001 // http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014770#000001 //------------------------ likely, we are uploading continuous data GLint prevAlignment; glGetIntegerv(GL_UNPACK_ALIGNMENT, &prevAlignment); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // update the texture image: glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); glTexSubImage2D(GL_TEXTURE_2D,0,0,0,w,h,glDataType,GL_UNSIGNED_BYTE,data); glDisable(GL_TEXTURE_2D); //------------------------ back to normal. glPixelStorei(GL_UNPACK_ALIGNMENT, prevAlignment); bFlipTexture = false; } //---------------------------------------------------------- void ofTexture::loadScreenData(int x, int y, int w, int h){ if (!ofbOriginBottomLeft()){ int height = ofGetHeight(); y = height - y; y -= h; // top, bottom issues bFlipTexture = true; } if ( w > tex_w || h > tex_h) { printf("image data too big for allocated texture. not uploading... \n"); return; } width = w; height = h; //compute new tex co-ords based on the ratio of data's w, h to texture w,h; tex_t = (float)(w) / (float)tex_w; tex_u = (float)(h) / (float)tex_h; glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); glCopyTexSubImage2D(GL_TEXTURE_2D, 0,0,0,x,y,w,h); glDisable(GL_TEXTURE_2D); } //---------------------------------------------------------- void ofTexture::draw(float x, float y, float w, float h){ glEnable(GL_TEXTURE_2D); // bind the texture glBindTexture( GL_TEXTURE_2D, (GLuint)texName[0] ); float px0 = x ; // up to you to get the aspect ratio right float py0 = y ; float px1 = x+w; float py1 = y+h; if (bFlipTexture == true){ float temp = py0; py0 = py1; py1 = temp; } // for rect mode center, let's do this: if (ofGetRectMode() == OF_RECTMODE_CENTER){ px0 = x-w/2; py0 = y-h/2; px1 = x+w/2; py1 = y+h/2; } // ------------------------------------------------- // complete hack to remove border artifacts. // slightly, slightly alters an image, scaling... // to remove the border. // we need a better solution for this, but // to constantly add a 2 pixel border on all uploaded images // is insane.. float offsetw = 1.0f/(tex_w*2.0f); float offseth = 1.0f/(tex_h*2.0f); // ------------------------------------------------- float tx0 = 0+offsetw; float ty0 = 0+offseth; float tx1 = tex_t - offsetw; float ty1 = tex_u - offseth; glBegin( GL_QUADS ); glTexCoord2f(tx0,ty0); glVertex3f(px0, py0,0); glTexCoord2f(tx1,ty0); glVertex3f(px1, py0,0); glTexCoord2f(tx1,ty1); glVertex3f(px1, py1,0); glTexCoord2f(tx0,ty1); glVertex3f(px0, py1,0); glEnd(); glDisable(GL_TEXTURE_2D); } //---------------------------------------------------------- void ofTexture::draw(float x, float y){ draw(x,y,width, height); } Node-path: graphics/ofTexture.h Node-kind: file Node-action: change Text-content-length: 742 Text-content-md5: 86a72307218875d5a90e725c493d26a9 Content-length: 742 #ifndef _IMAGE_TEXTURE_H_ #define _IMAGE_TEXTURE_H_ #include "ofConstants.h" #include "ofGraphics.h" class ofTexture { public : ofTexture(); void allocate(int w, int h, int internalGlDataType); void clear(); void loadData(unsigned char * data, int w, int h, int glDataType); void loadScreenData(int x, int y, int w, int h); void draw(float x, float y, float w, float h); void draw(float x, float y); float tex_t, tex_u; int width, height; // private: float offset_x, offset_y; int tex_w, tex_h; unsigned int texName[1]; bool bFlipTexture; // if we copy screen data & 0,0 top left; // vs not happy with dynamic allocation of this... }; #endif Node-path: graphics/ofTrueTypeFont.cpp Node-kind: file Node-action: change Text-content-length: 12500 Text-content-md5: 17d3c24ffc3eaa211cae1e56c1e481b2 Content-length: 12500 #include "ofTrueTypeFont.h" //-------------------------- #ifdef TARGET_WIN32 #include #include #include #include #include #endif #ifdef TARGET_OSX #include "ft2build.h" #include "freetype.h" #include "ftglyph.h" #include "ftoutln.h" #include "fttrigon.h" #endif //------------------------------------------------------------------ ofTrueTypeFont::ofTrueTypeFont(){ bLoadedOk = false; } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize){ // load anti-aliased, non-full character set: loadFont(filename, fontsize, true, false); } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet){ bLoadedOk = false; bAntiAlised = _bAntiAliased; bFullCharacterSet = _bFullCharacterSet; fontSize = fontsize; //--------------- load the library and typeface FT_Library library; if (FT_Init_FreeType( &library )){ printf("PROBLEM WITH FT lib \n"); return; } FT_Face face; if (FT_New_Face( library, filename, 0, &face )) { return; } FT_Set_Char_Size( face,fontsize << 6,fontsize << 6,96,96); lineHeight = fontsize * 1.43f; //------------------------------------------------------ //kerning would be great to support: //printf("FT_HAS_KERNING ? %i \n", FT_HAS_KERNING(face)); //------------------------------------------------------ nCharacters = bFullCharacterSet ? 256 : 128 - NUM_CHARACTER_TO_START; //--------------- initialize character info and textures cps = new charProps[nCharacters]; texNames = new GLuint[nCharacters]; glGenTextures(nCharacters, texNames); //--------------------- load each char ----------------------- for (int i = 0 ; i < nCharacters; i++){ //------------------------------------------ anti aliased or not: if (bAntiAlised == true){ if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph %i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); } else { if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph%i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO); } //------------------------------------------ FT_Bitmap& bitmap= face->glyph->bitmap; // 1 pixel border around the glyph int border = 2; // prepare the texture: int width = ofNextPow2( bitmap.width + border); int height = ofNextPow2( bitmap.rows + border); // ------------------------- this is fixing a bug with small type // ------------------------- appearantly, opengl has trouble with // ------------------------- width or height textures of 1, so we // ------------------------- we just set it to 2... if (width == 1) width = 2; if (height == 1) height = 2; // ------------------------- // info about the character: cps[i].value = i; cps[i].height = face->glyph->bitmap_top; cps[i].width = face->glyph->bitmap.width; cps[i].setWidth = face->glyph->advance.x >> 6; cps[i].topExtent = face->glyph->bitmap.rows; cps[i].leftExtent = face->glyph->bitmap_left; // texture internals cps[i].tTex = (float)bitmap.width / (float)width; cps[i].vTex = (float)bitmap.rows / (float)height; cps[i].xOff = ((1.0+(float)bitmap.width) / (float)width) - cps[i].tTex; cps[i].yOff = ((1.0+(float)bitmap.rows) / (float)height) - cps[i].vTex; /* sanity check: printf("%i %i %i %i %i %i \n", cps[i].value , cps[i].height , cps[i].width , cps[i].setWidth , cps[i].topExtent , cps[i].leftExtent ); */ // Allocate Memory For The Texture Data. unsigned char* expanded_data = new unsigned char[ 2 * width * height]; //-------------------------------- clear data: for(int j=0; j =bitmap.width || j-1>=bitmap.rows) ? 0 : 255; expanded_data[2*(k+j*width)+1] = (k-1>=bitmap.width || j-1>=bitmap.rows) ? 0 : bitmap.buffer[k-1 + bitmap.width*(j-1)]; } } //----------------------------------- } else { //----------------------------------- // true type packs monochrome info in a // 1-bit format, hella funky // here we unpack it: unsigned char *src = bitmap.buffer; for(int j=0; j = nCharacters){ //printf("Error : char (%i) not allocated -- line %d in %s\n", (c + NUM_CHARACTER_TO_START), __LINE__,__FILE__); return; } //----------------------- int cu = c; float height = cps[cu].height; float bwidth = cps[cu].width; float top = cps[cu].topExtent - cps[cu].height; float lextent = cps[cu].leftExtent; float t = cps[cu].tTex; float v = cps[cu].vTex; float xOff = cps[cu].xOff; float yOff = cps[cu].yOff; //this is for topLeftDrawing only float corr = ( (fontSize - height) + top) - fontSize; if (glIsTexture(texNames[cu])) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texNames[cu]); glNormal3f(0, 0, 1); if (ofbOriginBottomLeft()){ glBegin(GL_QUADS); glTexCoord2d(xOff,yOff); glVertex2f(x + lextent, y + height); glTexCoord2d(xOff,v+yOff); glVertex2f(x + lextent, y-top); glTexCoord2d(t+xOff,v+yOff); glVertex2f(x + lextent + bwidth, y-top); glTexCoord2d(t+xOff,yOff); glVertex2f(x + lextent + bwidth, y + height); glEnd(); } else { glBegin(GL_QUADS); glTexCoord2d(t+xOff,v+yOff); glVertex2f(x + lextent + bwidth, y + height + corr); glTexCoord2d(t+xOff,yOff); glVertex2f(x + lextent + bwidth, (y-top) + corr); glTexCoord2d(xOff,yOff); glVertex2f(x + lextent, (y-top) + corr); glTexCoord2d(xOff,v+yOff); glVertex2f(x + lextent, y + height + corr); glEnd(); } glDisable(GL_TEXTURE_2D); } else { //let's add verbosity levels somewhere... //this error, for example, is kind of annoying to see //all the time: //printf("Warning : texture not bound for character -- line %d in %s\n", __LINE__,__FILE__); } } //----------------------------------------------------------- float ofTrueTypeFont::stringWidth(char *c) { float width = 0; int index = 0; float widthTemp = 0; bool bMultiLine = false; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { width = MAX(width, widthTemp); widthTemp = 0; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; widthTemp += cps[cy].width; } else { widthTemp += cps[cy].setWidth; } } index++; } width = MAX(width, widthTemp); return width; } //----------------------------------------------------------- float ofTrueTypeFont::stringHeight(char *c) { float height = 0; int index = 0; float maxHeight = 0; bool bFirstLineOfMultiLine = true; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { if (bFirstLineOfMultiLine == true){ bFirstLineOfMultiLine = false; height += maxHeight; } else { height += lineHeight; } maxHeight = 0; } else if (c[index] == ' ') { } else { float ht = cps[cy].height; if (ht > maxHeight) maxHeight = ht; } } index++; } height += maxHeight; return height; } //===================================================================== void ofTrueTypeFont::drawString(char *c, float x, float y) { if (!bLoadedOk){ printf("Error : font not allocated -- line %d in %s\n", __LINE__,__FILE__); return; }; // we need transparency to draw text, but we don't know // if that is set up in outside of this function // we "pushAttrib", turn on alpha and "popAttrib" // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushattrib.html // **** note **** // I have read that pushAttrib() is slow, if used often, // maybe there is a faster way to do this? // ie, check if blending is enabled, etc... // glIsEnabled().... glGet()... // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/get.html // ************** // (a) record the current "alpha state, blend func, etc" glPushAttrib(GL_COLOR_BUFFER_BIT); // (b) enable our regular ALPHA blending! glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); float startX = x; int index = 0; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { x = startX; int cy = (int)'M' - NUM_CHARACTER_TO_START; if(ofbOriginBottomLeft() ) y -= lineHeight; else y += lineHeight; y = (int)y; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; x += cps[cy].width; } else { drawChar(cy, x, y); x += cps[cy].setWidth; } } index++; } // (c) return back to the way things were (with blending, blend func, etc) glPopAttrib(); } Node-path: utils/ofConstants.h Node-kind: file Node-action: change Text-content-length: 3322 Text-content-md5: ad2fbf21218a28f622c3b53530a62f82 Content-length: 3322 #ifndef OF_CONSTANTS #define OF_CONSTANTS //------------------------------- // pc or mac ? // soon: pc, mac or linux... #ifndef __APPLE_CC__ #define TARGET_WIN32 #else #define TARGET_OSX #endif //------------------------------- // load glee for all platforms (must come before other includes) #include "GLee.h" // then the the platform specific includes: #ifdef TARGET_WIN32 #include #include "glut.h" #define __WINDOWS_DS__ #define __WINDOWS_MM__ #if (_MSC_VER) // microsoft visual studio #pragma warning(disable : 4996) // disable all deprecation warnings #pragma warning(disable : 4068) // unknown pragmas #pragma warning(disable : 4101) // unreferenced local variable #pragma warning(disable : 4312) // type cast conversion (in qt vp) #pragma warning(disable : 4311) // type cast pointer truncation (qt vp) #endif #define TARGET_LITTLE_ENDIAN // intel cpu // some gl.h files, like dev-c++, are old - this is pretty universal #ifndef GL_BGR_EXT #define GL_BGR_EXT 0x80E0 // #define WIN32_HIGH_RES_TIMING // note: this is experimental! // uncomment to turn this on (only for windows machines) // if you want to try setting the timer to be high resolution // this could make camera grabbing and other low level // operations quicker, but you must quit the app normally, // ie, using "esc", rather than killing the process or closing // the console window in order to set the timer resolution back // to normal (since the high res timer might give the OS // problems) // info: http://www.geisswerks.com/ryan/FAQS/timing.html #endif #endif #ifdef TARGET_OSX #define __MACOSX_CORE__ #include #include #if defined(__LITTLE_ENDIAN__) #define TARGET_LITTLE_ENDIAN // intel cpu #endif #endif #ifndef __MWERKS__ #define OF_EXIT_APP(val) exit(val); #else #define OF_EXIT_APP(val) std::exit(val); #endif // comment out this line, if you'd like to use the // quicktime capture interface on windows // if not, we default to videoInput library for // direct show capture, which is quite #define OF_SWITCH_TO_DSHOW_FOR_WIN_VIDCAP #ifdef OF_SWITCH_TO_DSHOW_FOR_WIN_VIDCAP #ifdef TARGET_OSX #define OF_VIDEO_CAPTURE_QUICKTIME #else #define OF_VIDEO_CAPTURE_DIRECTSHOW #endif #else // all quicktime, all the time #define OF_VIDEO_CAPTURE_QUICKTIME #endif // core: --------------------------- #include #include #include #include #include #ifndef PI #define PI 3.14159265358979323846 #endif #ifndef TWO_PI #define TWO_PI 6.28318530717958647693 #endif #ifndef M_TWO_PI #define M_TWO_PI 6.28318530717958647693 #endif #ifndef FOUR_PI #define FOUR_PI 12.56637061435917295385 #endif #ifndef HALF_PI #define HALF_PI 1.57079632679489661923 #endif #ifndef DEG_TO_RAD #define DEG_TO_RAD (PI/180.0) #endif #ifndef RAD_TO_DEG #define RAD_TO_DEG (180.0/PI) #endif #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #endif #ifndef ABS #define ABS(x) (((x) < 0) ? -(x) : (x)) #endif #define OF_FILLED 0x01 #define OF_OUTLINE 0x02 #define OF_WINDOW 0 #define OF_FULLSCREEN 1 #define OF_RECTMODE_CORNER 0 #define OF_RECTMODE_CENTER 1 #endif Revision-number: 58 Prop-content-length: 193 Content-length: 193 K 7 svn:log V 91 Theo: ttf fix for blackedges and cropped pixels and small change to comment in ofSerial.h K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-07T09:51:21.723360Z PROPS-END Node-path: communication/ofSerial.h Node-kind: file Node-action: change Text-content-length: 2133 Text-content-md5: 6729b9b827b4c74b8bbed5946a124da7 Content-length: 2133 #ifndef OF_SERIAL_H #define OF_SERIAL_H #include "ofConstants.h" // this serial code contains small portions of the following code-examples: // --------------------------------------------------- // http://todbot.com/arduino/host/arduino-serial/arduino-serial.c // web.mac.com/miked13/iWeb/Arduino/Serial%20Write_files/main.cpp // www.racer.nl/docs/libraries/qlib/qserial.htm // --------------------------------------------------- // notes: // ---------------------------- // when callign ofSerialSetup("....") you need to pass in // the name of the com port the device is attached to // for example, on a mac, it might look like: // // ofSerialSetup("/dev/tty.usbserial-3B1", 9600) // // and on a pc, it might look like: // // ofSerialSetup("COM4", 9600) // // if you are using an arduino board, for example, // you should check what ports you device is on in the // arduino program // to do: // ---------------------------- // a) support multiple serial connections/ports // (currently supports only one) // b) support blocking / non-blocking // c) support numChars available type functions // ---------------------------- // (also useful, might be this serial example - worth checking out: // http://web.mit.edu/kvogt/Public/osrc/src/ // if has evolved ways of dealing with blocking // and non-blocking instances) // ---------------------------- #if TARGET_OS_MAC #include #include #include #else #include #include #include #include #endif #include /* Standard input/output definitions */ #include #include /* Standard types */ #include /* String function definitions */ #include /* UNIX standard function definitions */ #include /* File control definitions */ #include /* Error number definitions */ void ofSerialSetup (char * portName, int baud); int ofSerialWrite (char * str); int ofSerialRead (char * buffer, int length); #endif Node-path: graphics/ofTrueTypeFont.cpp Node-kind: file Node-action: change Text-content-length: 12528 Text-content-md5: f4cd29c564143419e8e7e1fe0dc5a022 Content-length: 12528 #include "ofTrueTypeFont.h" //-------------------------- #ifdef TARGET_WIN32 #include #include #include #include #include #endif #ifdef TARGET_OSX #include "ft2build.h" #include "freetype.h" #include "ftglyph.h" #include "ftoutln.h" #include "fttrigon.h" #endif //------------------------------------------------------------------ ofTrueTypeFont::ofTrueTypeFont(){ bLoadedOk = false; } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize){ // load anti-aliased, non-full character set: loadFont(filename, fontsize, true, false); } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet){ bLoadedOk = false; bAntiAlised = _bAntiAliased; bFullCharacterSet = _bFullCharacterSet; fontSize = fontsize; //--------------- load the library and typeface FT_Library library; if (FT_Init_FreeType( &library )){ printf("PROBLEM WITH FT lib \n"); return; } FT_Face face; if (FT_New_Face( library, filename, 0, &face )) { return; } FT_Set_Char_Size( face,fontsize << 6,fontsize << 6,96,96); lineHeight = fontsize * 1.43f; //------------------------------------------------------ //kerning would be great to support: //printf("FT_HAS_KERNING ? %i \n", FT_HAS_KERNING(face)); //------------------------------------------------------ nCharacters = bFullCharacterSet ? 256 : 128 - NUM_CHARACTER_TO_START; //--------------- initialize character info and textures cps = new charProps[nCharacters]; texNames = new GLuint[nCharacters]; glGenTextures(nCharacters, texNames); //--------------------- load each char ----------------------- for (int i = 0 ; i < nCharacters; i++){ //------------------------------------------ anti aliased or not: if (bAntiAlised == true){ if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph %i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); } else { if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph%i \n", i); } FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO); } //------------------------------------------ FT_Bitmap& bitmap= face->glyph->bitmap; // 1 pixel border around the glyph int border = 2; // prepare the texture: int width = ofNextPow2( bitmap.width + border); int height = ofNextPow2( bitmap.rows + border); // ------------------------- this is fixing a bug with small type // ------------------------- appearantly, opengl has trouble with // ------------------------- width or height textures of 1, so we // ------------------------- we just set it to 2... if (width == 1) width = 2; if (height == 1) height = 2; // ------------------------- // info about the character: cps[i].value = i; cps[i].height = face->glyph->bitmap_top; cps[i].width = face->glyph->bitmap.width; cps[i].setWidth = face->glyph->advance.x >> 6; cps[i].topExtent = face->glyph->bitmap.rows; cps[i].leftExtent = face->glyph->bitmap_left; // texture internals cps[i].tTex = (float)(bitmap.width+border) / (float)width; cps[i].vTex = (float)(bitmap.rows+border) / (float)height; cps[i].xOff = ((float)(bitmap.width+border) / (float)width) - cps[i].tTex; cps[i].yOff = ((float)(bitmap.rows+border) / (float)height) - cps[i].vTex; /* sanity check: printf("%i %i %i %i %i %i \n", cps[i].value , cps[i].height , cps[i].width , cps[i].setWidth , cps[i].topExtent , cps[i].leftExtent ); */ // Allocate Memory For The Texture Data. unsigned char* expanded_data = new unsigned char[ 2 * width * height]; //-------------------------------- clear data: for(int j=0; j = nCharacters){ //printf("Error : char (%i) not allocated -- line %d in %s\n", (c + NUM_CHARACTER_TO_START), __LINE__,__FILE__); return; } //----------------------- int cu = c; float height = cps[cu].height; float bwidth = cps[cu].width; float top = cps[cu].topExtent - cps[cu].height; float lextent = cps[cu].leftExtent; float t = cps[cu].tTex; float v = cps[cu].vTex; float xOff = cps[cu].xOff; float yOff = cps[cu].yOff; //this is for topLeftDrawing only float corr = ( (fontSize - height) + top) - fontSize; if (glIsTexture(texNames[cu])) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texNames[cu]); glNormal3f(0, 0, 1); if (ofbOriginBottomLeft()){ glBegin(GL_QUADS); glTexCoord2d(xOff,yOff); glVertex2f(x + lextent, y + height); glTexCoord2d(xOff,v+yOff); glVertex2f(x + lextent, y-top); glTexCoord2d(t+xOff,v+yOff); glVertex2f(x + lextent + bwidth, y-top); glTexCoord2d(t+xOff,yOff); glVertex2f(x + lextent + bwidth, y + height); glEnd(); } else { glBegin(GL_QUADS); glTexCoord2d(t+xOff,v+yOff); glVertex2f(x + lextent + bwidth, y + height + corr); glTexCoord2d(t+xOff,yOff); glVertex2f(x + lextent + bwidth, (y-top) + corr); glTexCoord2d(xOff,yOff); glVertex2f(x + lextent, (y-top) + corr); glTexCoord2d(xOff,v+yOff); glVertex2f(x + lextent, y + height + corr); glEnd(); } glDisable(GL_TEXTURE_2D); } else { //let's add verbosity levels somewhere... //this error, for example, is kind of annoying to see //all the time: //printf("Warning : texture not bound for character -- line %d in %s\n", __LINE__,__FILE__); } } //----------------------------------------------------------- float ofTrueTypeFont::stringWidth(char *c) { float width = 0; int index = 0; float widthTemp = 0; bool bMultiLine = false; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { width = MAX(width, widthTemp); widthTemp = 0; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; widthTemp += cps[cy].width; } else { widthTemp += cps[cy].setWidth; } } index++; } width = MAX(width, widthTemp); return width; } //----------------------------------------------------------- float ofTrueTypeFont::stringHeight(char *c) { float height = 0; int index = 0; float maxHeight = 0; bool bFirstLineOfMultiLine = true; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { if (bFirstLineOfMultiLine == true){ bFirstLineOfMultiLine = false; height += maxHeight; } else { height += lineHeight; } maxHeight = 0; } else if (c[index] == ' ') { } else { float ht = cps[cy].height; if (ht > maxHeight) maxHeight = ht; } } index++; } height += maxHeight; return height; } //===================================================================== void ofTrueTypeFont::drawString(char *c, float x, float y) { if (!bLoadedOk){ printf("Error : font not allocated -- line %d in %s\n", __LINE__,__FILE__); return; }; // we need transparency to draw text, but we don't know // if that is set up in outside of this function // we "pushAttrib", turn on alpha and "popAttrib" // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushattrib.html // **** note **** // I have read that pushAttrib() is slow, if used often, // maybe there is a faster way to do this? // ie, check if blending is enabled, etc... // glIsEnabled().... glGet()... // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/get.html // ************** // (a) record the current "alpha state, blend func, etc" glPushAttrib(GL_COLOR_BUFFER_BIT); // (b) enable our regular ALPHA blending! glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); float startX = x; int index = 0; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { x = startX; int cy = (int)'M' - NUM_CHARACTER_TO_START; if(ofbOriginBottomLeft() ) y -= lineHeight; else y += lineHeight; y = (int)y; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; x += cps[cy].width; } else { drawChar(cy, x, y); x += cps[cy].setWidth; } } index++; } // (c) return back to the way things were (with blending, blend func, etc) glPopAttrib(); } Revision-number: 59 Prop-content-length: 197 Content-length: 197 K 7 svn:log V 95 Theo: major ttf rework and small change to ofTexture - using glVertexi combined with translated K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-08T12:13:44.302389Z PROPS-END Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: change Text-content-length: 9051 Text-content-md5: 10e197d8f39ef66a0cc45b6c2b391100 Content-length: 9051 #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); bool bSmoothHinted = false; bool bBakgroundAuto = true; int cornerMode = OF_RECTMODE_CORNER; //---------------------------------------------------------- void ofSetRectMode(int mode){ if (mode == OF_RECTMODE_CORNER) cornerMode = OF_RECTMODE_CORNER; else if (mode == OF_RECTMODE_CENTER) cornerMode = OF_RECTMODE_CENTER; } //---------------------------------------------------------- int ofGetRectMode(){ return cornerMode; } //---------------------------------------------------------- void ofSetBackgroundAuto(bool bAuto){ bBakgroundAuto = bAuto; } //---------------------------------------------------------- bool ofbClearBg(){ return bBakgroundAuto; } //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- bool ofbOriginBottomLeft(){ return true; // because people are certainly asking for it! } //---------------------------------------------------------- void ofBackground(int r, int g, int b){ bgColor[0] = (float)r / (float)255.0f; bgColor[1] = (float)g / (float)255.0f; bgColor[2] = (float)b / (float)255.0f; bgColor[3] = 1.0f; // if we are in not-auto mode, then clear with a bg call... if (ofbClearBg() == false){ glClearColor(bgColor[0],bgColor[1],bgColor[2], bgColor[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void startSmoothing(){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void endSmoothing(){ glPopAttrib(); } //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); // draw: glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); // draw: glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); if (cornerMode == OF_RECTMODE_CENTER){ glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x-w/2,y-h/2); glVertex2f(x+w/2,y-h/2); glVertex2f(x+w/2,y+h/2); glVertex2f(x-w/2,y+h/2); glEnd(); } else { glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); } // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b, int _a){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); float a = (float)_a / 255.0f; a = MAX(0,MIN(a,1.0f)); glColor4f(r,g,b,a); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } //---------------------------------------------------------- void ofEnableAlphaBlending(){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void ofDisableAlphaBlending(){ glDisable(GL_BLEND); } //---------------------------------------------------------- void ofEnableSmoothing(){ // please see: // http://www.opengl.org/resources/faq/technical/rasterization.htm bSmoothHinted = true; } //---------------------------------------------------------- void ofDisableSmoothing(){ bSmoothHinted = false; } //-------------------------------------------------- void ofDrawBitmapString(char *string, float x, float y){ //--------------------------------------------------- // for now this is fixed to the 8_BY_13 glut character // http://pyopengl.sourceforge.net/documentation/manual/glutBitmapCharacter.3GLUT.html //--------------------------------------------------- char *c; float yOffset = 0; float fontSize = 8.0f; glRasterPos2f(x,y); bool bOrigin = ofbOriginBottomLeft(); for (c=string; *c != '\0'; c++) { if(*c == '\n') { yOffset += bOrigin ? -1 : 1 * (fontSize*1.7); glRasterPos2f(x,y + (int)yOffset); } else if (((int)*c) >= 32){ // < 32 = control characters - don't draw // solves a bug with control characters // getting drawn when they ought to not be glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c); } } } //---------------------------------------------------------- void ofSetupScreen(){ int w, h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (!ofbOriginBottomLeft()){ glScalef(1, -1, 1); // invert Y axis so increasing Y goes down. glTranslatef(0, -h, 0); // shift origin up to upper-left corner. } } Node-path: graphics/ofTexture.cpp Node-kind: file Node-action: change Text-content-length: 6143 Text-content-md5: 3e3cf87841a34c13137385bd8c398f86 Content-length: 6143 #include "ofTexture.h" #include "ofUtils.h" // for nextPow2() //---------------------------------------------------------- ofTexture::ofTexture(){ texName[0] = 0; bFlipTexture = false; } //---------------------------------------------------------- void ofTexture::clear(){ // try to free up the texture memory so we don't reallocate // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/deletetextures.html if (texName[0] != 0){ glDeleteTextures(1, (GLuint *)texName); } width = 0; height = 0; bFlipTexture = false; } //---------------------------------------------------------- void ofTexture::allocate(int w, int h, int internalGlDataType){ // can pass in anything (320x240) (10x5) // here we make it power of 2 for opengl (512x256), (16x8) tex_w = ofNextPow2(w); tex_h = ofNextPow2(h); tex_u = 1.0f; tex_t = 1.0f; // attempt to free the previous bound texture, if we can: clear(); glGenTextures(1, (GLuint *)texName); // could be more then one, but for now, just one glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); // upload 0 or white pixels.... glTexImage2D(GL_TEXTURE_2D, 0, internalGlDataType, tex_w, tex_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); // init to black... glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); width = w; height = h; bFlipTexture = false; } //---------------------------------------------------------- void ofTexture::loadData(unsigned char * data, int w, int h, int glDataType){ // can we allow for uploads bigger then texture and // just take as much as the texture can? // // ie: // int uploadW = MIN(w, tex_w); // int uploadH = MIN(h, tex_h); // but with a "step" size of w? // check "glTexSubImage2D" if ( w > tex_w || h > tex_h) { printf("image data too big for allocated texture. not uploading... \n"); return; } width = w; height = h; //compute new tex co-ords based on the ratio of data's w, h to texture w,h; tex_t = (float)(w) / (float)tex_w; tex_u = (float)(h) / (float)tex_h; // ok this is an ultra annoying bug : // opengl texels and linear filtering - // when we have a sub-image, and we scale it // we can clamp the border pixels to the border, // but the borders of the sub image get mixed with // neighboring pixels... // grr... // // the best solution would be to pad out the image // being uploaded with 2 pixels on all sides, and // recompute tex_t coordinates.. // another option is a gl_arb non pow 2 textures... // the current hack is to alter the tex_t, tex_u calcs, but // that makes the image slightly off... // this is currently being done in draw... // // we need a good solution for this.. // // http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014770#000001 // http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014770#000001 //------------------------ likely, we are uploading continuous data GLint prevAlignment; glGetIntegerv(GL_UNPACK_ALIGNMENT, &prevAlignment); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // update the texture image: glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); glTexSubImage2D(GL_TEXTURE_2D,0,0,0,w,h,glDataType,GL_UNSIGNED_BYTE,data); glDisable(GL_TEXTURE_2D); //------------------------ back to normal. glPixelStorei(GL_UNPACK_ALIGNMENT, prevAlignment); bFlipTexture = false; } //---------------------------------------------------------- void ofTexture::loadScreenData(int x, int y, int w, int h){ if (!ofbOriginBottomLeft()){ int height = ofGetHeight(); y = height - y; y -= h; // top, bottom issues bFlipTexture = true; } if ( w > tex_w || h > tex_h) { printf("image data too big for allocated texture. not uploading... \n"); return; } width = w; height = h; //compute new tex co-ords based on the ratio of data's w, h to texture w,h; tex_t = (float)(w) / (float)tex_w; tex_u = (float)(h) / (float)tex_h; glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, (GLuint)texName[0]); glCopyTexSubImage2D(GL_TEXTURE_2D, 0,0,0,x,y,w,h); glDisable(GL_TEXTURE_2D); } //---------------------------------------------------------- void ofTexture::draw(float x, float y, float w, float h){ glEnable(GL_TEXTURE_2D); // bind the texture glBindTexture( GL_TEXTURE_2D, (GLuint)texName[0] ); GLint px0 = 0; // up to you to get the aspect ratio right GLint py0 = 0; GLint px1 = (GLint)w; GLint py1 = (GLint)h; if (bFlipTexture == true){ GLint temp = py0; py0 = py1; py1 = temp; } // for rect mode center, let's do this: if (ofGetRectMode() == OF_RECTMODE_CENTER){ px0 = (GLint)-w/2; py0 = (GLint)-h/2; px1 = (GLint)+w/2; py1 = (GLint)+h/2; } // ------------------------------------------------- // complete hack to remove border artifacts. // slightly, slightly alters an image, scaling... // to remove the border. // we need a better solution for this, but // to constantly add a 2 pixel border on all uploaded images // is insane.. GLfloat offsetw = 1.0f/(tex_w); GLfloat offseth = 1.0f/(tex_h); // ------------------------------------------------- GLfloat tx0 = 0+offsetw; GLfloat ty0 = 0+offseth; GLfloat tx1 = tex_t - offsetw; GLfloat ty1 = tex_u - offseth; glPushMatrix(); glTranslated(x, y, 0); glBegin( GL_QUADS ); glTexCoord2f(tx0,ty0); glVertex3i(px0, py0,0); glTexCoord2f(tx1,ty0); glVertex3i(px1, py0,0); glTexCoord2f(tx1,ty1); glVertex3i(px1, py1,0); glTexCoord2f(tx0,ty1); glVertex3i(px0, py1,0); glEnd(); glPopMatrix(); glDisable(GL_TEXTURE_2D); } //---------------------------------------------------------- void ofTexture::draw(float x, float y){ draw(x,y,width, height); } Node-path: graphics/ofTrueTypeFont.cpp Node-kind: file Node-action: change Text-content-length: 12822 Text-content-md5: 210ce5af2f76cc03c632bdc553fe1f81 Content-length: 12822 #include "ofTrueTypeFont.h" //-------------------------- #ifdef TARGET_WIN32 #include #include #include #include #include #endif #ifdef TARGET_OSX #include "ft2build.h" #include "freetype.h" #include "ftglyph.h" #include "ftoutln.h" #include "fttrigon.h" #endif //------------------------------------------------------------------ ofTrueTypeFont::ofTrueTypeFont(){ bLoadedOk = false; } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize){ // load anti-aliased, non-full character set: loadFont(filename, fontsize, true, false); } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(const char *filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet){ bLoadedOk = false; bAntiAlised = _bAntiAliased; bFullCharacterSet = _bFullCharacterSet; fontSize = fontsize; //--------------- load the library and typeface FT_Library library; if (FT_Init_FreeType( &library )){ printf("PROBLEM WITH FT lib \n"); return; } FT_Face face; if (FT_New_Face( library, filename, 0, &face )) { return; } FT_Set_Char_Size( face, fontsize << 6, fontsize << 6, 96, 96); lineHeight = fontsize * 1.43f; //------------------------------------------------------ //kerning would be great to support: //printf("FT_HAS_KERNING ? %i \n", FT_HAS_KERNING(face)); //------------------------------------------------------ nCharacters = bFullCharacterSet ? 256 : 128 - NUM_CHARACTER_TO_START; //--------------- initialize character info and textures cps = new charProps[nCharacters]; texNames = new GLuint[nCharacters]; glGenTextures(nCharacters, texNames); //--------------------- load each char ----------------------- for (int i = 0 ; i < nCharacters; i++){ //------------------------------------------ anti aliased or not: if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph %i \n", i); } if (bAntiAlised == true) FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); else FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO); //------------------------------------------ FT_Bitmap& bitmap= face->glyph->bitmap; // 3 pixel border around the glyph // We show 2 pixels of this, so that blending looks good. // 1 pixels is hidden because we don't want to see the real edge of the texture border = 3; visibleBorder = 2; // prepare the texture: int width = ofNextPow2( bitmap.width + border*2 ); int height = ofNextPow2( bitmap.rows + border*2 ); // ------------------------- this is fixing a bug with small type // ------------------------- appearantly, opengl has trouble with // ------------------------- width or height textures of 1, so we // ------------------------- we just set it to 2... if (width == 1) width = 2; if (height == 1) height = 2; // ------------------------- // info about the character: cps[i].value = i; cps[i].height = face->glyph->bitmap_top; cps[i].width = face->glyph->bitmap.width; cps[i].setWidth = face->glyph->advance.x >> 6; cps[i].topExtent = face->glyph->bitmap.rows; cps[i].leftExtent = face->glyph->bitmap_left; // texture internals cps[i].tTex = (float)(bitmap.width + visibleBorder*2) / (float)width; cps[i].vTex = (float)(bitmap.rows + visibleBorder*2) / (float)height; cps[i].xOff = (float)(border - visibleBorder) / (float)width; cps[i].yOff = (float)(border - visibleBorder) / (float)height; /* sanity check: printf("%i %i %i %i %i %i \n", cps[i].value , cps[i].height , cps[i].width , cps[i].setWidth , cps[i].topExtent , cps[i].leftExtent ); */ // Allocate Memory For The Texture Data. unsigned char* expanded_data = new unsigned char[ 2 * width * height]; //-------------------------------- clear data: for(int j=0; j = nCharacters){ //printf("Error : char (%i) not allocated -- line %d in %s\n", (c + NUM_CHARACTER_TO_START), __LINE__,__FILE__); return; } //----------------------- int cu = c; GLint height = cps[cu].height; GLint bwidth = cps[cu].width; GLint top = cps[cu].topExtent - cps[cu].height; GLint lextent = cps[cu].leftExtent; GLint x1, y1, x2, y2, corr, stretch; GLfloat t1, v1, t2, v2; //this accounts for the fact that we are showing 2*visibleBorder extra pixels //so we make the size of each char that many pixels bigger stretch = visibleBorder * 2; if (ofbOriginBottomLeft()){ t1 = cps[cu].xOff; v1 = cps[cu].yOff; t2 = cps[cu].tTex + t1; v2 = cps[cu].vTex + v1; x1 = lextent; y1 = height + stretch; x2 = lextent + bwidth + stretch; y2 = -top; } else{ t2 = cps[cu].xOff; v2 = cps[cu].yOff; t1 = cps[cu].tTex + t2; v1 = cps[cu].vTex + v2; corr = ( (fontSize - height) + top) - fontSize; x1 = lextent + bwidth + stretch; y1 = height + corr + stretch; x2 = lextent; y2 = -top + corr; } if (glIsTexture(texNames[cu])) { glBindTexture(GL_TEXTURE_2D, texNames[cu]); glNormal3f(0, 0, 1); glBegin(GL_QUADS); glTexCoord2d(t1,v1); glVertex2i(x1, y1); glTexCoord2d(t1,v2); glVertex2i(x1, y2); glTexCoord2d(t2,v2); glVertex2i(x2, y2); glTexCoord2d(t2,v1); glVertex2i(x2, y1); glEnd(); } else { //let's add verbosity levels somewhere... //this error, for example, is kind of annoying to see //all the time: //printf("Warning : texture not bound for character -- line %d in %s\n", __LINE__,__FILE__); } } //----------------------------------------------------------- float ofTrueTypeFont::stringWidth(char *c) { float width = 0; int index = 0; float widthTemp = 0; bool bMultiLine = false; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { width = MAX(width, widthTemp); widthTemp = 0; } else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; widthTemp += cps[cy].width; } else { widthTemp += cps[cy].setWidth; } } index++; } width = MAX(width, widthTemp); return width; } //----------------------------------------------------------- float ofTrueTypeFont::stringHeight(char *c) { float height = 0; int index = 0; float maxHeight = 0; bool bFirstLineOfMultiLine = true; while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { if (bFirstLineOfMultiLine == true){ bFirstLineOfMultiLine = false; height += maxHeight; } else { height += lineHeight; } maxHeight = 0; } else if (c[index] == ' ') { } else { float ht = cps[cy].height; if (ht > maxHeight) maxHeight = ht; } } index++; } height += maxHeight; return height; } //===================================================================== void ofTrueTypeFont::drawString(char *c, float x, float y) { if (!bLoadedOk){ printf("Error : font not allocated -- line %d in %s\n", __LINE__,__FILE__); return; }; // we need transparency to draw text, but we don't know // if that is set up in outside of this function // we "pushAttrib", turn on alpha and "popAttrib" // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushattrib.html // **** note **** // I have read that pushAttrib() is slow, if used often, // maybe there is a faster way to do this? // ie, check if blending is enabled, etc... // glIsEnabled().... glGet()... // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/get.html // ************** GLint index = 0; GLfloat X = 0; GLfloat Y = 0; GLfloat startX = x; // (a) record the current "alpha state, blend func, etc" glPushAttrib(GL_COLOR_BUFFER_BIT); // (b) enable our regular ALPHA blending! glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // (c) enable texture once before we start drawing each char (no point turning it on and off constantly) glEnable(GL_TEXTURE_2D); // (d) store the current matrix position and do a translation to the drawing position glPushMatrix(); glTranslated(x, y, 0); while (c[index] != 0) { int cy = (unsigned char)c[index] - NUM_CHARACTER_TO_START; if (cy < nCharacters){ // full char set or not? if (c[index] == '\n') { if(ofbOriginBottomLeft() ) Y = -(int)lineHeight; else Y = (int)lineHeight; glTranslated(-X, Y, 0); X = 0 ; //reset X Pos back to zero }else if (c[index] == ' ') { int cy = (int)'p' - NUM_CHARACTER_TO_START; X += cps[cy].width; glTranslated(cps[cy].width, 0, 0); } else { drawChar(cy, 0, 0); X += cps[cy].setWidth; glTranslated(cps[cy].setWidth, 0, 0); } } index++; } glPopMatrix(); glDisable(GL_TEXTURE_2D); // (c) return back to the way things were (with blending, blend func, etc) glPopAttrib(); } Node-path: graphics/ofTrueTypefont.h Node-kind: file Node-action: change Text-content-length: 1305 Text-content-md5: 047e67945a62dd0f83a6a4b66d4ba683 Content-length: 1305 #ifndef _OF_TTF_FONT_H_ #define _OF_TTF_FONT_H_ #include "ofConstants.h" #include "ofGraphics.h" //-------------------------------------------------- typedef struct { int value; int height; int width; int setWidth; int topExtent; int leftExtent; float tTex; float vTex; //0-1 pct of bitmap... float xOff; float yOff; } charProps; //-------------------------------------------------- #define NUM_CHARACTER_TO_START 33 // 0 - 32 are control characters, no graphics needed. class ofTrueTypeFont{ public: ofTrueTypeFont(); // -- default, non-full char set, anti aliased: void loadFont(const char *filename, int fontsize); void loadFont(const char *filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet); bool bLoadedOk; bool bAntiAlised; bool bFullCharacterSet; float getLineHeight(); void setLineHeight(float height); float stringWidth(char *s); float stringHeight(char *c); void drawString(char *c, float x, float y); int nCharacters; protected: float lineHeight; charProps * cps; // properties for each character GLuint * texNames; // textures for each character int fontSize; void drawChar(int c, float x, float y); int ofNextPow2(int a); int border, visibleBorder; }; #endif Revision-number: 60 Prop-content-length: 126 Content-length: 126 K 7 svn:log V 24 // zach - small cleanups K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-15T18:08:04.955846Z PROPS-END Node-path: communication/ofSerial.cpp Node-kind: file Node-action: change Text-content-length: 4686 Text-content-md5: 1d46615442bf70397fc6d49ea5b5611f Content-length: 4686 #include "ofSerial.h" static bool bInited; #ifdef TARGET_WIN32 static HANDLE hComm; // the handle to the serial port pc #else static int fd; // the handle to the serial port mac #endif //---------------------------------------------------------------- void ofSerialInit (char * portName, int baud){ bInited = false; //--------------------------------------------- #ifdef TARGET_OSX //--------------------------------------------- struct termios toptions; printf("ofSerialInit: opening port %s @ %d bps\n", portName,baud); fd = open(portName, O_RDWR | O_NOCTTY | O_NDELAY); if(fd == -1){ printf("open: unable to open port"); } struct termios options; tcgetattr(fd,&options); switch(baud){ case 9600: cfsetispeed(&options,B9600); cfsetospeed(&options,B9600); break; case 19200: cfsetispeed(&options,B19200); cfsetospeed(&options,B19200); break; case 38400: cfsetispeed(&options,B38400); cfsetospeed(&options,B38400); break; default: cfsetispeed(&options,B9600); cfsetospeed(&options,B9600); break; } options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; tcsetattr(fd,TCSANOW,&options); bInited = true; printf("sucess in opening serial connection\n"); return; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- // open the serial port: // "COM4", etc... hComm=CreateFileA(portName,GENERIC_READ|GENERIC_WRITE,0,0, OPEN_EXISTING,0,0); if(hComm==INVALID_HANDLE_VALUE){ printf("error opening port %s\n please check to see if it's in use, or the right port\n", portName); return; } // now try the settings: COMMCONFIG cfg; DWORD cfgSize; char buf[80]; cfgSize=sizeof(cfg); GetCommConfig(hComm,&cfg,&cfgSize); int bps = baud; // Set baudrate and bits etc. // Note that BuildCommDCB() clears XON/XOFF and hardware control by default sprintf(buf,"baud=%d parity=N data=8 stop=1",bps); if(!BuildCommDCB(buf,&cfg.dcb)){ printf("Can't build comm dcb; %s",buf); } if(!SetCommState(hComm,&cfg.dcb)){ printf("Can't set comm state"); } printf(buf,"bps=%d, xio=%d/%d\n",cfg.dcb.BaudRate,cfg.dcb.fOutX,cfg.dcb.fInX); // Set communication timeouts (NT) COMMTIMEOUTS tOut; GetCommTimeouts(hComm,&tOut); // Make timeout so that: // - return immediately with buffered characters tOut.ReadIntervalTimeout=MAXDWORD; tOut.ReadTotalTimeoutMultiplier=0; tOut.ReadTotalTimeoutConstant=0; SetCommTimeouts(hComm,&tOut); bInited = true; //--------------------------------------------- #endif //--------------------------------------------- } //---------------------------------------------------------------- int ofSerialWrite (char * str){ if (!bInited){ printf("error: serial not inited\n"); return 0; } //--------------------------------------------- #ifdef TARGET_OSX //--------------------------------------------- int len = strlen(str); int numWritten = write(fd, str, len); printf("numWritten %i \n", numWritten); return numWritten; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- DWORD written; int len = strlen(str); if(!WriteFile(hComm,str,len,&written,0)){ printf("Can't write to com port"); return 0; } return (int)written; //--------------------------------------------- #endif //--------------------------------------------- } //---------------------------------------------------------------- int ofSerialRead (char * buffer, int length){ if (!bInited){ printf("error: serial not inited\n"); return 0; } //--------------------------------------------- #ifdef TARGET_OSX //--------------------------------------------- int nRead = read(fd,buffer,length); return nRead; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- DWORD nRead; if (!ReadFile(hComm,buffer,length,&nRead,0)){ printf("trouble reading from port"); return 0; } return nRead; //--------------------------------------------- #endif //--------------------------------------------- } Revision-number: 61 Prop-content-length: 166 Content-length: 166 K 7 svn:log V 64 //zach - fixes for multiplay, added a couple of getter functions K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-15T18:14:51.606109Z PROPS-END Node-path: sound/ofSoundPlayer.cpp Node-kind: file Node-action: change Text-content-length: 6490 Text-content-md5: 834a83a7e5113659dcbca7e27d31fd12 Content-length: 6490 #include "ofSoundPlayer.h" // these are global functions, that affect every sound / channel: // ------------------------------------------------------------ // ------------------------------------------------------------ bool bUseSpectrum = false; float fftValues[512]; // max # bands is 512 //-------------------- void ofSoundStopAll(){ FSOUND_StopSound(FSOUND_ALL); } //-------------------- void ofSoundSetVolume(float vol){ FSOUND_SetVolume(FSOUND_ALL, (int)(vol*255.0f)); } //-------------------- void ofSoundSetUseSpectrum(bool use){ bUseSpectrum = use; FSOUND_DSP_SetActive( FSOUND_DSP_GetFFTUnit( ), bUseSpectrum); } //-------------------- float * ofSoundGetSpectrum(int nBands){ // ------------------------------------ // [note] this code snippet comes from: // http://qepsilon.org/doc/snd__main_8cpp-source.html // via gamedev.net forum // ------------------------------------ if (nBands > 512){ printf("error in ofSoundGetSpectrum, the maximum number of bands is 512 - you asked for %i\nwe will return 512\n", nBands); nBands = 512; } // now, get the spectrum and // place it into fftValues array with the nBands requested // for returning: float *spectrum = FSOUND_DSP_GetSpectrum( ); int ctr = 0; int FreqPerBand = 448 / nBands; for (int i = 0; i < nBands; i++){ fftValues[i] = 0.0f; for (int j = 0; j < FreqPerBand; j++){ fftValues[i] += spectrum[ctr++]; } fftValues[i] = fftValues[i] / 1.5f; if (fftValues[i] > 1.0f){ fftValues[i] = 1.0f; } } return fftValues; } // ------------------------------------------------------------ // ------------------------------------------------------------ // now, the individual sound player: //------------------------------------------------------------ ofSoundPlayer::ofSoundPlayer(){ bLoop = false; bLoadedOk = false; channel = -1; pan = 0.5f; volume = 1.0f; internalFreq = 44100; speed = 1; bPaused = false; } //------------------------------------------------------------ void ofSoundPlayer::loadSound(char * fileName){ // fmod uses IO posix internally, might have trouble // with unicode paths... // says this code: // http://66.102.9.104/search?q=cache:LM47mq8hytwJ:www.cleeker.com/doxygen/audioengine__fmod_8cpp-source.html+FSOUND_Sample_Load+cpp&hl=en&ct=clnk&cd=18&client=firefox-a // for now we use FMODs way, but we could switch if // there are problems: bMultiPlay = false; // [1] init fmod, if necessary initializeFmod(); // [2] try to unload any previously loaded sounds // & prevent user-created memory leaks // if they call "loadSound" repeatedly, for example unloadSound(); // [3] load sound samp = FSOUND_Sample_Load(FSOUND_UNMANAGED, fileName, FSOUND_NORMAL, 0, 0); if (!samp){ bLoadedOk = false; } else { bLoadedOk = true; length = FSOUND_Sample_GetLength(samp); } } //------------------------------------------------------------ void ofSoundPlayer::unloadSound(){ if (bLoadedOk){ stop(); // try to stop the sound FSOUND_Sample_Free(samp); // & free the sample } } //------------------------------------------------------------ bool ofSoundPlayer::getIsPlaying(){ if (channel == -1 || !bLoadedOk) return false; return FSOUND_IsPlaying(channel); } //------------------------------------------------------------ float ofSoundPlayer::getSpeed(){ return speed; } //------------------------------------------------------------ float ofSoundPlayer::getPan(){ return pan; } //------------------------------------------------------------ void ofSoundPlayer::setVolume(float vol){ if (getIsPlaying() == true){ FSOUND_SetVolume(channel, (int)(vol*255.0f)); volume = vol; } } //------------------------------------------------------------ void ofSoundPlayer::setPosition(float pct){ if (getIsPlaying() == true){ int sampleToBeAt = (int)(length * pct); FSOUND_SetCurrentPosition(channel, sampleToBeAt); } } //------------------------------------------------------------ float ofSoundPlayer::getPosition(){ if (getIsPlaying() == true){ int sampleImAt; sampleImAt = (int)FSOUND_GetCurrentPosition(channel); float pct = 0.0f; if (length > 0){ pct = sampleImAt / (float)length; } return pct; } else { return 0; } } //------------------------------------------------------------ void ofSoundPlayer::setPan(float p){ if (getIsPlaying() == true){ FSOUND_SetPan(channel, (int)(p*255.0f)); pan = p; } } //------------------------------------------------------------ void ofSoundPlayer::setPaused(bool bP){ if (getIsPlaying() == true){ FSOUND_SetPaused(channel, bP); bPaused = bP; } } //------------------------------------------------------------ void ofSoundPlayer::setSpeed(float spd){ FSOUND_SetFrequency(channel, (int)(internalFreq * spd)); speed = spd; } //------------------------------------------------------------ void ofSoundPlayer::setLoop(bool bLp){ FSOUND_SetLoopMode(channel, (bLp == true) ? FSOUND_LOOP_NORMAL : FSOUND_LOOP_OFF); bLoop = bLp; } // ---------------------------------------------------------------------------- void ofSoundPlayer::setMultiPlay(bool bMp){ bMultiPlay = bMp; // be careful with this... } // ---------------------------------------------------------------------------- void ofSoundPlayer::play(){ // if it's a looping sound, we should try to kill it, no? // or else people will have orphan channels that are looping if (bLoop == true){ FSOUND_StopSound(channel); } // if the sound is not set to multiplay, then stop the current, // before we start another if (!bMultiPlay){ FSOUND_StopSound(channel); } channel = FSOUND_PlaySound(FSOUND_FREE, samp); internalFreq = FSOUND_GetFrequency(channel); FSOUND_SetVolume(channel, (int)(volume*255.0f)); FSOUND_SetPan(channel, (int)(pan*255.0f)); FSOUND_SetPaused(channel, bPaused); FSOUND_SetFrequency(channel, (int)(internalFreq * speed)); FSOUND_SetLoopMode(channel, (bLoop == true) ? FSOUND_LOOP_NORMAL : FSOUND_LOOP_OFF); } // ---------------------------------------------------------------------------- void ofSoundPlayer::stop(){ FSOUND_StopSound(channel); } Node-path: sound/ofSoundPlayer.h Node-kind: file Node-action: change Text-content-length: 1660 Text-content-md5: 13c81bbe9e0b086d52a2b522814364e8 Content-length: 1660 #ifndef _OF_SAMPLE_SOUND #define _OF_SAMPLE_SOUND #include "fmod.h" #include "ofFmodUtils.h" // TO DO : // --------------------------- // -fft via fmod, as in the last time... // -close fmod if it's up // -streaming (long mp3s, urls, etc) // -loadSoundForStreaming(char * fileName); // --------------------------- // interesting: // http://www.compuphase.com/mp3/mp3loops.htm // ---------------------------------------------------------------------------- SOUND SYSTEM FMOD // --------------------- global functions: void ofSoundStopAll(); void ofSoundSetVolume(float vol); void ofSoundSetUseSpectrum(bool use); float * ofSoundGetSpectrum(int nBands); // max 512... // --------------------- player functions: class ofSoundPlayer{ public: ofSoundPlayer(); void loadSound(char * fileName); void unloadSound(); void play(); void stop(); void setVolume(float vol); void setPan(float vol); void setSpeed(float spd); void setPaused(bool bP); void setLoop(bool bLp); void setMultiPlay(bool bMp); void setPosition(float pct); // 0 = start, 1 = end; float getPosition(); bool getIsPlaying(); float getSpeed(); float getPan(); bool bMultiPlay; bool bLoop; bool bLoadedOk; bool bPaused; int channel; // in Fmod, what channel am I playing on? float pan; // 0 - 1 float volume; // 0 - 1 float internalFreq; // 44100 ? float speed; // -n to n, 1 = normal, -1 backwards int length; // in samples; FSOUND_SAMPLE * samp; }; #endif // _OF_SAMPLE_SOUND Revision-number: 62 Prop-content-length: 175 Content-length: 175 K 7 svn:log V 73 // zach - fixed some small bugs, like mouseMoved before window opens, etc K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-15T18:15:53.758440Z PROPS-END Node-path: app/ofAppGlutGlue.h Node-kind: file Node-action: change Text-content-length: 4335 Text-content-md5: 8b1a20cc671ecb7865e93d51675e006f Content-length: 4335 void display(void); void mouse_cb(int button, int state, int x, int y); void motion_cb(int x, int y); void passive_motion_cb(int x, int y); void idle_cb(void); void keyboard_cb(unsigned char key, int x, int y); void special_key_cb(int key, int x, int y) ; static int buttonInUse = 0; //-------------------------------- static float timeNow, timeThen, fps; static int nFramesForFPS; static int nFrameCount = 0; static bool bFrameRateSet; int millisForFrame; int prevMillis; int diffMillis; //------------------------------------------------------------ void display(void){ //-------------------------------- // when I had "glutFullScreen()" // in the initOpenGl, I was gettings a "heap" allocation error // when debugging via visual studio. putting it here, changes that. // maybe it's voodoo, or I am getting rid of the problem // by removing something unrelated, but everything seems // to work if I put fullscreen on the first frame of display. if (nFrameCount == 0 && windowMode == OF_FULLSCREEN) glutFullScreen(); width = ofGetWidth(); height = ofGetHeight(); height = height > 0 ? height : 1; // set viewport, clear the screen glViewport( 0, 0, width, height ); float * bgPtr = ofBgColorPtr(); bool bClearAuto = ofbClearBg(); // I don't know why, I need more than one frame at the start in fullscreen mode // also, in non-fullscreen mode, windows/intel graphics, this bClearAuto just fails. // I seem to have 2 buffers, alot of flickering // and don't accumulate the way I expect. // with this line: if ((bClearAuto == true) || nFrameCount < 3){ // we do nFrameCount < 3, so that the buffers are cleared at the start of the app // or else we have video memory garbage to draw on to... if ((bClearAuto == true || windowMode == OF_WINDOW) || nFrameCount < 3){ glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } ofSetupScreen(); OFSAptr->draw(); glutSwapBuffers(); // -------------- fps calculation: timeNow = ofGetElapsedTimef(); if( (timeNow-timeThen) > 0.05f || nFramesForFPS == 0 ) { fps = (double)nFramesForFPS / (timeNow-timeThen); timeThen = timeNow; nFramesForFPS = 0; ofFrameRate = 0.9f * ofFrameRate + 0.1f * fps; } nFramesForFPS++; // -------------- nFrameCount++; // increase the overall frame count } //------------------------------------------------------------ void mouse_cb(int button, int state, int x, int y) { if (!ofbOriginBottomLeft()){ y = height - y; } if (nFrameCount > 0){ OFSAptr->mouseX = x; OFSAptr->mouseY = height - y; if (state == GLUT_DOWN) { OFSAptr->mousePressed(x, height - y, button); } else if (state == GLUT_UP) { OFSAptr->mouseReleased(); } buttonInUse = button; } } //------------------------------------------------------------ void motion_cb(int x, int y) { if (!ofbOriginBottomLeft()){ y = height - y; } if (nFrameCount > 0){ OFSAptr->mouseX = x; OFSAptr->mouseY = height - y; OFSAptr->mouseDragged(x, height - y, buttonInUse); } } //------------------------------------------------------------ void passive_motion_cb(int x, int y) { if (!ofbOriginBottomLeft()){ y = height - y; } if (nFrameCount > 0){ OFSAptr->mouseX = x; OFSAptr->mouseY = height - y; OFSAptr->mouseMoved(x, height - y); } } //------------------------------------------------------------ void idle_cb(void) { if (nFrameCount != 0 && bFrameRateSet == true){ diffMillis = ofGetElapsedTimeMillis() - prevMillis; if (diffMillis > millisForFrame){ ; // we do nothing, we are already slower than target frame } else { int waitMillis = millisForFrame - diffMillis; #ifdef TARGET_WIN32 Sleep(waitMillis); //windows sleep in milliseconds #else usleep(waitMillis * 1000); //mac sleep in microseconds - cooler :) #endif } } OFSAptr->update(); glutPostRedisplay(); prevMillis = ofGetElapsedTimeMillis(); } //------------------------------------------------------------ void keyboard_cb(unsigned char key, int x, int y) { OFSAptr->keyPressed((int)key); if (key == 27){ // "escape" OF_EXIT_APP(0); } } //------------------------------------------------------------ void special_key_cb(int key, int x, int y) { OFSAptr->keyPressed((int)key); } Node-path: app/ofAppRunner.cpp Node-kind: file Node-action: change Text-content-length: 4045 Text-content-md5: 5d329fd601d888a29df89f47c59c55db Content-length: 4045 #include "ofAppRunner.h" //======================================================================== // static variables: static ofSimpleApp * OFSAptr; int windowMode; bool bMousePressed; bool bRightButton; int width, height; static float ofFrameRate; //======================================================================== // callbacks: #include "ofAppGlutGlue.h" //-------------------------------------- void ofSetupOpenGL(int w, int h, int screenMode){ int argc = 1; char *argv = "openframeworks"; char **vptr = &argv; glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA); glutInit(&argc, vptr); //if (screenMode == OF_WINDOW) glutInitWindowSize(w, h); glutCreateWindow(""); windowMode = screenMode; ofBackground(200,200,200); // default bg color ofSetColor(0xFFFFFF); // default draw color // used to be black, but // black + texture = black // so maybe grey bg // and "white" fg color // as default works the best... } //----------------------- gets called when the app exits // currently looking at who to turn off // at the end of the application void ofExitCallback(); void ofExitCallback(){ // who to kill off ? // -- fmod // -- quicktime // -- freeImage // anyone else? #ifdef WIN32_HIGH_RES_TIMING timeEndPeriod(1); #endif //delete OFSAptr; } //-------------------------------------- void ofRunApp(ofSimpleApp * OFSA){ OFSAptr = OFSA; atexit(ofExitCallback); #ifdef WIN32_HIGH_RES_TIMING timeBeginPeriod(1); // ! experimental, sets high res time // you need to call timeEndPeriod. // if you quit the app other than "esc" // (ie, close the console, kill the process, etc) // at exit wont get called, and the time will // remain high res, that could mess things // up on your system. // info here:http://www.geisswerks.com/ryan/FAQS/timing.html #endif bFrameRateSet = false; //---------------------- // setup the callbacks glutMouseFunc(mouse_cb); glutMotionFunc(motion_cb); glutPassiveMotionFunc(passive_motion_cb); glutIdleFunc(idle_cb); glutDisplayFunc(display); glutKeyboardFunc(keyboard_cb); glutSpecialFunc(special_key_cb); //---------------------- ofSeedRandom(); // seed the random generator // (users can seed it to a value in setup // if they want it fixed); OFSA->setup(); glutMainLoop(); } //-------------------------------------- float ofGetFrameRate(){ return ofFrameRate; } //-------------------------------------- void ofSetFrameRate(int targetRate){ // given this FPS, what is the amount of millis per frame // that should elapse? // --- > f / s if (targetRate == 0){ bFrameRateSet = false; return; } bFrameRateSet = true; float durationOfFrame = 1.0f / (float)targetRate; millisForFrame = (int)(1000.0f * durationOfFrame); } //-------------------------------------- void ofHideCursor(){ glutSetCursor(GLUT_CURSOR_NONE); } //-------------------------------------- void ofShowCursor(){ glutSetCursor(GLUT_CURSOR_RIGHT_ARROW); } //-------------------------------------- void ofSetVerticalSync(bool bSync){ //---------------------------- #ifdef TARGET_WIN32 //---------------------------- if (bSync) { if (GLEE_WGL_EXT_swap_control) wglSwapIntervalEXT (1); } else { if (GLEE_WGL_EXT_swap_control) wglSwapIntervalEXT (0); } //---------------------------- #endif //---------------------------- //-------------------------------------- #ifdef TARGET_OSX //-------------------------------------- long sync = bSync == true ? 1 : 0; CGLSetParameter (CGLGetCurrentContext(), kCGLCPSwapInterval, &sync); //-------------------------------------- #endif //-------------------------------------- } Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: change Text-content-length: 8998 Text-content-md5: 03c8c71b1b6637c849d40134d23c769a Content-length: 8998 #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); bool bSmoothHinted = false; bool bBakgroundAuto = true; int cornerMode = OF_RECTMODE_CORNER; //---------------------------------------------------------- void ofSetRectMode(int mode){ if (mode == OF_RECTMODE_CORNER) cornerMode = OF_RECTMODE_CORNER; else if (mode == OF_RECTMODE_CENTER) cornerMode = OF_RECTMODE_CENTER; } //---------------------------------------------------------- int ofGetRectMode(){ return cornerMode; } //---------------------------------------------------------- void ofSetBackgroundAuto(bool bAuto){ bBakgroundAuto = bAuto; } //---------------------------------------------------------- bool ofbClearBg(){ return bBakgroundAuto; } //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- bool ofbOriginBottomLeft(){ return false; // because people are certainly asking for it! } //---------------------------------------------------------- void ofBackground(int r, int g, int b){ bgColor[0] = (float)r / (float)255.0f; bgColor[1] = (float)g / (float)255.0f; bgColor[2] = (float)b / (float)255.0f; bgColor[3] = 1.0f; // if we are in not-auto mode, then clear with a bg call... if (ofbClearBg() == false){ glClearColor(bgColor[0],bgColor[1],bgColor[2], bgColor[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void startSmoothing(){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void endSmoothing(){ glPopAttrib(); } //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); // draw: glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ // use smoothness, if requested: if (bSmoothHinted) startSmoothing(); // draw: glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted) endSmoothing(); } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); if (cornerMode == OF_RECTMODE_CENTER){ glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x-w/2,y-h/2); glVertex2f(x+w/2,y-h/2); glVertex2f(x+w/2,y+h/2); glVertex2f(x-w/2,y+h/2); glEnd(); } else { glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); } // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b, int _a){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); float a = (float)_a / 255.0f; a = MAX(0,MIN(a,1.0f)); glColor4f(r,g,b,a); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } //---------------------------------------------------------- void ofEnableAlphaBlending(){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void ofDisableAlphaBlending(){ glDisable(GL_BLEND); } //---------------------------------------------------------- void ofEnableSmoothing(){ // please see: // http://www.opengl.org/resources/faq/technical/rasterization.htm bSmoothHinted = true; } //---------------------------------------------------------- void ofDisableSmoothing(){ bSmoothHinted = false; } //-------------------------------------------------- void ofDrawBitmapString(char *string, float x, float y){ //--------------------------------------------------- // for now this is fixed to the 8_BY_13 glut character // http://pyopengl.sourceforge.net/documentation/manual/glutBitmapCharacter.3GLUT.html //--------------------------------------------------- char *c; float yOffset = 0; float fontSize = 8.0f; glRasterPos2f(x,y); bool bOrigin = ofbOriginBottomLeft(); for (c=string; *c != '\0'; c++) { if(*c == '\n') { yOffset += bOrigin ? -1 : 1 * (fontSize*1.7); glRasterPos2f(x,y + (int)yOffset); } else if (((int)*c) >= 32){ // < 32 = control characters - don't draw // solves a bug with control characters // getting drawn when they ought to not be glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c); } } } //---------------------------------------------------------- void ofSetupScreen(){ int w, h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (!ofbOriginBottomLeft()){ glScalef(1, -1, 1); // invert Y axis so increasing Y goes down. glTranslatef(0, -h, 0); // shift origin up to upper-left corner. } } Revision-number: 63 Prop-content-length: 179 Content-length: 179 K 7 svn:log V 77 // zach - glee include per platform, needed to change order for visual studio K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-15T18:26:55.381433Z PROPS-END Node-path: utils/ofConstants.h Node-kind: file Node-action: change Text-content-length: 3277 Text-content-md5: 51f43bc223e6f9d62323f2755c1e2b95 Content-length: 3277 #ifndef OF_CONSTANTS #define OF_CONSTANTS //------------------------------- // pc or mac ? // soon: pc, mac or linux... #ifndef __APPLE_CC__ #define TARGET_WIN32 #else #define TARGET_OSX #endif //------------------------------- // then the the platform specific includes: #ifdef TARGET_WIN32 #include #include "GLee.h" #include "glut.h" #define __WINDOWS_DS__ #define __WINDOWS_MM__ #if (_MSC_VER) // microsoft visual studio #pragma warning(disable : 4996) // disable all deprecation warnings #pragma warning(disable : 4068) // unknown pragmas #pragma warning(disable : 4101) // unreferenced local variable #pragma warning(disable : 4312) // type cast conversion (in qt vp) #pragma warning(disable : 4311) // type cast pointer truncation (qt vp) #endif #define TARGET_LITTLE_ENDIAN // intel cpu // some gl.h files, like dev-c++, are old - this is pretty universal #ifndef GL_BGR_EXT #define GL_BGR_EXT 0x80E0 #endif // #define WIN32_HIGH_RES_TIMING // note: this is experimental! // uncomment to turn this on (only for windows machines) // if you want to try setting the timer to be high resolution // this could make camera grabbing and other low level // operations quicker, but you must quit the app normally, // ie, using "esc", rather than killing the process or closing // the console window in order to set the timer resolution back // to normal (since the high res timer might give the OS // problems) // info: http://www.geisswerks.com/ryan/FAQS/timing.html #endif #ifdef TARGET_OSX #define __MACOSX_CORE__ #include #include "GLee.h" #include #if defined(__LITTLE_ENDIAN__) #define TARGET_LITTLE_ENDIAN // intel cpu #endif #endif #ifndef __MWERKS__ #define OF_EXIT_APP(val) exit(val); #else #define OF_EXIT_APP(val) std::exit(val); #endif // comment out this line, if you'd like to use the // quicktime capture interface on windows // if not, we default to videoInput library for // direct show capture, which is quite #define OF_SWITCH_TO_DSHOW_FOR_WIN_VIDCAP #ifdef OF_SWITCH_TO_DSHOW_FOR_WIN_VIDCAP #ifdef TARGET_OSX #define OF_VIDEO_CAPTURE_QUICKTIME #else #define OF_VIDEO_CAPTURE_DIRECTSHOW #endif #else // all quicktime, all the time #define OF_VIDEO_CAPTURE_QUICKTIME #endif // core: --------------------------- #include #include #include #include #include #ifndef PI #define PI 3.14159265358979323846 #endif #ifndef TWO_PI #define TWO_PI 6.28318530717958647693 #endif #ifndef M_TWO_PI #define M_TWO_PI 6.28318530717958647693 #endif #ifndef FOUR_PI #define FOUR_PI 12.56637061435917295385 #endif #ifndef HALF_PI #define HALF_PI 1.57079632679489661923 #endif #ifndef DEG_TO_RAD #define DEG_TO_RAD (PI/180.0) #endif #ifndef RAD_TO_DEG #define RAD_TO_DEG (180.0/PI) #endif #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #endif #ifndef ABS #define ABS(x) (((x) < 0) ? -(x) : (x)) #endif #define OF_FILLED 0x01 #define OF_OUTLINE 0x02 #define OF_WINDOW 0 #define OF_FULLSCREEN 1 #define OF_RECTMODE_CORNER 0 #define OF_RECTMODE_CENTER 1 #endif Revision-number: 64 Prop-content-length: 207 Content-length: 207 K 7 svn:log V 104 // zach - needed to add some visual studio specific junk (wide chars) to ofSerial, changed some includes K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-15T18:28:17.785946Z PROPS-END Node-path: communication/ofSerial.cpp Node-kind: file Node-action: change Text-content-length: 5017 Text-content-md5: 7a4463f39284369c66036ce2ab349dc2 Content-length: 5017 #include "ofSerial.h" static bool bInited; #ifdef TARGET_WIN32 static HANDLE hComm; // the handle to the serial port pc #else static int fd; // the handle to the serial port mac #endif //---------------------------------------------------------------- void ofSerialInit (char * portName, int baud){ bInited = false; //--------------------------------------------- #ifdef TARGET_OSX //--------------------------------------------- struct termios toptions; printf("ofSerialInit: opening port %s @ %d bps\n", portName,baud); fd = open(portName, O_RDWR | O_NOCTTY | O_NDELAY); if(fd == -1){ printf("open: unable to open port"); } struct termios options; tcgetattr(fd,&options); switch(baud){ case 9600: cfsetispeed(&options,B9600); cfsetospeed(&options,B9600); break; case 19200: cfsetispeed(&options,B19200); cfsetospeed(&options,B19200); break; case 38400: cfsetispeed(&options,B38400); cfsetospeed(&options,B38400); break; default: cfsetispeed(&options,B9600); cfsetospeed(&options,B9600); break; } options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; tcsetattr(fd,TCSANOW,&options); bInited = true; printf("sucess in opening serial connection\n"); return; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- // open the serial port: // "COM4", etc... hComm=CreateFileA(portName,GENERIC_READ|GENERIC_WRITE,0,0, OPEN_EXISTING,0,0); if(hComm==INVALID_HANDLE_VALUE){ printf("error opening port %s\n please check to see if it's in use, or the right port\n", portName); return; } // now try the settings: COMMCONFIG cfg; DWORD cfgSize; char buf[80]; cfgSize=sizeof(cfg); GetCommConfig(hComm,&cfg,&cfgSize); int bps = baud; sprintf(buf,"baud=%d parity=N data=8 stop=1",bps); // BuildCommDCB on visual studio seems to need this // because BuildCommDCB expects unicode input #if (_MSC_VER) // microsoft visual studio wchar_t bufWide[80]; mbstowcs(bufWide, buf, strlen(buf)); if(!BuildCommDCB(bufWide,&cfg.dcb)){ printf("Can't build comm dcb; %s",buf); } #else if(!BuildCommDCB(buf,&cfg.dcb)){ printf("Can't build comm dcb; %s",buf); } #endif // Set baudrate and bits etc. // Note that BuildCommDCB() clears XON/XOFF and hardware control by default if(!SetCommState(hComm,&cfg.dcb)){ printf("Can't set comm state"); } printf(buf,"bps=%d, xio=%d/%d\n",cfg.dcb.BaudRate,cfg.dcb.fOutX,cfg.dcb.fInX); // Set communication timeouts (NT) COMMTIMEOUTS tOut; GetCommTimeouts(hComm,&tOut); // Make timeout so that: // - return immediately with buffered characters tOut.ReadIntervalTimeout=MAXDWORD; tOut.ReadTotalTimeoutMultiplier=0; tOut.ReadTotalTimeoutConstant=0; SetCommTimeouts(hComm,&tOut); bInited = true; //--------------------------------------------- #endif //--------------------------------------------- } //---------------------------------------------------------------- int ofSerialWrite (char * str){ if (!bInited){ printf("error: serial not inited\n"); return 0; } //--------------------------------------------- #ifdef TARGET_OSX //--------------------------------------------- int len = strlen(str); int numWritten = write(fd, str, len); printf("numWritten %i \n", numWritten); return numWritten; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- DWORD written; int len = (int)strlen(str); if(!WriteFile(hComm,str,len,&written,0)){ printf("Can't write to com port"); return 0; } return (int)written; //--------------------------------------------- #endif //--------------------------------------------- } //---------------------------------------------------------------- int ofSerialRead (char * buffer, int length){ if (!bInited){ printf("error: serial not inited\n"); return 0; } //--------------------------------------------- #ifdef TARGET_OSX //--------------------------------------------- int nRead = read(fd,buffer,length); return nRead; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- DWORD nRead; if (!ReadFile(hComm,buffer,length,&nRead,0)){ printf("trouble reading from port"); return 0; } return nRead; //--------------------------------------------- #endif //--------------------------------------------- } Node-path: communication/ofSerial.h Node-kind: file Node-action: change Text-content-length: 1984 Text-content-md5: 1dd4a338986739717da752542f36d89b Content-length: 1984 #ifndef OF_SERIAL_H #define OF_SERIAL_H #include "ofConstants.h" // this serial code contains small portions of the following code-examples: // --------------------------------------------------- // http://todbot.com/arduino/host/arduino-serial/arduino-serial.c // web.mac.com/miked13/iWeb/Arduino/Serial%20Write_files/main.cpp // www.racer.nl/docs/libraries/qlib/qserial.htm // --------------------------------------------------- // notes: // ---------------------------- // when callign ofSerialSetup("....") you need to pass in // the name of the com port the device is attached to // for example, on a mac, it might look like: // // ofSerialSetup("/dev/tty.usbserial-3B1", 9600) // // and on a pc, it might look like: // // ofSerialSetup("COM4", 9600) // // if you are using an arduino board, for example, // you should check what ports you device is on in the // arduino program // to do: // ---------------------------- // a) support multiple serial connections/ports // (currently supports only one) // b) support blocking / non-blocking // c) support numChars available type functions // ---------------------------- // (also useful, might be this serial example - worth checking out: // http://web.mit.edu/kvogt/Public/osrc/src/ // if has evolved ways of dealing with blocking // and non-blocking instances) // ---------------------------- #if TARGET_OS_MAC #include #include #include #else #include #include #endif #include /* Standard input/output definitions */ #include #include /* String function definitions */ #include /* File control definitions */ #include /* Error number definitions */ #include void ofSerialSetup (char * portName, int baud); int ofSerialWrite (char * str); int ofSerialRead (char * buffer, int length); #endif Revision-number: 65 Prop-content-length: 129 Content-length: 129 K 7 svn:log V 27 // zach - fixes for serial K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-16T16:25:02.787900Z PROPS-END Node-path: communication/ofSerial.cpp Node-kind: file Node-action: change Text-content-length: 5043 Text-content-md5: fbbe38bf636f6d5adb4cfcc41dc90afc Content-length: 5043 #include "ofSerial.h" static bool bInited; #ifdef TARGET_WIN32 static HANDLE hComm; // the handle to the serial port pc #else static int fd; // the handle to the serial port mac #endif //---------------------------------------------------------------- void ofSerialSetup (char * portName, int baud){ bInited = false; //--------------------------------------------- #ifdef TARGET_OSX //--------------------------------------------- struct termios toptions; printf("ofSerialInit: opening port %s @ %d bps\n", portName,baud); fd = open(portName, O_RDWR | O_NOCTTY | O_NDELAY); if(fd == -1){ printf("open: unable to open port"); } struct termios options; tcgetattr(fd,&options); switch(baud){ case 9600: cfsetispeed(&options,B9600); cfsetospeed(&options,B9600); break; case 19200: cfsetispeed(&options,B19200); cfsetospeed(&options,B19200); break; case 38400: cfsetispeed(&options,B38400); cfsetospeed(&options,B38400); break; default: cfsetispeed(&options,B9600); cfsetospeed(&options,B9600); break; } options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; tcsetattr(fd,TCSANOW,&options); bInited = true; printf("sucess in opening serial connection\n"); return; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- // open the serial port: // "COM4", etc... hComm=CreateFileA(portName,GENERIC_READ|GENERIC_WRITE,0,0, OPEN_EXISTING,0,0); if(hComm==INVALID_HANDLE_VALUE){ printf("error opening port %s\n please check to see if it's in use, or the right port\n", portName); return; } // now try the settings: COMMCONFIG cfg; DWORD cfgSize; char buf[80]; cfgSize=sizeof(cfg); GetCommConfig(hComm,&cfg,&cfgSize); int bps = baud; sprintf(buf,"baud=%d parity=N data=8 stop=1",bps); // BuildCommDCB on visual studio seems to need this // because BuildCommDCB expects unicode input #if (_MSC_VER) // microsoft visual studio wchar_t bufWide[80]; mbstowcs(bufWide, buf, strlen(buf)); if(!BuildCommDCB(bufWide,&cfg.dcb)){ printf("ofSerial: unable to build comm dcb; (%s) \n",buf); } #else if(!BuildCommDCB(buf,&cfg.dcb)){ printf("Can't build comm dcb; %s",buf); } #endif // Set baudrate and bits etc. // Note that BuildCommDCB() clears XON/XOFF and hardware control by default if(!SetCommState(hComm,&cfg.dcb)){ printf("Can't set comm state"); } //printf(buf,"bps=%d, xio=%d/%d\n",cfg.dcb.BaudRate,cfg.dcb.fOutX,cfg.dcb.fInX); // Set communication timeouts (NT) COMMTIMEOUTS tOut; GetCommTimeouts(hComm,&tOut); // Make timeout so that: // - return immediately with buffered characters tOut.ReadIntervalTimeout=MAXDWORD; tOut.ReadTotalTimeoutMultiplier=0; tOut.ReadTotalTimeoutConstant=0; SetCommTimeouts(hComm,&tOut); bInited = true; //--------------------------------------------- #endif //--------------------------------------------- } //---------------------------------------------------------------- int ofSerialWrite (char * str){ if (!bInited){ printf("error: serial not inited\n"); return 0; } //--------------------------------------------- #ifdef TARGET_OSX //--------------------------------------------- int len = strlen(str); int numWritten = write(fd, str, len); printf("numWritten %i \n", numWritten); return numWritten; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- DWORD written; int len = (int)strlen(str); if(!WriteFile(hComm,str,len,&written,0)){ printf("Can't write to com port"); return 0; } return (int)written; //--------------------------------------------- #endif //--------------------------------------------- } //---------------------------------------------------------------- int ofSerialRead (char * buffer, int length){ if (!bInited){ printf("error: serial not inited\n"); return 0; } //--------------------------------------------- #ifdef TARGET_OSX //--------------------------------------------- int nRead = read(fd,buffer,length); return nRead; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- DWORD nRead; if (!ReadFile(hComm,buffer,length,&nRead,0)){ printf("trouble reading from port"); return 0; } return (int)nRead; //--------------------------------------------- #endif //--------------------------------------------- } Node-path: ofMain.h Node-kind: file Node-action: change Text-content-length: 631 Text-content-md5: 161f9300ef5ed291c4cd7bbe8c9e3a62 Content-length: 631 #ifndef OF_MAIN_H #define OF_MAIN_H //-------------------------- // utils #include "ofConstants.h" #include "ofMath.h" #include "ofUtils.h" //-------------------------- // communication #include "ofSerial.h" //-------------------------- // graphics #include "ofTexture.h" #include "ofTrueTypeFont.h" #include "ofGraphics.h" #include "ofImage.h" //-------------------------- // app #include "ofSimpleApp.h" #include "ofAppRunner.h" //-------------------------- // audio #include "ofAudioStream.h" #include "ofSoundPlayer.h" //-------------------------- // video #include "ofVideoGrabber.h" #include "ofVideoPlayer.h" #endif Revision-number: 66 Prop-content-length: 168 Content-length: 168 K 7 svn:log V 66 //zach - renamed ofAudioStream to ofSoundStream to make more sense K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-16T16:28:10.964001Z PROPS-END Node-path: ofMain.h Node-kind: file Node-action: change Text-content-length: 631 Text-content-md5: 4f548773a1b787453318870d4ec00ab4 Content-length: 631 #ifndef OF_MAIN_H #define OF_MAIN_H //-------------------------- // utils #include "ofConstants.h" #include "ofMath.h" #include "ofUtils.h" //-------------------------- // communication #include "ofSerial.h" //-------------------------- // graphics #include "ofTexture.h" #include "ofTrueTypeFont.h" #include "ofGraphics.h" #include "ofImage.h" //-------------------------- // app #include "ofSimpleApp.h" #include "ofAppRunner.h" //-------------------------- // audio #include "ofSoundStream.h" #include "ofSoundPlayer.h" //-------------------------- // video #include "ofVideoGrabber.h" #include "ofVideoPlayer.h" #endif Node-path: sound/ofSoundStream.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 3594 Text-content-md5: 2c3b750c8e8461c812bef5647e46d4a6 Content-length: 3604 PROPS-END #include "ofSoundStream.h" #include "rtAudio.h" //----------------------------------- static variables: static ofSimpleApp * OFSAptr; RtAudio * audio; int nInputChannels; int nOutputChannels; int receiveAudioBufferAndCallSimpleApp(char *buffer, int bufferSize, void *data); //------------------------------------------------------------------------------ int receiveAudioBufferAndCallSimpleApp(char *buffer, int bufferSize, void *data){ // rtAudio uses a system by which the audio // can be of different formats // char, float, etc. // we choose float float * fPtr = (float *)buffer; // [zach] memset output to zero before output call // this is because of how rtAudio works: duplex w/ one callback // you need to cut in the middle. if the simpleApp // doesn't produce audio, we pass silence instead of duplex... if (nInputChannels > 0){ OFSAptr->audioReceived(fPtr, bufferSize, nInputChannels); memset(fPtr, 0, bufferSize * nInputChannels * sizeof(float)); } if (nOutputChannels > 0) OFSAptr->audioRequested(fPtr, bufferSize, nOutputChannels); return 0; } //--------------------------------------------------------- void ofSoundStreamSetup(int nOutputs, int nInputs, ofSimpleApp * OFSA){ ofSoundStreamSetup(nOutputs, nInputs, OFSA, 44100, 256, 4); } //--------------------------------------------------------- void ofSoundStreamSetup(int nOutputs, int nInputs, ofSimpleApp * OFSA, int sampleRate, int bufferSize, int nBuffers){ nInputChannels = nInputs; nOutputChannels = nOutputs; int device = 0; // default OFSAptr = OFSA; bufferSize = ofNextPow2(bufferSize); // must be pow2 try { audio = new RtAudio(); audio->openStream( device, nOutputs, device, nInputs, RTAUDIO_FLOAT32, sampleRate, &bufferSize, nBuffers); } catch (RtError &error) { error.printMessage(); //std::exit(EXIT_FAILURE); // need case here } try { audio->setStreamCallback(&receiveAudioBufferAndCallSimpleApp, (void *)NULL); audio->startStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofSoundStreamStop(){ try { audio->stopStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofSoundStreamStart(){ try{ audio->startStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofSoundStreamEnd(){ try { audio->stopStream(); audio->closeStream(); } catch (RtError &error) { error.printMessage(); } } //--------------------------------------------------------- void ofSoundStreamListDevices(){ RtAudio *audioTemp = 0; try { audioTemp = new RtAudio(); } catch (RtError &error) { error.printMessage(); } int devices = audioTemp->getDeviceCount(); RtAudioDeviceInfo info; for (int i=1; i<=devices; i++) { try { info = audioTemp->getDeviceInfo(i); } catch (RtError &error) { error.printMessage(); break; } std::cout << "device = " << i << " (" << info.name << ")\n"; if (info.isDefault) std::cout << "----* default ----* \n"; std::cout << "maximum output channels = " << info.outputChannels << "\n"; std::cout << "maximum input channels = " << info.inputChannels << "\n"; std::cout << "-----------------------------------------\n"; } delete audioTemp; } Node-path: sound/ofSoundStream.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 448 Text-content-md5: c538eefca6edd8aa89364492c0e82292 Content-length: 458 PROPS-END #ifndef _OF_SOUND_STREAM #define _OF_SOUND_STREAM #include "ofMain.h" #include "ofSimpleApp.h" void ofSoundStreamSetup(int nOutputChannels, int nInputChannels, ofSimpleApp * OFSA); void ofSoundStreamSetup(int nOutputChannels, int nInputChannels, ofSimpleApp * OFSA, int sampleRate, int bufferSize, int nBuffers); void ofSoundStreamStop(); void ofSoundStreamStart(); void ofSoundStreamEnd(); void ofSoundStreamListDevices(); #endif Node-path: sound/ofAudioStream.h Node-action: delete Node-path: sound/ofAudioStream.cpp Node-action: delete Revision-number: 67 Prop-content-length: 123 Content-length: 123 K 7 svn:log V 21 Theo: OSX warning fix K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-04-16T17:17:04.991112Z PROPS-END Node-path: utils/ofConstants.h Node-kind: file Node-action: change Text-content-length: 3311 Text-content-md5: c32ebf67aea3cd311377019f18dbf6a4 Content-length: 3311 #ifndef OF_CONSTANTS #define OF_CONSTANTS //------------------------------- // pc or mac ? // soon: pc, mac or linux... #ifndef __APPLE_CC__ #define TARGET_WIN32 #else #define TARGET_OSX #endif //------------------------------- // then the the platform specific includes: #ifdef TARGET_WIN32 #include #include "GLee.h" #include "glut.h" #define __WINDOWS_DS__ #define __WINDOWS_MM__ #if (_MSC_VER) // microsoft visual studio #pragma warning(disable : 4996) // disable all deprecation warnings #pragma warning(disable : 4068) // unknown pragmas #pragma warning(disable : 4101) // unreferenced local variable #pragma warning(disable : 4312) // type cast conversion (in qt vp) #pragma warning(disable : 4311) // type cast pointer truncation (qt vp) #endif #define TARGET_LITTLE_ENDIAN // intel cpu // some gl.h files, like dev-c++, are old - this is pretty universal #ifndef GL_BGR_EXT #define GL_BGR_EXT 0x80E0 #endif // #define WIN32_HIGH_RES_TIMING // note: this is experimental! // uncomment to turn this on (only for windows machines) // if you want to try setting the timer to be high resolution // this could make camera grabbing and other low level // operations quicker, but you must quit the app normally, // ie, using "esc", rather than killing the process or closing // the console window in order to set the timer resolution back // to normal (since the high res timer might give the OS // problems) // info: http://www.geisswerks.com/ryan/FAQS/timing.html #endif #ifdef TARGET_OSX #ifndef __MACOSX_CORE__ #define __MACOSX_CORE__ #endif #include #include "GLee.h" #include #if defined(__LITTLE_ENDIAN__) #define TARGET_LITTLE_ENDIAN // intel cpu #endif #endif #ifndef __MWERKS__ #define OF_EXIT_APP(val) exit(val); #else #define OF_EXIT_APP(val) std::exit(val); #endif // comment out this line, if you'd like to use the // quicktime capture interface on windows // if not, we default to videoInput library for // direct show capture, which is quite #define OF_SWITCH_TO_DSHOW_FOR_WIN_VIDCAP #ifdef OF_SWITCH_TO_DSHOW_FOR_WIN_VIDCAP #ifdef TARGET_OSX #define OF_VIDEO_CAPTURE_QUICKTIME #else #define OF_VIDEO_CAPTURE_DIRECTSHOW #endif #else // all quicktime, all the time #define OF_VIDEO_CAPTURE_QUICKTIME #endif // core: --------------------------- #include #include #include #include #include #ifndef PI #define PI 3.14159265358979323846 #endif #ifndef TWO_PI #define TWO_PI 6.28318530717958647693 #endif #ifndef M_TWO_PI #define M_TWO_PI 6.28318530717958647693 #endif #ifndef FOUR_PI #define FOUR_PI 12.56637061435917295385 #endif #ifndef HALF_PI #define HALF_PI 1.57079632679489661923 #endif #ifndef DEG_TO_RAD #define DEG_TO_RAD (PI/180.0) #endif #ifndef RAD_TO_DEG #define RAD_TO_DEG (180.0/PI) #endif #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #endif #ifndef ABS #define ABS(x) (((x) < 0) ? -(x) : (x)) #endif #define OF_FILLED 0x01 #define OF_OUTLINE 0x02 #define OF_WINDOW 0 #define OF_FULLSCREEN 1 #define OF_RECTMODE_CORNER 0 #define OF_RECTMODE_CENTER 1 #endif Revision-number: 68 Prop-content-length: 165 Content-length: 165 K 7 svn:log V 63 theo - converted char * to string and new serial modes for os x K 10 svn:author V 7 ofadmin K 8 svn:date V 27 2007-06-30T19:00:23.667010Z PROPS-END Node-path: communication/ofSerial.cpp Node-kind: file Node-action: change Text-content-length: 6119 Text-content-md5: 20bfc41254cb1b5d7e240cf7fef4a990 Content-length: 6119 #include "ofSerial.h" static bool bInited; #ifdef TARGET_WIN32 static HANDLE hComm; // the handle to the serial port pc #else static int fd; // the handle to the serial port mac #endif //---------------------------------------------------------------- void ofSerialSetup (string portName, int baud){ bInited = false; //--------------------------------------------- #ifdef TARGET_OSX //--------------------------------------------- struct termios toptions; printf("ofSerialInit: opening port %s @ %d bps\n", portName.c_str(), baud); fd = open(portName.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); if(fd == -1){ printf("open: unable to open port"); } struct termios options; tcgetattr(fd,&options); switch(baud){ case 300: cfsetispeed(&options,B300); cfsetospeed(&options,B300); break; case 1200: cfsetispeed(&options,B1200); cfsetospeed(&options,B1200); break; case 2400: cfsetispeed(&options,B2400); cfsetospeed(&options,B2400); break; case 4800: cfsetispeed(&options,B4800); cfsetospeed(&options,B4800); break; case 9600: cfsetispeed(&options,B9600); cfsetospeed(&options,B9600); break; case 14400: cfsetispeed(&options,B14400); cfsetospeed(&options,B14400); break; case 19200: cfsetispeed(&options,B19200); cfsetospeed(&options,B19200); break; case 28800: cfsetispeed(&options,B28800); cfsetospeed(&options,B28800); break; case 38400: cfsetispeed(&options,B38400); cfsetospeed(&options,B38400); break; case 57600: cfsetispeed(&options,B57600); cfsetospeed(&options,B57600); break; case 115200: cfsetispeed(&options,B115200); cfsetospeed(&options,B115200); break; default: cfsetispeed(&options,B9600); cfsetospeed(&options,B9600); printf("ofSerialInit: cannot set %i baud setting baud to 9600\n", baud); break; } options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; tcsetattr(fd,TCSANOW,&options); bInited = true; printf("sucess in opening serial connection\n"); return; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- // open the serial port: // "COM4", etc... hComm=CreateFileA(portName.c_str(),GENERIC_READ|GENERIC_WRITE,0,0, OPEN_EXISTING,0,0); if(hComm==INVALID_HANDLE_VALUE){ printf("error opening port %s\n please check to see if it's in use, or the right port\n", portName); return; } // now try the settings: COMMCONFIG cfg; DWORD cfgSize; char buf[80]; cfgSize=sizeof(cfg); GetCommConfig(hComm,&cfg,&cfgSize); int bps = baud; sprintf(buf,"baud=%d parity=N data=8 stop=1",bps); // BuildCommDCB on visual studio seems to need this // because BuildCommDCB expects unicode input #if (_MSC_VER) // microsoft visual studio wchar_t bufWide[80]; mbstowcs(bufWide, buf, strlen(buf)); if(!BuildCommDCB(bufWide,&cfg.dcb)){ printf("ofSerial: unable to build comm dcb; (%s) \n",buf); } #else if(!BuildCommDCB(buf,&cfg.dcb)){ printf("Can't build comm dcb; %s",buf); } #endif // Set baudrate and bits etc. // Note that BuildCommDCB() clears XON/XOFF and hardware control by default if(!SetCommState(hComm,&cfg.dcb)){ printf("Can't set comm state"); } //printf(buf,"bps=%d, xio=%d/%d\n",cfg.dcb.BaudRate,cfg.dcb.fOutX,cfg.dcb.fInX); // Set communication timeouts (NT) COMMTIMEOUTS tOut; GetCommTimeouts(hComm,&tOut); // Make timeout so that: // - return immediately with buffered characters tOut.ReadIntervalTimeout=MAXDWORD; tOut.ReadTotalTimeoutMultiplier=0; tOut.ReadTotalTimeoutConstant=0; SetCommTimeouts(hComm,&tOut); bInited = true; //--------------------------------------------- #endif //--------------------------------------------- } //---------------------------------------------------------------- int ofSerialWrite (string str){ if (!bInited){ printf("error: serial not inited\n"); return 0; } //--------------------------------------------- #ifdef TARGET_OSX //--------------------------------------------- int len = str.length(); int numWritten = write(fd, str.c_str(), len); printf("numWritten %i \n", numWritten); return numWritten; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- DWORD written; int len = str.length(); if(!WriteFile(hComm, str.c_str(), len, &written,0)){ printf("Can't write to com port"); return 0; } return (int)written; //--------------------------------------------- #endif //--------------------------------------------- } //---------------------------------------------------------------- int ofSerialRead (string & buffer, int length){ if (!bInited){ printf("error: serial not inited\n"); return 0; } char tmpBuff[1024]; memset(tmpBuff, 0, 1024); //--------------------------------------------- #ifdef TARGET_OSX //--------------------------------------------- int nRead = read(fd, tmpBuff,length); if( strlen(tmpBuff) != 0)buffer = tmpBuff;; return nRead; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- DWORD nRead; if (!ReadFile(hComm,tmpBuff,length,&nRead,0)){ printf("trouble reading from port\n"); return 0; } if( strlen(tmpBuff) != 0)buffer = tmpBuff;; return (int)nRead; //--------------------------------------------- #endif //--------------------------------------------- } Node-path: communication/ofSerial.h Node-kind: file Node-action: change Text-content-length: 1986 Text-content-md5: 0b683eaee28b57e2113dcef971137539 Content-length: 1986 #ifndef OF_SERIAL_H #define OF_SERIAL_H #include "ofConstants.h" // this serial code contains small portions of the following code-examples: // --------------------------------------------------- // http://todbot.com/arduino/host/arduino-serial/arduino-serial.c // web.mac.com/miked13/iWeb/Arduino/Serial%20Write_files/main.cpp // www.racer.nl/docs/libraries/qlib/qserial.htm // --------------------------------------------------- // notes: // ---------------------------- // when callign ofSerialSetup("....") you need to pass in // the name of the com port the device is attached to // for example, on a mac, it might look like: // // ofSerialSetup("/dev/tty.usbserial-3B1", 9600) // // and on a pc, it might look like: // // ofSerialSetup("COM4", 9600) // // if you are using an arduino board, for example, // you should check what ports you device is on in the // arduino program // to do: // ---------------------------- // a) support multiple serial connections/ports // (currently supports only one) // b) support blocking / non-blocking // c) support numChars available type functions // ---------------------------- // (also useful, might be this serial example - worth checking out: // http://web.mit.edu/kvogt/Public/osrc/src/ // if has evolved ways of dealing with blocking // and non-blocking instances) // ---------------------------- #if TARGET_OS_MAC #include #include #include #else #include #include #endif #include /* Standard input/output definitions */ #include #include /* String function definitions */ #include /* File control definitions */ #include /* Error number definitions */ #include void ofSerialSetup (string portName, int baud); int ofSerialWrite (string str); int ofSerialRead (string & buffer, int length); #endif Node-path: graphics/ofGraphics.cpp Node-kind: file Node-action: change Text-content-length: 9048 Text-content-md5: 86eb78b0053bae5df8a91f5e2557e6f1 Content-length: 9048 #include "ofGraphics.h" //---------------------------------------------------------- // static GLuint precachedCircle; static float drawMode = OF_FILLED; static bool bSetupCircle = false; float bgColor[4] = {0,0,0,0}; void setupCircle(); bool bSmoothHinted = false; bool bBakgroundAuto = true; int cornerMode = OF_RECTMODE_CORNER; //---------------------------------------------------------- void ofSetRectMode(int mode){ if (mode == OF_RECTMODE_CORNER) cornerMode = OF_RECTMODE_CORNER; else if (mode == OF_RECTMODE_CENTER) cornerMode = OF_RECTMODE_CENTER; } //---------------------------------------------------------- int ofGetRectMode(){ return cornerMode; } //---------------------------------------------------------- void ofSetBackgroundAuto(bool bAuto){ bBakgroundAuto = bAuto; } //---------------------------------------------------------- bool ofbClearBg(){ return bBakgroundAuto; } //---------------------------------------------------------- float * ofBgColorPtr(){ return bgColor; } //---------------------------------------------------------- bool ofbOriginBottomLeft(){ return false; // because people are certainly asking for it! } //---------------------------------------------------------- void ofBackground(int r, int g, int b){ bgColor[0] = (float)r / (float)255.0f; bgColor[1] = (float)g / (float)255.0f; bgColor[2] = (float)b / (float)255.0f; bgColor[3] = 1.0f; // if we are in not-auto mode, then clear with a bg call... if (ofbClearBg() == false){ glClearColor(bgColor[0],bgColor[1],bgColor[2], bgColor[3]); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } } //---------------------------------------------------------- void ofNoFill(){ drawMode = OF_OUTLINE; }; //---------------------------------------------------------- void ofFill(){ drawMode = OF_FILLED; }; //---------------------------------------------------------- void startSmoothing(){ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void endSmoothing(){ glPopAttrib(); } //---------------------------------------------------------- void setupCircle(){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)CIRC_RESOLUTION; for (float i = 0; i < CIRC_RESOLUTION; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } //---------------------------------------------------------- void ofSetCircleResolution(int res){ if (res > 1){ precachedCircle = glGenLists(1); glNewList(precachedCircle, GL_COMPILE); float angle = 0.0f; float angleAdder = M_TWO_PI / (float)res; for (float i = 0; i < res; i++){ glVertex2f( cos(angle), sin(angle)); angle += angleAdder; } glEndList(); bSetupCircle = true; } } //---------------------------------------------------------- void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3){ // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); // draw: glBegin( (drawMode == OF_FILLED) ? GL_TRIANGLES : GL_LINE_LOOP); glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofCircle(float x,float y, float radius){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(radius, radius, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofEllipse(float x, float y, float width, float height){ if (!bSetupCircle) setupCircle(); // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); // draw: glPushMatrix(); glTranslatef(x, y, 0); glScalef(width, height, 1); glBegin( (drawMode == OF_FILLED) ? GL_POLYGON : GL_LINE_LOOP); glCallList(precachedCircle); glEnd(); glPopMatrix(); // back to normal, if smoothness is on if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofLine(float x1,float y1,float x2,float y2){ // use smoothness, if requested: if (bSmoothHinted) startSmoothing(); // draw: glBegin( GL_LINES ); glVertex2f(x1,y1); glVertex2f(x2,y2); glEnd(); // back to normal, if smoothness is on if (bSmoothHinted) endSmoothing(); } //---------------------------------------------------------- void ofRect(float x,float y,float w,float h){ // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) startSmoothing(); if (cornerMode == OF_RECTMODE_CENTER){ glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x-w/2,y-h/2); glVertex2f(x+w/2,y-h/2); glVertex2f(x+w/2,y+h/2); glVertex2f(x-w/2,y+h/2); glEnd(); } else { glBegin( (drawMode == OF_FILLED) ? GL_QUADS : GL_LINE_LOOP); glVertex2f(x,y); glVertex2f(x+w,y); glVertex2f(x+w,y+h); glVertex2f(x,y+h); glEnd(); } // use smoothness, if requested: if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); glColor3f(r,g,b); } //---------------------------------------------------------- void ofSetColor(int _r, int _g, int _b, int _a){ float r = (float)_r / 255.0f; r = MAX(0,MIN(r,1.0f)); float g = (float)_g / 255.0f; g = MAX(0,MIN(g,1.0f)); float b = (float)_b / 255.0f; b = MAX(0,MIN(b,1.0f)); float a = (float)_a / 255.0f; a = MAX(0,MIN(a,1.0f)); glColor4f(r,g,b,a); } //---------------------------------------------------------- void ofSetColor(int hexColor){ int r = (hexColor >> 16) & 0xff; int g = (hexColor >> 8) & 0xff; int b = (hexColor >> 0) & 0xff; ofSetColor(r,g,b); } //---------------------------------------------------------- void ofEnableAlphaBlending(){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //---------------------------------------------------------- void ofDisableAlphaBlending(){ glDisable(GL_BLEND); } //---------------------------------------------------------- void ofEnableSmoothing(){ // please see: // http://www.opengl.org/resources/faq/technical/rasterization.htm bSmoothHinted = true; } //---------------------------------------------------------- void ofDisableSmoothing(){ bSmoothHinted = false; } //-------------------------------------------------- void ofDrawBitmapString(string textString, float x, float y){ //--------------------------------------------------- // for now this is fixed to the 8_BY_13 glut character // http://pyopengl.sourceforge.net/documentation/manual/glutBitmapCharacter.3GLUT.html //--------------------------------------------------- int len = textString.length(); float yOffset = 0; float fontSize = 8.0f; glRasterPos2f(x,y); bool bOrigin = ofbOriginBottomLeft(); for(int c = 0; c < len; c++) { if(textString[c] == '\n') { yOffset += bOrigin ? -1 : 1 * (fontSize*1.7); glRasterPos2f(x,y + (int)yOffset); } else if (textString[c] >= 32){ // < 32 = control characters - don't draw // solves a bug with control characters // getting drawn when they ought to not be glutBitmapCharacter(GLUT_BITMAP_8_BY_13, textString[c]); } } } //---------------------------------------------------------- void ofSetupScreen(){ int w, h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); float halfFov, theTan, screenFov, aspect; screenFov = 60.0f; float eyeX = (float)w / 2.0; float eyeY = (float)h / 2.0; halfFov = PI * screenFov / 360.0; theTan = tanf(halfFov); float dist = eyeY / theTan; float nearDist = dist / 10.0; // near / far clip plane float farDist = dist * 10.0; aspect = (float)w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(screenFov, aspect, nearDist, farDist); gluLookAt(eyeX, eyeY, dist, eyeX, eyeY, 0.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (!ofbOriginBottomLeft()){ glScalef(1, -1, 1); // invert Y axis so increasing Y goes down. glTranslatef(0, -h, 0); // shift origin up to upper-left corner. } } Node-path: graphics/ofGraphics.h Node-kind: file Node-action: change Text-content-length: 1621 Text-content-md5: 7b317805e9ad064d4f65384824ed923c Content-length: 1621 #ifndef OF_GEOM #define OF_GEOM #include "ofConstants.h" #define CIRC_RESOLUTION 22 // 22 pts for a circle... // bg color float * ofBgColorPtr(); void ofBackground(int r, int g, int b); // user's access to settings (bgAuto, corner mode): void ofSetBackgroundAuto(bool bManual); // default is true void ofSetRectMode(int mode); // set the mode, either to OF_RECTMODE_CORNER or OF_RECTMODE_CENTER // OF's access to settings (bgAuto, origin, corner mode): bool ofbOriginBottomLeft(); bool ofbClearBg(); int ofGetRectMode(); // default is OF_RECTMODE_CORNER // geometry void ofTriangle(float x1,float y1,float x2,float y2,float x3, float y3); void ofCircle(float x,float y, float radius); void ofEllipse(float x, float y, float width, float height); void ofLine(float x1,float y1,float x2,float y2); void ofRect(float x1,float y1,float w, float h); void ofSetCircleResolution(int res); // if there 22 is a problem, you can change it here // drawing options void ofNoFill(); void ofFill(); // color options void ofSetColor(int r, int g, int b); // 0-255 void ofSetColor(int r, int g, int b, int a); // 0-255 void ofSetColor(int hexColor); // hex, like web 0xFF0033; // transparency void ofEnableAlphaBlending(); // this just turns on and off opengl blending, the common mode void ofDisableAlphaBlending(); // smooth void ofEnableSmoothing(); void ofDisableSmoothing(); // bitmapped type // ** note, this uses glDrawPixels and may be S L 0 W on some graphics cards void ofDrawBitmapString(string textString, float x, float y); // screen coordinate things... void ofSetupScreen(); #endif Node-path: graphics/ofImage.cpp Node-kind: file Node-action: change Text-content-length: 10388 Text-content-md5: 3df2eaeb4bfaf4abd1b28fdcc5b5d143 Content-length: 10388 #include "ofImage.h" #include "freeImage.h" static bool bFreeImageInited = false; //----------------------------------------- // class freeImageBitmap{ public: FIBITMAP * bmp; // when OF users ask for pixels // we will get them contiguous memory // ie, non-aligned // see the pixel access chapter of the freeImage pdf // these pixel will also be RGB // on both platforms // bmp will be RGB / BGR depending // on the endianess of the platform. unsigned char * pixels; //----------------------- freeImageBitmap(){ bmp = NULL; } //----------------------- //swap my image out in a (hopefully) non-memory leakish way void swap(FIBITMAP *dst) { if(dst == NULL) return; if(bmp != NULL) FreeImage_Unload(bmp); bmp = dst; } //----------------------- void setSize(FREE_IMAGE_TYPE image_type, WORD width, WORD height, WORD bpp) { if(bmp == NULL) { FreeImage_Unload(bmp); } bmp = FreeImage_AllocateT(image_type, width, height, bpp); } //----------------------- bool isValid(){ return (bmp != NULL) ? true : false; } }; //---------------------------------------------------------- ofImage::ofImage(){ //----------------------- init free image if necessary if (!bFreeImageInited){ FreeImage_Initialise(); bFreeImageInited = true; } //----------------------- IMG = new freeImageBitmap(); width = height = bpp = 0; type = OF_IMAGE_UNDEFINED; bUseTexture = true; // the default is, yes, use a texture bAllocatedPixels = false; } //---------------------------------------------------------- void ofImage::grabScreen(int _x, int _y, int _w, int _h){ if (IMG->isValid()){ // flip y if origin is top: if (!ofbOriginBottomLeft()){ int height = ofGetHeight(); _y = height - _y; _y -= _h; // top, bottom issues } if (!(width == _w && height == _h)){ resize(_w, _h); } unsigned char * pixels = (unsigned char *)FreeImage_GetBits(IMG->bmp); switch (bpp){ case 8: glReadPixels(_x, _y, _w, _h, GL_LUMINANCE,GL_UNSIGNED_BYTE, pixels); break; case 24: #ifdef TARGET_LITTLE_ENDIAN glReadPixels(_x, _y, _w, _h, GL_BGR_EXT,GL_UNSIGNED_BYTE, pixels); #else glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); #endif break; case 32: glReadPixels(_x, _y, _w, _h, GL_RGBA,GL_UNSIGNED_BYTE, pixels); break; } // we will need to flip images // if the 0,0 position is in the top left: if (!ofbOriginBottomLeft()){ FreeImage_FlipVertical(IMG->bmp); } update(); } else { // assume that this is color.... IMG->setSize(FIT_BITMAP, _w, _h, 24); unsigned char * pixels = (unsigned char *)FreeImage_GetBits(IMG->bmp); // flip y if origin is top: if (!ofbOriginBottomLeft()){ int height = ofGetHeight(); _y = height - _y; _y -= _h; // top, bottom issues } #ifdef TARGET_LITTLE_ENDIAN glReadPixels(_x, _y, _w, _h, GL_BGR_EXT,GL_UNSIGNED_BYTE, pixels); #else glReadPixels(_x, _y, _w, _h, GL_RGB,GL_UNSIGNED_BYTE, pixels); #endif // we will need to flip images // if the 0,0 position is in the top left: if (!ofbOriginBottomLeft()){ FreeImage_FlipVertical(IMG->bmp); } update(); } } //---------------------------------------------------------- void ofImage::allocate(int _w, int _h, int _type){ int newbpp; switch (_type){ case OF_IMAGE_GRAYSCALE: newbpp = 8; break; case OF_IMAGE_COLOR: newbpp = 24; break; case OF_IMAGE_COLOR_ALPHA: newbpp = 32; break; default: newbpp = 24; break; } IMG->setSize(FIT_BITMAP, _w, _h, newbpp); } //---------------------------------------------------------- void ofImage::update(){ width = FreeImage_GetWidth(IMG->bmp); height = FreeImage_GetHeight(IMG->bmp); bpp = FreeImage_GetBPP(IMG->bmp); // this is check to see if it's a gif bool bNoPallette = (FreeImage_GetColorType(IMG->bmp) != FIC_PALETTE); switch (bpp){ case 8: if (bNoPallette) { //!bUsesPallette){ type = OF_IMAGE_GRAYSCALE; } else { // convert to RGB - // this is a gif (or other) with 256 colors, not b&w. setImageType(OF_IMAGE_COLOR); } break; case 24: type = OF_IMAGE_COLOR; break; case 32: type = OF_IMAGE_COLOR_ALPHA; break; default: // if we've got here, something is wrong, the image // is not 8bit, 24bit or 32bit, so let's at least // make it color: setImageType(OF_IMAGE_COLOR); break; } //---------------------------------- // now, since the "freeImage" memory is padded // (see freeImage392.pdf - "Pixel access functions") // lets get the data into contiguous memory - to make it easier // for folks to work with... if (IMG->pixels != NULL && bAllocatedPixels == true) delete IMG->pixels; // delete anything that might have existed int byteCount = bpp / 8; // bytes ber pixel (not bits per pixel) IMG->pixels = new unsigned char[width*height*byteCount]; //allocate that memory for the image (contiguously) bAllocatedPixels = true; FreeImage_ConvertToRawBits(IMG->pixels, IMG->bmp, width*byteCount, bpp, FI_RGBA_RED_MASK,FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE); // get bits #ifdef TARGET_LITTLE_ENDIAN if (type == OF_IMAGE_COLOR) swapChannels(false); if (type == OF_IMAGE_COLOR_ALPHA) swapChannels(true); #endif //---------------------------------- // if we are using a texture and the ofImage is upadate, // allocate (or reallocate) the texture and upload the data // I will upload from the contguous memory, and use pixelStorei to // make sure opengl knows I am contiguous. if (bUseTexture){ switch (type){ case OF_IMAGE_GRAYSCALE: tex.allocate(width,height,GL_LUMINANCE); tex.loadData(IMG->pixels, width,height, GL_LUMINANCE); break; case OF_IMAGE_COLOR: tex.allocate(width,height,GL_RGB); tex.loadData(IMG->pixels, width,height, GL_RGB); break; case OF_IMAGE_COLOR_ALPHA: tex.allocate(width,height,GL_RGBA); tex.loadData(IMG->pixels, width,height, GL_RGBA); break; } } } //---------------------------------------------------------- void ofImage::loadImage(string fileName){ bool bLoaded = false; //----------------------------- find the format FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName.c_str(), 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName.c_str()); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { if(IMG->isValid()) { FreeImage_Unload(IMG->bmp); } IMG->bmp = FreeImage_Load(fif, fileName.c_str(), 0); bLoaded = true; if(!IMG->isValid()){ bLoaded = false; } } //----------------------------- if (bLoaded){ // we will need to flip images // if the 0,0 position is in the top left: if (!ofbOriginBottomLeft()){ FreeImage_FlipVertical(IMG->bmp); } update(); } else { width = height = bpp = 0; } } //---------------------------------------------------------- void ofImage::saveImage(string fileName){ if (IMG->isValid()){ FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName.c_str(), 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName.c_str()); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { // ok, if we are 0,0 top left, flip once, save and flip back // this is because the native format for freeImage is 0,0 lower left // there be a smarter way to do this (ie, just draw upside down) // as opposed to continually if (!ofbOriginBottomLeft()){ FreeImage_FlipVertical(IMG->bmp); } FreeImage_Save(fif, IMG->bmp, fileName.c_str(), 0); if (!ofbOriginBottomLeft()){ FreeImage_FlipVertical(IMG->bmp); } } } } //---------------------------------------------------------- unsigned char * ofImage::getPixels(){ // be careful! might not be allocated. you need to check for null... if (IMG->isValid()){ return (unsigned char *)IMG->pixels; } else { return NULL; } } //---------------------------------------------------------- void ofImage::resize(int newWidth, int newHeight){ if (IMG->isValid()){ FIBITMAP * scaledBmp = FreeImage_Rescale(IMG->bmp, newWidth, newHeight, FILTER_BICUBIC); IMG->swap(scaledBmp); update(); } } //---------------------------------------------------------- void ofImage::setImageType(int newType){ if (IMG->isValid()){ switch (newType){ //------------------------------------ case OF_IMAGE_GRAYSCALE: if (type != OF_IMAGE_GRAYSCALE){ FIBITMAP * convertedBmp = FreeImage_ConvertToGreyscale(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_GRAYSCALE; } break; //------------------------------------ case OF_IMAGE_COLOR: if (type != OF_IMAGE_COLOR){ FIBITMAP * convertedBmp = FreeImage_ConvertTo24Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR; } break; //------------------------------------ case OF_IMAGE_COLOR_ALPHA: if (type != OF_IMAGE_COLOR_ALPHA){ FIBITMAP * convertedBmp = FreeImage_ConvertTo32Bits(IMG->bmp); IMG->swap(convertedBmp); type = OF_IMAGE_COLOR_ALPHA; } break; } update(); } } //------------------------------------ void ofImage::swapChannels(bool bAlpha){ // this swaps the red and blue channel of an image // turning an bgr image to rgb and vice versa... // needed because of windows byte order... if (IMG->isValid()){ unsigned char * pixels = IMG->pixels; unsigned char temp; int totalPixels = width*height; // unoptimized for now... if (bAlpha == false){ for (int i = 0; i < totalPixels; i++){ temp = pixels[i*3 + 2]; pixels[i*3 + 2] = pixels[i*3]; pixels[i*3] = temp; } } else { for (int i = 0; i < totalPixels; i++){ temp = pixels[i*4]; pixels[i*4] = pixels[i*4 + 2]; pixels[i*4 + 2] = temp; } } } } //------------------------------------ void ofImage::setUseTexture(bool bUse){ bUseTexture = bUse; } //------------------------------------ void ofImage::draw(float _x, float _y, float _w, float _h){ if (bUseTexture){ tex.draw(_x, _y, _w, _h); } } //------------------------------------ void ofImage::draw(float x, float y){ draw(x,y,width,height); } Node-path: graphics/ofImage.h Node-kind: file Node-action: change Text-content-length: 1410 Text-content-md5: 4ab788c6ce887751db6216de4a014e21 Content-length: 1410 #ifndef _OF_IMAGE_H_ #define _OF_IMAGE_H_ #include "ofConstants.h" #include "ofTexture.h" #include "ofGraphics.h" #include "ofUtils.h" #define OF_IMAGE_GRAYSCALE 0x00 #define OF_IMAGE_COLOR 0x01 #define OF_IMAGE_COLOR_ALPHA 0x02 #define OF_IMAGE_UNDEFINED 0x03 //------------------------- // forward class declaration, something // we will need in order to compile "OF" as a lib // so that you don't need freeImage, quicktime, etc.. class freeImageBitmap; //------------------------- class ofImage { public : ofImage(); void loadImage(string fileName); void saveImage(string fileName); void allocate(int w, int h, int type); unsigned char * getPixels(); // up to you to get this right void setImageType(int type); void resize(int newWidth, int newHeight); void grabScreen(int x, int y, int w, int h); // grab pixels from opengl, using glreadpixels int type; // what type of image it is (as above) int width, height, bpp; // w,h, bits per pixel void setUseTexture(bool bUse); void draw(float x, float y, float w, float h); void draw(float x, float y); private: void swapChannels(bool bAlpha); void update(); freeImageBitmap * IMG; ofTexture tex; bool bUseTexture; bool bAllocatedPixels; }; #endif Node-path: graphics/ofTrueTypeFont.cpp Node-kind: file Node-action: change Text-content-length: 12857 Text-content-md5: f84847e1d97672e826882d7d67a9d7ce Content-length: 12857 #include "ofTrueTypeFont.h" //-------------------------- #ifdef TARGET_WIN32 #include #include #include #include #include #endif #ifdef TARGET_OSX #include "ft2build.h" #include "freetype.h" #include "ftglyph.h" #include "ftoutln.h" #include "fttrigon.h" #endif //------------------------------------------------------------------ ofTrueTypeFont::ofTrueTypeFont(){ bLoadedOk = false; } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(string filename, int fontsize){ // load anti-aliased, non-full character set: loadFont(filename, fontsize, true, false); } //------------------------------------------------------------------ void ofTrueTypeFont::loadFont(string filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet){ bLoadedOk = false; bAntiAlised = _bAntiAliased; bFullCharacterSet = _bFullCharacterSet; fontSize = fontsize; //--------------- load the library and typeface FT_Library library; if (FT_Init_FreeType( &library )){ printf("PROBLEM WITH FT lib \n"); return; } FT_Face face; if (FT_New_Face( library, filename.c_str(), 0, &face )) { return; } FT_Set_Char_Size( face, fontsize << 6, fontsize << 6, 96, 96); lineHeight = fontsize * 1.43f; //------------------------------------------------------ //kerning would be great to support: //printf("FT_HAS_KERNING ? %i \n", FT_HAS_KERNING(face)); //------------------------------------------------------ nCharacters = bFullCharacterSet ? 256 : 128 - NUM_CHARACTER_TO_START; //--------------- initialize character info and textures cps = new charProps[nCharacters]; texNames = new GLuint[nCharacters]; glGenTextures(nCharacters, texNames); //--------------------- load each char ----------------------- for (int i = 0 ; i < nCharacters; i++){ //------------------------------------------ anti aliased or not: if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){ printf("error with FT_Load_Glyph %i \n", i); } if (bAntiAlised == true) FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); else FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO); //------------------------------------------ FT_Bitmap& bitmap= face->glyph->bitmap; // 3 pixel border around the glyph // We show 2 pixels of this, so that blending looks good. // 1 pixels is hidden because we don't want to see the real edge of the texture border = 3; visibleBorder = 2; // prepare the texture: int width = ofNextPow2( bitmap.width + border*2 ); int height = ofNextPow2( bitmap.rows + border*2 ); // ------------------------- this is fixing a bug with small type // ------------------------- appearantly, opengl has trouble with // ------------------------- width or height textures of 1, so we // ------------------------- we just set it to 2... if (width == 1) width = 2; if (height == 1) height = 2; // ------------------------- // info about the character: cps[i].value = i; cps[i].height = face->glyph->bitmap_top; cps[i].width = face->glyph->bitmap.width; cps[i].setWidth = face->glyph->advance.x >> 6; cps[i].topExtent = face->glyph->bitmap.rows; cps[i].leftExtent = face->glyph->bitmap_left; // texture internals cps[i].tTex = (float)(bitmap.width + visibleBorder*2) / (float)width; cps[i].vTex = (float)(bitmap.rows + visibleBorder*2) / (float)height; cps[i].xOff = (float)(border - visibleBorder) / (float)width; cps[i].yOff = (float)(border - visibleBorder) / (float)height; /* sanity check: printf("%i %i %i %i %i %i \n", cps[i].value , cps[i].height , cps[i].width , cps[i].setWidth , cps[i].topExtent , cps[i].leftExtent ); */ // Allocate Memory For The Texture Data. unsigned char* expanded_data = new unsigned char[ 2 * width * height]; //-------------------------------- clear data: for(int j=0; j