Guest User

Grafika példa program

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