Advertisement
GeeckoDev

gLib2D.c PC 2

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