📄 game_render.cpp
字号:
#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 + -