图形缓存和动画
下面的代码开始是为了修复一些图形缓存问题的测试,后来在动画循环中更新了图形。在另一个项目中,我正在编写一个模拟器
在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 ***** 嗨,Paul,
这些是强制更新的步骤。
需要这个吗:
actrTransactionManager-> enableGraphicsFlush(k true);?
为什么不放置:
draw graphics();
之后?也许吧
可能不需要enableGraphicsFlush(kTrue)将在一段时间内将其取出并进行测试,
否则它是实验的遗留代码
您的意思是“之后绘制图形”是什么?你是说把它放在函数<br>navBadGraphicsRunIt之后?现在的方式不再需要转发DrawGraphics的引用。
谢谢
在调用acedDragGen()之前,我已经在一个函数中使用了这个函数;这就是为什么
我指的是这个……它和你现在的方式一样-但我不太了解它。
actrTransactionManager->queueForGraphicsFlush();
actrTransactionManager->flushGraphics();
acedUpdateDisplay();
DrawGraphics();
啊,我明白你在说什么了。否,需要先调用DrawGraphics函数,然后排队,然后更改并强制重画。否则,
显示的图形元素不同步一步。
页:
[1]