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

📄 main.cpp

📁 一本关于OPenGL的很好的电子书
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		thisTexture = LoadPCXTexture(filename);
	/*
	else if ((strcmp(extStr, "TGA") == 0) || (strcmp(extStr, "tga") == 0) )
		thisTexture = LoadTGATexture(filename);
		//texType = TGA;
	*/
	return thisTexture;
}

// SetupMD2Texture()
// desc: sets up a texture for use with an MD2 model
void SetupMD2Texture(texture_t *thisTexture)
{
	// set the proper parameters for an MD2 texture
	glGenTextures(1, &thisTexture->texID);
	glBindTexture(GL_TEXTURE_2D, thisTexture->texID);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

	switch (thisTexture->textureType)
	{
		case BMP:
			gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, thisTexture->width, thisTexture->height, 
							  GL_RGB, GL_UNSIGNED_BYTE, thisTexture->data);
			break;
		case PCX:
			gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, thisTexture->width, thisTexture->height,
							  GL_RGBA, GL_UNSIGNED_BYTE, thisTexture->data);
		case TGA:
			break;
		default:
			break;
	}
}

// LoadMD2Model()
// desc: loads an MD2 model specified by filename and with the texture
// specified by textureName
modelData_t *LoadMD2Model(char *filename, char *textureName)
{
	FILE *filePtr;						// file pointer
	int fileLen;						// length of model file
    char *buffer;						// file buffer
		
	modelData_t *model;					// the model
	modelHeader_t *modelHeader;			// model header
	texture_t *md2Texture;				// model texture

	stIndex_t *stPtr;					// texture data
    frame_t *frame;						// frame data
	vector_t *pointListPtr;				// index variable
    mesh_t *triIndex, *bufIndexPtr;		// index variables
    int i, j;							// index variables

	// open the model file
	filePtr = fopen(filename, "rb");
	if (filePtr == NULL)
		return NULL;

	// find length of file
    fseek(filePtr, 0, SEEK_END);
    fileLen = ftell(filePtr);
    fseek(filePtr, 0, SEEK_SET);
	
    // read entire file into buffer
    buffer = (char*)malloc(fileLen + 1);
    fread(buffer, sizeof(char), fileLen, filePtr);

	// extract model file header from buffer
    modelHeader = (modelHeader_t*)buffer;

	// allocate memory for model data
   	model = (modelData_t*)malloc(sizeof(modelData_t));
	if (model == NULL)
		return NULL;

	// allocate memory for all vertices used in model, including animations
    model->pointList = (vector_t*)malloc(sizeof(vector_t)*modelHeader->numXYZ * modelHeader->numFrames);

	// store vital model data
    model->numPoints = modelHeader->numXYZ;
    model->numFrames = modelHeader->numFrames;
	model->frameSize = modelHeader->framesize;

    // loop number of frames in model file
    for(j = 0; j < modelHeader->numFrames; j++)
    {
       // offset to the points in this frame
       frame = (frame_t*)&buffer[modelHeader->offsetFrames + modelHeader->framesize * j];

	   // calculate the point positions based on frame details
       pointListPtr = (vector_t*)&model->pointList[modelHeader->numXYZ * j];
       for(i = 0; i < modelHeader->numXYZ; i++)
       {
          pointListPtr[i].point[0] = frame->scale[0] * frame->fp[i].v[0] + frame->translate[0];
          pointListPtr[i].point[1] = frame->scale[1] * frame->fp[i].v[1] + frame->translate[1];
          pointListPtr[i].point[2] = frame->scale[2] * frame->fp[i].v[2] + frame->translate[2];
       }
    }
			 
	// load the model texture
	md2Texture = LoadTexture(textureName);
	if (md2Texture != NULL)
	{
		// setup texture for opengl and store it in model data structure
		SetupMD2Texture(md2Texture);
		model->modelTex = md2Texture;
	}
	else
		return NULL;

    // allocate memory for the model texture coordinates
    model->st = (texCoord_t*)malloc(sizeof(texCoord_t)*modelHeader->numST);

	// store number of texture coordinates
    model->numST = modelHeader->numST;

	// set texture pointer to texture coordinate offset
    stPtr = (stIndex_t*)&buffer[modelHeader->offsetST];

	// calculate and store the texture coordinates for the model
    for (i = 0; i < modelHeader->numST; i++)
    {
		model->st[i].s = (float)stPtr[i].s / (float)md2Texture->width;
        model->st[i].t = (float)stPtr[i].t / (float)md2Texture->height;
    }

	// allocate an index of triangles
	triIndex = (mesh_t*)malloc(sizeof(mesh_t) * modelHeader->numTris);

	// set total number of triangles
	model->numTriangles = modelHeader->numTris;
	model->triIndex = triIndex;
	
	// point to triangle indexes in buffer
	bufIndexPtr = (mesh_t*)&buffer[modelHeader->offsetTris];

	// create a mesh (triangle) list
	for (j = 0; j < model->numFrames; j++)		
	{
		// for all triangles in each frame
		for(i = 0; i < modelHeader->numTris; i++)
		{
		   triIndex[i].meshIndex[0] = bufIndexPtr[i].meshIndex[0];
		   triIndex[i].meshIndex[1] = bufIndexPtr[i].meshIndex[1];
		   triIndex[i].meshIndex[2] = bufIndexPtr[i].meshIndex[2];
		   triIndex[i].stIndex[0] = bufIndexPtr[i].stIndex[0];
		   triIndex[i].stIndex[1] = bufIndexPtr[i].stIndex[1];
		   triIndex[i].stIndex[2] = bufIndexPtr[i].stIndex[2];
		}
	}

	// close file and free memory
	fclose(filePtr);
    free(buffer);

	model->currentFrame = 0;
	model->nextFrame = 1;
	model->interpol = 0.0;

    return model;
}

// CalculateNormal()
// desc: given 3 points, calculates the normal to the points
void CalculateNormal( float *p1, float *p2, float *p3 )
{
   float a[3], b[3], result[3];
   float length;

   a[0] = p1[0] - p2[0];
   a[1] = p1[1] - p2[1];
   a[2] = p1[2] - p2[2];

   b[0] = p1[0] - p3[0];
   b[1] = p1[1] - p3[1];
   b[2] = p1[2] - p3[2];

   result[0] = a[1] * b[2] - b[1] * a[2];
   result[1] = b[0] * a[2] - a[0] * b[2];
   result[2] = a[0] * b[1] - b[0] * a[1];

   // calculate the length of the normal
   length = (float)sqrt(result[0]*result[0] + result[1]*result[1] + result[2]*result[2]);

   // normalize and specify the normal
   glNormal3f(result[0]/length, result[1]/length, result[2]/length);
}

// DisplayMD2()
// desc: displays the frameNum frame of an MD2 model
void DisplayMD2(modelData_t *model, int frameNum)
{
	vector_t *pointList;
	int i;

    // create a pointer to the frame we want to show
    pointList = &model->pointList[model->numPoints * frameNum];

	// set the texture
	glBindTexture(GL_TEXTURE_2D, model->modelTex->texID);

	// display the textured model with proper lighting normals
    glBegin(GL_TRIANGLES);
		for(i = 0; i < model->numTriangles; i++)
        {
			CalculateNormal(pointList[model->triIndex[i].meshIndex[0]].point,
                             pointList[model->triIndex[i].meshIndex[2]].point,
                             pointList[model->triIndex[i].meshIndex[1]].point);
			glTexCoord2f(model->st[model->triIndex[i].stIndex[0]].s,
						 model->st[model->triIndex[i].stIndex[0]].t);
			glVertex3fv(pointList[model->triIndex[i].meshIndex[0]].point);

			glTexCoord2f(model->st[model->triIndex[i].stIndex[2]].s ,
					     model->st[model->triIndex[i].stIndex[2]].t);
            glVertex3fv(pointList[model->triIndex[i].meshIndex[2]].point);

			glTexCoord2f(model->st[model->triIndex[i].stIndex[1]].s,
					     model->st[model->triIndex[i].stIndex[1]].t);
            glVertex3fv(pointList[model->triIndex[i].meshIndex[1]].point);
        }
    glEnd();
}

// DisplayMD2Interpolate()
// desc: displays an animated MD2 model with keyframe interpolation
void DisplayMD2Interpolate(modelData_t *model)
{
	vector_t *pointList;			// current frame vertices
	vector_t *nextPointList;		// next frame vertices
	int i;							// index counter
	float x1, y1, z1;				// current frame point values
	float x2, y2, z2;				// next frame point values

	vector_t vertex[3];	

	if (model == NULL)
		return;

	if (model->interpol >= 1.0)
	{
		model->interpol = 0.0f;
		model->currentFrame++;
		if (model->currentFrame >= model->numFrames)
			model->currentFrame = 0;

		model->nextFrame = model->currentFrame + 1;

		if (model->nextFrame >= model->numFrames)
			model->nextFrame = 0;
	}

	pointList = &model->pointList[model->numPoints*model->currentFrame];
	nextPointList = &model->pointList[model->numPoints*model->nextFrame];
	
	glBindTexture(GL_TEXTURE_2D, model->modelTex->texID);
	glBegin(GL_TRIANGLES);
		for (i = 0; i < model->numTriangles; i++)
		{
			// get first points of each frame
			x1 = pointList[model->triIndex[i].meshIndex[0]].point[0];
			y1 = pointList[model->triIndex[i].meshIndex[0]].point[1];
			z1 = pointList[model->triIndex[i].meshIndex[0]].point[2];
			x2 = nextPointList[model->triIndex[i].meshIndex[0]].point[0];
			y2 = nextPointList[model->triIndex[i].meshIndex[0]].point[1];
			z2 = nextPointList[model->triIndex[i].meshIndex[0]].point[2];

			// xi + percentage * (xf - xi)
			// store first interpolated vertex of triangle
			vertex[0].point[0] = x1 + model->interpol * (x2 - x1);
			vertex[0].point[1] = y1 + model->interpol * (y2 - y1);
			vertex[0].point[2] = z1 + model->interpol * (z2 - z1);
		
			// get second points of each frame
			x1 = pointList[model->triIndex[i].meshIndex[2]].point[0];
			y1 = pointList[model->triIndex[i].meshIndex[2]].point[1];
			z1 = pointList[model->triIndex[i].meshIndex[2]].point[2];
			x2 = nextPointList[model->triIndex[i].meshIndex[2]].point[0];
			y2 = nextPointList[model->triIndex[i].meshIndex[2]].point[1];
			z2 = nextPointList[model->triIndex[i].meshIndex[2]].point[2];

			// store second interpolated vertex of triangle
			vertex[2].point[0] = x1 + model->interpol * (x2 - x1);
			vertex[2].point[1] = y1 + model->interpol * (y2 - y1);
			vertex[2].point[2] = z1 + model->interpol * (z2 - z1);	
	
			// get third points of each frame
			x1 = pointList[model->triIndex[i].meshIndex[1]].point[0];
			y1 = pointList[model->triIndex[i].meshIndex[1]].point[1];
			z1 = pointList[model->triIndex[i].meshIndex[1]].point[2];
			x2 = nextPointList[model->triIndex[i].meshIndex[1]].point[0];
			y2 = nextPointList[model->triIndex[i].meshIndex[1]].point[1];
			z2 = nextPointList[model->triIndex[i].meshIndex[1]].point[2];

			// store third interpolated vertex of triangle
			vertex[1].point[0] = x1 + model->interpol * (x2 - x1);
			vertex[1].point[1] = y1 + model->interpol * (y2 - y1);
			vertex[1].point[2] = z1 + model->interpol * (z2 - z1);

			// calculate the normal of the triangle
			CalculateNormal(vertex[0].point, vertex[2].point, vertex[1].point);

			// render properly textured triangle
			glTexCoord2f(model->st[model->triIndex[i].stIndex[0]].s,
						 model->st[model->triIndex[i].stIndex[0]].t);
			glVertex3fv(vertex[0].point);

			glTexCoord2f(model->st[model->triIndex[i].stIndex[2]].s ,
					     model->st[model->triIndex[i].stIndex[2]].t);
			glVertex3fv(vertex[2].point);

			glTexCoord2f(model->st[model->triIndex[i].stIndex[1]].s,
					     model->st[model->triIndex[i].stIndex[1]].t);
			glVertex3fv(vertex[1].point);
		}
	glEnd();

	model->interpol += 0.05f;	// increase percentage of interpolation between frames
}

// DisplayMD2Interpolate()
// desc: displays a frame of the model between startFrame and endFrame with an interpolation percent
void DisplayMD2Interpolate(modelData_t *model, int startFrame, int endFrame, float percent)
{
	vector_t *pointList;			// current frame vertices
	vector_t *nextPointList;			// next frame vertices
	int i;					// index counter
	float x1, y1, z1;				// current frame point values
	float x2, y2, z2;				// next frame point values

	vector_t vertex[3];	

	if (model == NULL)
		return;
	
	if ( (startFrame < 0) || (endFrame < 0) )
		return;

	if ( (startFrame >= model->numFrames) || (endFrame >= model->numFrames) )
		return;

	if (model->interpol >= 1.0)
	{
		model->interpol = 0.0f;
		model->currentFrame++;
		if (model->currentFrame >= endFrame)//model->numFrames)
			model->currentFrame = startFrame; //0;

		model->nextFrame = model->currentFrame + 1;

		if (model->nextFrame >= endFrame)
			model->nextFrame = startFrame;
	}

	pointList = &model->pointList[model->numPoints*model->currentFrame];
	nextPointList = &model->pointList[model->numPoints*model->nextFrame];
	
	glBindTexture(GL_TEXTURE_2D, model->modelTex->texID);
	glBegin(GL_TRIANGLES);
		for (i = 0; i < model->numTriangles; i++)
		{
			// get first points of each frame
			x1 = pointList[model->triIndex[i].meshIndex[0]].point[0];
			y1 = pointList[model->triIndex[i].meshIndex[0]].point[1];
			z1 = pointList[model->triIndex[i].meshIndex[0]].point[2];
			x2 = nextPointList[model->triIndex[i].meshIndex[0]].point[0];
			y2 = nextPointList[model->triIndex[i].meshIndex[0]].point[1];
			z2 = nextPointList[model->triIndex[i].meshIndex[0]].point[2];

			// store first interpolated vertex of triangle
			vertex[0].point[0] = x1 + model->interpol * (x2 - x1);
			vertex[0].point[1] = y1 + model->interpol * (y2 - y1);
			vertex[0].point[2] = z1 + model->interpol * (z2 - z1);

⌨️ 快捷键说明

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