Advertisement
GeeckoDev

glib2d.c - PC

Sep 11th, 2011
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 18.78 KB | None | 0 0
  1. // gLib2D by Geecko - A simple, fast, light-weight 2D graphics library.
  2. //
  3. // This work is licensed under the Creative Commons BY-SA 3.0 Unported License.
  4. // See LICENSE for more details.
  5. //
  6. // Please report bugs at : geecko.dev@free.r
  7.  
  8. #include "glib2d.h"
  9.  
  10. #include <GL/gl.h>
  11. #include <SDL/SDL.h>
  12. #include <SDL/SDL_image.h>
  13. #include <stdio.h>
  14. #include <malloc.h>
  15. #include <string.h>
  16. #include <math.h>
  17.  
  18. #ifdef USE_PNG
  19. #include <png.h>
  20. #endif
  21.  
  22. #ifdef USE_JPEG
  23. #include <jpeglib.h>
  24. #include <jerror.h>
  25. #endif
  26.  
  27. #define PSP_LINE_SIZE       (512)
  28. #define PIXEL_SIZE          (4)
  29. #define FRAMEBUFFER_SIZE    (PSP_LINE_SIZE*G2D_SCR_H*PIXEL_SIZE)
  30. #define MALLOC_STEP         (128)
  31. #define TRANSFORM_STACK_MAX (64)
  32. #define SLICE_WIDTH         (64)
  33.  
  34. #define DEFAULT_SIZE       (10)
  35. #define DEFAULT_COORD_MODE (G2D_UP_LEFT)
  36. #define DEFAULT_X          (0.)
  37. #define DEFAULT_Y          (0.)
  38. #define DEFAULT_Z          (0.)
  39. #define DEFAULT_COLOR      (WHITE)
  40. #define DEFAULT_ALPHA      (0xFF)
  41.  
  42. #define CURRENT_OBJ obj_list[obj_list_size-1]
  43. #define CURRENT_TRANSFORM transform_stack[transform_stack_size-1]
  44. #define I_OBJ obj_list[i]
  45.  
  46. enum Obj_Types { RECTS, LINES, QUADS, POINTS };
  47.  
  48. typedef struct
  49. {
  50.   float x, y, z;
  51.   float rot, rot_sin, rot_cos;
  52.   float scale_w, scale_h;
  53. } Transform;
  54.  
  55. typedef struct
  56. {
  57.   float x, y, z;
  58.   float rot_x, rot_y; // Rotation center
  59.   float rot, rot_sin, rot_cos;
  60.   int crop_x, crop_y;
  61.   int crop_w, crop_h;
  62.   float scale_w, scale_h;
  63.   g2dColor color;
  64.   g2dAlpha alpha;
  65. } Object;
  66.  
  67.  
  68. // * Main vars *
  69. static bool init = false, start = false, zclear = true, scissor = false,
  70.             vsync = false;
  71. static Transform transform_stack[TRANSFORM_STACK_MAX];
  72. static int transform_stack_size;
  73. static float global_scale = 1.f;
  74. // * Object vars *
  75. static Object *obj_list = NULL, obj;
  76. static g2dEnum obj_type;
  77. static int obj_list_size;
  78. static bool obj_begin = false, obj_line_strip;
  79. static bool obj_use_z, obj_use_vert_color, obj_use_blend, obj_use_rot,
  80.             obj_use_tex_linear, obj_use_tex_repeat;
  81. static g2dEnum obj_coord_mode;
  82. static int obj_colors_count;
  83. static g2dImage* obj_tex;
  84.  
  85. // * Internal functions *
  86.  
  87. void _g2dEvents()
  88. {
  89.   SDL_Event event;
  90.  
  91.   while(SDL_PollEvent(&event))
  92.   {
  93.     if (event.type == SDL_QUIT)
  94.     {
  95.       SDL_Quit();
  96.       exit(0);
  97.     }
  98.   }
  99. }
  100.  
  101.  
  102. void _g2dInit()
  103. {  
  104.   // Setup SDL
  105.   SDL_Init(SDL_INIT_VIDEO);
  106.   SDL_GL_SetAttribute(SDL_GL_RED_SIZE,8);
  107.   SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8);
  108.   SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,8);
  109.   SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,16);
  110.   SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
  111.   SDL_SetVideoMode(G2D_SCR_W,G2D_SCR_H,24,SDL_OPENGL);
  112.   SDL_WM_SetCaption("gLib2D",NULL);
  113.  
  114.   // Setup OpenGL
  115.   glMatrixMode(GL_PROJECTION);
  116.   glLoadIdentity();
  117.   glOrtho(0,G2D_SCR_W,G2D_SCR_H,0,0,1);
  118.   glMatrixMode(GL_MODELVIEW);
  119.  
  120.   g2dResetScissor();
  121.   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  122.  
  123.   glEnable(GL_BLEND);
  124.   glDepthFunc(GL_LEQUAL);
  125.   glDepthRange(0,65535);
  126.   glClearDepth(65535);
  127.  
  128.   init = true;
  129. }
  130.  
  131.  
  132. void _g2dStart()
  133. {
  134.   if (!init) _g2dInit();
  135.  
  136.   start = true;
  137. }
  138.  
  139.  
  140. void _g2dSetVertex(int i, float vx, float vy)
  141. {
  142.   // Texture
  143.   if (obj_tex != NULL)
  144.   {
  145.     glTexCoord2d(vx,vy);
  146.   }
  147.  
  148.   // Color
  149.   glColor4f(G2D_GET_R(I_OBJ.color)/255.,
  150.             G2D_GET_G(I_OBJ.color)/255.,
  151.             G2D_GET_B(I_OBJ.color)/255.,
  152.             G2D_GET_A(I_OBJ.color)/255.);
  153.  
  154.   // Coord
  155.   float x = I_OBJ.x + (obj_type == RECTS ? vx * I_OBJ.scale_w : 0.);
  156.   float y = I_OBJ.y + (obj_type == RECTS ? vy * I_OBJ.scale_h : 0.);
  157.   float z = I_OBJ.z;
  158.  
  159.   // Then apply the rotation
  160.   if (obj_use_rot && obj_type == RECTS)
  161.   {
  162.     float tx = x-I_OBJ.rot_x, ty = y-I_OBJ.rot_y;
  163.     x = I_OBJ.rot_x - I_OBJ.rot_sin*ty + I_OBJ.rot_cos*tx,
  164.     y = I_OBJ.rot_y + I_OBJ.rot_cos*ty + I_OBJ.rot_sin*tx;
  165.   }
  166.  
  167.   glVertex3f(x,y,z);
  168. }
  169.  
  170.  
  171. // Insertion sort, because it is a fast and _stable_ sort.
  172. void _g2dVertexSort()
  173. {
  174.   int i, j;
  175.   Object obj_tmp;
  176.   for (i=1; i<obj_list_size; i++)
  177.   {
  178.     j = i;
  179.     memcpy(&obj_tmp,obj_list+j,sizeof(Object));
  180.     while (j>0 && obj_list[j-1].z < obj_tmp.z)
  181.     {
  182.       memcpy(obj_list+j,obj_list+j-1,sizeof(Object));
  183.       j--;
  184.     }
  185.     memcpy(obj_list+j,&obj_tmp,sizeof(Object));
  186.   }
  187. }
  188.  
  189. // * Main functions *
  190.  
  191. void g2dClear(g2dColor color)
  192. {
  193.   if (!start) _g2dStart();
  194.  
  195.   glClearColor(G2D_GET_R(color),G2D_GET_G(color),
  196.                G2D_GET_B(color),G2D_GET_A(color));
  197.   glClear(GL_COLOR_BUFFER_BIT | (zclear ? GL_DEPTH_BUFFER_BIT : 0));
  198.   zclear = false;
  199. }
  200.  
  201.  
  202. void g2dClearZ()
  203. {
  204.   if (!start) _g2dStart();
  205.  
  206.   glClear(GL_DEPTH_BUFFER_BIT);
  207.   zclear = true;
  208. }
  209.  
  210.  
  211. void _g2dBeginCommon()
  212. {
  213.   if (!start) _g2dStart();
  214.  
  215.   obj_list_size = 0;
  216.   obj_list = realloc(obj_list,MALLOC_STEP * sizeof(Object));
  217.  
  218.   obj_use_z = false;
  219.   obj_use_vert_color = false;
  220.   obj_use_blend = false;
  221.   obj_use_rot = false;
  222.   obj_colors_count = 0;
  223.   g2dReset();
  224.  
  225.   obj_begin = true;
  226. }
  227.  
  228.  
  229. void g2dBeginRects(g2dImage* tex)
  230. {
  231.   if (obj_begin) return;
  232.  
  233.   obj_type = RECTS;
  234.   obj_tex = tex;
  235.   _g2dBeginCommon();
  236. }
  237.  
  238.  
  239. void g2dBeginLines(g2dEnum line_mode)
  240. {
  241.   if (obj_begin) return;
  242.  
  243.   obj_type = LINES;
  244.   obj_tex = NULL;
  245.   obj_line_strip = (line_mode & G2D_STRIP);
  246.   _g2dBeginCommon();
  247. }
  248.  
  249.  
  250. void g2dBeginQuads(g2dImage* tex)
  251. {
  252.   if (obj_begin) return;
  253.  
  254.   obj_type = QUADS;
  255.   obj_tex = tex;
  256.   _g2dBeginCommon();
  257. }
  258.  
  259.  
  260. void g2dBeginPoints()
  261. {
  262.   if (obj_begin) return;
  263.  
  264.   obj_type = POINTS;
  265.   obj_tex = NULL;
  266.   _g2dBeginCommon();
  267. }
  268.  
  269.  
  270. void _g2dEndRects()
  271. {
  272.   // Horror : we need to sort the vertices.
  273.   if (obj_use_z && obj_use_blend) _g2dVertexSort();
  274.  
  275.   glBegin(GL_TRIANGLES);
  276.  
  277.   // Add each object
  278.   int i;
  279.   for (i=0; i<obj_list_size; i+=1)
  280.   {
  281.     _g2dSetVertex(i,0.,0.);
  282.     _g2dSetVertex(i,1.f,0.);
  283.     _g2dSetVertex(i,0.,1.f);
  284.     _g2dSetVertex(i,0.,1.f);
  285.     _g2dSetVertex(i,1.f,0.);
  286.     _g2dSetVertex(i,1.f,1.f);
  287.   }
  288.  
  289.   // Then put it in the display list.
  290.   glEnd();
  291. }
  292.  
  293.  
  294. void _g2dEndLines()
  295. {
  296.   glBegin(obj_line_strip ? GL_LINE_STRIP : GL_LINES);
  297.  
  298.   // Add each object
  299.   int i;
  300.   if (obj_line_strip)
  301.   {
  302.     _g2dSetVertex(0,0.,0.);
  303.     for (i=1; i<obj_list_size; i+=1)
  304.     {
  305.       _g2dSetVertex(i,0.,0.);
  306.     }
  307.   }
  308.   else
  309.   {
  310.     for (i=0; i+1<obj_list_size; i+=2)
  311.     {
  312.       _g2dSetVertex(i  ,0.,0.);
  313.       _g2dSetVertex(i+1,0.,0.);
  314.     }
  315.   }
  316.  
  317.   // Then put it in the display list.
  318.   glEnd();
  319. }
  320.  
  321.  
  322. void _g2dEndQuads()
  323. {
  324.   glBegin(GL_TRIANGLES);
  325.  
  326.   // Add each object
  327.   int i;
  328.   for (i=0; i+3<obj_list_size; i+=4)
  329.   {
  330.     _g2dSetVertex(i  ,0.,0.);
  331.     _g2dSetVertex(i+1,1.f,0.);
  332.     _g2dSetVertex(i+3,0.,1.f);
  333.     _g2dSetVertex(i+3,0.,1.f);
  334.     _g2dSetVertex(i+1,1.f,0.);
  335.     _g2dSetVertex(i+2,1.f,1.f);
  336.   }
  337.  
  338.   // Then put it in the display list.
  339.   glEnd();
  340. }
  341.  
  342.  
  343. void _g2dEndPoints()
  344. {
  345.   glBegin(GL_POINTS);
  346.  
  347.   // Add each object
  348.   int i;
  349.   for (i=0; i<obj_list_size; i+=1)
  350.   {
  351.     _g2dSetVertex(i,0.,0.);
  352.   }
  353.  
  354.   // Then put it in the display list.
  355.   glEnd();
  356. }
  357.  
  358.  
  359. void g2dEnd()
  360. {
  361.   if (!obj_begin || obj_list_size <= 0)
  362.   {
  363.     obj_begin = false;
  364.     return;
  365.   }
  366.  
  367.   // Manage extensions
  368.   if (obj_use_z)          glEnable(GL_DEPTH_TEST);
  369.   else                    glDisable(GL_DEPTH_TEST);
  370.   if (obj_use_blend)      glEnable(GL_BLEND);
  371.   else                    glDisable(GL_BLEND);
  372.   if (obj_tex == NULL)    glDisable(GL_TEXTURE_2D);
  373.   else
  374.   {
  375.     glEnable(GL_TEXTURE_2D);
  376.     glBindTexture(GL_TEXTURE_2D,obj_tex->id);
  377.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,
  378.                     obj_use_tex_linear ? GL_LINEAR : GL_NEAREST);
  379.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,
  380.                     obj_use_tex_linear ? GL_LINEAR : GL_NEAREST);
  381.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,
  382.                     obj_use_tex_linear ? GL_REPEAT : GL_CLAMP);
  383.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,
  384.                     obj_use_tex_linear ? GL_REPEAT : GL_CLAMP);
  385.   }
  386.  
  387.   switch (obj_type)
  388.   {
  389.     case RECTS:  _g2dEndRects();  break;
  390.     case LINES:  _g2dEndLines();  break;
  391.     case QUADS:  _g2dEndQuads();  break;
  392.     case POINTS: _g2dEndPoints(); break;
  393.   }
  394.  
  395.   glColor3f(1.f,1.f,1.f);
  396.   glEnable(GL_BLEND);
  397.  
  398.   obj_begin = false;
  399.   if (obj_use_z) zclear = true;
  400. }
  401.  
  402.  
  403. void g2dReset()
  404. {
  405.   g2dResetCoord();
  406.   g2dResetScale();
  407.   g2dResetColor();
  408.   g2dResetAlpha();
  409.   g2dResetRotation();
  410.   g2dResetCrop();
  411.   g2dResetTex();
  412. }
  413.  
  414.  
  415. void g2dFlip(g2dEnum flip_mode)
  416. {
  417.   if (scissor) g2dResetScissor();
  418.  
  419.   glFinish();
  420.   SDL_GL_SwapBuffers();
  421.   _g2dEvents();
  422.  
  423.   start = false;
  424. }
  425.  
  426.  
  427. void g2dAdd()
  428. {
  429.   if (!obj_begin) return;
  430.   if (obj.scale_w == 0 || obj.scale_h == 0) return;
  431.  
  432.   if (!(obj_list_size % MALLOC_STEP))
  433.   {
  434.     obj_list = realloc(obj_list,(obj_list_size+MALLOC_STEP) * sizeof(Object));
  435.   }
  436.  
  437.   obj_list_size++;
  438.   obj.rot_x = obj.x;
  439.   obj.rot_y = obj.y;
  440.   CURRENT_OBJ = obj;
  441.  
  442.   // Coord mode stuff
  443.   CURRENT_OBJ.x -= (obj_coord_mode == G2D_UP_RIGHT ||
  444.                     obj_coord_mode == G2D_DOWN_RIGHT ?
  445.                     CURRENT_OBJ.scale_w :
  446.                    (obj_coord_mode == G2D_CENTER ?
  447.                     CURRENT_OBJ.scale_w/2 : 0));
  448.   CURRENT_OBJ.y -= (obj_coord_mode == G2D_DOWN_LEFT ||
  449.                     obj_coord_mode == G2D_DOWN_RIGHT ?
  450.                     CURRENT_OBJ.scale_h :
  451.                    (obj_coord_mode == G2D_CENTER ?
  452.                     CURRENT_OBJ.scale_h/2 : 0));
  453.  
  454.   // Alpha stuff
  455.   CURRENT_OBJ.color = G2D_MODULATE(CURRENT_OBJ.color,255,obj.alpha);
  456. }
  457.  
  458.  
  459. void g2dPush()
  460. {
  461.   if (transform_stack_size >= TRANSFORM_STACK_MAX) return;
  462.   transform_stack_size++;
  463.   CURRENT_TRANSFORM.x = obj.x;
  464.   CURRENT_TRANSFORM.y = obj.y;
  465.   CURRENT_TRANSFORM.z = obj.z;
  466.   CURRENT_TRANSFORM.rot = obj.rot;
  467.   CURRENT_TRANSFORM.rot_sin = obj.rot_sin;
  468.   CURRENT_TRANSFORM.rot_cos = obj.rot_cos;
  469.   CURRENT_TRANSFORM.scale_w = obj.scale_w;
  470.   CURRENT_TRANSFORM.scale_h = obj.scale_h;
  471. }
  472.  
  473.  
  474. void g2dPop()
  475. {
  476.   if (transform_stack_size <= 0) return;
  477.   obj.x = CURRENT_TRANSFORM.x;
  478.   obj.y = CURRENT_TRANSFORM.y;
  479.   obj.z = CURRENT_TRANSFORM.z;
  480.   obj.rot = CURRENT_TRANSFORM.rot;
  481.   obj.rot_sin = CURRENT_TRANSFORM.rot_sin;
  482.   obj.rot_cos = CURRENT_TRANSFORM.rot_cos;
  483.   obj.scale_w = CURRENT_TRANSFORM.scale_w;
  484.   obj.scale_h = CURRENT_TRANSFORM.scale_h;
  485.   if (obj.rot != 0.) obj_use_rot = true;
  486.   if (obj.z != 0.) obj_use_z = true;
  487.   transform_stack_size--;
  488. }
  489.  
  490. // * Coord functions *
  491.  
  492. void g2dResetCoord()
  493. {
  494.   obj_coord_mode = DEFAULT_COORD_MODE;
  495.   obj.x = DEFAULT_X;
  496.   obj.y = DEFAULT_Y;
  497.   obj.z = DEFAULT_Z;
  498. }
  499.  
  500.  
  501. void g2dSetCoordMode(g2dEnum coord_mode)
  502. {
  503.   if (coord_mode < G2D_UP_LEFT || coord_mode > G2D_CENTER) return;
  504.   obj_coord_mode = coord_mode;
  505. }
  506.  
  507.  
  508. void g2dGetCoordXYZ(float* x, float* y, float* z)
  509. {
  510.   if (x != NULL) *x = obj.x;
  511.   if (y != NULL) *y = obj.y;
  512.   if (z != NULL) *z = obj.z;
  513. }
  514.  
  515.  
  516. void g2dSetCoordXY(float x, float y)
  517. {
  518.   obj.x = x * global_scale;
  519.   obj.y = y * global_scale;
  520.   obj.z = 0.;
  521. }
  522.  
  523.  
  524. void g2dSetCoordXYZ(float x, float y, float z)
  525. {
  526.   obj.x = x * global_scale;
  527.   obj.y = y * global_scale;
  528.   obj.z = z * global_scale;
  529.   if (z != 0.) obj_use_z = true;
  530. }
  531.  
  532.  
  533. void g2dSetCoordXYRelative(float x, float y)
  534. {
  535.   float inc_x = x, inc_y = y;
  536.   if (obj.rot_cos != 1.f)
  537.   {
  538.     inc_x = -obj.rot_sin*y + obj.rot_cos*x;
  539.     inc_y =  obj.rot_cos*y + obj.rot_sin*x;
  540.   }
  541.   obj.x += inc_x * global_scale;
  542.   obj.y += inc_y * global_scale;  
  543. }
  544.  
  545.  
  546. void g2dSetCoordXYZRelative(float x, float y, float z)
  547. {
  548.   g2dSetCoordXYRelative(x,y);
  549.   obj.z += z * global_scale;
  550.   if (z != 0.) obj_use_z = true;
  551. }
  552.  
  553. // * Scale functions *
  554.  
  555. void g2dResetGlobalScale()
  556. {
  557.   global_scale = 1.f;
  558. }
  559.  
  560.  
  561. void g2dResetScale()
  562. {
  563.   if (obj_tex == NULL)
  564.   {
  565.     obj.scale_w = DEFAULT_SIZE;
  566.     obj.scale_h = DEFAULT_SIZE;
  567.   }
  568.   else
  569.   {
  570.     obj.scale_w = obj_tex->w;
  571.     obj.scale_h = obj_tex->h;
  572.   }
  573.  
  574.   obj.scale_w *= global_scale;
  575.   obj.scale_h *= global_scale;
  576. }
  577.  
  578.  
  579. void g2dGetGlobalScale(float* scale)
  580. {
  581.   if (scale != NULL) *scale = global_scale;
  582. }
  583.  
  584.  
  585. void g2dGetScaleWH(float* w, float* h)
  586. {
  587.   if (w != NULL) *w = obj.scale_w;
  588.   if (h != NULL) *h = obj.scale_h;
  589. }
  590.  
  591.  
  592. void g2dSetGlobalScale(float scale)
  593. {
  594.   global_scale = scale;
  595. }
  596.  
  597.  
  598. void g2dSetScale(float w, float h)
  599. {
  600.   g2dResetScale();
  601.   g2dSetScaleRelative(w,h);
  602. }
  603.  
  604.  
  605. void g2dSetScaleWH(float w, float h)
  606. {
  607.   obj.scale_w = w * global_scale;
  608.   obj.scale_h = h * global_scale;
  609.   // A trick to prevent an unexpected behavior when mirroring with GU_SPRITES.
  610.   if (obj.scale_w < 0 || obj.scale_h < 0) obj_use_rot = true;
  611. }
  612.  
  613.  
  614. void g2dSetScaleRelative(float w, float h)
  615. {
  616.   obj.scale_w *= w;
  617.   obj.scale_h *= h;
  618.  
  619.   if (obj.scale_w < 0 || obj.scale_h < 0) obj_use_rot = true;
  620. }
  621.  
  622.  
  623. void g2dSetScaleWHRelative(float w, float h)
  624. {
  625.   obj.scale_w += w * global_scale;
  626.   obj.scale_h += h * global_scale;
  627.  
  628.   if (obj.scale_w < 0 || obj.scale_h < 0) obj_use_rot = true;
  629. }
  630.  
  631. // * Color functions *
  632.  
  633. void g2dResetColor()
  634. {
  635.   obj.color = DEFAULT_COLOR;
  636. }
  637.  
  638.  
  639. void g2dResetAlpha()
  640. {
  641.   obj.alpha = DEFAULT_ALPHA;
  642. }
  643.  
  644.  
  645. void g2dGetAlpha(g2dAlpha* alpha)
  646. {
  647.   if (alpha != NULL) *alpha = obj.alpha;
  648. }
  649.  
  650.  
  651. void g2dSetColor(g2dColor color)
  652. {
  653.   obj.color = color;
  654.   if (++obj_colors_count > 1) obj_use_vert_color = true;
  655.   if (G2D_GET_A(obj.color) < 255) obj_use_blend = true;
  656. }
  657.  
  658.  
  659. void g2dSetAlpha(g2dAlpha alpha)
  660. {
  661.   if (alpha < 0) alpha = 0;
  662.   if (alpha > 255) alpha = 255;
  663.   obj.alpha = alpha;
  664.   if (++obj_colors_count > 1) obj_use_vert_color = true;
  665.   if (obj.alpha < 255) obj_use_blend = true;
  666. }
  667.  
  668.  
  669. void g2dSetAlphaRelative(int alpha)
  670. {
  671.   g2dSetAlpha(obj.alpha + alpha);
  672. }
  673.  
  674. // * Rotations functions *
  675.  
  676. void g2dResetRotation()
  677. {
  678.   obj.rot = 0.;
  679.   obj.rot_sin = 0.;
  680.   obj.rot_cos = 1.f;
  681. }
  682.  
  683.  
  684. void g2dGetRotationRad(float* radians)
  685. {
  686.   if (radians != NULL) *radians = obj.rot;
  687. }
  688.  
  689.  
  690. void g2dGetRotation(float* degrees)
  691. {
  692.   if (degrees != NULL) *degrees = obj.rot * 180. / M_PI;
  693. }
  694.  
  695.  
  696. void g2dSetRotationRad(float radians)
  697. {
  698.   if (radians == obj.rot) return;
  699.   obj.rot = radians;
  700.   obj.rot_sin = sin(radians);
  701.   obj.rot_cos = cos(radians);
  702.   if (radians != 0.) obj_use_rot = true;
  703. }
  704.  
  705.  
  706. void g2dSetRotation(float degrees)
  707. {
  708.   g2dSetRotationRad(degrees * M_PI / 180.);
  709. }
  710.  
  711.  
  712. void g2dSetRotationRadRelative(float radians)
  713. {
  714.   g2dSetRotationRad(obj.rot + radians);
  715. }
  716.  
  717.  
  718. void g2dSetRotationRelative(float degrees)
  719. {
  720.   g2dSetRotationRadRelative(degrees * M_PI / 180.);
  721. }
  722.  
  723. // * Crop functions *
  724.  
  725. void g2dResetCrop()
  726. {
  727.   if (obj_tex == NULL) return;
  728.   obj.crop_x = 0;
  729.   obj.crop_y = 0;
  730.   obj.crop_w = obj_tex->w;
  731.   obj.crop_h = obj_tex->h;
  732. }
  733.  
  734.  
  735. void g2dGetCropXY(int* x, int* y)
  736. {
  737.   if (obj_tex == NULL) return;
  738.   if (x != NULL) *x = obj.crop_x;
  739.   if (y != NULL) *y = obj.crop_y;
  740. }
  741.  
  742.  
  743. void g2dGetCropWH(int* w, int* h)
  744. {
  745.   if (obj_tex == NULL) return;
  746.   if (w != NULL) *w = obj.crop_w;
  747.   if (h != NULL) *h = obj.crop_h;
  748. }
  749.  
  750.  
  751. void g2dSetCropXY(int x, int y)
  752. {
  753.   if (obj_tex == NULL) return;
  754.   obj.crop_x = x;
  755.   obj.crop_y = y;
  756. }
  757.  
  758.  
  759. void g2dSetCropWH(int w, int h)
  760. {
  761.   if (obj_tex == NULL) return;
  762.   obj.crop_w = w;
  763.   obj.crop_h = h;
  764. }
  765.  
  766.  
  767. void g2dSetCropXYRelative(int x, int y)
  768. {
  769.   if (obj_tex == NULL) return;
  770.   g2dSetCropXY(obj.crop_x + x, obj.crop_y + y);
  771. }
  772.  
  773.  
  774. void g2dSetCropWHRelative(int w, int h)
  775. {
  776.   if (obj_tex == NULL) return;
  777.   g2dSetCropWH(obj.crop_w + w, obj.crop_h + h);
  778. }
  779.  
  780. // * Texture functions *
  781.  
  782. void g2dResetTex()
  783. {
  784.   if (obj_tex == NULL) return;
  785.   obj_use_tex_repeat = false;
  786.   obj_use_tex_linear = true;
  787.   obj_use_blend = true;
  788. }
  789.  
  790.  
  791. void g2dSetTexRepeat(bool use)
  792. {
  793.   if (obj_tex == NULL) return;
  794.   obj_use_tex_repeat = use;
  795. }
  796.  
  797.  
  798. void g2dSetTexBlend(bool use)
  799. {
  800.   if (obj_tex == NULL) return;
  801.   obj_use_blend = use;
  802. }
  803.  
  804.  
  805. void g2dSetTexLinear(bool use)
  806. {
  807.   if (obj_tex == NULL) return;
  808.   obj_use_tex_linear = use;
  809. }
  810.  
  811. // * Texture management *
  812.  
  813. SDL_Surface* _g2dFlipSurface(SDL_Surface* surface)
  814. {
  815.     int current_line, pitch;
  816.     SDL_Surface * fliped_surface =
  817.       SDL_CreateRGBSurface(SDL_SWSURFACE,surface->w,surface->h,
  818.                            surface->format->BitsPerPixel,
  819.                            surface->format->Rmask,
  820.                            surface->format->Gmask,
  821.                            surface->format->Bmask,
  822.                            surface->format->Amask);
  823.  
  824.     SDL_LockSurface(surface);
  825.     SDL_LockSurface(fliped_surface);
  826.  
  827.     pitch = surface->pitch;
  828.     for (current_line = 0; current_line < surface->h; current_line ++)
  829.     {
  830.         memcpy(&((unsigned char* )fliped_surface->pixels)[current_line*pitch],
  831.                &((unsigned char* )surface->pixels)[(surface->h - 1  -
  832.                                                     current_line)*pitch],
  833.                pitch);
  834.     }
  835.  
  836.     SDL_UnlockSurface(fliped_surface);
  837.     SDL_UnlockSurface(surface);
  838.     return fliped_surface;
  839. }
  840.  
  841.  
  842. void g2dTexFree(g2dImage** tex)
  843. {
  844.   if (tex == NULL) return;
  845.   if (*tex == NULL) return;
  846.   glDeleteTextures(1,&(*tex)->id);
  847.   free(*tex);
  848.   *tex = NULL;
  849. }
  850.  
  851.  
  852. g2dImage* g2dTexLoad(const char* path, g2dEnum tex_mode)
  853. {
  854.   if (path == NULL) return NULL;
  855.  
  856.   if (!start) _g2dStart();
  857.  
  858.   g2dImage* tex = malloc(sizeof(g2dImage));
  859.   SDL_Surface *picture_surface = NULL;
  860.   SDL_Surface *gl_surface = NULL;
  861.   SDL_Surface *gl_fliped_surface = NULL;
  862.   Uint32 rmask, gmask, bmask, amask;
  863.  
  864.   picture_surface = IMG_Load(path);
  865.   if (picture_surface == NULL) return NULL;
  866.  
  867. #if SDL_BYTEORDER == SDL_BIG_ENDIAN
  868.   rmask = 0xff000000;
  869.   gmask = 0x00ff0000;
  870.   bmask = 0x0000ff00;
  871.   amask = 0x000000ff;
  872. #else
  873.   rmask = 0x000000ff;
  874.   gmask = 0x0000ff00;
  875.   bmask = 0x00ff0000;
  876.   amask = 0xff000000;
  877. #endif
  878.  
  879.   SDL_PixelFormat format = *(picture_surface->format);
  880.   format.BitsPerPixel = 32;
  881.   format.BytesPerPixel = 4;
  882.   format.Rmask = rmask;
  883.   format.Gmask = gmask;
  884.   format.Bmask = bmask;
  885.   format.Amask = amask;
  886.  
  887.   gl_surface = SDL_ConvertSurface(picture_surface,&format,SDL_SWSURFACE);
  888.   gl_fliped_surface = _g2dFlipSurface(gl_surface);
  889.  
  890.   tex->w = gl_fliped_surface->w;
  891.   tex->h = gl_fliped_surface->h;
  892.  
  893.   glGenTextures(1, &tex->id);
  894.   glBindTexture(GL_TEXTURE_2D, tex->id);
  895.   glTexImage2D(GL_TEXTURE_2D, 0, 4, gl_fliped_surface->w,
  896.                gl_fliped_surface->h, 0, GL_RGBA,GL_UNSIGNED_BYTE,
  897.                gl_fliped_surface->pixels);
  898.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  899.   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  900.  
  901.   SDL_FreeSurface(gl_fliped_surface);
  902.   SDL_FreeSurface(gl_surface);
  903.   SDL_FreeSurface(picture_surface);
  904.  
  905.   return tex;
  906. }
  907.  
  908. // * Scissor functions *
  909.  
  910. void g2dResetScissor()
  911. {
  912.   g2dSetScissor(0,0,G2D_SCR_W,G2D_SCR_H);
  913.   scissor = false;
  914. }
  915.  
  916.  
  917. void g2dSetScissor(int x, int y, int w, int h)
  918. {
  919.   glScissor(x,y,w,h);
  920.   scissor = true;
  921. }
  922.  
  923. // EOF
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement