pkohut 发表于 2009-6-8 08:38:31

图形缓存和动画

下面的代码开始是为了修复一些图形缓存问题的测试,后来
在动画循环中更新了图形。在另一个项目中,我正在编写一个模拟器
在AutoCAD中运行,并且需要在动画循环中更新图形。问题
首先是缓存被打乱,其次是图形直到
应用程序完成后才更新。我想我已经解决了代码be的问题,但是我想知道
queueForGraphicsFlush()、flushGraphics()和acedUpdateDisplay是否正确实现。
它似乎可以工作,但是我不确定我是否正确地实现了它(参见代码末尾)。
谢谢,
Paul
运行代码:
创建一个新项目,并用下面的代码替换“acrxEntryPoint.cpp”的内容。
编译并运行,在AutoCAD命令行中键入RUNIT(可能需要最大化显示
并再次运行)。
// Animate the circle 1000 times
// Written by Paul Kohut, June 8, 2009
// paulkohut@hotmail.com
// Implements a fairly smooth aniniation loop within AutoCAD.
//-----------------------------------------------------------------------------
//----- acrxEntryPoint.h
//-----------------------------------------------------------------------------
#include "StdAfx.h"
#include "resource.h"
#define _USE_MATH_DEFINES 1
#include
#define index(x, y, c) (y * c + x)
//-----------------------------------------------------------------------------
#define szRDS _RXST("nav")
#pragma comment(linker, "/export:_acrxGetApiVersion,PRIVATE")
//#pragma comment(linker, "/export:_acrxEntryPoint,PRIVATE")
//-----------------------------------------------------------------------------
//----- ObjectARX EntryPoint
class CBadGraphicsApp : public AcRxArxApp {
public:
        CBadGraphicsApp () : AcRxArxApp () {}
        virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
                AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;
                return (retCode) ;
        }
        virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
                AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;
                return (retCode) ;
        }
        virtual void RegisterServerComponents () {
        }
        static void EraseAllEntity(AcDbBlockTableRecordPointer & pBtr)
        {
                AcDbBlockTableRecordIterator * pIter;
                pBtr->newIterator(pIter);
                for(pIter->start(); !pIter->done(); pIter->step()) {
                        AcDbObjectId entId;
                        if(pIter->getEntityId(entId) == Acad::eOk) {
                                AcDbObject *pEnt;
                                if(actrTransactionManager->getObject(pEnt, entId, AcDb::kForWrite) == Acad::eOk)
                                {
                                        pEnt->erase();
                                }
                        }
                }
        }
        // draws a checker board, grid lines, and animates a circle.
        static void DrawGraphics(void)
        {
                int nMapSizeX = 8;
                int nMapSizeY = 8;
                double dGridSizeX = 1.0, dGridSizeY = 1.0;
                AcCmColor colorBlack;               
                AcCmColor colorGrid;
                AcCmColor colorWhite;
                AcCmColor colorRed;
                colorBlack.setRGB(0, 0, 0);
                colorGrid.setRGB(91, 91, 91);
                colorWhite.setRGB(255, 255, 255);
                colorRed.setRGB(255, 0, 0);
                double x = 0.0, y = 0.0;
                // Draw the checker board layout
                AcDbDatabase * pDb = acdbHostApplicationServices()->workingDatabase();
                AcDbBlockTableRecordPointer pRcd(ACDB_MODEL_SPACE, pDb, AcDb::kForWrite);
                if(pRcd.openStatus() == Acad::eOk) {
                        EraseAllEntity(pRcd);                       
                        for(int j = 0; j setColor((index(i, j, nMapSizeX) + j) % 2 ? colorBlack : colorWhite);
                                        AcDbObjectId objId;
                                        if(pRcd->appendAcDbEntity(objId, pSolid) == Acad::eOk)
                                        {
                                                actrTransactionManager->addNewlyCreatedDBRObject(pSolid);
                                                pSolid->draw();
                                        }
                                        else
                                                delete pSolid;
                                        x += dGridSizeX;
                                }
                                y -= dGridSizeY;
                        }               
                        // Draw vertical grid lines
                        x = 0.0;
                        y = 0.0;
                        double gridLineWidth = 0.05;
                        for(int i = 0; i addVertexAt(pPline->numVerts(), AcGePoint2d(x, y), 0.0, gridLineWidth, gridLineWidth);
                                pPline->addVertexAt(pPline->numVerts(), AcGePoint2d(x, y - (dGridSizeY * nMapSizeY)), 0.0, gridLineWidth, gridLineWidth);
                                pPline->setColor(colorGrid);
                                AcDbObjectId objId;
                                if(pRcd->appendAcDbEntity(objId, pPline) == Acad::eOk)
                                {
                                        actrTransactionManager->addNewlyCreatedDBRObject(pPline);
                                        pPline->draw();
                                }
                                else
                                        delete pPline;
                                x += dGridSizeX;
                        }
                        // Draw horizontal grid lines
                        x = 0.0;
                        y = 0.0;
                        for(int i = 0; i addVertexAt(pPline->numVerts(), AcGePoint2d(x, y), 0.0, gridLineWidth, gridLineWidth);
                                pPline->addVertexAt(pPline->numVerts(), AcGePoint2d(x + (dGridSizeX * nMapSizeX), y), 0.0, gridLineWidth, gridLineWidth);
                                pPline->setColor(colorGrid);                       
                                if(pRcd->appendAcDbEntity(pPline) == Acad::eOk)
                                {
                                        actrTransactionManager->addNewlyCreatedDBRObject(pPline);
                                        pPline->draw();
                                }
                                else
                                        delete pPline;
                                y -= dGridSizeY;
                        }
                        // Animate a circle going in a circle
                        static double stepp = M_PI_2 / 180.0;
                        static double x1 = nMapSizeX * dGridSizeX * 0.5;
                        static double y1 = -nMapSizeY * dGridSizeY * 0.5;
                        static double ang = 0.0;
                        AcDbCircle * pCircle = new AcDbCircle();
                        pCircle->setCenter(AcGePoint3d(cos(ang) * 2.0 + x1, sin(ang) * 2.0 + y1, 0.0));
                        pCircle->setRadius(0.25);
                        pCircle->setColor(colorRed);
                        if(pRcd->appendAcDbEntity(pCircle) == Acad::eOk)
                        {
                                actrTransactionManager->addNewlyCreatedDBRObject(pCircle);                       
                        }
                        else
                                delete pCircle;
                        ang += stepp;
                }
        }
        // call when the user types RUNIT from the AutoCAD command line.
        // Questions??? Is the queueing, flushing, and updating of the
        // graphics done correctly? It works, but is this the right way?
        static void navBadGraphicsRunIt(void)
        {
                AcTransaction * pTrans = actrTransactionManager->startTransaction();               
                actrTransactionManager->enableGraphicsFlush(kTrue);
                for(int i = 0; i queueForGraphicsFlush();
                        actrTransactionManager->flushGraphics();
                        acedUpdateDisplay();
                }
                actrTransactionManager->endTransaction();
        }
} ;
//-----------------------------------------------------------------------------
IMPLEMENT_ARX_ENTRYPOINT(CBadGraphicsApp)
ACED_ARXCOMMAND_ENTRY_AUTO(CBadGraphicsApp, navBadGraphics, RunIt, RunIt, ACRX_CMD_TRANSPARENT, NULL)

**** Hidden Message *****

pkohut 发表于 2009-6-8 11:09:17

嗨,Paul,
这些是强制更新的步骤。
需要这个吗:
actrTransactionManager-> enableGraphicsFlush(k true);?
为什么不放置:
draw graphics();
之后?也许吧

pkohut 发表于 2009-6-8 11:18:39


可能不需要enableGraphicsFlush(kTrue)将在一段时间内将其取出并进行测试,
否则它是实验的遗留代码
您的意思是“之后绘制图形”是什么?你是说把它放在函数<br>navBadGraphicsRunIt之后?现在的方式不再需要转发DrawGraphics的引用。
谢谢

pkohut 发表于 2009-6-8 11:31:50


在调用acedDragGen()之前,我已经在一个函数中使用了这个函数;这就是为什么
我指的是这个……它和你现在的方式一样-但我不太了解它。
actrTransactionManager->queueForGraphicsFlush();
actrTransactionManager->flushGraphics();
acedUpdateDisplay();
DrawGraphics();

pkohut 发表于 2009-6-8 11:59:36


啊,我明白你在说什么了。否,需要先调用DrawGraphics函数,然后排队,然后更改并强制重画。否则,
显示的图形元素不同步一步。
页: [1]
查看完整版本: 图形缓存和动画