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

📄 obj.c

📁 游戏编程精粹,对刚入门的游戏开发者很有帮助
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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" *//*==============================================================================*//* Real-time cast shadows							*//*										*//* - Simple Wavefront OBJ file reader						*//*										*//* AUTHOR:	Gabor Nagy							*//* DATE:	2000-May-02 14:45:38						*//*  v1.0									*//*										*//* For Game Programming Graphics Gems						*//*==============================================================================*/#include <math.h>#include <stdio.h>#include <stdlib.h>#ifdef _WIN32#include <string.h>#define MAXPATHLEN 255#else#include <strings.h>#include <sys/param.h>#endif#include "obj.h"#include "str.h"typedef struct{ char*		Name; E3dMaterial*	Material; E3dPolygon*	Polygons; unsigned long	NumOfPolygons,NumOfPolygonsAllocated;} E3dOBJPolyGroup;/*======================================================*//* Add a polygon group to an E3dOBJPolyGroup array	*//*======================================================*/E3dOBJPolyGroup* E3d_OBJPolyGroupAdd(E3dOBJPolyGroup* LOBJPolyGroups,unsigned int LNumOfPolyGroups,char* LGroupName){ E3dOBJPolyGroup*	LOBJPolyGroupsT; if(LOBJPolyGroups==NULL) {  LOBJPolyGroups=(E3dOBJPolyGroup*)EMalloc(sizeof(E3dOBJPolyGroup)); } else {  if((LOBJPolyGroupsT=(E3dOBJPolyGroup*)ERealloc(LOBJPolyGroups,sizeof(E3dOBJPolyGroup)*(LNumOfPolyGroups+1)))!=NULL)  {   LOBJPolyGroups=LOBJPolyGroupsT;  } } if(LOBJPolyGroups!=NULL) {  LOBJPolyGroups[LNumOfPolyGroups].Name=strdup(LGroupName);  LOBJPolyGroups[LNumOfPolyGroups].Material=NULL;  LOBJPolyGroups[LNumOfPolyGroups].Polygons=NULL;  LOBJPolyGroups[LNumOfPolyGroups].NumOfPolygons=0;  LOBJPolyGroups[LNumOfPolyGroups].NumOfPolygonsAllocated=0; } return(LOBJPolyGroups);}/*======================================*//* Read Material(s) from a ".mtl" file	*//*======================================*/static E3dMaterial** E3d_MaterialReadMTL(char* LFileName, int* LNumOfMaterialsPtr){ char		LBuffer[128]; FILE*		LInFile; E3dMaterial*	LMaterial; E3dMaterial**	LMaterials; E3dMaterial**	LMaterialsT; int		LNumOfMaterials; float		LRF,LGF,LBF; if((LInFile = fopen(LFileName, "r"))!=NULL) {// Count the number of materials in the file//  LNumOfMaterials = 0;  LMaterials = NULL;  LMaterial = NULL;  while(fscanf(LInFile, "%s", LBuffer) != EOF)  {   switch(LBuffer[0])   {    case '#':						// Comment     fgets(LBuffer, sizeof(LBuffer), LInFile);		// Skip the rest of the line    break;    case 'n':						// "newmtl"     fgets(LBuffer, sizeof(LBuffer), LInFile);     sscanf(LBuffer, "%s %s", LBuffer, LBuffer);     if(LMaterials==NULL) LMaterials=(E3dMaterial**)EMalloc(sizeof(E3dMaterial*));     else     {      if((LMaterialsT=(E3dMaterial**)ERealloc(LMaterials,sizeof(E3dMaterial*)*(LNumOfMaterials+1)))!=NULL)      {       LMaterials=LMaterialsT;      }      else { EFree(LMaterials);return(NULL); }     }     if((LMaterial=E3d_MaterialAllocate())!=NULL)     {            LMaterials[LNumOfMaterials]=LMaterial;      LMaterial->Name=strdup(LBuffer);      LMaterial->Type=E3dMAT_LAMBERT;      LNumOfMaterials++;     }    break;    case 'K':     switch(LBuffer[1])     {      case 'a':       fscanf(LInFile, "%f %f %f", &LRF, &LGF, &LBF);       LMaterial->Ambient[0]=LRF;       LMaterial->Ambient[1]=LGF;       LMaterial->Ambient[2]=LBF;      break;      case 'd':       fscanf(LInFile, "%f %f %f", &LRF, &LGF, &LBF);       LMaterial->Diffuse[0]=LRF;       LMaterial->Diffuse[1]=LGF;       LMaterial->Diffuse[2]=LBF;      break;      case 's':       fscanf(LInFile, "%f %f %f", &LRF, &LGF, &LBF);       LMaterial->Specular[0]=LRF;       LMaterial->Specular[1]=LGF;       LMaterial->Specular[2]=LBF;       LMaterial->Type=E3dMAT_PHONG;      break;      default:       fgets(LBuffer, sizeof(LBuffer), LInFile);		// Skip the rest of the line      break;     }    break;    case 'N':     if(LMaterial!=NULL)     {      fscanf(LInFile, "%f", &LRF);// Wavefront shininess is from [0, 1000], so scale for OpenGL//      LRF /= 1000.0;LRF*= 128.0;      LMaterial->Specularity = LRF;      LMaterial->Type=E3dMAT_PHONG;     }    break;    default:     fgets(LBuffer, sizeof(LBuffer), LInFile);			// Skip the rest of the line    break;   }  }  if(LNumOfMaterialsPtr!=NULL) *LNumOfMaterialsPtr=LNumOfMaterials;  fclose(LInFile);  return(LMaterials); } return(NULL);}/*==============================================*//* Get information about the geometry		*//*==============================================*/static int E3d_OBJReadMesh(FILE* LFile, char* LFileName,E3dMesh* LMesh){ char			LGroupName[256]; char			LMaterialName[256]; char			LBuffer[256]; char			LPathName[MAXPATHLEN+1]; char			LMtlFileName[MAXPATHLEN+1]; E3dVertexNode*		LVertexNode; E3dPolygon*		LPolygon; E3dVertex*		LVertex; E3dVertex*		LVertices; E3dVertex*		LVerticesT; E3dVector*		LNormal; E3dVector*		LNormals; E3dVector*		LNormalsT; E3dST*			LST; E3dST*			LSTs; E3dST*			LSTsT; E3dPolyGroup*		LPolyGroup; E3dOBJPolyGroup*	LOBJPolyGroup; E3dOBJPolyGroup*	LOBJPolyGroups; unsigned long		LNumOfVertices, LNumOfVerticesAllocated,			LNumOfNormals, LNumOfNormalsAllocated,			LNumOfPolyGroups, LNumOfPolyGroupsAllocated,			LNumOfSTs, LNumOfSTsAllocated, LC, LN; unsigned long		LFilePos; E3dMaterial*		LMaterial; E3dMaterial**		LMaterials; int			LVtxId, LNormalId, LSTId, LI, LNumOfMaterials; float			LFX, LFY, LFZ; LOBJPolyGroup=NULL; LGroupName[0]='\0'; LNumOfMaterials=0; LMaterial=NULL; LMaterials=NULL; LNumOfVertices = LNumOfNormals = LNumOfSTs = 0; LNumOfPolyGroups = LNumOfPolyGroupsAllocated = 0; LOBJPolyGroups=NULL; LPathName[0]='\0'; EStr_GetPathName(LFileName,LPathName,MAXPATHLEN);// Allocate first chunk of vertex array// if((LVertices=(E3dVertex*)EMalloc(sizeof(E3dVertex)*E3dVTXALLOC_INCREMENT))!=NULL) {  LNumOfVerticesAllocated=E3dVTXALLOC_INCREMENT;  LVertex=LVertices; } else return(0);// Allocate first chunk of normal array// if((LNormals=(E3dVector*)EMalloc(sizeof(E3dVector)*E3dVTXALLOC_INCREMENT))!=NULL) {  LNumOfNormalsAllocated=E3dVTXALLOC_INCREMENT;  LNormal=LNormals; } else { EFree(LVertices);return(0); }// Initialize ST array// LSTs = NULL; LNumOfSTsAllocated = 0; while(fscanf(LFile, "%s", LBuffer) != EOF) {  switch(LBuffer[0])  {   case '#':	fgets(LBuffer, sizeof(LBuffer), LFile);break;		// Comment, skip the rest of the line   case 'v':								// v, vn or vt    switch(LBuffer[1])    {     case '\0':								// Vertex array      if(LNumOfVertices>=LNumOfVerticesAllocated)      {       if((LVerticesT=(E3dVertex*)ERealloc(LVertices, sizeof(E3dVertex)*(LNumOfVertices+E3dVTXALLOC_INCREMENT)))!=NULL)       {        LVertices=LVerticesT;        LNumOfVerticesAllocated+=E3dVTXALLOC_INCREMENT;        LVertex=LVertices+LNumOfVertices;       }       else       {	EFree(LVertices);EFree(LNormals);	if(LSTs!=NULL) EFree(LSTs);	return(0);       }      }      fscanf(LFile, "%f %f %f", &LFX, &LFY, &LFZ);      LVertex->X=LFX;      LVertex->Y=LFY;      LVertex->Z=LFZ;      LVertex++;      LNumOfVertices++;     break;     case 'n':								// Normal array      if(LNumOfNormals>=LNumOfNormalsAllocated)      {       if((LNormalsT=(E3dVector*)ERealloc(LNormals, sizeof(E3dVector)*(LNumOfNormals+E3dVTXALLOC_INCREMENT)))!=NULL)       {        LNormals=LNormalsT;        LNumOfNormalsAllocated+=E3dVTXALLOC_INCREMENT;        LNormal=LNormals+LNumOfNormals;       }       else       {	EFree(LNormals);EFree(LNormals);	if(LSTs!=NULL) EFree(LSTs);	return(0);       }      }      fscanf(LFile, "%f %f %f", &LFX, &LFY, &LFZ);      LNormal->X=LFX;      LNormal->Y=LFY;      LNormal->Z=LFZ;      LNormal++;      LNumOfNormals++;     break;     case 't':								// Texture UVs      if(LNumOfSTs>=LNumOfSTsAllocated)      {       if((LSTsT=(E3dST*)ERealloc(LSTs, sizeof(E3dST)*(LNumOfSTs+E3dVTXALLOC_INCREMENT)))!=NULL)       {        LSTs=LSTsT;        LNumOfSTsAllocated+=E3dVTXALLOC_INCREMENT;        LST=LSTs+LNumOfSTs;       }       else       {	EFree(LNormals);EFree(LNormals);	if(LSTs!=NULL) EFree(LSTs);	return(0);       }      }      fscanf(LFile, "%f %f", &LFX, &LFY);      LST->S=LFX;      LST->T=LFY;      LST++;      LNumOfSTs++;     break;     default:      printf("OBJ reader: Unknown token: [%s]\n", LBuffer);      exit(1);     break;    }   break;   case 'm':								// Material reference    fgets(LBuffer, sizeof(LBuffer), LFile);				// Skip the rest of the line    sscanf(LBuffer, "%s %s", LBuffer, LBuffer);

⌨️ 快捷键说明

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