Guest User

Grafika példa program

a guest
Jan 20th, 2014
16
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.49 KB | None | 0 0
  1. #include <math.h>
  2. #include <stdlib.h>
  3.  
  4. #if defined(__APPLE__)
  5.   #include <OpenGL/gl.h>
  6.   #include <OpenGL/glu.h>
  7.   #include <GLUT/glut.h>
  8. #else
  9.   #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
  10.     #include <windows.h>
  11.   #endif
  12.   #include <GL/gl.h>
  13.   #include <GL/glu.h>
  14.   #include <GL/glut.h>
  15. #endif
  16.  
  17. // Egyszerű 2D vektor osztály
  18. struct Vector {
  19.   float x, y;
  20.   Vector(float v = 0.0f) : x(v), y(v) {}
  21.   Vector(float x, float y) : x(x), y(y) {}
  22.   void operator+=(const Vector& v) {
  23.     x += v.x;
  24.     y += v.y;
  25.   }
  26.   Vector& operator=(const Vector& v) {
  27.     x = v.x;
  28.     y = v.y;
  29.     return *this;
  30.   }
  31.   Vector operator*(const Vector& v) const {
  32.     return Vector(x*v.x, y*v.y);
  33.   }
  34. } ball_pos, ball_speed(-0.46f, 1.13f); // Két globális változó, a labda jelenlegi állapotát tárolják.
  35.  
  36. struct Color {
  37.   float r, g, b;
  38.   Color(float r, float g, float b) : r(r), g(g), b(b) { }
  39. };
  40.  
  41. #define CIRCLE_RESOLUTION 16
  42. const float ball_radius = 0.1f;
  43.  
  44. // A lasztit kirajzoló függvény
  45. void drawBall(const Vector pos, const Color& color) {
  46.   glBegin(GL_TRIANGLE_FAN); {
  47.    
  48.     glColor3f(color.r, color.g, color.b);
  49.     glVertex2f(pos.x, pos.y);
  50.    
  51.     for(int i = 0; i <= CIRCLE_RESOLUTION; i++) {
  52.       float angle = float(i) / CIRCLE_RESOLUTION * 2.0f * M_PI;
  53.       glVertex2f(pos.x + ball_radius*cos(angle), pos.y + ball_radius*sin(angle));
  54.     }
  55.   } glEnd();
  56. }
  57.  
  58. const int memory_size = 200;
  59.  
  60. // Az elmúlt 200 frameben a labda helyzeteit tároló osztály. Emiatt húz csíkot.
  61. // Ez lényegében egy fixen 200 elemű várakozási sor, az egyszerűség kedvéért egy
  62. // tömbbel megvalósítva.
  63. struct BallTrail {
  64.   Vector positions[memory_size];
  65.   int current_top;
  66.  
  67.   BallTrail() : current_top(0) { }
  68.   void addPosition(const Vector& v) {
  69.     current_top = (current_top + 1) % memory_size;
  70.     positions[current_top] = v;
  71.   }
  72.   void draw() {
  73.     // Rajzoljuk ki a labdát, és az összes előzményét
  74.     for(int i = 1; i <= memory_size; i++) {
  75.       drawBall(
  76.         positions[(current_top + i) % memory_size],
  77.         Color( // A színe függjön a labda korától
  78.           0.0f, i == memory_size ? 0.1f : 0.1f*i/memory_size,
  79.           i == memory_size ? 0.8f : 0.2f*i/memory_size
  80.         )
  81.       );
  82.     }
  83.   }
  84. } balltrail;
  85.  
  86. void onDisplay() {
  87.   glClear(GL_COLOR_BUFFER_BIT);
  88.  
  89.   balltrail.addPosition(ball_pos); // Hozzáadjuk a jelenlegi helyzetet a memóriához.
  90.   balltrail.draw(); // És kirajzoljuk az összeset.
  91.  
  92.   glutSwapBuffers();
  93. }
  94.  
  95. // std::min helyett
  96. template<typename T>
  97. T min(const T& a, const T& b) {
  98.   if(a < b) {
  99.     return a;
  100.   } else {
  101.     return b;
  102.   }
  103. }
  104.  
  105. void onIdle() {
  106.   static int last_time = glutGet(GLUT_ELAPSED_TIME); // Visszaadja a jelenlegi időt miliszekundumban
  107.   int curr_time = glutGet(GLUT_ELAPSED_TIME);
  108.   int diff = curr_time - last_time; // Az előző onIdle óta eltelt idő
  109.   last_time = curr_time; // A következő meghíváskor az előző idő majd a mostani idő lesz.
  110.  
  111.   // Két onIdle között eltelt idő nagyon változó tud lenni, és akár elég nagy is lehet
  112.   // ahhoz, hogy a labda látványosan bele menjen a falba, mielőtt visszapattan. Ezért
  113.   // osszuk fel az elelt időt kisebb részekre, pl. max 5 miliszekundumos egységekre,
  114.   // és ilyen időközönként nézzük meg, hogy a labda ütközött-e a fallal.
  115.   const int time_step = 5;
  116.   for(int i = 0; i < diff; i += time_step) {
  117.     // Az időosztás végén egy kisebb egység marad, mint az idő egység. Pl. ha a diff 11,
  118.     // akkor azt akarjuk, hogy 5, 5, 1 egységekre bontsuk azt, ne 5, 5, 5-re. És utána
  119.     // számoljuk át a másodperce.
  120.     float dt = min(diff-i, time_step) / 1000.0f;
  121.  
  122.     // Módosítsuk a sebességet ha ütközött a fallal, teljesen rugalmas ütközést feltételezve.
  123.     // Ilyenkor a labda a fal irányára merőlegesen pontosan ellentétes irányba halad tovább.
  124.     // Hogy ne legyen olyan unalmas a pattogás, adjuk a sebességéhez egy kis random számot,
  125.     // hogy pár fokkal meg is változzon a visszapattanás szöge.
  126.     if(ball_pos.x + ball_radius > 1) {
  127.       ball_speed.x = -fabs(ball_speed.x) + (0.1f - 0.2f*rand()/RAND_MAX);
  128.     } else if(ball_pos.x - ball_radius < -1) {
  129.       ball_speed.x = fabs(ball_speed.x) + (0.1f - 0.2f*rand()/RAND_MAX);
  130.     }
  131.     if(ball_pos.y + ball_radius > 1) {
  132.       ball_speed.y = -fabs(ball_speed.y) + (0.1f - 0.2f*rand()/RAND_MAX);
  133.     } else if(ball_pos.y - ball_radius < -1) {
  134.       ball_speed.y = fabs(ball_speed.y) + (0.1f - 0.2f*rand()/RAND_MAX);
  135.     }
  136.  
  137.     // Mozgassuk a labdát a ds = v * dt képlet alapján.
  138.     ball_pos += ball_speed * dt;
  139.   }
  140.  
  141.   glutPostRedisplay(); // Megváltozott a jelenet, újra kell rajzolni
  142. }
  143.  
  144. void onInitialization() {}
  145.  
  146. void onMouse(int, int, int, int) {}
  147.  
  148. void onMouseMotion(int, int) {}
  149.  
  150. void onKeyboard(unsigned char, int, int) {}
  151.  
  152. void onKeyboardUp(unsigned char, int, int) {}
  153.  
  154. int main(int argc, char **argv) {
  155.   glutInit(&argc, argv);
  156.   glutInitWindowSize(600, 600);
  157.   glutInitWindowPosition(100, 100);
  158.   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
  159.  
  160.   glutCreateWindow("Grafika pelda program");
  161.  
  162.   glMatrixMode(GL_MODELVIEW);
  163.   glLoadIdentity();
  164.   glMatrixMode(GL_PROJECTION);
  165.   glLoadIdentity();
  166.  
  167.   onInitialization();
  168.  
  169.   glutDisplayFunc(onDisplay);
  170.   glutMouseFunc(onMouse);
  171.   glutIdleFunc(onIdle);
  172.   glutKeyboardFunc(onKeyboard);
  173.   glutKeyboardUpFunc(onKeyboardUp);
  174.   glutMotionFunc(onMouseMotion);
  175.  
  176.   glutMainLoop();
  177.  
  178.   return 0;
  179. }
Advertisement
Add Comment
Please, Sign In to add comment