Advertisement
KeithS

generic height map loader Ogl A5.1

Mar 29th, 2012
523
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.76 KB | None | 0 0
  1. #include <allegro5/allegro.h>
  2. #include <allegro5/allegro_opengl.h>
  3. #include <allegro5/allegro_image.h>
  4. #include <GL/glu.h>
  5. #include <vector>
  6.  
  7. using namespace std;
  8.  
  9. // GENERAL COMMENTS
  10. //---------------------------------------------------------------------
  11. /* linker configuration
  12. `pkg-config --libs allegro-5.1 allegro_image-5.1`
  13. -lGL
  14. -lGLU
  15. */
  16.  
  17. // GLOBALS
  18. //---------------------------------------------------------------------
  19.  
  20. const int SCREEN_X = 800;
  21. const int SCREEN_Y = 600;
  22.  
  23. // FUNCTIONS
  24. //---------------------------------------------------------------------
  25.  
  26. void setup_allegro5(    ALLEGRO_DISPLAY     **Disp,
  27.                         ALLEGRO_EVENT_QUEUE **Event_Q,
  28.                         ALLEGRO_TIMER       **FPS_Tm,
  29.                         const float         fps)
  30. {
  31.     al_init();
  32.     al_init_image_addon();
  33.  
  34.     al_set_new_display_flags(ALLEGRO_OPENGL);
  35.     al_set_new_display_option(ALLEGRO_VSYNC, 1, ALLEGRO_SUGGEST);
  36.     *Disp = al_create_display(SCREEN_X, SCREEN_Y);
  37.     *Event_Q = al_create_event_queue();
  38.     *FPS_Tm = al_create_timer(1.0f / fps);
  39.  
  40.     al_register_event_source(*Event_Q, al_get_display_event_source(*Disp));
  41.     al_register_event_source(*Event_Q, al_get_timer_event_source(*FPS_Tm));
  42. }
  43.  
  44. //---------------------------------------------------------------------
  45.  
  46. void exit_allegro5(     ALLEGRO_DISPLAY     **Disp,
  47.                         ALLEGRO_EVENT_QUEUE **Event_Q,
  48.                         ALLEGRO_TIMER       **FPS_Tm)
  49. {
  50.     al_destroy_display(*Disp);
  51.     al_destroy_event_queue(*Event_Q);
  52.     al_destroy_timer(*FPS_Tm);
  53. }
  54. //---------------------------------------------------------------------
  55.  
  56. void load_ht_map(       int &BMP_HT,
  57.                         int &BMP_WD,
  58.                         vector<GLfloat> &verts)
  59. {
  60.     ALLEGRO_BITMAP *ht_bmp = NULL;
  61.     ALLEGRO_COLOR ht_pixel;
  62.     int bmp_x = 0;
  63.     int bmp_z = 0;
  64.     GLfloat land_scale = 5.0f;
  65.     GLfloat height_scale = 200.0f;
  66.     GLfloat height_true = 0.0f;
  67.     unsigned char r, g, b;
  68.  
  69.     ht_bmp = al_load_bitmap("landtile.jpg");
  70.  
  71.     // locking the bitmap makes the reading of it noticably faster...
  72.     al_lock_bitmap(ht_bmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY);
  73.  
  74.     BMP_HT = al_get_bitmap_height(ht_bmp);
  75.     BMP_WD = al_get_bitmap_width(ht_bmp);
  76.  
  77.     // autocentering variables
  78.     GLfloat cent_wd = GLfloat((BMP_WD) / 2.0f) * land_scale;
  79.     GLfloat cent_ht = GLfloat((BMP_HT) / 2.0f) * land_scale;
  80.  
  81.     verts.reserve(BMP_HT * BMP_WD * 3);
  82.  
  83.     for(bmp_z = 0; bmp_z < BMP_HT; bmp_z++)
  84.     {
  85.         for(bmp_x = 0; bmp_x < BMP_WD; bmp_x++)
  86.         {
  87.             verts.push_back(GLfloat((bmp_x * land_scale) - cent_wd));
  88.  
  89.             ht_pixel = al_get_pixel(ht_bmp, bmp_x, bmp_z); // get pixel color
  90.             al_unmap_rgb(ht_pixel, &r, &g, &b);
  91.             height_true = GLfloat(float(r) / 255.0f) * height_scale;
  92.  
  93.             verts.push_back(height_true);
  94.             verts.push_back(GLfloat((bmp_z * land_scale) - cent_ht));
  95.         }
  96.     }
  97.     al_unlock_bitmap(ht_bmp);
  98.     al_destroy_bitmap(ht_bmp);
  99. }
  100.  
  101. //---------------------------------------------------------------------
  102.  
  103. void make_point_connections(    int BMP_HT,
  104.                                 int BMP_WD,
  105.                                 vector<GLuint> &points)
  106. {
  107.     GLuint i = 0;
  108.     size_t point_count = (BMP_WD - 1) * (BMP_HT - 1) * 6;
  109.     GLuint triangle_count = ((BMP_WD - 1) * (BMP_HT - 1)) + (BMP_HT - 1);
  110.     points.reserve(point_count);
  111.  
  112.     int width_cnt = 0;
  113.  
  114.     for(i = 0; i < triangle_count; i++)
  115.     {
  116.         if(width_cnt == (BMP_WD - 1))
  117.         {
  118.             width_cnt = 0;
  119.             continue;
  120.         }
  121.         else
  122.         {
  123.             // Triangle 1
  124.             points.push_back(i);
  125.             points.push_back(i + 1);
  126.             points.push_back(i + BMP_WD);
  127.  
  128.             // Triangle 2
  129.             points.push_back(i + 1);
  130.             points.push_back(i + BMP_WD + 1);
  131.             points.push_back(i + BMP_WD);
  132.         // Mod: both triangles go around counter clockwise now...
  133.  
  134.             width_cnt++;
  135.         }
  136.     }
  137. }
  138.  
  139. //---------------------------------------------------------------------
  140.  
  141. void camera_3D_setup()
  142. {
  143.     glMatrixMode(GL_PROJECTION);
  144.     glLoadIdentity();
  145.     gluPerspective(35.0, (GLdouble)SCREEN_X / (GLdouble)SCREEN_Y, 1.0, 1000.0);
  146.  
  147.     glRotatef(15.0f, 1.0f, 0.0f, 0.0f);
  148.     glTranslatef(0.0, -150.0f, -550.0f);
  149.  
  150. }
  151.  
  152. //---------------------------------------------------------------------
  153.  
  154. void draw_scene(    vector<GLfloat> verts,
  155.                     vector<GLuint> points,
  156.                     GLsizei count,
  157.                     GLfloat _ang)
  158. {
  159.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  160.     al_clear_to_color(al_map_rgb(0,0,30));
  161.  
  162.     glMatrixMode(GL_MODELVIEW);
  163.     glLoadIdentity();
  164.  
  165.     glRotatef(_ang, 0.0f, 1.0f, 0.0f);
  166.  
  167.     // again I resort to using gl_ClientState, but this time employing glDrawElements
  168.     glEnableClientState(GL_VERTEX_ARRAY);
  169.     glVertexPointer(3, GL_FLOAT, 0, &verts.at(0));
  170.     glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, &points.at(0));
  171.     glDisableClientState(GL_VERTEX_ARRAY);
  172.  
  173.     glFlush();
  174. }
  175.  
  176. // MAIN()
  177. //---------------------------------------------------------------------
  178.  
  179. int main(int argc, char *argv[])
  180. {
  181.     ALLEGRO_DISPLAY *display = NULL;
  182.     ALLEGRO_EVENT_QUEUE *event_queue = NULL;
  183.     ALLEGRO_TIMER *FPS_timer = NULL;
  184.  
  185.     const float FPS = 60.0f;
  186.     GLfloat angle = 0.0f;
  187.  
  188.     int BMP_HEIGHT = 0;
  189.     int BMP_WIDTH = 0;
  190.  
  191.     bool draw = false;
  192.     bool loop = true;
  193.  
  194.     vector<GLfloat> land_vertices; // float
  195.     vector<GLuint> connect_points; // unsigned int
  196.  
  197.     setup_allegro5(&display, &event_queue, &FPS_timer, FPS);
  198.     load_ht_map(BMP_HEIGHT, BMP_WIDTH, land_vertices);
  199.     make_point_connections(BMP_HEIGHT, BMP_WIDTH, connect_points);
  200.  
  201.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  202.  
  203.     al_start_timer(FPS_timer);
  204.  
  205.     camera_3D_setup();
  206.  
  207.     while(loop)
  208.     {
  209.         ALLEGRO_EVENT event;
  210.         al_wait_for_event(event_queue, &event);
  211.  
  212.         switch(event.type)
  213.         {
  214.             case ALLEGRO_EVENT_DISPLAY_CLOSE:
  215.                 loop = false;
  216.                 break;
  217.  
  218.             case ALLEGRO_EVENT_TIMER:
  219.                 draw = true;
  220.                 break;
  221.  
  222.             default:
  223.                 break;
  224.         }
  225.  
  226.         if(draw == true && al_event_queue_is_empty(event_queue))
  227.         {
  228.             draw = false;
  229.             angle += 0.5f;
  230.             if(angle > 360.0f)
  231.                 angle -= 360.0f;
  232.  
  233.             draw_scene(land_vertices, connect_points, GLsizei(connect_points.size()), angle);
  234.             al_flip_display();
  235.         }
  236.     }
  237.  
  238.     al_stop_timer(FPS_timer);
  239.     exit_allegro5(&display, &event_queue, &FPS_timer);
  240.     return 0;
  241. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement