📄 ball.c
字号:
/* ball.c**** code for creating the GL-ball display-lists** Copyright (C) 2001 Florian Berger** Email: harpin_floh@yahoo.de, florian.berger@jk.uni-linz.ac.at**** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License Version 2 as** published by the Free Software Foundation;**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***/#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <GL/glu.h>#include <GL/gl.h>#include "billard.h"#include "billmove.h"#include "ball.h"#include "png_loader.h"#include "options.h"#include "font.h"#ifdef GL_VERTEX_ARRAY #define USE_VERTEX_ARRAYS#else #undef USE_VERTEX_ARRAYS#endif#ifdef GL_ARB_multitexture #define MULTITEX_ENABLED#else #undef MULTITEX_ENABLED#endif#define USE_TRISTRIPS//#undef USE_VERTEX_ARRAYS#ifndef NO_NV_FRESNEL#define USE_BALL_FRESNEL#endif//#define TEST_FRESNELstatic int fresnel_vert_prog_bind;static const unsigned char * fresnel_vert_prog_world_coord_str= "!!VP1.0 \n"// #// # c[0-3] = projection matrix// # TrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_PROJECTION, GL_IDENTITY_NV);// # c[4-7] = texture matrix// # TrackMatrixNV(GL_VERTEX_PROGRAM_NV, 4, GL_TEXTURE, GL_IDENTITY_NV);// # c[8].z = offset for correct z-buffering// # c[8].x = 0.0// # c[8].y = 1.0// # c[8].w = Rmax(=1) - Rmin// # c[9] = ball_pos// # c[10].x = ball_r// # c[10].y = cuberef offset in viewer dir// # c[12-15] = modelview matrix// # TrackMatrixNV(GL_VERTEX_PROGRAM_NV, 12, GL_MODELVIEW, GL_IDENTITY_NV);// # /* R1 = pos = -campos */ "DP4 R1.x, c[12], v[OPOS]; \n" "DP4 R1.y, c[13], v[OPOS]; \n" "DP4 R1.z, c[14], v[OPOS]; \n" "DP4 R1.w, c[15], v[OPOS]; \n" /* R0 = nrml */ "DP3 R0.x, c[12], v[NRML]; \n" "DP3 R0.y, c[13], v[NRML]; \n" "DP3 R0.z, c[14], v[NRML]; \n" /* R4=camdir=dist(cam,pos) */ "MOV R4, -R1; \n" /* normalize */ "MOV R5, R4; \n" "DP3 R4.w, R5, R5; \n" "RSQ R4.w, R4.w; \n" "MUL R4.xyz, R5, R4.w; \n" /* R5 = refdir = -cam+2n*cam.n */ "DP3 R3.w, R4, R0; \n" "ADD R3.w, R3.w, R3.w; \n" "MAD R5, R3.w, R0, -R4; \n" /* offset consideration for R5 *//* "ADD R3, -c[9], v[OPOS]; \n" "MOV R1, c[15]; \n" "ADD R1, R1, -c[9]; \n" "DP3 R5.w, R2, R1; \n" "MUL R2.xyz, R1, R5.w; \n" "DP3 R5.w, R1, R1; \n" "RCP R5.w, R5.w; \n" "MUL R2.xyz, R2, R5.w; \n" "RCP R5.w, c[10].x; \n" "MUL R2.xyz, R2, R5.w; \n"*/ /* col0 = fresnel(n) = e.n */ "DP3 R3.x, R4, R0; \n"// "ADD R3.x, c[8].y, -R3.x; \n"// "MUL R3.x, R3.x, R3.x; \n"// "ADD R3.x, c[8].y, -R3.x; \n" "MUL R3.x, R3.x, c[8].w; \n" "ADD R3.x, R3.x, R3.x; \n" "ADD R3.x, R3.x, -c[8].w; \n" "ADD o[COL0].xyz, c[8].y, -R3.x; \n" /* o[TEX0] = refl vect in table coords */ "DP3 o[TEX0].x, R5, c[4]; \n" "DP3 o[TEX0].y, R5, c[5]; \n" "DP3 o[TEX0].z, R5, c[6]; \n" /* apply modelview + projection */ "DP4 o[HPOS].x, c[0], R1; \n" "DP4 o[HPOS].y, c[1], R1; \n" "DP4 R3.z, c[2], R1; \n" "DP4 o[HPOS].w, c[3], R1; \n" "ADD o[HPOS].z, R3.z, -c[8].z; \n" "END \n";static const unsigned char * fresnel_vert_prog_obj_coord_str= /* object coordinates */ "!!VP1.0 \n"// #// # c[0-3] = modelview projection (composite) matrix// # TrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV);// # c[4-7] = texture matrix// # TrackMatrixNV(GL_VERTEX_PROGRAM_NV, 4, GL_TEXTURE, GL_IDENTITY_NV);// # c[8].z = offset for correct z-buffering// # c[8].x = 0.0// # c[8].y = 1.0// # c[8].w = Rmax(=1) - Rmin// # c[10].x = ball_r// # c[10].y = cuberef offset in viewer dir// # c[12-15] = modelview inverse matrix// # TrackMatrixNV(GL_VERTEX_PROGRAM_NV, 12, GL_MODELVIEW, GL_INVERSE_TRANSPOSE);// # => eye vector is one line and upper 3x3 matrix = modelview identity// # /* offset consideration */ "MOV R0, c[15]; \n" /* normalize */ "MOV R5, R0; \n" "DP3 R0.w, R5, R5; \n" "RSQ R0.w, R0.w; \n" "MUL R0.xyz, R5, R0.w; \n" "DP3 R1.w, v[OPOS], R0; \n" "ADD R1.w, R1.w, -c[10].y; \n" "RCP R3.w, c[10].x; \n" "MUL R1.w, R1.w, R3.w; \n" "MUL R2.xyz, R0, R1.w; \n"/* "MUL R0.xyz, R0, c[10].y; \n" "ADD R2, -R0, v[OPOS]; \n" "MOV R1, c[15]; \n" "ADD R1, R1, -R0; \n" "DP3 R5.w, R2, R1; \n" "MUL R2.xyz, R1, R5.w; \n" "DP3 R5.w, R1, R1; \n" "RCP R5.w, R5.w; \n" "MUL R2.xyz, R2, R5.w; \n" "RCP R5.w, c[10].x; \n" "MUL R2.xyz, R2, R5.w; \n"*/ /* R4=camdir=dist(cam,pos) */ "ADD R4, c[15], -v[OPOS]; \n" /* normalize */ "MOV R5, R4; \n" "DP3 R4.w, R5, R5; \n" "RSQ R4.w, R4.w; \n" "MUL R4.xyz, R5, R4.w; \n" /* R5 = refdir = -cam+2n*cam.n */ "DP3 R3.w, R4, v[NRML]; \n" "ADD R3.w, R3.w, R3.w; \n" "MAD R5, R3.w, v[NRML], -R4; \n" /* col0 = fresnel(n) = e.n */ "DP3 R3.x, R4, v[NRML]; \n"// "ADD R3.x, c[8].y, -R3.x; \n"// "MUL R3.x, R3.x, R3.x; \n"// "ADD R3.x, c[8].y, -R3.x; \n" "MUL R3.x, R3.x, c[8].w; \n" "ADD R3.x, R3.x, R3.x; \n" "ADD R3.x, R3.x, -c[8].w; \n" "ADD o[COL0].xyz, c[8].y, -R3.x; \n" /* R3 = refl vect in world coords */ "ADD R5, R5, -R2; \n" "DP3 R3.x, R5, c[12]; \n" "DP3 R3.y, R5, c[13]; \n" "DP3 R3.z, R5, c[14]; \n" /* o[TEX0] = refl vect in table coords */ "DP3 o[TEX0].x, R3, c[4]; \n" "DP3 o[TEX0].y, R3, c[5]; \n" "DP3 o[TEX0].z, R3, c[6]; \n" /* apply modelview + projection */ "DP4 o[HPOS].x, c[0], v[OPOS]; \n" "DP4 o[HPOS].y, c[1], v[OPOS]; \n" "DP4 R3.z, c[2], v[OPOS]; \n" "DP4 o[HPOS].w, c[3], v[OPOS]; \n" "ADD o[HPOS].z, R3.z, -c[8].z; \n" "END \n";#define fresnel_vert_prog_str fresnel_vert_prog_obj_coord_strstatic char * balltexdata[22];static GLuint balltexbind[22];static int balltexw,balltexh;static int shadowtexw,shadowtexh;static char * shadowtexdata;static GLuint shadowtexbind;static int depth;static GLfloat col_null [4] = {0.0, 0.0, 0.0, 0.0}; /* dont need any specular because of reflections */static GLfloat col_spec [4] = {0.0, 0.0, 0.0, 1.0}; /* dont need any specular because of reflections */static GLfloat col_spec2[4] = {1.0, 1.0, 1.0, 1.0}; /* dont need any specular because of reflections *///static GLfloat col_refl [4] = {1.0, 1.0, 1.0, 0.28};static GLfloat col_refl [4] = {1.0, 1.0, 1.0, 0.28};static GLfloat col_refl3[4] = {1.0, 1.0, 1.0, 0.60}; /* for rendered cubemap */static GLfloat col_refl4[4] = {1.0, 1.0, 1.0, 1.0}; /* for rendered cubemap (fresnel) */static GLfloat col_diff [4] = {0.7, 0.7, 0.7, 1.0};static GLfloat col_diff2[4] = {0.75, 0.75, 0.75, 1.0};static GLfloat col_diff3[4] = {0.69, 0.69, 0.69, 1.0};static GLfloat col_amb [4] = {0.2, 0.2, 0.2, 1.0};static GLfloat col_amb2 [4] = {0.45, 0.45, 0.45, 1.0}; /* for simple reflections */static GLfloat col_amb3 [4] = {0.31, 0.31, 0.31, 1.0}; /* for simple reflections */static GLfloat col_shad [4] = {0.5, 0.0, 0.0, 0.0};enum BallSet { BALLSET_POOL, BALLSET_CARAMBOL, BALLSET_SNOOKER, BALLSET_NONE };enum BallSet g_ballset=BALLSET_NONE;void normalize(float *v) /*FOLD00*/{ GLfloat d; d = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); v[0] /= d; v[1] /= d; v[2] /= d;}void rescale(float *v, float r){ GLfloat d; d = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2])/r; v[0] /= d; v[1] /= d; v[2] /= d;}/*void normalize_my(myfloat *v){ GLfloat d; d = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); v[0] /= d; v[1] /= d; v[2] /= d;}*/static int in_array_old( ElemArray * array, GLfloat * v, GLfloat tex_x, GLfloat tex_y ){ int i; for(i=0;i<array->vnr;i++){ if( v[0]==array->vert[i*3+0] && v[1]==array->vert[i*3+1] && v[2]==array->vert[i*3+2] && tex_x==array->tex[i*2+0] && tex_y==array->tex[i*2+1] ){ return i; } } for(i=0;i<array->vnr;i++){ if( v[0]==array->vert[i*3+0] && v[1]==array->vert[i*3+1] && v[2]==array->vert[i*3+2] ){ return -2; } } return -1;}static int in_array( ElemArray * array, GLfloat * v, GLfloat tex_x, GLfloat tex_y ){ int i; for(i=0;i<array->vnr;i++){ if( fabs(v[0]-array->vert[i*3+0])<1.0E-6 && fabs(v[1]-array->vert[i*3+1])<1.0E-6 && fabs(v[2]-array->vert[i*3+2])<1.0E-6 && fabs(tex_x-array->tex[i*2+0])<1.0E-6 && fabs(tex_y-array->tex[i*2+1])<1.0E-6 ){ return i; } } for(i=0;i<array->vnr;i++){ if( fabs(v[0]-array->vert[i*3+0])<1.0E-6 && fabs(v[1]-array->vert[i*3+1])<1.0E-6 && fabs(v[2]-array->vert[i*3+2])<1.0E-6 ){ return -2; } } return -1;}void createvertex( float * v, float * n, float tex_x, float tex_y, ElemArray * array ){ static int count; int pos; if ( array == NULL ){// fprintf(stderr,"creating glMultiTexCoord2fARB\n");// glMultiTexCoord2fARB(GL_TEXTURE0_ARB,tex_x, tex_y );// glMultiTexCoord2fARB(GL_TEXTURE1_ARB,tex_x, tex_y ); DPRINTF("creating vertex (non-array)\n"); glTexCoord2f( tex_x, tex_y ); glNormal3fv(n); glVertex3fv(v); } else { if(array->indnr==0) count=0; pos = in_array( array,v, tex_x, tex_y ); if( pos>-1 ){ array->index[array->indnr] = pos; array->indnr++; } else { array->vert[array->vnr*3+0]=v[0]; array->vert[array->vnr*3+1]=v[1]; array->vert[array->vnr*3+2]=v[2]; if( pos!=-1 ){ count++; DPRINTF("count=%d\n",count);// fprintf(stderr,"texx,texy=(%f,%f);\n",tex_x,tex_y);// array->vert[array->vnr*3+0]*=1.1;// array->vert[array->vnr*3+1]*=1.1;// array->vert[array->vnr*3+2]*=1.1; } array->norm[array->vnr*3+0]=n[0]; array->norm[array->vnr*3+1]=n[1]; array->norm[array->vnr*3+2]=n[2]; array->tex[array->vnr*2+0]=tex_x; array->tex[array->vnr*2+1]=tex_y; array->index[array->indnr] = array->vnr; array->vnr++; array->indnr++; DPRINTF("createvertex: array->vnr=%d\n",array->vnr); } }}// because used in ball_subdivide_recvoid ball_subdivide9_rec(float *v1, float *v2, float *v3, const int depth, float r, ElemArray *array);void ball_subdivide_rec(float *v1, float *v2, float *v3, const int depth, float r, ElemArray *array)/* if array=0 just make vertices */{ GLfloat v12[3], v23[3], v31[3], v123[3]; GLfloat n1[3], n2[3], n3[3]; GLint i; int otherside; double xt,yt,rho;// DPRINTF("ball_subdivide_rec\n");// fprintf(stderr,"depth=%d\n",depth); if (depth == 0 || depth==1) { for(i=0;i<3;i++){ n1[i]=v1[i]; n2[i]=v2[i]; n3[i]=v3[i]; } normalize(n1); normalize(n2); normalize(n3); rescale(v1,r); rescale(v2,r); rescale(v3,r);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -