static void PAINTER_New( DaoProcess *proc, DaoValue *p[], int N ) { DaoxPainter *self = DaoxPainter_New(); DaoProcess_PutValue( proc, (DaoValue*) self ); }
static void WIN_Show( DaoProcess *proc, DaoValue *p[], int N ) { DaoxWindow *self = (DaoxWindow*) p[0]; DaoxCanvas *canvas = (DaoxCanvas*) DaoValue_CastCstruct( p[1], daox_type_canvas ); DaoxScene *scene = (DaoxScene*) DaoValue_CastCstruct( p[1], daox_type_scene ); DaoxFont *font = DaoxFont_GetDefault(); int fpsLimit = p[2]->xInteger.value; int fpsTest = p[3]->xBoolean.value; double fpsTestTime = 0.0; double timeInterval = 0.0; double lastFrameStart = 0.0; float currentFPS = 0.0; size_t fpsCount = 0; char chars[32]; if( fpsTest && self->widget == NULL ){ char *fpsText = "FPS: "; DaoxColor bgcolor = {0.0,0.0,0.0,0.0}; DaoxBrush *brush; self->widget = DaoxCanvas_New( NULL ); self->widget->viewport.right = self->width; self->widget->viewport.top = self->height; DaoGC_IncRC( (DaoValue*) self->widget ); DaoxCanvas_SetBackground( self->widget, bgcolor ); brush = DaoxCanvas_PushBrush( self->widget, 0 ); brush->strokeColor.blue = 1.0; brush->fillColor.blue = 1.0; brush->fillColor.alpha = 1.0; brush->fontSize = 20; self->fpsLabel = DaoxCanvas_AddText( self->widget, fpsText, 10, self->height - 20, 0 ); } if( self->painter == NULL && (canvas != NULL || self->widget != NULL) ){ self->painter = DaoxPainter_New( self->context ); DaoGC_IncRC( (DaoValue*) self->painter ); } if( self->renderer == NULL && scene != NULL ){ self->renderer = DaoxRenderer_New( self->context ); DaoGC_IncRC( (DaoValue*) self->renderer ); } if( canvas != NULL ){ float dm = sqrt(self->width*self->width + self->height*self->height ); float cx = 0.5*(canvas->viewport.left + canvas->viewport.right); float cy = 0.5*(canvas->viewport.top + canvas->viewport.bottom); float w = canvas->viewport.right - canvas->viewport.left; float h = canvas->viewport.top - canvas->viewport.bottom; float d = sqrt(w*w + h*h); w = 0.5 * self->width * d / dm; h = 0.5 * self->height * d / dm; canvas->viewport.left = cx - w; canvas->viewport.right = cx + w; canvas->viewport.bottom = cy - h; canvas->viewport.top = cy + h; } GC_Assign( & self->model, p[1] ); self->visible = 1; glfwShowWindow( self->handle ); glfwMakeContextCurrent( self->handle ); glfwSetKeyCallback( self->handle, DaoxWindow_KeyCallback ); glfwSetCursorPosCallback( self->handle, DaoxWindow_CursorMoveCallback ); glfwSetCursorEnterCallback( self->handle, DaoxWindow_CursorEnterCallback ); glfwSetWindowFocusCallback( self->handle, DaoxWindow_FocusCallback ); #ifdef SAVE_RENDERED_SCENE char name[50]; int frame = 1; DaoxImage *image = DaoxImage_New(); image->depth = DAOX_IMAGE_BIT32; DaoxImage_Resize( image, self->width, self->height ); #endif while( self->visible && ! glfwWindowShouldClose( self->handle ) ){ double frameStartTime = 0.0; double frameEndTime = 0.0; frameStartTime = glfwGetTime(); if( canvas ) DaoxPainter_Paint( self->painter, canvas, canvas->viewport ); if( scene ){ #ifdef SAVE_RENDERED_SCENE DaoxScene_Update( scene, 1.0/30.0 ); glReadBuffer( GL_BACK ); glPixelStorei( GL_UNPACK_ALIGNMENT, 4 ); glPixelStorei( GL_PACK_ROW_LENGTH, image->width ); DaoxRenderer_Render( self->renderer, scene, scene->camera ); glReadPixels( 0, 0, self->width, self->height, GL_RGBA, GL_UNSIGNED_BYTE, image->imageData ); sprintf( name, "rama_attack_frame_%03i.png", frame ); DaoxImage_SavePNG( image, name ); frame += 1; if( frame > 155 ) break; #else DaoxScene_Update( scene, frameStartTime - lastFrameStart ); DaoxRenderer_Render( self->renderer, scene, scene->camera ); #endif } lastFrameStart = frameStartTime; if( fpsTest ){ if( fpsCount % 10 == 0 ){ int i, n = sprintf( chars, "%.1f", currentFPS ); for(i=0; i<n; ++i){ DaoxGlyph *glyph = DaoxFont_GetGlyph( font, chars[i] ); DaoxCanvasNode *chnode = self->fpsLabel->children->items.pCanvasNode[i+5]; DaoxPath *path = DaoxPathCache_FindPath( self->widget->pathCache, glyph->shape ); GC_Assign( & chnode->path, path ); DaoxCanvasNode_MarkDataChanged( chnode ); } } DaoxPainter_Paint( self->painter, self->widget, self->widget->viewport ); } glfwSwapBuffers( self->handle ); glfwPollEvents(); if( fpsTest == 0 ) continue; frameEndTime = glfwGetTime(); timeInterval = frameEndTime - frameStartTime; if( timeInterval < 1.0/fpsLimit ) usleep( 1000000 * (1.0/fpsLimit - timeInterval) ); fpsCount += 1; currentFPS = fpsCount / (frameEndTime - fpsTestTime); if( frameEndTime > (fpsTestTime + 3) ){ fpsTestTime = frameEndTime - 1.0; fpsCount = currentFPS; /* Frame count estimation in the past second; */ } } glfwHideWindow( self->handle ); }