⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 render.cpp

📁 游戏《家园》源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	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 + -