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

📄 polygons.c

📁 游戏编程精粹,对刚入门的游戏开发者很有帮助
💻 C
字号:
/* Copyright (C) Gabor Nagy, 2000.  * All rights reserved worldwide. * * This software is provided "as is" without express or implied * warranties. You may freely copy and compile this source into * applications you distribute provided that the copyright text * below is included in the resulting source code, for example: * "Portions Copyright (C) Gabor Nagy, 2000" *//*==============================================================================*//* Simple 3D library for reading/displaying geometry				*//*										*//* - Polygon-related functions							*//*										*//* AUTHOR:	Gabor Nagy							*//* DATE:	2000-May-02 14:46:31						*//*  v1.0									*//*										*//* For Game Programming Graphics Gems						*//*==============================================================================*/#ifdef _WIN32#include <windows.h>#include <string.h>#else#include <strings.h>#endif#include <stdio.h>#include <math.h>#include <stdlib.h>#include <GL/gl.h>#include "geo.h"#include "str.h"/*======================================*//* Allocate vertex nodes for a polygon	*//*======================================*/E3dVertexNode* E3d_PolygonVertexNodeAllocate(E3dPolygon* LPolygon,int LNumOfVertexNodes){ E3dVertexNode*	LVertexNodes; if(LNumOfVertexNodes>0) {  LVertexNodes=(E3dVertexNode*)EMalloc(sizeof(E3dVertexNode)*LNumOfVertexNodes);  if(LVertexNodes!=NULL)  {   LPolygon->NumOfVertices=LNumOfVertexNodes;  }  LPolygon->VertexNodes=LVertexNodes; } return(LVertexNodes);}/*======================================*//* Default a Polygon			*//*======================================*/void E3d_PolygonDefault(E3dPolygon* LPolygon){ LPolygon->NumOfVertices=0; LPolygon->VertexNodes=NULL;}/*======================================*//* Allocate polygons array		*//*======================================*/E3dPolygon* E3d_PolygonsAllocate(unsigned long LNumOfPolys){ E3dPolygon*	LAPolygon; E3dPolygon*	LIPolygon; unsigned long	LC; if(LNumOfPolys>0) LAPolygon=(E3dPolygon*)EMalloc(sizeof(E3dPolygon)*LNumOfPolys); if(LAPolygon!=NULL) {  LIPolygon=LAPolygon;  for(LC=0;LC<LNumOfPolys;LC++,LIPolygon++)  {   E3d_PolygonDefault(LIPolygon);  } } return(LAPolygon);}/*======================================*//* Add a polygon to Polygon array	*//*======================================*/E3dPolygon* E3d_PolygonAddOneToArray(E3dPolygon* LPolygons,unsigned long LNumOfPolys,unsigned long* LNumOfPolysAllocatedPtr){ unsigned long	LNumOfPolysAllocated; E3dPolygon*	LPolygonsT; if(LNumOfPolysAllocatedPtr!=NULL) LNumOfPolysAllocated=*LNumOfPolysAllocatedPtr; else LNumOfPolysAllocated=0; if(LPolygons==NULL) {  if((LPolygons=E3d_PolygonsAllocate(E3dPOLYALLOC_INCREMENT))!=NULL)  {   if(LNumOfPolysAllocatedPtr!=NULL) *LNumOfPolysAllocatedPtr=E3dPOLYALLOC_INCREMENT;  }  else return(NULL); } else {  if(LNumOfPolys>=LNumOfPolysAllocated)  {   if((LPolygonsT=(E3dPolygon*)ERealloc(LPolygons,sizeof(E3dPolygon)*(LNumOfPolys+E3dPOLYALLOC_INCREMENT)))!=NULL)   {    LPolygons=LPolygonsT;    if(LNumOfPolysAllocatedPtr!=NULL) *LNumOfPolysAllocatedPtr=LNumOfPolysAllocated+E3dPOLYALLOC_INCREMENT;   }   else return(NULL);  } } if(LPolygons!=NULL) E3d_PolygonDefault(LPolygons+LNumOfPolys); return(LPolygons);}/*======================================*//* Allocate PolyGroup			*//*======================================*/E3dPolyGroup* E3d_PolyGroupAllocate(){ E3dPolyGroup*	LPolyGroup; if((LPolyGroup=(E3dPolyGroup*)EMalloc(sizeof(E3dPolyGroup)))!=NULL) {  LPolyGroup->RefCnt=0;  LPolyGroup->Name=NULL;  LPolyGroup->Material=NULL;  LPolyGroup->NormalFlags=E3dNONE;  LPolyGroup->NumOfPolygons=0;  LPolyGroup->Polygons=NULL;  LPolyGroup->ShadowPass=FALSE; } return(LPolyGroup);}/*======================================*//* Allocate a polygon mesh		*//*======================================*/E3dMesh* E3d_MeshAllocate(){ E3dMesh*	LMesh; if((LMesh=(E3dMesh*)EMalloc(sizeof(E3dMesh)))!=NULL) {  LMesh->RefCnt=0;  LMesh->NumOfVertices=0;  LMesh->Vertices=NULL;  LMesh->NumOfPolyGroups=0;  LMesh->PolyGroups=NULL;  return(LMesh); } return(NULL);}/*======================================*//* Add a polygon group to a Mesh	*//*======================================*/E3dPolyGroup* E3d_MeshAddPolyGroup(E3dMesh* LMesh){ E3dPolyGroup*	LPolyGroup; E3dPolyGroup**	LPolyGroups; if(LMesh->PolyGroups==NULL) {  if((LPolyGroups=(E3dPolyGroup**)EMalloc(sizeof(E3dPolyGroup*)))!=NULL) LMesh->PolyGroups=LPolyGroups; } else {  if((LPolyGroups=(E3dPolyGroup**)ERealloc(LMesh->PolyGroups,sizeof(E3dPolyGroup*)*(LMesh->NumOfPolyGroups+1)))!=NULL)  {   LMesh->PolyGroups=LPolyGroups;  } } if(LPolyGroups!=NULL) {  if((LPolyGroup=E3d_PolyGroupAllocate())!=NULL)  {   LPolyGroups[LMesh->NumOfPolyGroups]=LPolyGroup;   LPolyGroup->RefCnt=1;   LMesh->NumOfPolyGroups+=1;  } } return(LPolyGroup);}/*==============================================================================*//* Refresh GL vertices and GL polygon and vertex normals of the polygons a mesh	*//*==============================================================================*/void E3d_MeshRefreshGLPolyVertices(E3dMesh* LMesh,EBool LDoNormals){ register unsigned long		LGCnt,LGNum,LVNum,LVCnt,LPCnt,LPNum; register long			LVertexID; register E3dVertex*		LVertices; E3dVertex*			LVertex; register E3dVertexNode*	LVertexNode; E3dPolyGroup*			LPolyGroup; E3dPolyGroup**			LPolyGroups; register E3dPolygon*		LPolygon; float				LCX,LCY,LCZ,LX,LY,LZ; LVertices=LMesh->Vertices; LGNum=LMesh->NumOfPolyGroups;LPolyGroups=LMesh->PolyGroups; for(LGCnt=0;LGCnt<LGNum;LGCnt++) {  LPolyGroup=LPolyGroups[LGCnt];  LPNum=LPolyGroup->NumOfPolygons;LPolygon=LPolyGroup->Polygons;  for(LPCnt=0;LPCnt<LPNum;LPCnt++,LPolygon++)  {   LVNum=LPolygon->NumOfVertices;   LVertexNode=LPolygon->VertexNodes;   LCX=LCY=LCZ=0.0;   for(LVCnt=0;LVCnt<LVNum;LVCnt++,LVertexNode++)   {    if((LVertexID=LVertexNode->VertexID)>=0)    {     LVertexID=LVertexNode->VertexID;LVertex=LVertices+LVertexID;          LX=LVertex->X;LY=LVertex->Y;LZ=LVertex->Z;     LVertexNode->GLVertex[0]=LX;     LVertexNode->GLVertex[1]=LY;     LVertexNode->GLVertex[2]=LZ;     LCX+=LX;LCY+=LY;LCZ+=LZ;    }   }  } } if(LDoNormals) {  for(LGCnt=0;LGCnt<LGNum;LGCnt++)  {   LPolyGroup=LPolyGroups[LGCnt];   LPNum=LPolyGroup->NumOfPolygons;LPolygon=LPolyGroup->Polygons;   for(LPCnt=0;LPCnt<LPNum;LPCnt++,LPolygon++)   {    LVNum=LPolygon->NumOfVertices;    LVertexNode=LPolygon->VertexNodes;    for(LVCnt=0;LVCnt<LVNum;LVCnt++,LVertexNode++)    {     if(LVertexNode->VertexID!=-1)     {      LVertexNode->GLNormal[0]=LVertexNode->Normal.X;      LVertexNode->GLNormal[1]=LVertexNode->Normal.Y;      LVertexNode->GLNormal[2]=LVertexNode->Normal.Z;     }    }   }  } }}/*======================================================*//* Recalculate polygon normals of a polygon group	*//*======================================================*/void E3d_PolyGroupRefreshPolygonNormals(E3dMesh* LMesh,E3dPolyGroup* LPolyGroup){ unsigned long		LMeshVertNum,LPCnt,LNumOfPolys,LVertNum,LV0,LV1,LV2; E3dVertex*		LMeshVertices; E3dPolygon*		LPolygon; E3dVertexNode*		LActPolyVertNode; E3dCoordType		LX0,LY0,LZ0,LX1,LY1,LZ1,LX2,LY2,LZ2,LNormalX,LNormalY,LNormalZ; E3dCoordType		r; LNumOfPolys=LPolyGroup->NumOfPolygons; LMeshVertNum=LMesh->NumOfVertices; LMeshVertices=LMesh->Vertices; LPolygon=LPolyGroup->Polygons; for(LPCnt=0;LPCnt<LNumOfPolys;LPCnt++,LPolygon++) {  if((LVertNum=LPolygon->NumOfVertices)>2)  {   LActPolyVertNode=LPolygon->VertexNodes;   if(LVertNum==3)   {    LV0=LActPolyVertNode[0].VertexID;    LV1=LActPolyVertNode[1].VertexID;    LV2=LActPolyVertNode[2].VertexID;    LX0=LMeshVertices[LV0].X;LY0=LMeshVertices[LV0].Y;LZ0=LMeshVertices[LV0].Z;    LX1=LMeshVertices[LV1].X;LY1=LMeshVertices[LV1].Y;LZ1=LMeshVertices[LV1].Z;    LX2=LMeshVertices[LV2].X;LY2=LMeshVertices[LV2].Y;LZ2=LMeshVertices[LV2].Z;    LNormalX=-((LY2-LY1)*(LZ2-LZ0)-(LZ2-LZ1)*(LY2-LY0));    LNormalY=(LX2-LX1)*(LZ2-LZ0)-(LZ2-LZ1)*(LX2-LX0);    LNormalZ=-((LX2-LX1)*(LY2-LY0)-(LY2-LY1)*(LX2-LX0));   }   r=(E3dCoordType)sqrt(LNormalX*LNormalX+LNormalY*LNormalY+LNormalZ*LNormalZ);   if(r>0.0) { r=1.0f/r;LNormalX*=r;LNormalY*=r;LNormalZ*=r; }   LPolygon->Normal.X=LNormalX;LPolygon->Normal.Y=LNormalY;LPolygon->Normal.Z=LNormalZ;  }  else  {   LPolygon->Normal.X=0.0;LPolygon->Normal.Y=0.0;LPolygon->Normal.Z=0.0;  } } LPolyGroup->NormalFlags|=E3dPOLY_NORMALS_UPTODATE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -