📄 render.cpp
字号:
aLookAt[1]=aEye[1]-aFocus[1];
aLookAt[2]=aEye[2]-aFocus[2];
// Translate camera eye
aEye[0]-=aFocus[0];
aEye[1]-=aFocus[1];
aEye[2]-=aFocus[2];
// Calculate camera focus right and camera focus up vectors
matCrossProduct(aRight,aAxisy,aLookAt);
// Set rotation matrix
matNormalize(aRight);
matIdentity(aRot);
if(fAngh != 0.0F) matRotate(aRot,aAxisy,fAngh);
// Rotate look-at vector
if(fAngv != 0.0F) matRotate(aRot,aRight,fAngv);
matVectProduct(NULL,aEye,aRot);
// Translate camera eye
aEye[0]+=aFocus[0];
aEye[1]+=aFocus[1];
aEye[2]+=aFocus[2];
// Set context camera
rendSetContCamera(pContext,aEye,aFocus,pContext->nCamCol);
return(OK);
}
__declspec(dllexport) int __stdcall rendUpdateCont(RENDCONT *pContext)
{
// Update
return(ddUpdate((DDCONT *)pContext->pDdc,pContext));
}
__declspec(dllexport) int __stdcall rendResizeCont(RENDCONT *pContext)
{
// Resize and update
if(ddResize((DDCONT *)pContext->pDdc) < 0) return(ERR);
return(ddUpdate((DDCONT *)pContext->pDdc,pContext));
}
__declspec(dllexport) int __stdcall rendPaintCont(RENDCONT *pContext)
{
// Paint
return(ddPaint((DDCONT *)pContext->pDdc));
}
__declspec(dllexport) int __stdcall rendGetSel(char *szPrefix,short *nCount,char **szKeys)
{
short nSize;
char szKey[256];
RENDOBJ *pCur;
// Reset count
*nCount=0;
// Reset size
nSize=0;
// Set pointer to first object
pCur=pFirst;
while(1)
{
// Check pointer
if(pCur == NULL) break;
// Check object mode
if(pCur->nMode == REND_OSEL)
{
// Get size
sprintf(szKey,"%s%ld",szPrefix,pCur->nKey);
nSize=nSize+strlen(szKey)+1;
// Increment count
(*nCount)++;
}
// Set pointer to next object
pCur=pCur->pNext;
}
// Allocate memory for keys
*szKeys=(char *)calloc(nSize,sizeof(char));
if(*szKeys == NULL) return(ERR);
// Reset count
*nCount=0;
// Reset size
nSize=0;
// Set pointer to first object
pCur=pFirst;
while(1)
{
// Check pointer
if(pCur == NULL) break;
// Check object mode
if(pCur->nMode == REND_OSEL)
{
// Copy key
sprintf(szKey,"%s%ld",szPrefix,pCur->nKey);
if(*nCount > 0) strcat(*szKeys," ");
strcat(*szKeys,szKey);
// Increment count
(*nCount)++;
}
// Set pointer to next object
pCur=pCur->pNext;
}
return(OK);
}
__declspec(dllexport) int __stdcall rendSetSel(char *szPrefix,char *szKeys)
{
char *pKey,szKey[256],*szList;
RENDOBJ *pCur;
// Set pointer to first object
pCur=pFirst;
while(1)
{
// Check pointer
if(pCur == NULL) break;
// Check ans set object mode to show
if(pCur->nMode != REND_OHIDE) pCur->nMode=REND_OSHOW;
// Set pointer to next object
pCur=pCur->pNext;
}
// Allocate memory for list
szList=(char *)calloc(strlen(szKeys)+1,sizeof(char));
if(szList == NULL) return(ERR);
// Copy keys to list
strcpy(szList,szKeys);
// Find and check first key
pKey=strtok(szList," ");
if(pKey == NULL) pKey=szKeys;
while(1)
{
// Check key
if(pKey == NULL) break;
// Set pointer to first object
pCur=pFirst;
while(1)
{
// Check pointer
if(pCur == NULL) break;
// Check key
sprintf(szKey,"%s%ld",szPrefix,pCur->nKey);
if(strcmp(pKey,szKey) == 0)
{
// Check and set object mode
if(pCur->nMode != REND_OHIDE) pCur->nMode=REND_OSEL;
break;
}
// Set pointer to next object
pCur=pCur->pNext;
}
// Find next key
pKey=strtok(NULL," ");
}
// Free list
free(szList);
return(OK);
}
__declspec(dllexport) int __stdcall rendTransSel(float x,float y,float z)
{
RENDOBJ *pCur;
// Set pointer to first object
pCur=pFirst;
while(1)
{
// Check pointer
if(pCur == NULL) break;
// Check object mode
if(pCur->nMode == REND_OSEL)
{
// Set translation
pCur->aTrans[0]+=x;
pCur->aTrans[1]+=y;
pCur->aTrans[2]+=z;
// Translate object
pCur->aTransform[12]+=x;
pCur->aTransform[13]+=y;
pCur->aTransform[14]+=z;
}
// Set pointer to next object
pCur=pCur->pNext;
}
return(OK);
}
__declspec(dllexport) int __stdcall rendScaleSel(float x,float y,float z)
{
RENDOBJ *pCur;
// Set pointer to first object
pCur=pFirst;
while(1)
{
// Check pointer
if(pCur == NULL) break;
// Check object mode
if(pCur->nMode == REND_OSEL)
{
// Set scale
pCur->aScale[0]*=x;
pCur->aScale[1]*=y;
pCur->aScale[2]*=z;
// Scale object
matScale(pCur->aTransform,x,y,z);
}
// Set pointer to next object
pCur=pCur->pNext;
}
return(OK);
}
__declspec(dllexport) int __stdcall rendRotSel(RENDCONT *pContext,float x,float y,float z)
{
RENDOBJ *pCur;
Euler *eObj,*eWorld,eRes;
float aObj[16],aRes[16],aWorld[16];
// Set pointer to first object
pCur=pFirst;
// Contruct world matrix
eWorld=new Euler(x*PI/180.0F,y*PI/180.0F,z*PI/180.0F,EulOrdXYZr);
eWorld->ToMatrix(aWorld);
while(1)
{
// Check pointer
if(pCur == NULL) break;
// Check object mode
if(pCur->nMode == REND_OSEL)
{
// Check object
if(pCur == NULL)
{
// Destroy world matrix
delete eWorld;
return(ERR);
}
// Contruct object matrix
eObj=new Euler(pCur->aRot[0]*PI/180.0F,pCur->aRot[1]*PI/180.0F,pCur->aRot[2]*PI/180.0F,EulOrdXYZr);
eObj->ToMatrix(aObj);
// Multiply matrices
matProduct(aRes,aWorld,aObj);
// Get angles
eRes.FromMatrix(aRes,EulOrdXYZr);
// Set rotation
pCur->aRot[0]=eRes.x*180.0F/PI;
pCur->aRot[1]=eRes.y*180.0F/PI;
pCur->aRot[2]=eRes.z*180.0F/PI;
// Destroy object matrix
delete eObj;
// Check angles
if(pCur->aRot[0] > REND_AMAX) pCur->aRot[0]=REND_AMIN;
if(pCur->aRot[0] < REND_AMIN) pCur->aRot[0]=REND_AMAX;
if(pCur->aRot[1] > REND_AMAX) pCur->aRot[1]=REND_AMIN;
if(pCur->aRot[1] < REND_AMIN) pCur->aRot[1]=REND_AMAX;
if(pCur->aRot[2] > REND_AMAX) pCur->aRot[2]=REND_AMIN;
if(pCur->aRot[2] < REND_AMIN) pCur->aRot[2]=REND_AMAX;
// Set transformation matrix to identity matrix
matIdentity(pCur->aTransform);
// Rotate object
matRotate(pCur->aTransform,aAxisx,pCur->aRot[0]);
matRotate(pCur->aTransform,aAxisy,pCur->aRot[1]);
matRotate(pCur->aTransform,aAxisz,pCur->aRot[2]);
// Scale object
matScale(pCur->aTransform,pCur->aScale[0],pCur->aScale[1],pCur->aScale[2]);
// Check context
if(pContext != NULL)
{
// Get vector
pCur->aTrans[0]-=pContext->aCursor[0];
pCur->aTrans[1]-=pContext->aCursor[1];
pCur->aTrans[2]-=pContext->aCursor[2];
// Rotate vector
matVectProduct(NULL,pCur->aTrans,aWorld);
// Set vector
pCur->aTrans[0]+=pContext->aCursor[0];
pCur->aTrans[1]+=pContext->aCursor[1];
pCur->aTrans[2]+=pContext->aCursor[2];
}
// Translate object
pCur->aTransform[12]=pCur->aTrans[0];
pCur->aTransform[13]=pCur->aTrans[1];
pCur->aTransform[14]=pCur->aTrans[2];
}
// Set pointer to next object
pCur=pCur->pNext;
}
// Destroy world matrix
delete eWorld;
return(OK);
}
// Internal functions
int rendRendCont(RENDCONT *pContext,HDC hdc)
{
short n,m,nVert,nFlag;
int i,j,nPosx,nPosy;
float fDot,fSize,fInvSize,fWork,fArea;
float aVerts[LWOB_SIZE+1][3],aCubeVerts[REND_DNVERTS];
float aWork[3],aLookAt[3],aEye[3],aFocus[3],aCursor[3],aMin[3],aMax[3];
HPEN hpen,hdefault;
LOGBRUSH lb;
RENDOBJ *pCur,rCubeObj;
// Check context
if(pContext == NULL) return(ERR);
// Check camera
if(pContext->nMode == REND_CCAM)
{
// Calculate look-at vector
aLookAt[0]=pContext->aFocus[0]-pContext->aEye[0];
aLookAt[1]=pContext->aFocus[1]-pContext->aEye[1];
aLookAt[2]=pContext->aFocus[2]-pContext->aEye[2];
}
// Set brush
lb.lbStyle=BS_SOLID;
lb.lbHatch=0;
// Check camera
if((pContext->nMode != REND_CCAM) && (pContext->nCamCol != REND_NONE))
{
// Copy eye and focus
memcpy(aEye,pContext->aEye,nSizeOfFloatTimes3);
memcpy(aFocus,pContext->aFocus,nSizeOfFloatTimes3);
// Check context mode
switch(pContext->nMode)
{
// X (front) view
case REND_CX:
// Set eye and focus
aEye[0]=-aEye[2]*pContext->fScale-pContext->fOffsetx;
aEye[1]=-aEye[1]*pContext->fScale-pContext->fOffsety;
aEye[2]=0.0F;
aFocus[0]=-aFocus[2]*pContext->fScale-pContext->fOffsetx;
aFocus[1]=-aFocus[1]*pContext->fScale-pContext->fOffsety;
aFocus[2]=0.0F;
break;
// Y (top) view
case REND_CY:
// Set eye and focus
fWork=-aEye[0]*pContext->fScale-pContext->fOffsety;
aEye[0]=-aEye[2]*pContext->fScale-pContext->fOffsetx;
aEye[1]=fWork;
aEye[2]=0.0F;
fWork=-aFocus[0]*pContext->fScale-pContext->fOffsety;
aFocus[0]=-aFocus[2]*pContext->fScale-pContext->fOffsetx;
aFocus[1]=fWork;
aFocus[2]=0.0F;
break;
// Z (side) view
case REND_CZ:
// Set eye and focus
aEye[0]=aEye[0]*pContext->fScale-pContext->fOffsetx;
aEye[1]=-aEye[1]*pContext->fScale-pContext->fOffsety;
aEye[2]=0.0F;
aFocus[0]=aFocus[0]*pContext->fScale-pContext->fOffsetx;
aFocus[1]=-aFocus[1]*pContext->fScale-pContext->fOffsety;
aFocus[2]=0.0F;
break;
}
// Set band box color
lb.lbColor=pContext->nCamCol;
// Create pen
hpen=ExtCreatePen(PS_COSMETIC|PS_SOLID,1,&lb,0,NULL);
// Set color and width
hdefault=(HPEN)SelectObject(hdc,hpen);
// Draw eye
MoveToEx(hdc,(int)aEye[0]+REND_SCAM,(int)aEye[1]+REND_SCAM,NULL);
LineTo(hdc,(int)aEye[0]+REND_SCAM,(int)aEye[1]-REND_SCAM);
LineTo(hdc,(int)aEye[0]-REND_SCAM,(int)aEye[1]-REND_SCAM);
LineTo(hdc,(int)aEye[0]-REND_SCAM,(int)aEye[1]+REND_SCAM);
LineTo(hdc,(int)aEye[0]+REND_SCAM,(int)aEye[1]+REND_SCAM);
// Reset to default
SelectObject(hdc,hdefault);
// Delete pen
DeleteObject(hpen);
// Create pen
hpen=ExtCreatePen(PS_COSMETIC|PS_DASH,1,&lb,0,NULL);
// Set color and width
hdefault=(HPEN)SelectObject(hdc,hpen);
// Draw line
MoveToEx(hdc,(int)aEye[0],(int)aEye[1],NULL);
LineTo(hdc,(int)aFocus[0],(int)aFocus[1]);
// Reset to default
SelectObject(hdc,hdefault);
// Delete pen
DeleteObject(hpen);
// Create pen
hpen=ExtCreatePen(PS_COSMETIC|PS_SOLID,1,&lb,0,NULL);
// Set color and width
hdefault=(HPEN)SelectObject(hdc,hpen);
// Draw focus
MoveToEx(hdc,(int)aFocus[0]+REND_SCAM,(int)aFocus[1],NULL);
LineTo(hdc,(int)aFocus[0],(int)aFocus[1]+REND_SCAM);
LineTo(hdc,(int)aFocus[0]-REND_SCAM,(int)aFocus[1]);
LineTo(hdc,(int)aFocus[0],(int)aFocus[1]-REND_SCAM);
LineTo(hdc,(int)aFocus[0]+REND_SCAM,(int)aFocus[1]);
// Reset to default
SelectObject(hdc,hdefault);
// Delete pen
DeleteObject(hpen);
}
// Check rotation flag
if((pContext->nMode != REND_CCAM) && (pContext->pRotObj != NULL) &&
(pContext->nRotCol != REND_NONE))
{
// Set rotation color
lb.lbColor=pContext->nRotCol;
// Create pen
hpen=ExtCreatePen(PS_COSMETIC|PS_SOLID,1,&lb,0,NULL);
// Set color and width
hdefault=(HPEN)SelectObject(hdc,hpen);
// Set vertices
memset(aVerts[0],0,nSizeOfFloatTimes3);
aVerts[0][0]=pContext->pRotObj->aSize[0]*(float)REND_SROT;
memset(aVerts[1],0,nSizeOfFloatTimes3);
aVerts[1][1]=pContext->pRotObj->aSize[1]*(float)REND_SROT;
memset(aVerts[2],0,nSizeOfFloatTimes3);
aVerts[2][2]=pContext->pRotObj->aSize[2]*(float)REND_SROT;
memset(aVerts[3],0,nSizeOfFloatTimes3);
// Check context mode
switch(pContext->nMode)
{
// X (front) view
case REND_CX:
// Loop thru vertices
for(n=0;n<=LWOB_SIZE;n++)
{
// Object-to-world transformation
matVectProduct(NULL,aVerts[n],pContext->pRotObj->aTransform);
// Set cursor
aVerts[n][0]=-aVerts[n][2]*pContext->fScale-pContext->fOffsetx;
aVerts[n][1]=-aVerts[n][1]*pContext->fScale-pContext->fOffsety;
aVerts[n][2]=0.0F;
}
break;
// Y (top) view
case REND_CY:
// Loop thru vertices
for(n=0;n<=LWOB_SIZE;n++)
{
// Object-to-world transformation
matVectProduct(NULL,aVerts[n],pContext->pRotObj->aTransform);
// Set cursor
fWork=-aVerts[n][0]*pContext->fScale-pContext->fOffsety;
aVerts[n][0]=-aVerts[n][2]*pContext->fScale-pContext->fOffsetx;
aVerts[n][1]=fWork;
aVerts[n][2]=0.0F;
}
break;
// Z (side) view
case REND_CZ:
// Loop thru vertices
for(n=0;n<=LWOB_SIZE;n++)
{
// Object-to-world transformation
matVectProduct(NULL,aVerts[n],pContext->pRotObj->aTransform);
// Set cursor
aVerts[n][0]=aVerts[n][0]*pContext->fScale-pContext->fOffsetx;
aVerts[n][1]=-aVerts[n][1]*pContext->fScale-pContext->fOffsety;
aVerts[n][2]=0.0F;
}
break;
}
// Draw rotation
MoveToEx(hdc,(int)aVerts[3][0],(int)aVerts[3][1],NULL);
LineTo(hdc,(int)aVerts[0][0],(int)aVerts[0][1]);
MoveToEx(hdc,(int)aVerts[3][0],(int)aVerts[3][1],NULL);
LineTo(hdc,(int)aVerts[1][0],(int)aVerts[1][1]);
MoveToEx(hdc,(int)aVerts[3][0],(int)aVerts[3][1],NULL);
LineTo(hdc,(int)aVerts[2][0],(int)aVerts[2][1]);
// Reset to default
SelectObject(hdc,hdefault);
// Delete pen
DeleteObject(hpen);
}
// Check grid size
if((pContext->nMode != REND_CCAM) && (pContext->fGridSize > 0.0) &&
(pContext->nGridCol != REND_NONE))
{
// Set band box color
lb.lbColor=pContext->nGridCol;
// Create pen
hpen=ExtCreatePen(PS_COSMETIC|PS_SOLID,1,&lb,0,NULL);
// Set color and width
hdefault=(HPEN)SelectObject(hdc,hpen);
// Calc size
fSize=pContext->fGridSize*pContext->fScale;
// Adjust size
while(fSize < REND_CGLIM) fSize*=REND_CGLIM;
fInvSize=1.0F/fSize;
// Loop
for(i=(int)(pContext->fOffsetx*fInvSize);
i<=(int)((pContext->fWidth+pContext->fOffsetx)*fInvSize);i++)
{
nPosx=(int)(fSize*(float)i-pContext->fOffsetx);
for(j=(int)(pContext->fOffsety*fInvSize);
j<=(int)((pContext->fHeight+pContext->fOffsety)*fInvSize);j++)
{
// Calc y position
nPosy=(int)(fSize*(float)j-pContext->fOffsety);
// Draw fine grid
MoveToEx(hdc,nPosx,nPosy,NULL);
LineTo(hdc,nPosx+1,nPosy);
// Check indexes
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -