/**************************************************************************** ** ** Kugel.cpp Stefan Disch, Tobias Nopper, Martina Welte 2001 ** *****************************************************************************/ #include #include #include #include "LA.h" // Zum Handling von .bmp-Files bzw. Matrix-Bildern #include "bmp.h" #include "Kugel.h" #include "createTexture.h" // Funktion zum Generieren einer Textur aus einem // Matrix-Bild (aus "Ubungen) #include "SchattenKreis.h" // zeichnet Schatten // leerer Konstruktor (OpenGL macht hier dumm)... Kugel::Kugel() { Position[0]=0; Position[1]=0; Position[2]=0; Nummer=-1; for (GLint i=0;i<30;i++) { sphereIndex[i]=0; sphereIndexStatisch[i]=0; StatischExistiert[i]=0; } schattenIndex=0; schattenIndexStatisch=0; Schatten=0; InAnimation=0; StatischExistiertSchatten=0; //GLfloat DrehMatrix[16]; Schatten1_x=0; Schatten1_y=0; Schatten1_scale=0; Schatten1_winkel=0; Schatten2_x=0; Schatten2_y=0; Schatten2_scale=0; Schatten2_winkel=0; Schatten3_x=0; Schatten3_y=0; Schatten3_scale=0; Schatten3_winkel=0; AlteTexturgroesse=1; /* */ Texturen[1]=0; Texturen[2]=0; Texturen[4]=0; Texturen[8]=0; } GLint exp2(GLint a) { //b=2^a return 1<8) TG=1; if (!Texturen[TG]) glGenTextures(1,&Texturen[TG]); glBindTexture(GL_TEXTURE_2D,Texturen[TG]); sprintf(Name,"Texturen/%i/%i.bmp",TG,Nr); loadBMP(tex_r,tex_g,tex_b,Name); GLfloat *texcoord; if (tex_r.nrh!=tex_r.nch) { GLfloat Aspekt=(tex_r.nch+1.0)/(tex_r.nrh+1.0); texcoord = (GLfloat*) malloc (20*(Aufloesung+1)*(Aufloesung+2)*sizeof(GLfloat)); for (GLint a=0;a<20*(Aufloesung+1)*(Aufloesung+2);a+=2) { texcoord[a]=ball_texcoord[Aufloesung][a]/Aspekt; texcoord[a+1]=ball_texcoord[Aufloesung][a+1]; } } createTexture(tex_r,tex_g,tex_b); glNewList(sphereIndex[Aufloesung],GL_COMPILE_AND_EXECUTE); GLfloat mat_diffuse[]={1.0,1.0,1.0,1.0}; GLfloat mat_specular[]={0.5,0.5,0.5,1.0}; //GLfloat mat_specular[]={0.0,0.0,0.0,0.0}; GLfloat mat_shininess = 80.0; glMaterialfv(GL_FRONT, GL_AMBIENT,mat_diffuse); glMaterialfv(GL_FRONT, GL_DIFFUSE,mat_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR,mat_specular); glMaterialf(GL_FRONT, GL_SHININESS,mat_shininess); //createTexture(tex_r,tex_g,tex_b,Nearest,0); glBindTexture(GL_TEXTURE_2D,Texturen[TG]); glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glNormalPointer(GL_FLOAT, 0, ball_vertices[Aufloesung]); glVertexPointer(3, GL_FLOAT, 0, ball_vertices[Aufloesung]); if (tex_r.nrh!=tex_r.nch) { glTexCoordPointer(2, GL_FLOAT, 0, texcoord); } else { glTexCoordPointer(2, GL_FLOAT, 0, ball_texcoord[Aufloesung]); } glDrawElements(GL_TRIANGLES,20*3*Aufloesung*Aufloesung, GL_UNSIGNED_INT,ball_indices[Aufloesung]); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); glEndList(); tex_r.free_FMatrix(); tex_g.free_FMatrix(); tex_b.free_FMatrix(); if (tex_r.nrh!=tex_r.nch) { free(texcoord); } } StatischExistiert[Aufloesung]=0; StatischExistiertSchatten=0; InAnimation=1; } } if (!schattenIndex) { schattenIndex=glGenLists(1); schattenIndexStatisch=glGenLists(1); glNewList(schattenIndex,GL_COMPILE_AND_EXECUTE); SchattenKreis(18, .7, 1.2, 0.2, 0.0); glEndList(); Schatten=Schatten_; Schatten1_x=0; Schatten1_y=0; Schatten1_scale=1; Schatten1_winkel=0; Schatten2_x=0; Schatten2_y=0; Schatten2_scale=1; Schatten2_winkel=0; Schatten3_x=0; Schatten3_y=0; Schatten3_scale=1; Schatten3_winkel=0; } if (!schatten2Index) { schatten2Index=glGenLists(1); glNewList(schatten2Index,GL_COMPILE_AND_EXECUTE); SchattenKreis(14, 0.1, 0.5, 0.5, 0.0); glEndList(); } AlteTexturgroesse=Texturgroesse; } // Zeichnet die Kugel mit Hilfe der Display List void Kugel::male(GLint Aufloesung) { if (Position[0]!=3000) { if (InAnimation) { glPushMatrix(); // Matrix auf Stack glScalef(2.8575,2.8575,2.8575);// Skalieren auf Zentimetersystem; // Kugel auf die Position verschieben glTranslatef(Position[0],Position[1],Position[2]); glMultMatrixf(DrehMatrix); // Kugel mit der Drehmatrix drehen glCallList(sphereIndex[Aufloesung]); // Kugel zeichnen glPopMatrix(); // Matrix wiederherstellen InAnimation=0; for (int i=0;i<30;i++) { StatischExistiert[i]=0; } } else if (StatischExistiert[Aufloesung]) { /* glPushMatrix(); glTranslatef(0,0,-5.715); glScalef(1,1,-1); glFrontFace(GL_CW); glDisable(GL_DEPTH_TEST); glCallList(sphereIndexStatisch[Aufloesung]); glEnable(GL_DEPTH_TEST); glFrontFace(GL_CCW); glPopMatrix(); */ glCallList(sphereIndexStatisch[Aufloesung]); } else { glNewList(sphereIndexStatisch[Aufloesung],GL_COMPILE_AND_EXECUTE); glPushMatrix(); // Matrix auf Stack glScalef(2.8575,2.8575,2.8575);// Skalieren auf Zentimetersystem; // Kugel auf die Position verschieben glTranslatef(Position[0],Position[1],Position[2]); glMultMatrixf(DrehMatrix); // Kugel mit der Drehmatrix drehen glCallList(sphereIndex[Aufloesung]); // Kugel zeichnen glPopMatrix(); // Matrix wiederherstellen glEndList(); StatischExistiert[Aufloesung]=1; } } } void Kugel::maleSchatten() { if (Schatten&&(Position[0]!=3000)&&(Position[2]>=0)) { if (InAnimation) { glPushMatrix(); glScalef(2.8575,2.8575,2.8575);// Skalieren auf Zentimetersystem; glTranslatef(Position[0],Position[1],Position[2]-1); glCallList(schatten2Index); //TEST glPushMatrix(); glTranslatef(Schatten1_x,Schatten1_y,0); glRotatef(Schatten1_winkel,0,0,1); glScalef(Schatten1_scale,1,1); glCallList(schattenIndex); glPopMatrix(); glPushMatrix(); glTranslatef(Schatten2_x,Schatten2_y,0); glRotatef(Schatten2_winkel,0,0,1); glScalef(Schatten2_scale,1,1); glCallList(schattenIndex); glPopMatrix(); glPushMatrix(); glTranslatef(Schatten3_x,Schatten3_y,0); glRotatef(Schatten3_winkel,0,0,1); glScalef(Schatten3_scale,1,1); glCallList(schattenIndex); glPopMatrix(); glPopMatrix(); StatischExistiertSchatten=0; } else if (StatischExistiertSchatten) { glCallList(schattenIndexStatisch); } else { glNewList(schattenIndexStatisch,GL_COMPILE_AND_EXECUTE); glPushMatrix(); glScalef(2.8575,2.8575,2.8575);// Skalieren auf Zentimetersystem; glTranslatef(Position[0],Position[1],Position[2]-1); glCallList(schatten2Index); //TEST glPushMatrix(); glTranslatef(Schatten1_x,Schatten1_y,0); glRotatef(Schatten1_winkel,0,0,1); glScalef(Schatten1_scale,1,1); glCallList(schattenIndex); glPopMatrix(); glPushMatrix(); glTranslatef(Schatten2_x,Schatten2_y,0); glRotatef(Schatten2_winkel,0,0,1); glScalef(Schatten2_scale,1,1); glCallList(schattenIndex); glPopMatrix(); glPushMatrix(); glTranslatef(Schatten3_x,Schatten3_y,0); glRotatef(Schatten3_winkel,0,0,1); glScalef(Schatten3_scale,1,1); glCallList(schattenIndex); glPopMatrix(); glPopMatrix(); glEndList(); StatischExistiertSchatten=1; } } } void Kugel::neuePosition(GLfloat neuPos[]) { GLfloat dx=neuPos[0]-Position[0]; // Differenzvektor bestimmen GLfloat dy=neuPos[1]-Position[1]; //printf("%i %f %f\n",Nummer,Position[0],Position[1]); if (dx || dy) { glPushMatrix(); // Matrix auf Stack glLoadIdentity(); // Einheitsmatrix laden // um die L"ange des Diff.vektors (umgerechnet in Gradma"s) um die // Achse senkrecht zum Differenzvektor rotieren glRotatef(sqrt(dx*dx+dy*dy)*20.051016*2,-dy,dx,0.0); glMultMatrixf(DrehMatrix); // Die alte Drehmatrix dazumultiplizieren // Die neue Drehmatrix abspeichern glGetFloatv(GL_MODELVIEW_MATRIX,DrehMatrix); glPopMatrix(); // Matrix wiederherstellen Position[0]=neuPos[0]; // neue Position setzen Position[1]=neuPos[1]; Position[2]=(neuPos[2]>0)?0:neuPos[2]; if (Schatten) { Schatten1_x=neuPos[0]/34; Schatten1_x=(Schatten1_x)?Schatten1_x:.0001; Schatten1_y=neuPos[1]/34; Schatten1_scale=sqrt(Schatten1_x*Schatten1_x+Schatten1_y*Schatten1_y+1); Schatten1_winkel=57.3*atan(Schatten1_y/Schatten1_x); Schatten2_x=(neuPos[0]-22.22)/34; Schatten2_x=(Schatten2_x)?Schatten2_x:.0001; Schatten2_y=Schatten1_y; Schatten2_scale=sqrt(Schatten2_x*Schatten2_x+Schatten2_y*Schatten2_y+1); Schatten2_winkel=57.3*atan(Schatten2_y/Schatten2_x); Schatten3_x=(neuPos[0]+22.22)/34; Schatten3_x=(Schatten3_x)?Schatten3_x:.0001; Schatten3_y=Schatten1_y; Schatten3_scale=sqrt(Schatten3_x*Schatten3_x+Schatten3_y*Schatten3_y+1); Schatten3_winkel=57.3*atan(Schatten3_y/Schatten3_x); } } InAnimation=1; } /* Das gleiche noch viele hundert Mal (in verschiedenen Masseinheiten etc.)*/ void Kugel::neuePosition(GLfloat neuPos_x,GLfloat neuPos_y,GLfloat neuPos_z) { GLfloat Pos[]={neuPos_x,neuPos_y,neuPos_z}; neuePosition(Pos); } void Kugel::neuePosition(GLfloat neuPos_x,GLfloat neuPos_y) { GLfloat Pos[]={neuPos_x,neuPos_y,0.0}; neuePosition(Pos); } void Kugel::neuePositionCM(GLfloat neuPos[]) { GLfloat Pos[]={neuPos[0]/2.8575,neuPos[1]/2.8575,neuPos[2]/2.8575}; neuePosition(Pos); } void Kugel::neuePositionCM(GLfloat neuPos_x,GLfloat neuPos_y,GLfloat neuPos_z) { GLfloat Pos[]={neuPos_x/2.8575,neuPos_y/2.8575,neuPos_z/2.8575}; neuePosition(Pos); } void Kugel::neuePositionCM(GLfloat neuPos_x,GLfloat neuPos_y) { GLfloat Pos[]={neuPos_x/2.8575,neuPos_y/2.8575,0.0}; neuePosition(Pos); } void Kugel::neuePositionD(GLfloat neuPos[]) { GLfloat Pos[]={neuPos[0]*2,neuPos[1]*2,neuPos[2]*2}; neuePosition(Pos); } void Kugel::neuePositionD(GLfloat neuPos_x,GLfloat neuPos_y,GLfloat neuPos_z) { GLfloat Pos[]={neuPos_x*2,neuPos_y*2,neuPos_z*2}; neuePosition(Pos); } void Kugel::neuePositionD(GLfloat neuPos_x,GLfloat neuPos_y) { GLfloat Pos[]={neuPos_x*2,neuPos_y*2,0.0}; neuePosition(Pos); } void Kugel::neuePositionINCH(GLfloat neuPos[]) { GLfloat Pos[]={neuPos[0]/1.125,neuPos[1]/1.125,neuPos[2]/1.125}; neuePosition(Pos); } void Kugel::neuePositionINCH(GLfloat neuPos_x,GLfloat neuPos_y,GLfloat neuPos_z) { GLfloat Pos[]={neuPos_x/1.125,neuPos_y/1.125,neuPos_z/1.125}; neuePosition(Pos); } void Kugel::neuePositionINCH(GLfloat neuPos_x,GLfloat neuPos_y) { GLfloat Pos[]={neuPos_x/1.125,neuPos_y/1.125,0.0}; neuePosition(Pos); } // l"a"st die Kugel verschwinden void Kugel::ausblenden() { GLfloat Pos[]={3000.0,3000.0,0.0}; neuePosition(Pos); } // Liefert die Kugelposition in verschiedenen Ma"seinheiten zur"uck GLfloat Kugel::Pos_x() { return Position[0]; } GLfloat Kugel::Pos_y() { return Position[1]; } GLfloat Kugel::Pos_xD() { return Position[0]*.5; } GLfloat Kugel::Pos_yD() { return Position[1]*.5; } GLfloat Kugel::Pos_xCM() { return Position[0]*2.8575; } GLfloat Kugel::Pos_yCM() { return Position[1]*2.8575; }