Want more features on Pastebin? Sign Up, it's FREE!
Guest

draw.cpp (tex 2d replacement functions)

By: a guest on Jul 5th, 2012  |  syntax: C++  |  size: 9.10 KB  |  views: 8  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
This paste has a previous version, view the difference. Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include "Draw.h"
  2. ///vars to add to structs
  3. struct OGL_Texture{
  4.         float bw,bh;//blit width/height if non pwr 2 textures
  5. };
  6. struct OGL_Surface : OGL_Texture{
  7.         float bw,bh;
  8. };
  9.  
  10. ///Draw Funcs to replace (also replace "GL_TEXTURE_RECTANGLE_NV" with "GL_TEXTURE_2D")
  11. bool IsPowerOfTwo(uint32_t x)
  12. {
  13.     return ((x & (x - 1)) == 0);
  14. }
  15. int HighestBit(uint32_t x)
  16. {
  17.         if (IsPowerOfTwo(x)){return x;}
  18.         uint32_t y = 1<<31;
  19.         while (y>x){y=y>>1;}
  20.         return y<<1;
  21. }
  22. void OGL_Texture::gen_texture(uint16_t width, uint16_t height, uint8_t *PixData){
  23.         if (width==0 || height==0){printf("ERROR! WIDTH OR HEIGHT OF TEXTURE == 0"); exit(1);}
  24.         //delete old texture if existing
  25.         if (texture_generated && Texture_ID){
  26.                 glDeleteTextures(1,&Texture_ID);
  27.         }
  28.         //Power of two texture support
  29.         w = width;
  30.         h = height;
  31.         uint8_t *NewPixData = PixData;
  32.         bool todelete = false;
  33.         if (!(IsPowerOfTwo(w) && IsPowerOfTwo(h))){
  34.                 uint32_t new_w = HighestBit(w);
  35.                 uint32_t new_h = HighestBit(h);
  36.                 NewPixData = new uint8_t[new_w*new_h*4];
  37.                 memset(NewPixData,255, new_w*new_h*4);
  38.                 uint32_t pos1 = 0;
  39.                 uint32_t pos2 = 0;
  40.                 for (uint32_t y = 0; y<h; y++){
  41.                         for (uint32_t x = 0; x<w; x++){
  42.                                 NewPixData[pos1]  = PixData[pos2];
  43.                                 NewPixData[pos1+1]= PixData[pos2+1];
  44.                                 NewPixData[pos1+2]= PixData[pos2+2];
  45.                                 NewPixData[pos1+3]= PixData[pos2+3];
  46.                                 pos1+=4;
  47.                                 pos2+=4;
  48.                         }
  49.                         pos1+=(new_w-w)*4;
  50.                 }
  51.                 width= new_w;
  52.                 height= new_h;
  53.                 bw = float(w)/float(new_w);
  54.                 bh = float(h)/float(new_h);
  55.                 todelete = true;
  56.         }
  57.         //generate texture
  58.         glGenTextures(1,&Texture_ID);
  59.         if (Texture_ID==0){printf("ERROR IN TEXTURE GENERATION! NO DEVICE CONTEXT?"); exit(1);}
  60.         glEnable(GL_TEXTURE_2D);
  61.                 glBindTexture(GL_TEXTURE_2D, Texture_ID);
  62.                 //2d texture, level of detail, number of components (3=rgb), w,h, border, byte order, data format, data
  63.                 glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA8, width, height, 0, GL_BGRA,GL_UNSIGNED_BYTE, NewPixData);
  64.                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  65.                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  66.                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  67.                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  68.                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  69.                 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
  70.         glDisable(GL_TEXTURE_2D);
  71.         texture_generated = true;
  72.         //cleanup
  73.         if (todelete){delete [] NewPixData;}
  74. }
  75.  
  76. ///////////////
  77. //OGL Surface//
  78. ///////////////
  79. void OGL_Surface::Create_Surface(uint16_t set_w,uint16_t set_h, char set_bpp){
  80.         if (set_bpp==24){bpp=3;}
  81.         if (set_bpp==32){bpp=4;}
  82.         // if surface already exists and width or height change delete old texture
  83.         if (texture_generated && (w != set_w || h != set_h)){
  84.                 glDeleteTextures(1,&Texture_ID);
  85.                 texture_generated = false;
  86.         }
  87.         // if surface already exists delete old data
  88.         if (PixData != nullptr) {delete [] PixData;}
  89.         w = set_w;
  90.         h = set_h;
  91.         bpp = set_bpp;
  92.         PixData = new uint8_t[w*h*bpp];
  93.         memset(PixData,255, w*h*bpp);
  94.         if (!(IsPowerOfTwo(w) && IsPowerOfTwo(h))){printf("WARNING: non pow two surface, may be slow\n");}
  95. }
  96. void OGL_Surface::gen_texture(){
  97.         if (w==0 || h==0){printf("ERROR! WIDTH OR HEIGHT OF SURFACE == 0"); exit(1);}
  98.         //Power of two texture support
  99.         uint32_t width = w;
  100.         uint32_t height= h;
  101.         uint8_t *NewPixData = PixData;
  102.         bool todelete = false;
  103.         if (!(IsPowerOfTwo(w) && IsPowerOfTwo(h))){
  104.                 uint32_t new_w = HighestBit(w);
  105.                 uint32_t new_h = HighestBit(h);
  106.                 NewPixData = new uint8_t[new_w*new_h*4];
  107.                 memset(NewPixData,255, new_w*new_h*4);
  108.                 uint32_t pos1 = 0;
  109.                 uint32_t pos2 = 0;
  110.                 for (uint32_t y = 0; y<h; y++){
  111.                         for (uint32_t x = 0; x<w; x++){
  112.                                 NewPixData[pos1]  = PixData[pos2];
  113.                                 NewPixData[pos1+1]= PixData[pos2+1];
  114.                                 NewPixData[pos1+2]= PixData[pos2+2];
  115.                                 NewPixData[pos1+3]= PixData[pos2+3];
  116.                                 pos1+=4;
  117.                                 pos2+=4;
  118.                         }
  119.                         pos1+=(new_w-w)*4;
  120.                 }
  121.                 width= new_w;
  122.                 height= new_h;
  123.                 bw = w/new_w;
  124.                 bh = h/new_h;
  125.                 todelete = true;
  126.         }
  127.         //only generate a texture once
  128.         if (!texture_generated){
  129.                 glGenTextures(1,&Texture_ID);
  130.                 if (Texture_ID==0){printf("ERROR IN TEXTURE GENERATION! NO DEVICE CONTEXT?"); exit(1);}
  131.         }
  132.         glEnable(GL_TEXTURE_2D);
  133.                 glBindTexture(GL_TEXTURE_2D, Texture_ID);
  134.                 //glTexImage2D respecifies the entire texture, changing its size, deleting the previous data etc.
  135.                 //only do this if texture doesn't exist or if w/h change
  136.                 if (!texture_generated){
  137.                         switch (bpp){
  138.                         //2d texture, level of detail, number of components (3=rgb), w,h, border, byte order, data format, data
  139.                                 case 3: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, NewPixData); break;
  140.                                 case 4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA,GL_UNSIGNED_BYTE, NewPixData); break;
  141.                         }
  142.                 }
  143.                 //glTexSubImage2D only modifies pixel data within the texture.
  144.                 //do this when pixels need to be updated
  145.                 else{
  146.                         switch (bpp){
  147.                                 //2d texture, level of detail, xoffset,yoffset, w,h,  byte order, data format, data
  148.                                 case 3: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, NewPixData); break;
  149.                                 case 4: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA,GL_UNSIGNED_BYTE, NewPixData); break;
  150.                         }
  151.                 }
  152.                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  153.                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  154.                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  155.                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  156.                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  157.                 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
  158.         glDisable(GL_TEXTURE_2D);
  159.         texture_generated = true;
  160.         //cleanup
  161.         if (todelete){delete [] NewPixData;}
  162. }
  163. //BLIT//
  164. ////////
  165. //glBlendFunc(source_blend, dst_blend)
  166. //GL_ZERO                                               colour is ignored
  167. //GL_ONE                                                full colour is taken into addition
  168. //GL_(DST/SRC)_COLOR                    colour is multiplied by (DST/SRC) color
  169. //GL_ONE_MINUS_(DST/SRC)_COLOR  colour is multiplied by inverted (DST/SRC) color
  170. //GL_(DST/SRC)_ALPHA                    colour is multiplied by (DST/SRC) alpha value
  171. //GL_ONE_MINUS_(DST/SRC)_ALPHA  colour is multiplied by inverted (DST/SRC) alpha value
  172. //overall colour (GL_SRC_ALPHA, GL_ONE) -addative- = (r1*a1,g1*a1,b1*a1)+(r2,g2,b2)
  173. void DrawImage(OGL_Texture *Texture, int dx, int dy, float rot,float scale_x,float scale_y,float alpha,int options){
  174.         if (options & IMG_HFLIP){dx+=Texture->w; scale_x=-1;}
  175.         if (options & IMG_VFLIP){dy+=Texture->h; scale_y=-1;}
  176.         glLoadIdentity();
  177.         glTranslatef(dx, dy, 0.0);
  178.         if (scale_x!=1 && scale_y!=1){glScaled(scale_x, scale_y, 0);}
  179.         if (rot!=0){
  180.                 int tmpw = Texture->w/2;
  181.                 int tmph = Texture->h/2;
  182.                 glTranslatef(tmpw, tmph, 0.0);
  183.                 glRotatef(rot, 0, 0, 1.0);
  184.                 glTranslatef(-tmpw, -tmph, 0.0);
  185.         }
  186.         glEnable(GL_TEXTURE_2D);
  187.         glEnable(GL_BLEND);
  188.                 //additive blending - gray + gray = white
  189.                 if (options &= IMG_ADD_BLEND){glBlendFunc(GL_SRC_ALPHA, GL_ONE);}
  190.                 //regular alpha blending - gray + gray = gray
  191.                 else{glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);}
  192.                 //blit
  193.                 glColor4f(1.0f, 1.0f, 1.0f, alpha);
  194.                 glBindTexture(GL_TEXTURE_2D, Texture->Texture_ID);
  195.                 glBegin(GL_QUADS);
  196.                         glTexCoord2f(0,0);
  197.                         glVertex2d(0, 0);
  198.                         glTexCoord2f(Texture->bw,0);
  199.                         glVertex2d(Texture->w, 0);
  200.                         glTexCoord2f(Texture->bw,Texture->bh);
  201.                         glVertex2d(Texture->w, Texture->h);
  202.                         glTexCoord2f(0,Texture->bh);
  203.                         glVertex2d(0, Texture->h);
  204.                 glEnd();
  205.         glDisable(GL_BLEND);
  206.         glDisable(GL_TEXTURE_2D);
  207.         glLoadIdentity();
  208. }
  209. void DrawSubImage(OGL_Texture *Texture, int sx, int sy, int sw, int sh, int dx, int dy, float rot,float scale_x,float scale_y,float alpha,int options){
  210.         float tex_coord_x1 = (float)sx/(float)Texture->w;
  211.         float tex_coord_y1 = (float)sy/(float)Texture->h;
  212.         float tex_coord_x2 = tex_coord_x1+((float)sw/(float)Texture->w);
  213.         float tex_coord_y2 = tex_coord_y1+((float)sh/(float)Texture->h);
  214.         tex_coord_x1 *= Texture->bw;
  215.         tex_coord_y1 *= Texture->bh;
  216.         tex_coord_x2 *= Texture->bw;
  217.         tex_coord_y2 *= Texture->bh;
  218.         if (options & IMG_HFLIP){dx+=Texture->w; scale_x=-1;}
  219.         if (options & IMG_VFLIP){dy+=Texture->h; scale_y=-1;}
  220.         glLoadIdentity();
  221.         glTranslatef(dx, dy, 0.0);
  222.         if (scale_x!=1 && scale_y!=1){glScaled(scale_x, scale_y, 0);}
  223.         if (rot!=0){
  224.                 int tmpw = Texture->w/2;
  225.                 int tmph = Texture->h/2;
  226.                 glTranslatef(tmpw, tmph, 0.0);
  227.                 glRotatef(rot, 0, 0, 1.0);
  228.                 glTranslatef(-tmpw, -tmph, 0.0);
  229.         }
  230.         glEnable(GL_TEXTURE_2D);
  231.         glEnable(GL_BLEND);
  232.                 //additive blending - gray + gray = white
  233.                 if (options &= IMG_ADD_BLEND){glBlendFunc(GL_SRC_ALPHA, GL_ONE);}
  234.                 //regular alpha blending - gray + gray = gray
  235.                 else{glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);}
  236.                 //blit
  237.                 glColor4f(1.0,1.0,1.0,alpha);
  238.                 glBindTexture(GL_TEXTURE_2D, Texture->Texture_ID);
  239.                 glBegin(GL_QUADS);
  240.                         glTexCoord2f(tex_coord_x1,tex_coord_y1);
  241.                         glVertex2d(0, 0);
  242.                         glTexCoord2f(tex_coord_x2,tex_coord_y1);
  243.                         glVertex2d(sw, 0);
  244.                         glTexCoord2f(tex_coord_x2,tex_coord_y2);
  245.                         glVertex2d(sw, sh);
  246.                         glTexCoord2f(tex_coord_x1,tex_coord_y2);
  247.                         glVertex2d(0, sh);
  248.                 glEnd();
  249.         glDisable(GL_BLEND);
  250.         glDisable(GL_TEXTURE_2D);
  251.         glLoadIdentity();
  252. }
clone this paste RAW Paste Data