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

📄 billiards.cpp

📁 一款3d台球游戏,包含引擎代码和资源,非常精致
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// Billiard ball simulator// Created by Nelis Franken// -----------------------------------------------------------//  Main implementation file// -----------------------------------------------------------#include "billiards.h"// Loads 24-bit bitmap files with 1 plane only.// (Disclaimer: This function originally obtained from http://nehe.gamedev.net)int ImageLoad(const char *filename, Image *image) {    FILE *file;    unsigned long size;    unsigned long i;    unsigned short int planes;    unsigned short int bpp;    char temp, finalName[80];	strcpy(finalName, "textures/" );	strcat(finalName, filename );    if ((file = fopen(finalName, "rb"))==NULL) {		printf("File Not Found : %s\n",finalName);		return 0;    }    fseek(file, 18, SEEK_CUR);    if ((i = fread(&image->sizeX, 4, 1, file)) != 1) {		printf("Error reading width from %s.\n", finalName);		return 0;    }    if ((i = fread(&image->sizeY, 4, 1, file)) != 1) {		printf("Error reading height from %s.\n", finalName);		return 0;    }    size = image->sizeX * image->sizeY * 3;    if ((fread(&planes, 2, 1, file)) != 1) {		printf("Error reading planes from %s.\n", finalName);		return 0;    }    if (planes != 1) {		printf("Planes from %s is not 1: %u\n", finalName, planes);		return 0;    }    if ((i = fread(&bpp, 2, 1, file)) != 1) {		printf("Error reading bpp from %s.\n", finalName);		return 0;    }    if (bpp != 24) {	printf("Bpp from %s is not 24: %u\n", finalName, bpp);	return 0;    }    fseek(file, 24, SEEK_CUR);    image->data = (char *) malloc(size);    if (image->data == NULL) {		printf("Error allocating memory for color-corrected image data");		return 0;    }    if ((i = fread(image->data, size, 1, file)) != 1) {		printf("Error reading image data from %s.\n", finalName);		return 0;    }    for (i=0;i<size;i+=3) {		temp = image->data[i];		image->data[i] = image->data[i+2];		image->data[i+2] = temp;    }    return 1;}// Determines the normal from any three points on a plane.vector3 getNormal(GLfloat point1[3], GLfloat point3[3], GLfloat point4[3]) {	vector3 theNormal = vector3(0.0,0.0,0.0);	theNormal.x = (point1[1] - point4[1])*(point3[2] - point4[2]) - (point3[1] - point4[1])*(point1[2] - point4[2]);	theNormal.y = (point3[0] - point4[0])*(point1[2] - point4[2]) - (point1[0] - point4[0])*(point3[2] - point4[2]);	theNormal.z = (point1[0] - point4[0])*(point3[1] - point4[1]) - (point3[0] - point4[0])*(point1[1] - point4[1]);	return theNormal;}// Renders the billiard balls to screen (with dynamic shadows)void renderBalls() {	GLfloat m[16];	for (int i=0; i < 15; i++) m[i] = 0.0;	m[0] = m[5] = m[10] = 1.0;	m[7] = (-1.0)/(light0Pos[1] + 2.0);	for (int p=0; p < ballCount; p++) {		glPushMatrix();			glTranslatef(ballList[p].position.x,ballList[p].position.y,ballList[p].position.z);			// Determine shadows.			glPushMatrix();				glTranslatef(light0Pos[0], light0Pos[1]+0.65, light0Pos[2]);				glMultMatrixf(m);				glTranslatef(-1.0*light0Pos[0], -1.0*light0Pos[1], -1.0*light0Pos[2]);				glColor3f(0.0,0.0,0.0);				glBindTexture(GL_TEXTURE_2D, theTexture[BLACK]);				gluSphere(ballQuadric, ballList[p].radius, 32, 12);			glPopMatrix();			vector3 tempSpeed = vector3(0.0, 0.0, 0.0);			tempSpeed = ballList[p].speed;			tempSpeed.normalize();			vector3 speedNormal = vector3(0.0,0.0,0.0);			speedNormal.x = tempSpeed.z;			speedNormal.y = 0.0;			speedNormal.z = (-1.0)*tempSpeed.x;			if (ballList[p].rotation > 360.0) ballList[p].rotation =  ballList[p].rotation - 360.0;			ballList[p].rotation += ballList[p].speedSize/ballList[p].radius*(180.0/M_PI);			glBindTexture(GL_TEXTURE_2D, theTexture[p]);			glRotatef(ballList[p].rotation, speedNormal.x, speedNormal.y, speedNormal.z);			gluSphere(ballQuadric, ballList[p].radius, 32, 32);		glPopMatrix();	}}// Renders a flat surface to screen with predefined width/height, segments and texturevoid renderSurface(GLfloat width, GLfloat length, GLfloat widthSegments, GLfloat lengthSegments, GLfloat elevation, GLfloat texXTile, GLfloat texYTile, GLfloat normalX, GLfloat normalY, GLfloat normalZ, GLuint &surfaceTexture) {	glPushMatrix();		glBindTexture(GL_TEXTURE_2D, surfaceTexture);		for (GLfloat k=(width/(-2.0)); k < (width/(2.0)); k += (width/widthSegments)) {			for (GLfloat r=(length/(-2.0)); r < (length/(2.0)); r += (length/lengthSegments)) {			glBegin(GL_QUADS);				glNormal3f(normalX, normalY, normalZ);				glTexCoord2f(0.0, texYTile);				glVertex3f(k, elevation, r+length/lengthSegments);				glTexCoord2f(texXTile, texYTile);				glVertex3f(k+width/widthSegments, elevation, r+length/lengthSegments);				glTexCoord2f(texXTile, 0.0);				glVertex3f(k+width/widthSegments, elevation, r);				glTexCoord2f(0.0, 0.0);				glVertex3f(k, elevation, r);			glEnd();			}		}	glPopMatrix();}// Renders a quad represented by any 4 points to screen.void renderQuad(GLfloat point1[3], GLfloat point2[3], GLfloat point3[3], GLfloat point4[3], GLfloat orientation, GLfloat texXTile, GLfloat texYTile) {	glBegin(GL_QUADS);		vector3 theNormal = vector3(0.0, 0.0, 0.0);		theNormal = getNormal(point1, point3, point4);		theNormal = theNormal*orientation;		glNormal3f(theNormal.x, theNormal.y, theNormal.z);		glTexCoord2f(0.0, texYTile);		glVertex3fv(point1);		glNormal3f(theNormal.x, theNormal.y, theNormal.z);		glTexCoord2f(texXTile, texYTile);		glVertex3fv(point2);		glNormal3f(theNormal.x, theNormal.y, theNormal.z);		glTexCoord2f(texXTile, 0.0);		glVertex3fv(point3);		glNormal3f(theNormal.x, theNormal.y, theNormal.z);		glTexCoord2f(0.0, 0.0);		glVertex3fv(point4);	glEnd();}// Renders a curve (partial cylinder of any height and sweep) to screen.void renderCurve(GLfloat radius, GLfloat height, GLfloat sweep, GLuint segments, GLfloat orientation, GLuint &aTexture) {	glPushMatrix();		glBindTexture(GL_TEXTURE_2D, aTexture);		for (float t=0.0; t <= sweep-(sweep/segments); t += sweep/segments) {			GLfloat x = 0.0, y = 0.0, z = 0.0;			GLfloat point1[3] = {radius*cos(t), height, radius*sin(t)};			GLfloat point2[3] = {radius*cos(t+sweep/segments), height, radius*sin(t+sweep/segments)};			GLfloat point3[3] = {radius*cos(t+sweep/segments), 0.0, radius*sin(t+sweep/segments)};			GLfloat point4[3] = {radius*cos(t), 0.0, radius*sin(t)};			renderQuad(point1, point2, point3, point4, orientation, 1.0, 1.0);		}	glPopMatrix();}// Renders a disc (cap for a cylinder) of any sweep to screen.void renderCap(GLfloat inner_radius, GLfloat outer_radius, GLfloat inner_sweep, GLfloat outer_sweep, GLuint segments, GLuint &myTexture) {	glPushMatrix();		GLfloat ciX = 0.0, coX = 0.0, ciZ = 0.0, coZ = 0.0;		GLfloat angle = -1.0*outer_sweep/segments;		glBindTexture(GL_TEXTURE_2D, myTexture);		for (int k=0; k < segments; k++) {			ciX = inner_radius*cos(angle + inner_sweep/segments);			ciZ = inner_radius*sin(angle + inner_sweep/segments);			coX = outer_radius*cos(angle + outer_sweep/segments);			coZ = outer_radius*sin(angle + outer_sweep/segments);			angle += inner_sweep/segments;			glBegin(GL_QUADS);				glNormal3f(0.0,1.0,0.0);				glTexCoord2f(coX/(2.0*outer_radius), coZ/(2.0*outer_radius));				glVertex3f(coX, 0.0, coZ);				glNormal3f(0.0,1.0,0.0);				glTexCoord2f(outer_radius*cos(angle + outer_sweep/segments)/(2.0*outer_radius), outer_radius*sin(angle + outer_sweep/segments)/(2.0*outer_radius));				glVertex3f(outer_radius*cos(angle + outer_sweep/segments), 0.0, outer_radius*sin(angle + outer_sweep/segments));				glNormal3f(0.0,1.0,0.0);				glTexCoord2f(inner_radius*cos(angle + inner_sweep/segments)/(2.0*inner_radius), inner_radius*sin(angle + inner_sweep/segments)/(2.0*inner_radius));				glVertex3f(inner_radius*cos(angle + inner_sweep/segments), 0.0, inner_radius*sin(angle + inner_sweep/segments));				glNormal3f(0.0,1.0,0.0);				glTexCoord2f(ciX/(2.0*inner_radius), ciZ/(2.0*inner_radius));				glVertex3f(ciX, 0.0, ciZ);			glEnd();		}	glPopMatrix();}// Renders a pocket of generic alignment and predefined sweep to screen.void renderPocket(GLfloat sweep) {	glPushMatrix();		glTranslatef(0.0, -1.55, 0.0);		renderCurve(5.5, 2.55, sweep, 16, 1,  theTexture[DARK_WOOD]);		renderCurve(3.0, 2.55, sweep, 16, -1, theTexture[GREEN_CARPET]);		renderCap(0.0001, 5.5, 6.3, 6.3, 16, theTexture[BLACK]);	glPopMatrix();	glPushMatrix();		glTranslatef(0.0, 1.0, 0.0);		renderCap(3.0, 5.5, sweep, sweep, 16, theTexture[DARK_WOOD]);	glPopMatrix();	glPushMatrix();		glTranslatef(0.0, -1.4, 0.0);		if (sweep < M_PI+0.001) renderCap(0.0001, 3.0, M_PI, M_PI, 16, theTexture[BLACK]);		else renderCap(0.0001, 3.0, 6.3, 6.3, 16, theTexture[BLACK]);	glPopMatrix();}// Renders the curved table legs to screen.void renderTableLegs() {	glNewList(displayList[4], GL_COMPILE);	glBindTexture(GL_TEXTURE_2D, theTexture[DARK_WOOD]);	glPushMatrix();		for (double k=0; k < 3.0*M_PI; k+=1.4) {			for (double g=0; g < M_PI*2.0; g+=0.5) {				GLfloat point1[3] = {3.0*sin((k+1.4)/3.0)*cos(g), k*2, 3.0*sin((k+1.4)/3.0)*sin(g)};				GLfloat point2[3] = {3.0*sin((k+1.4)/3.0)*cos(g+0.5), k*2, 3.0*sin((k+1.4)/3.0)*sin(g+0.5)};				GLfloat point3[3] = {3.0*sin(k/3.0)*cos(g+0.5), k*2 - 2.8, 3.0*sin(k/3.0)*sin(g+0.5)};				GLfloat point4[3] = {3.0*sin(k/3.0)*cos(g), k*2 - 2.8, 3.0*sin(k/3.0)*sin(g)};				renderQuad(point1, point2, point3, point4, 1.0, 1.0, 1.0);			}		}		glRotatef(90.0, 1.0, 0.0 ,0.0);		glutSolidTorus(1.0, 1.8, 5, 8);		gluCylinder(pillarCylinder, 1.0, 3.0, 4.0, 8, 2);	glPopMatrix();	glEndList();}// Draws one side of the table (generically aligned)void drawSide() {	// Wooden side	glPushMatrix();		glTranslatef(0, -0.3, 0);		glScalef(1.0, 1.0, 2.0);		glRotatef(270.0, 0.0, 1.0, 0.0);		glRotatef(45.0, 0.0, 0.0, 1.0);		glBindTexture(GL_TEXTURE_2D, theTexture[WOOD]);		gluCylinder(pillarCylinder, 1.7, 1.7, tableWidth - 6, 4, 4);	glPopMatrix();	// Green carpeted side	glPushMatrix();		glTranslatef(-1.0*tableWidth + 6, 0.0, -2.35);		glRotatef(180.0, 0.0, 0.0, 1.0);		glRotatef(270.0, 0.0, 1.0, 0.0);		glScalef(0.5, 1.0, 1.0);		glBindTexture(GL_TEXTURE_2D, theTexture[GREEN_CARPET]);		gluCylinder(pillarCylinder, 1.7, 1.7, tableWidth - 6, 3, 3);	glPopMatrix();}// Draws the entire table to screenvoid renderTable() {	glNewList(displayList[1], GL_COMPILE);	glColor3f(1.0,1.0,1.0);	// Table carpeted area	renderSurface(tableWidth, tableLength, 10.0, 15.0, -1.5, 1.0, 1.0, 0.0, 1.0, 0.0, theTexture[GREEN_CARPET]);	// Anti-aliased game-lines on carpeted area	glPushMatrix();		glDisable(GL_TEXTURE_2D);		glDisable(GL_LIGHTING);		glEnable(GL_BLEND);		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);		glEnable(GL_LINE_SMOOTH);		glColor4f(0.5, 0.5, 0.5, 0.4);		glLineWidth(2.5f);		// Horisontal line		glTranslatef(0.0, -1.45, 0.0);		glBegin(GL_LINES);			glVertex3f(minX - pocketRadius, 0.0, minZ - minZ/3);			glVertex3f(maxX + pocketRadius, 0.0, minZ - minZ/3);		glEnd();		// Half-circle		glTranslatef(0.0, 0.0, minZ - minZ/3);		glRotatef(90.0, 0.0, 1.0, 0.0);		glBegin(GL_LINES);			for (GLfloat i = 0.0; i < M_PI-(M_PI/12.0); i+=M_PI/12.0) {				glVertex3f((maxZ/6.0)*sin(i), 0.0, (maxZ/6.0)*cos(i));				glVertex3f((maxZ/6.0)*sin(i+M_PI/12.0), 0.0, (maxZ/6.0)*cos(i+M_PI/12.0));			}		glEnd();		glLineWidth(1.0f);		// Start-point on line		glRotatef(90.0, 1.0, 0.0, 0.0);		gluDisk(pillarCylinder, 0, 0.3, 9, 1);		glDisable(GL_LINE_SMOOTH);		glDisable(GL_BLEND);		glEnable(GL_LIGHTING);		glEnable(GL_TEXTURE_2D);	glPopMatrix();	// Table sides	GLint divCount = -5, angleDirection = 1;	GLfloat offA = 2.4, offB = 3.0, offTemp = 0.0, sideAngle = 270.0;	for(GLint f=1; f >= -1; f--) {		for (GLfloat r=-1.0; r <= 1.0; r+=2.0) {			glPushMatrix();				glTranslatef(tableWidth/(r*2.0) + (abs(divCount)/divCount)*offA, 0.0, f*tableWidth + r*offB);				glRotatef(sideAngle, 0.0, 1.0, 0.0);				drawSide();			glPopMatrix();			divCount += 2;			if ((f == 0) && (r == -1.0)) {				offA = 2.4; offB = 3.0; offTemp = 0.0;				sideAngle = 90.0;				angleDirection = 1;			} else {				offTemp = offA; offA = offB; offB = offTemp;				sideAngle = sideAngle + angleDirection*90.0;				angleDirection *= -1;			}		}	}	// Pockets	GLfloat direction = -1.0, angle = 360.0, sweep = M_PI + M_PI/2.0;	bool sidePocket = false;	for (int g=-1; g <= 1; g+=2) {		for (int d=1; d >= -1; d-=1) {			glPushMatrix();				glTranslatef(g*tableWidth/(2.0), 0.0, d*tableWidth);				glRotatef(angle,0.0,1.0,0.0);				renderPocket(sweep);			glPopMatrix();			if (d == 1) {				sweep = M_PI;				if (g == -1) {					angle = angle + direction*90;					sidePocket = true;				}			} else {				if (sidePocket == false) angle = angle + direction*90; else sidePocket = false;				sweep = M_PI + M_PI/2.0;			}		}		direction = -1*direction;		angle = 90;	}

⌨️ 快捷键说明

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