📄 ball.c
字号:
enum BallSet ballset_for_gametype(enum gameType g){ switch(g){ case GAME_8BALL: return(BALLSET_POOL); break; case GAME_9BALL: return(BALLSET_POOL); break; case GAME_CARAMBOL: return(BALLSET_CARAMBOL); break; case GAME_SNOOKER: return(BALLSET_SNOOKER); break; default: return(BALLSET_NONE); }}void create_texbinds( BallsType *balls ){ switch(g_ballset){ case BALLSET_POOL: free_pooltexbinds(); break; case BALLSET_CARAMBOL: free_caramboltexbinds(); break; case BALLSET_SNOOKER: free_snookertexbinds(); break; case BALLSET_NONE: break; } switch(balls->gametype){ case GAME_8BALL: create_pooltex_binds(); break; case GAME_9BALL: create_pooltex_binds(); break; case GAME_CARAMBOL: create_caramboltex_binds(); break; case GAME_SNOOKER: create_snookertex_binds(); break; }}void draw_balls( BallsType balls, myvec cam_pos, GLfloat cam_FOV, int win_width, int spheretexbind, VMvect * lightpos, int lightnr, int * cuberef_binds ){ static int init = 0; static int fresnel_init = 0; int i,j; double fact; VMvect v,vn; GLfloat stretch_matrix[16]; if( !init ){ if(options_ball_shadows){ glGenTextures(1,&shadowtexbind); if(options_simple_ball_shadows){ // one threefold shadow under balls load_png("shadow_alpha.png",&shadowtexw,&shadowtexh,&depth,&shadowtexdata); }else{ load_png("shadow2.png",&shadowtexw,&shadowtexh,&depth,&shadowtexdata); } glBindTexture(GL_TEXTURE_2D,shadowtexbind); gluBuild2DMipmaps(GL_TEXTURE_2D, 1, shadowtexw, shadowtexh, GL_LUMINANCE, GL_UNSIGNED_BYTE, shadowtexdata); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, options_tex_min_filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, options_tex_mag_filter); DPRINTF("shadowtexbind=%d\n",shadowtexbind); } if(options_ball_tex){ create_texbinds(&balls); } init=1; }#ifdef GL_VERTEX_PROGRAM_NV#ifdef USE_BALL_FRESNEL if(options_ball_fresnel_refl && !fresnel_init){ glGenProgramsNV(1, &fresnel_vert_prog_bind); glBindProgramNV(GL_VERTEX_PROGRAM_NV, fresnel_vert_prog_bind); glLoadProgramNV(GL_VERTEX_PROGRAM_NV, fresnel_vert_prog_bind, strlen(fresnel_vert_prog_str), fresnel_vert_prog_str); fresnel_init=1; }#endif#endif { /* whole ball culling */ int i; GLfloat mat[16],x,y,w; glMatrixMode(GL_PROJECTION); glPushMatrix(); glGetFloatv(GL_MODELVIEW_MATRIX,mat);#define BORDER_SHIFT 2.0 glTranslatef(0,0,-BORDER_SHIFT*balls.ball[0].d); /* half FOV mut be >= asin(1/BORDER_SHIFT) */ glMultMatrixf(mat); glGetFloatv(GL_PROJECTION_MATRIX,mat); glPopMatrix(); glMatrixMode(GL_MODELVIEW); for(i=0;i<balls.nr;i++) if(balls.ball[i].in_game){ x = mat[0]*balls.ball[i].r.x + mat[4]*balls.ball[i].r.y + mat[8]*balls.ball[i].r.z + mat[12]; y = mat[1]*balls.ball[i].r.x + mat[5]*balls.ball[i].r.y + mat[9]*balls.ball[i].r.z + mat[13]; w = mat[3]*balls.ball[i].r.x + mat[7]*balls.ball[i].r.y + mat[11]*balls.ball[i].r.z + mat[15]; balls.ball[i].in_fov = ( x>-w && x<w && y>-w && y<w );// balls.ball[i].in_fov = 1; } } if(options_ball_tex && g_ballset!=ballset_for_gametype(balls.gametype)){ create_texbinds(&balls); }/* glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&i); fprintf(stderr,"max_ARB=%d\n",i);*/ if(options_ball_tex || options_ball_reflect){ glEnable(GL_TEXTURE_2D); } if( options_ball_reflect && !options_ball_reflections_blended ){ #ifdef MULTITEX_ENABLED glActiveTextureARB(GL_TEXTURE1_ARB); glBindTexture(GL_TEXTURE_2D,spheretexbind); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glMaterialfv(GL_FRONT, GL_DIFFUSE, col_refl); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glEnable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE0_ARB); #endif } // glClientActiveTextureARB(GL_TEXTURE0_ARB); /* draw balls */ if( options_ball_reflect && !options_ball_reflections_blended ){ glMaterialfv(GL_FRONT, GL_DIFFUSE, col_diff2); glMaterialfv(GL_FRONT, GL_AMBIENT, col_amb2 ); glMaterialfv(GL_FRONT, GL_SPECULAR, col_spec2); glMaterialf (GL_FRONT, GL_SHININESS, 20.0 ); }else if( !options_ball_reflect ){ glMaterialfv(GL_FRONT, GL_DIFFUSE, col_diff2); glMaterialfv(GL_FRONT, GL_AMBIENT, col_amb2 ); glMaterialfv(GL_FRONT, GL_SPECULAR, col_spec2); glMaterialf (GL_FRONT, GL_SHININESS, 10.0 ); }else if( options_ball_reflect && options_cuberef ){ glMaterialfv(GL_FRONT, GL_DIFFUSE, col_diff3); glMaterialfv(GL_FRONT, GL_AMBIENT, col_amb3 ); glMaterialfv(GL_FRONT, GL_SPECULAR, col_spec ); glMaterialf (GL_FRONT, GL_SHININESS, 0.0 ); }else{ glMaterialfv(GL_FRONT, GL_DIFFUSE, col_diff); glMaterialfv(GL_FRONT, GL_AMBIENT, col_amb ); glMaterialfv(GL_FRONT, GL_SPECULAR, col_spec); glMaterialf (GL_FRONT, GL_SHININESS, 0.0 ); } if( (!options_ball_tex) && (!options_ball_reflect) ){ glDisable(GL_TEXTURE_2D); } /* draw balls *//* if (options_ball_stencil_reflections){ glClearStencil(0x0); }*/ if( options_ball_tex || (options_ball_reflect && !options_ball_reflections_blended) ){ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); for(i=0;i<balls.nr;i++) if(balls.ball[i].in_game && balls.ball[i].in_fov){ glBindTexture(GL_TEXTURE_2D,balltexbind[balls.ball[i].nr]);/* if (options_ball_stencil_reflections){ glClear(GL_STENCIL_BUFFER_BIT); glDisable(GL_STENCIL_TEST); glEnable(GL_DEPTH_TEST); }*//* glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); glColor3f(0.0,0.0,0.0);*/#ifdef TEST_FRESNEL glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); glColor3f(0,0,0);#endif draw_ball(&balls.ball[i],cam_pos,cam_FOV,win_width,0);/* if (options_ball_stencil_reflections){ glEnable(GL_STENCIL_TEST); glDisable(GL_DEPTH_TEST); glStencilFunc(GL_EQUAL,1,1); }*/ } } /* only plain balls (no tex no reflexion) */ if( !(options_ball_tex || options_ball_reflect) ){ glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); for(i=0;i<balls.nr;i++) if(balls.ball[i].in_game && balls.ball[i].in_fov){ draw_ball(&balls.ball[i],cam_pos,cam_FOV,win_width,0); } } if( options_ball_reflect && !options_ball_reflections_blended ){ #ifdef MULTITEX_ENABLED glActiveTextureARB(GL_TEXTURE1_ARB); glDisable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE0_ARB); #endif } /* draw extra blended ball-reflections */ if( options_ball_reflect && options_ball_reflections_blended && !(options_cuberef && cuberef_binds==0) ){ float texmat[16]; glDepthMask (GL_FALSE); glEnable(GL_BLEND); glPolygonOffset( 0.0, -2.0 ); glEnable( GL_POLYGON_OFFSET_FILL );// glBlendFunc (GL_SRC_ALPHA, GL_ONE);// glBlendFunc (GL_ONE_MINUS_DST_COLOR, GL_ONE);// glBlendFunc (GL_ONE, GL_ONE); if(options_cuberef){#ifdef USE_BALL_FRESNEL if(options_ball_fresnel_refl) { glBlendFunc (GL_ONE, GL_ONE);// glBlendFunc (GL_ONE_MINUS_DST_COLOR, GL_ONE); glMaterialfv(GL_FRONT, GL_DIFFUSE, col_refl4);/* glDisable(GL_LIGHTING); glColor3f(1.0,1.0,1.0);*/ } else#endif { glBlendFunc (GL_ONE_MINUS_DST_COLOR, GL_ONE); glMaterialfv(GL_FRONT, GL_DIFFUSE, col_refl3); } } else { glBlendFunc (GL_SRC_ALPHA, GL_ONE); glMaterialfv(GL_FRONT, GL_DIFFUSE, col_refl); } glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if( options_cuberef && cuberef_binds!=0 ) { glDisable(GL_TEXTURE_2D);#ifndef TEST_FRESNEL glEnable(GL_TEXTURE_CUBE_MAP_ARB);#endif } else { glBindTexture(GL_TEXTURE_2D,spheretexbind); } if( options_calc_ball_reflections ){ }else if( options_cuberef && cuberef_binds!=0 ){ float dummy; glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glEnable(GL_TEXTURE_GEN_R); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); glGetFloatv(GL_MODELVIEW_MATRIX, texmat); /* maybe set this per ball to camaera direction */ texmat[12]=0.0; texmat[13]=0.0; texmat[14]=0.0;/* printf("texmat offs=%f %f %f\n", texmat[3], texmat[7], texmat[11]);*/ /* transpose */ dummy=texmat[1]; texmat[1]=texmat[4]; texmat[4]=dummy; dummy=texmat[2]; texmat[2]=texmat[8]; texmat[8]=dummy; dummy=texmat[6]; texmat[6]=texmat[9]; texmat[9]=dummy; glMatrixMode(GL_TEXTURE); glLoadMatrixf(texmat); glMatrixMode(GL_MODELVIEW);#ifdef GL_VERTEX_PROGRAM_NV#ifdef USE_BALL_FRESNEL if( options_ball_fresnel_refl ){ glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R); glEnable(GL_VERTEX_PROGRAM_NV); /* for world coord program *//* glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_PROJECTION, GL_IDENTITY_NV ); glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 4, GL_TEXTURE, GL_IDENTITY_NV ); glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 12, GL_MODELVIEW, GL_IDENTITY_NV );*/ /* for object coord program */ glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV ); glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 4, GL_TEXTURE, GL_IDENTITY_NV ); glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 12, GL_MODELVIEW, GL_INVERSE_TRANSPOSE_NV );// glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 9, GL_MODELVIEW, GL_IDENTITY_NV); glProgramParameter4fNV( GL_VERTEX_PROGRAM_NV, 8, /* c[8] */ 0.0, /* needed by vertex prog as constant 0.0 */ 1.0, /* dummy - not used */ 0.00001, /* z-shift for correct zbuffering when multisampling */ 0.6 /* Rmax(=1)-Rmin */ );// # c[8].z = offset for correct z-buffering glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glBindProgramNV(GL_VERTEX_PROGRAM_NV, fresnel_vert_prog_bind); }#endif#endif }else{ glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); } for(i=0;i<balls.nr;i++) if(balls.ball[i].in_game && balls.ball[i].in_fov){ if( options_calc_ball_reflections ){ draw_ball(&balls.ball[i],cam_pos,cam_FOV,win_width,1); } else if( options_cuberef && cuberef_binds!=0 ){ glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, cuberef_binds[i]);#ifdef GL_VERTEX_PROGRAM_NV { myvec cam_pos2;// cam_pos2=vec_scale(vec_unit(vec_diff(cam_pos,balls.ball[i].r)),BALL_D/2.5); cam_pos2=balls.ball[i].r; glProgramParameter4fNV( GL_VERTEX_PROGRAM_NV, 10, /* c[10] */ BALL_D/2.0,BALL_D/2.5,0,0 ); }#endif draw_ball(&balls.ball[i],cam_pos,cam_FOV,win_width,0); }else{ draw_ball(&balls.ball[i],cam_pos,cam_FOV,win_width,0); } } if( options_calc_ball_reflections ){ }else if( options_cuberef && cuberef_binds!=0 ){#ifdef GL_VERTEX_PROGRAM_NV#ifdef USE_BALL_FRESNEL if( options_ball_fresnel_refl ){ glDisable(GL_VERTEX_PROGRAM_NV); }#endif#endif glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R); glDisable(GL_BLEND); glDisable(GL_TEXTURE_CUBE_MAP_ARB); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glEnable(GL_TEXTURE_2D); }else{ glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_BLEND); } glDisable( GL_POLYGON_OFFSET_FILL ); glDepthMask (GL_TRUE); } /* draw shadows */ if(options_simple_ball_shadows) // one threefold shadow under balls if( options_ball_shadows ){ glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glMaterialfv(GL_FRONT, GL_DIFFUSE, col_shad); glDepthMask (GL_FALSE); glEnable(GL_BLEND);// glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // glBlendFunc ( GL_ONE, GL_SRC_ALPHA ); // glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glBindTexture(GL_TEXTURE_2D,shadowtexbind);#define SH_SZ 0.047 for(i=0;i<balls.nr;i++) if(balls.ball[i].in_game){ glBegin(GL_POLYGON); glNormal3f( 0.0,0.0,1.0 ); glTexCoord2f(0.0,1.0); glVertex3f( balls.ball[i].r.x-SH_SZ, balls.ball[i].r.y+SH_SZ, balls.ball[i].r.z-balls.ball[i].d/2.02 ); glTexCoord2f(1.0,1.0); glVertex3f( balls.ball[i].r.x+SH_SZ, balls.ball[i].r.y+SH_SZ, balls.ball[i].r.z-balls.ball[i].d/2.02 ); glTexCoord2f(1.0,0.0); glVertex3f( balls.ball[i].r.x+SH_SZ, balls.ball[i].r.y-SH_SZ, balls.ball[i].r.z-balls.ball[i].d/2.02 ); glTexCoord2f(0.0,0.0); glVertex3f( balls.ball[i].r.x-SH_SZ, balls.ball[i].r.y-S
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -