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

📄 game_render.cpp

📁 这是一个台球游戏的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "Game.h"
#include "Camera.h"
#include <math.h>

extern CPoolGame theGame;
extern CCamera theCamera;

static GLuint tex_floor, tex_rod;

bool LoadImageFromFile(const char *fname, 
	int * p_width, int * p_height, BYTE ** pp_image)
// fname:    Image file name
// p_width:  Width of the image (output)
// p_height: Height of the image (output)
// pp_image: Image bits in 32bit RGBA format (output)
// Return value: true --- successful, false --- failed
{
	// Load bitmap
	HBITMAP hbmp=(HBITMAP)LoadImage(NULL, fname, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
	if (hbmp==NULL) return false;

	// Get Device Context
	HDC dc = GetDC(NULL);

	// Initialize bitmap info structure
	BITMAPINFO bmpInfo;
	BITMAPINFOHEADER * pheader;
	ZeroMemory(&bmpInfo, sizeof(BITMAPINFO));
	pheader=&bmpInfo.bmiHeader;
	pheader->biSize=sizeof(BITMAPINFOHEADER);

	// Query bitmap size and format information
	GetDIBits(dc, hbmp, 0, 0, NULL, &bmpInfo, DIB_RGB_COLORS);
	*p_width=pheader->biWidth;
	if (pheader->biHeight < 0) pheader->biHeight=-pheader->biHeight;
	*p_height=pheader->biHeight;

	// Request 32bit non-compressed format
	pheader->biBitCount=32;
	pheader->biCompression=BI_RGB;

	// Read bitmap bits information
	int bmp_size=(*p_width)*(*p_height);
	*pp_image=new BYTE[bmp_size*4];
	GetDIBits(dc, hbmp, 0, *p_height, *pp_image, &bmpInfo, DIB_RGB_COLORS);

	// Change pixel format from BGRA to RGBA 
	// and set alpha value to opaque
	int k=0;
	for (int i=0; i<bmp_size; ++i)
	{
		BYTE btmp;
		btmp=(*pp_image)[k];
		(*pp_image)[k]=(*pp_image)[k+2];
		(*pp_image)[k+2]=btmp;
		(*pp_image)[k+3]=255;
		k+=4;
	}

	// Release Device Context
	ReleaseDC(NULL, dc);
	DeleteObject(hbmp);

	return true;
}

// Load texture image from a BMP file
GLuint GL_load_texture(const char *image_file, int width, int height)
{
	int nx, ny;
	GLubyte *p_image=NULL, *tex_image=NULL;

	tex_image=new GLubyte[width*height*4];

	if (!LoadImageFromFile(image_file, &nx, &ny, &p_image)) return 0;

	gluScaleImage(GL_RGBA, nx, ny, GL_UNSIGNED_BYTE, p_image,
		width, height, GL_UNSIGNED_BYTE, tex_image);
	delete [] p_image;

	GLuint tn;
	glGenTextures(1, &tn);
	glBindTexture(GL_TEXTURE_2D, tn);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 
		0, GL_RGBA, GL_UNSIGNED_BYTE, tex_image);

	delete [] tex_image;
	return tn;
}

double rod_length=1.0, rod_radius=0.006, rod_angle=8.0;
double tall=0.7, thick=0.06; // leg

void CPoolGame::Render(void)
{
	int i, j;

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	if (status==GS_REPOSITION)
	{
		gluLookAt(0.0, 0.0, 1.8, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
	}
	else
	{
		double lookat[3];
		theCamera.get_lookat_from_pos();
		gluLookAt(theCamera.m_x, theCamera.m_y, theCamera.m_z, 
			theCamera.m_lookat[0], theCamera.m_lookat[1], theCamera.m_lookat[2],
			0.0, 0.0, 1.0);
	}
	//light0
	static GLfloat light_position[] = {0.0f, 0.0f, 1.8f, 1.0f};
	static GLfloat light_direction[] = {0.0f, 0.0f, -1.0f};
	GLfloat light0_ambient[]= { 0.1f, 0.1f, 0.1f, 1.0f };
    GLfloat light0_diffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f };
    GLfloat light0_specular[] = { 0.3f, 0.3f, 0.3f, 1.0f };

	glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
	glLightfv(GL_LIGHT0, GL_SPECULAR,light0_specular);
	glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,0.5);
	glLightf (GL_LIGHT0, GL_SPOT_CUTOFF, 60.0);

    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
	glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_direction);
	//default
	glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION, 1.0);
	glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION, 0.0);
	glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION, 0.0);

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, tex_floor);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

	//draw the floor
	GLdouble floor_color[]={1.0, 1.0, 1.0, 1.0};
	GLdouble floor_scolor[]={0.0, 0.0, 0.0, 1.0};
	glMaterialf(GL_FRONT,GL_SHININESS,0);

	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
	glColor3dv(floor_color);
	glColorMaterial(GL_FRONT, GL_SPECULAR);
	glColor3dv(floor_scolor);
	
	double floor_width=5.0, floor_height=5.0;

	glPushMatrix();
	glNormal3f(0, 0, 1);
	
	glTranslated(0.0,0.0,-tall);
	glBegin(GL_QUADS);
		glTexCoord2f(0.0, 0.0);
		glVertex3f(0.5*floor_width, 0.5*floor_height, 0.0);
		glTexCoord2f(0.0, 5.0);
		glVertex3f(-0.5*floor_width, 0.5*floor_height, 0.0);
		glTexCoord2f(5.0, 5.0);
		glVertex3f(-0.5*floor_width, -0.5*floor_height, 0.0);
		glTexCoord2f(5.0, 0.0);
		glVertex3f(0.5*floor_width, -0.5*floor_height, 0.0);
	glEnd();
	glPopMatrix();

	//Draw the rod
	glBindTexture(GL_TEXTURE_2D, tex_rod);
	if (status==GS_AIMING || status==GS_HITTING)
	{
		glPushMatrix();
		glLoadIdentity();

		glMaterialf(GL_FRONT, GL_SHININESS, 100.0);
		glColorMaterial(GL_FRONT, GL_SPECULAR);
		glColor3ub(255, 255, 255);
		glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
		glColor3ub(255,255,255);

		glTranslated(0.0, 0.0, -theCamera.m_r);
		glRotatef(rod_angle, 1.0, 0.0, 0.0);
		glTranslated(0.0, 0.0, balls[0].r+rod_ball_dist+0.1);
		glCallList(rod_list);

		glPopMatrix();
	}

	glDisable(GL_TEXTURE_2D);

	//Draw legs
	double ry=0.075;
	glMaterialf(GL_FRONT, GL_SHININESS, 100.0);
	glColorMaterial(GL_FRONT, GL_SPECULAR);
	glColor3ub(200, 200, 200);
	
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

	glColor3ub(183,41,2);
	glPushMatrix();
	glTranslated(sizex/2-ry, sizey/2-ry, -0.01);
	glScalef(1.0, 1.0, 1.0);
	glCallList(leg_list);
	glPopMatrix();

	glColor3ub(183,41,2);
	glPushMatrix();
	glTranslated(sizex/2-ry, -sizey/2+ry, -0.01);
	glScalef(1.0, 1.0, 1.0);
	glCallList(leg_list);
	glPopMatrix();

	glPushMatrix();
	glTranslated(-sizex/2+ry, sizey/2-ry, -0.01);
	glScalef(1.0, 1.0, 1.0);
	glCallList(leg_list);
	glPopMatrix();

	glPushMatrix();
	glTranslated(-sizex/2+ry, -sizey/2+ry, -0.01);
	glScalef(1.0, 1.0, 1.0);
	glCallList(leg_list);
	glPopMatrix();


	// Draw balls
	int n=theGame.num_balls;
	glMaterialf(GL_FRONT, GL_SHININESS, 100.0);
	glColorMaterial(GL_FRONT, GL_SPECULAR);
	glColor3ub(200, 200, 200);
	
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
	for (i=0; i<n; ++i)
	{
		CBall *p;
		p=theGame.balls+i;
		glColor4ubv(p->color);
		glPushMatrix();
		glTranslated(p->x[0], p->x[1], p->x[2]);
		glScalef(p->r, p->r, p->r);
		glCallList(sphere_list);
		glPopMatrix();
	}

	//Draw the shadow of sphere
	glDisable(GL_LIGHTING);
	for (i=0; i<n; ++i)
	{
		CBall *p;
		p=theGame.balls+i;
		if(theGame.balls[i].status!= BS_IN_THE_HOLE 
			&& theGame.balls[i].status!= BS_REMOVED)
		{
			double x1,y1;	
			x1=(p->x[0]*light_position[2]-p->x[2]*light_position[0])/light_position[2];
			y1=(p->x[1]*light_position[2]-p->x[2]*light_position[1])/light_position[2];
			glColor3d(0.1, 0.1, 0.1);
			glPushMatrix();
			glTranslated(x1, y1, 0.001);
			glScalef(p->r, p->r, p->r);
			glCallList(shadow_list);
			glPopMatrix();		
		}
	}
	glEnable(GL_LIGHTING);
	// Draw desk top
	glMaterialf(GL_FRONT, GL_SHININESS, 0.0);
	glColorMaterial(GL_FRONT, GL_SPECULAR);
	glColor3ub(0, 0, 0);
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
	glColor3ub(0, 200, 100);
	
	glNormal3f(0.0, 0.0, 1.0);

	double bevel=0.01;
	int nx=40, ny=20;
	double deltax=(theGame.sizex+2*bevel)/nx;
	double deltay=(theGame.sizey+2*bevel)/ny;
	double x, y;

	y=-0.5*(theGame.sizey+2*bevel);
	for (j=0; j<ny; ++j)
	{
		x=-0.5*(theGame.sizex+2*bevel);
		glBegin(GL_QUAD_STRIP);
		for (i=0; i<=nx; ++i)
		{
			if((j==0 || j==ny-1) && (i==0 || i==nx));
			else{
				glVertex3f(x, y+deltay, 0.0);
				glVertex3f(x, y, 0.0);
			}
			x+=deltax;
		}
		glEnd();
		y+=deltay;
	}

	//white line
	glMaterialf(GL_FRONT, GL_SHININESS, 0.0);
	glColorMaterial(GL_FRONT, GL_SPECULAR);
	glColor3ub(0, 0, 0);
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
	glColor3ub(255, 255, 255);
	double ww=0.003, hh=0.001;
	glBegin(GL_QUADS);
		glVertex3f(0.76-ww, -0.5*sizey, hh);
		glVertex3f(0.76+ww, -0.5*sizey, hh);
		glVertex3f(0.76+ww, 0.5*sizey, hh);
		glVertex3f(0.76-ww, 0.5*sizey, hh);
	glEnd();

	//super holes
	glColor3ubv(theGame.boundaries[0].color);
	//腰洞
	double hx=theGame.holes[0].x[0], hy=theGame.holes[0].x[1], 
		hr=theGame.holes[0].r, beta=0.0, dt=0.115;
	double ks=theGame.boundaries[0].top;
	double x1,x2,x3,x4,x5,x6,y1,y2,y3,y4,y5,y6;
	for(int z=0;z<10;z++){
		x3=hx+hr*cos(beta);y3=hy+hr*sin(beta);
		beta+=PI/10;
		x4=hx+hr*cos(beta);y4=hy+hr*sin(beta);
		x2=x3;x1=x4;x5=x4;x6=x3;y5=y4;y6=y3;
		y1=y2=theGame.boundaries[0].x[0][1]+dt;

		glNormal3f(0.0, 0.0, 1.0);
		glBegin(GL_QUADS);
		glVertex3f(x4, y4, ks);
		glVertex3f(x3, y3, ks);
		glVertex3f(x2, y2, ks);
		glVertex3f(x1, y1, ks);
		glEnd();

		glNormal3f(-cos(beta), -sin(beta), 0.0);
		glBegin(GL_QUADS);
		glVertex3f(x3, y3, ks);
		glVertex3f(x4, y4, ks);
		glVertex3f(x5, y5, 0.0);
		glVertex3f(x6, y6, 0.0);
		glEnd();

		glNormal3f(0.0, 1.0, 0.0);
		glBegin(GL_QUADS);
		glVertex3f(x1, y1, ks);
		glVertex3f(x2, y2, ks);
		glVertex3f(x2, y2, 0.0);
		glVertex3f(x1, y1, 0.0);
		glEnd();
	}

	hx=theGame.holes[3].x[0], hy=theGame.holes[3].x[1], hr=theGame.holes[3].r, beta=PI;
	for(z=0;z<10;z++){
		x3=hx+hr*cos(beta);y3=hy+hr*sin(beta);
		beta+=PI/10;
		x4=hx+hr*cos(beta);y4=hy+hr*sin(beta);
		x2=x3;x1=x4;x5=x4;x6=x3;y5=y4;y6=y3;
		y1=y2=theGame.boundaries[2].x[0][1]-dt;

		glNormal3f(0.0, 0.0, 1.0);
		glBegin(GL_QUADS);
		glVertex3f(x4, y4, ks);
		glVertex3f(x3, y3, ks);
		glVertex3f(x2, y2, ks);
		glVertex3f(x1, y1, ks);
		glEnd();

		glNormal3f(-cos(beta), -sin(beta), 0.0);
		glBegin(GL_QUADS);
		glVertex3f(x3, y3, ks);
		glVertex3f(x4, y4, ks);
		glVertex3f(x5, y5, 0.0);
		glVertex3f(x6, y6, 0.0);
		glEnd();

		glNormal3f(0.0, -1.0, 0.0);
		glBegin(GL_QUADS);
		glVertex3f(x1, y1, ks);
		glVertex3f(x2, y2, ks);
		glVertex3f(x2, y2, 0.0);
		glVertex3f(x1, y1, 0.0);
		glEnd();
	}
	//角洞
	hx=theGame.holes[1].x[0], hy=theGame.holes[1].x[1], hr=theGame.holes[1].r, beta=-PI/3;
	double alfa=0.0;
	double bdx=theGame.boundaries[0].x[3][0],bdy=theGame.boundaries[1].x[0][1],
		bdr=theGame.boundaries[1].x[0][0]-theGame.boundaries[0].x[3][0]+dt;
	for(z=0;z<10;z++){
		x3=hx+hr*cos(beta);y3=hy+hr*sin(beta);
		x2=bdx+bdr*cos(alfa);y2=bdy+bdr*sin(alfa);
		beta+=7*PI/60;
		alfa+=PI/20;
		x4=hx+hr*cos(beta);y4=hy+hr*sin(beta);
		x1=bdx+bdr*cos(alfa);y1=bdy+bdr*sin(alfa);
		x5=x4;x6=x3;y5=y4;y6=y3;

		glNormal3f(0.0, 0.0, 1.0);
		glBegin(GL_QUADS);
		glVertex3f(x4, y4, ks);
		glVertex3f(x3, y3, ks);
		glVertex3f(x2, y2, ks);
		glVertex3f(x1, y1, ks);
		glEnd();

		glNormal3f(-cos(beta), -sin(beta), 0.0);
		glBegin(GL_QUADS);
		glVertex3f(x3, y3, ks);
		glVertex3f(x4, y4, ks);
		glVertex3f(x5, y5, 0.0);
		glVertex3f(x6, y6, 0.0);
		glEnd();

		glNormal3f(cos(alfa), sin(alfa), 0.0);
		glBegin(GL_QUADS);
		glVertex3f(x1, y1, ks);
		glVertex3f(x2, y2, ks);
		glVertex3f(x2, y2, 0.0);
		glVertex3f(x1, y1, 0.0);
		glEnd();
	}

	hx=theGame.holes[2].x[0], hy=theGame.holes[2].x[1], hr=theGame.holes[2].r, beta=7*PI/6;
	alfa=-PI/2;
	bdx=theGame.boundaries[2].x[0][0],bdy=theGame.boundaries[1].x[3][1],
		bdr=theGame.boundaries[1].x[0][0]-theGame.boundaries[2].x[0][0]+dt;
	for(z=0;z<10;z++){
		x3=hx+hr*cos(beta);y3=hy+hr*sin(beta);
		x2=bdx+bdr*cos(alfa);y2=bdy+bdr*sin(alfa);
		beta+=7*PI/60;
		alfa+=PI/20;
		x4=hx+hr*cos(beta);y4=hy+hr*sin(beta);
		x1=bdx+bdr*cos(alfa);y1=bdy+bdr*sin(alfa);
		x5=x4;x6=x3;y5=y4;y6=y3;

		glNormal3f(0.0, 0.0, 1.0);
		glBegin(GL_QUADS);
		glVertex3f(x4, y4, ks);
		glVertex3f(x3, y3, ks);
		glVertex3f(x2, y2, ks);
		glVertex3f(x1, y1, ks);
		glEnd();

		glNormal3f(-cos(beta), -sin(beta), 0.0);
		glBegin(GL_QUADS);
		glVertex3f(x3, y3, ks);
		glVertex3f(x4, y4, ks);
		glVertex3f(x5, y5, 0.0);
		glVertex3f(x6, y6, 0.0);
		glEnd();

⌨️ 快捷键说明

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