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

📄 3dsshape.cpp

📁 S.C.O.U.R.G.E.是一款类似Rogue的游戏
💻 CPP
字号:
/***************************************************************************                          3dsshape.cpp  -  description                             -------------------    begin                : Fri Oct 3 2003    copyright            : (C) 2003 by Gabor Torok    email                : cctorok@yahoo.com ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/ //#define DEBUG_3DS #define LIGHT_ANGLE 135.0f  #include "3dsshape.h"C3DSShape::C3DSShape(char *file_name, float div, ShapePalette *shapePal, 					 GLuint texture[],					 int width, int depth, int height,					 char *name, int descriptionGroup,					 Uint32 color, GLuint display_list, Uint8 shapePalIndex,					 int offsetx, int offsety) :  // passing 0 for texture causes glshape to not init#ifdef DEBUG_3DS  GLShape(texture, width, depth, height, name, descriptionGroup, color, display_list, shapePalIndex) {#else	GLShape(0, width, depth, height, name, descriptionGroup, color, display_list, shapePalIndex) {#endif	commonInit(file_name, div, shapePal, offsetx, offsety);    }C3DSShape::~C3DSShape() {  // When we are done, we need to free all the model data  // We do this by walking through all the objects and freeing their information  // Go through all the objects in the scene  for(int i = 0; i < g_3DModel.numOfObjects; i++) {	// Free the faces, normals, vertices, and texture coordinates.	delete [] g_3DModel.pObject[i].pFaces;	delete [] g_3DModel.pObject[i].pNormals;	delete [] g_3DModel.pObject[i].pVerts;	delete [] g_3DModel.pObject[i].pTexVerts;  } } void C3DSShape::commonInit(char *file_name, float div, ShapePalette *shapePal, int offsetx, int offsety) {   g_Texture[0] = 0;   g_ViewMode = GL_TRIANGLES;   this->div = div;   this->shapePal = shapePal;   this->offsetx = offsetx;   this->offsety = offsety;  // First we need to actually load the .3DS file.  We just pass in an address to  // our t3DModel structure and the file name string we want to load ("face.3ds").  char path[300];  strcpy(path, rootDir);  strcat(path, file_name);   fprintf(stderr, "Loading 3ds file: %s\n", path);  g_Load3ds.Import3DS(&g_3DModel, path);         // Load our .3DS file into our model structure  // Depending on how many textures we found, load each one (Assuming .BMP)  // If you want to load other files than bitmaps, you will need to adjust CreateTexture().  // Below, we go through all of the materials and check if they have a texture map to load.  // Otherwise, the material just holds the color information and we don't need to load a texture.  // Go through all the materials  for(int i = 0; i < g_3DModel.numOfMaterials; i++) {	// Check to see if there is a file name to load in this material	if(strlen(g_3DModel.pMaterials[i].strFile) > 0) {	  // Use the name of the texture file to load the bitmap, with a texture ID (i).	  // We pass in our global texture array, the name of the texture, and an ID to reference it. 	  fprintf(stderr, "Loading texture: %s\n", g_3DModel.pMaterials[i].strFile);	  //CreateTexture((GLuint*)g_Texture, g_3DModel.pMaterials[i].strFile, i);           	  // instead of loading the texture, get one of the already loaded textures	  g_Texture[i] = shapePal->findTextureByName(g_3DModel.pMaterials[i].strFile);	  fprintf(stderr, "\t%s\n", (g_Texture[i] ? "FOUND IT" : "NOT FOUND"));	}	// Set the texture ID for this material	g_3DModel.pMaterials[i].texureId = i;  }    // Find the lowest point  float minx, miny, minz;    float maxx, maxy, maxz;  minx = miny = minz = maxx = maxy = maxz = 0;  if(g_3DModel.pObject.size() > 0) {    // Get the current object that we are displaying    t3DObject *pObject = &g_3DModel.pObject[0];      for(int j = 0; j < pObject->numOfFaces; j++) {      for(int whichVertex = 0; whichVertex < 3; whichVertex++) {        int index = pObject->pFaces[j].vertIndex[whichVertex];        if(pObject->pVerts[ index ].x > maxx) maxx = pObject->pVerts[ index ].x;        if(pObject->pVerts[ index ].y > maxy) maxy = pObject->pVerts[ index ].y;        if(pObject->pVerts[ index ].z > maxz) maxz = pObject->pVerts[ index ].z;        if(pObject->pVerts[ index ].x < minx) minx = pObject->pVerts[ index ].x;        if(pObject->pVerts[ index ].y < miny) miny = pObject->pVerts[ index ].y;        if(pObject->pVerts[ index ].z < minz) minz = pObject->pVerts[ index ].z;              }    }  }  fprintf(stderr, "x=(%f,%f) y=(%f,%f) z=(%f,%f)\n",		  minx, maxx, miny, maxy, minz, maxz);  movex = minx;  movey = maxy;  movez = minz;  // pre-render the light  for(int i = 0; i < g_3DModel.numOfObjects; i++) {	if(g_3DModel.pObject.size() <= 0) break;	t3DObject *pObject = &g_3DModel.pObject[i];		for(int j = 0; j < pObject->numOfFaces; j++) {	  for(int whichVertex = 0; whichVertex < 3; whichVertex++) {		int index = pObject->pFaces[j].vertIndex[whichVertex];		// Simple light rendering:		// need the normal as mapped on the xy plane		// it's degree is the intensity of light it gets		float x = (pObject->pNormals[ index ].x == 0 ? 0.01f : pObject->pNormals[ index ].x);		float y = pObject->pNormals[ index ].y;		float rad = atan(y / x);		float angle = (180.0f * rad) / 3.14159;		  		// read about the arctan problem: 		// http://hyperphysics.phy-astr.gsu.edu/hbase/ttrig.html#c3		int q = 1;		if(x < 0) { 		// Quadrant 2 & 3		  q = ( y >= 0 ? 2 : 3);		  angle += 180;		} else if(y < 0) { // Quadrant 4		  q = 4;		  angle += 360;		}		  		// assertion		if(angle < 0 || angle > 360) {		  cerr << "Warning: angle=" << angle << " quadrant=" << q << endl;		}		  		// these are not used		//if(angle < 0) angle += 360.0f;		//if(angle > 360) angle -= 360.0f;		  		// calculate the angle distance from the light		float delta = 0;		if(angle > LIGHT_ANGLE && angle < LIGHT_ANGLE + 180.0f) {		  delta = angle - LIGHT_ANGLE;		} else {		  if(angle < LIGHT_ANGLE) angle += 360.0f;		  delta = (360 + LIGHT_ANGLE) - angle;		}		// assertion		if(delta < 0 || delta > 180.0f) {		  cerr << "WARNING: angle=" << angle << " delta=" << delta << endl;		}		// reverse and convert to value between 0 and 1		delta = 1.0f - (delta / 180.0f);		// store the value		pObject->shadingColorDelta[ index ] = delta;	  }	}  }}void C3DSShape::draw() {#ifdef DEBUG_3DS  GLShape::draw();#endif  glPushMatrix();  glDisable( GL_CULL_FACE );  //  glScalef( div, div, div );  //  glTranslatef( -movex, -movey, -movez );  glTranslatef(-movex * div, 0.0f, 0.0f);  glTranslatef(0.0f, (getDepth() / DIV) - (movey * div), 0.0f);//  glTranslatef(0.0f, 0.0f, -movez / 2.0f);  glTranslatef(0.0f, 0.0f, -movez);  glTranslatef((float)offsetx / DIV, (float)offsety / DIV, 0.0f);  // I am going to attempt to explain what is going on below up here as not to clutter the   // code below.  We have a model that has a certain amount of objects and textures.  We want   // to go through each object in the model, bind it's texture map to it, then render it.  // To render the current object, we go through all of it's faces (Polygons).    // What is a face you ask?  A face is just (in this case) a triangle of the object.  // For instance, a cube has 12 faces because each side has 2 triangles.  // You might be thinking.  Well, if there are 12 faces in a cube, that makes  // 36 vertices that we needed to read in for that object.  Not really true.  Because  // a lot of the vertices are the same, since they share sides, they only need to save  // 8 vertices, and ignore the duplicates.  Then, you have an array of all the  // unique vertices in that object.  No 2 vertices will be the same.  This cuts down  // on memory.  Then, another array is saved, which is the index numbers for each face,  // which index in to that array of vertices.  That might sound silly, but it is better  // than saving tons of duplicate vertices.  The same thing happens for UV coordinates.  // You don't save duplicate UV coordinates, you just save the unique ones, then an array  // that index's into them.  This might be confusing, but most 3D files use this format.  // This loop below will stay the same for most file formats that you load, so all you need  // to change is the loading code.  You don't need to change this loop (Except for animation).    // Since we know how many objects our model has, go through each of them.  for(int i = 0; i < g_3DModel.numOfObjects; i++) {	// Make sure we have valid objects just in case. (size() is in the vector class)	if(g_3DModel.pObject.size() <= 0) break;	// Get the current object that we are displaying	t3DObject *pObject = &g_3DModel.pObject[i];		// Check to see if this object has a texture map, if so bind the texture to it.    if(pObject->bHasTexture) {		// Bind the texture map to the object by it's materialID		glEnable(GL_TEXTURE_2D);		glBindTexture(GL_TEXTURE_2D, g_Texture[pObject->materialID]);	    if(!useShadow) glColor3ub(255, 255, 255);			  } else {		// Turn off texture mapping and turn on color		glDisable(GL_TEXTURE_2D);				// Reset the color to normal again		if(!useShadow) glColor3ub(255, 255, 255);	  }		float c[3];		// This determines if we are in wireframe or normal mode	glBegin(g_ViewMode);                    // Begin drawing with our selected mode (triangles or lines)		// Go through all of the faces (polygons) of the object and draw them	for(int j = 0; j < pObject->numOfFaces; j++) {	  // Go through each corner of the triangle and draw it.	  for(int whichVertex = 0; whichVertex < 3; whichVertex++) {		// Get the index for each point of the face		int index = pObject->pFaces[j].vertIndex[whichVertex];				// Give OpenGL the normal for this vertex.		glNormal3f(pObject->pNormals[ index ].x, pObject->pNormals[ index ].y, pObject->pNormals[ index ].z);		// If the object has a texture associated with it, give it a texture coordinate.		if(!useShadow) {		  if(pObject->bHasTexture) {			// texture color is white			c[0] = c[1] = c[2] = 1.0f;						// Make sure there was a UVW map applied to the object or else it won't have tex coords.			if(pObject->pTexVerts) {			  glTexCoord2f(pObject->pTexVerts[ index ].x, pObject->pTexVerts[ index ].y);			}		  } else {						// Make sure there is a valid material/color assigned to this object.			// You should always at least assign a material color to an object, 			// but just in case we want to check the size of the material list.			// if the size is at least one, and the material ID != -1,			// then we have a valid material.			if(g_3DModel.pMaterials.size() && pObject->materialID >= 0) {			  // Get and set the color that the object is, since it must not have a texture			  BYTE *pColor = g_3DModel.pMaterials[pObject->materialID].color;			  			  // Assign the current color to this model			  //glColor3ub(pColor[0], pColor[1], pColor[2]);			  c[0] = (float)pColor[0] / 255.0f;			  c[1] = (float)pColor[1] / 255.0f;			  c[2] = (float)pColor[2] / 255.0f;			}		  }		  		  // apply the precomputed shading to the current color		  c[0] *= pObject->shadingColorDelta[ index ];		  c[1] *= pObject->shadingColorDelta[ index ];		  c[2] *= pObject->shadingColorDelta[ index ];		  glColor3f(c[0], c[1], c[2]);		}				// Pass in the current vertex of the object (Corner of current face)		glVertex3f(pObject->pVerts[ index ].x * div, 				   pObject->pVerts[ index ].y * div, 				   pObject->pVerts[ index ].z * div);	  }	}		glEnd();                                // End the drawing  }  glPopMatrix();  if(!useShadow) glEnable(GL_TEXTURE_2D);  glEnable( GL_CULL_FACE );}void C3DSShape::setupBlending() {   glBlendFunc(GL_ONE, GL_ONE); }void C3DSShape::endBlending() { }bool C3DSShape::drawFirst() {   return true; }bool C3DSShape::drawLater() {   return false; }

⌨️ 快捷键说明

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