Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "Draw.h"
- ///vars to add to structs
- struct OGL_Texture{
- float bw,bh;//blit width/height if non pwr 2 textures
- };
- struct OGL_Surface : OGL_Texture{
- float bw,bh;
- };
- ///Draw Funcs to replace (also replace "GL_TEXTURE_RECTANGLE_NV" with "GL_TEXTURE_2D")
- bool IsPowerOfTwo(uint32_t x)
- {
- return ((x & (x - 1)) == 0);
- }
- int HighestBit(uint32_t x)
- {
- if (IsPowerOfTwo(x)){return x;}
- uint32_t y = 1<<31;
- while (y>x){y=y>>1;}
- return y<<1;
- }
- void OGL_Texture::gen_texture(uint16_t width, uint16_t height, uint8_t *PixData){
- if (width==0 || height==0){printf("ERROR! WIDTH OR HEIGHT OF TEXTURE == 0"); exit(1);}
- //delete old texture if existing
- if (texture_generated && Texture_ID){
- glDeleteTextures(1,&Texture_ID);
- }
- //Power of two texture support
- w = width;
- h = height;
- uint8_t *NewPixData = PixData;
- bool todelete = false;
- if (!(IsPowerOfTwo(w) && IsPowerOfTwo(h))){
- uint32_t new_w = HighestBit(w);
- uint32_t new_h = HighestBit(h);
- NewPixData = new uint8_t[new_w*new_h*4];
- memset(NewPixData,255, new_w*new_h*4);
- uint32_t pos1 = 0;
- uint32_t pos2 = 0;
- for (uint32_t y = 0; y<h; y++){
- for (uint32_t x = 0; x<w; x++){
- NewPixData[pos1] = PixData[pos2];
- NewPixData[pos1+1]= PixData[pos2+1];
- NewPixData[pos1+2]= PixData[pos2+2];
- NewPixData[pos1+3]= PixData[pos2+3];
- pos1+=4;
- pos2+=4;
- }
- pos1+=(new_w-w)*4;
- }
- width= new_w;
- height= new_h;
- bw = float(w)/float(new_w);
- bh = float(h)/float(new_h);
- todelete = true;
- }
- //generate texture
- glGenTextures(1,&Texture_ID);
- if (Texture_ID==0){printf("ERROR IN TEXTURE GENERATION! NO DEVICE CONTEXT?"); exit(1);}
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, Texture_ID);
- //2d texture, level of detail, number of components (3=rgb), w,h, border, byte order, data format, data
- glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA8, width, height, 0, GL_BGRA,GL_UNSIGNED_BYTE, NewPixData);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
- glDisable(GL_TEXTURE_2D);
- texture_generated = true;
- //cleanup
- if (todelete){delete [] NewPixData;}
- }
- ///////////////
- //OGL Surface//
- ///////////////
- void OGL_Surface::Create_Surface(uint16_t set_w,uint16_t set_h, char set_bpp){
- if (set_bpp==24){bpp=3;}
- if (set_bpp==32){bpp=4;}
- // if surface already exists and width or height change delete old texture
- if (texture_generated && (w != set_w || h != set_h)){
- glDeleteTextures(1,&Texture_ID);
- texture_generated = false;
- }
- // if surface already exists delete old data
- if (PixData != nullptr) {delete [] PixData;}
- w = set_w;
- h = set_h;
- bpp = set_bpp;
- PixData = new uint8_t[w*h*bpp];
- memset(PixData,255, w*h*bpp);
- if (!(IsPowerOfTwo(w) && IsPowerOfTwo(h))){printf("WARNING: non pow two surface, may be slow\n");}
- }
- void OGL_Surface::gen_texture(){
- if (w==0 || h==0){printf("ERROR! WIDTH OR HEIGHT OF SURFACE == 0"); exit(1);}
- //Power of two texture support
- uint32_t width = w;
- uint32_t height= h;
- uint8_t *NewPixData = PixData;
- bool todelete = false;
- if (!(IsPowerOfTwo(w) && IsPowerOfTwo(h))){
- uint32_t new_w = HighestBit(w);
- uint32_t new_h = HighestBit(h);
- NewPixData = new uint8_t[new_w*new_h*4];
- memset(NewPixData,255, new_w*new_h*4);
- uint32_t pos1 = 0;
- uint32_t pos2 = 0;
- for (uint32_t y = 0; y<h; y++){
- for (uint32_t x = 0; x<w; x++){
- NewPixData[pos1] = PixData[pos2];
- NewPixData[pos1+1]= PixData[pos2+1];
- NewPixData[pos1+2]= PixData[pos2+2];
- NewPixData[pos1+3]= PixData[pos2+3];
- pos1+=4;
- pos2+=4;
- }
- pos1+=(new_w-w)*4;
- }
- width= new_w;
- height= new_h;
- bw = w/new_w;
- bh = h/new_h;
- todelete = true;
- }
- //only generate a texture once
- if (!texture_generated){
- glGenTextures(1,&Texture_ID);
- if (Texture_ID==0){printf("ERROR IN TEXTURE GENERATION! NO DEVICE CONTEXT?"); exit(1);}
- }
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, Texture_ID);
- //glTexImage2D respecifies the entire texture, changing its size, deleting the previous data etc.
- //only do this if texture doesn't exist or if w/h change
- if (!texture_generated){
- switch (bpp){
- //2d texture, level of detail, number of components (3=rgb), w,h, border, byte order, data format, data
- case 3: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, NewPixData); break;
- case 4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA,GL_UNSIGNED_BYTE, NewPixData); break;
- }
- }
- //glTexSubImage2D only modifies pixel data within the texture.
- //do this when pixels need to be updated
- else{
- switch (bpp){
- //2d texture, level of detail, xoffset,yoffset, w,h, byte order, data format, data
- case 3: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, NewPixData); break;
- case 4: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA,GL_UNSIGNED_BYTE, NewPixData); break;
- }
- }
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
- glDisable(GL_TEXTURE_2D);
- texture_generated = true;
- //cleanup
- if (todelete){delete [] NewPixData;}
- }
- //BLIT//
- ////////
- //glBlendFunc(source_blend, dst_blend)
- //GL_ZERO colour is ignored
- //GL_ONE full colour is taken into addition
- //GL_(DST/SRC)_COLOR colour is multiplied by (DST/SRC) color
- //GL_ONE_MINUS_(DST/SRC)_COLOR colour is multiplied by inverted (DST/SRC) color
- //GL_(DST/SRC)_ALPHA colour is multiplied by (DST/SRC) alpha value
- //GL_ONE_MINUS_(DST/SRC)_ALPHA colour is multiplied by inverted (DST/SRC) alpha value
- //overall colour (GL_SRC_ALPHA, GL_ONE) -addative- = (r1*a1,g1*a1,b1*a1)+(r2,g2,b2)
- void DrawImage(OGL_Texture *Texture, int dx, int dy, float rot,float scale_x,float scale_y,float alpha,int options){
- if (options & IMG_HFLIP){dx+=Texture->w; scale_x=-1;}
- if (options & IMG_VFLIP){dy+=Texture->h; scale_y=-1;}
- glLoadIdentity();
- glTranslatef(dx, dy, 0.0);
- if (scale_x!=1 && scale_y!=1){glScaled(scale_x, scale_y, 0);}
- if (rot!=0){
- int tmpw = Texture->w/2;
- int tmph = Texture->h/2;
- glTranslatef(tmpw, tmph, 0.0);
- glRotatef(rot, 0, 0, 1.0);
- glTranslatef(-tmpw, -tmph, 0.0);
- }
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- //additive blending - gray + gray = white
- if (options &= IMG_ADD_BLEND){glBlendFunc(GL_SRC_ALPHA, GL_ONE);}
- //regular alpha blending - gray + gray = gray
- else{glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);}
- //blit
- glColor4f(1.0f, 1.0f, 1.0f, alpha);
- glBindTexture(GL_TEXTURE_2D, Texture->Texture_ID);
- glBegin(GL_QUADS);
- glTexCoord2f(0,0);
- glVertex2d(0, 0);
- glTexCoord2f(Texture->bw,0);
- glVertex2d(Texture->w, 0);
- glTexCoord2f(Texture->bw,Texture->bh);
- glVertex2d(Texture->w, Texture->h);
- glTexCoord2f(0,Texture->bh);
- glVertex2d(0, Texture->h);
- glEnd();
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
- glLoadIdentity();
- }
- 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){
- float tex_coord_x1 = (float)sx/(float)Texture->w;
- float tex_coord_y1 = (float)sy/(float)Texture->h;
- float tex_coord_x2 = tex_coord_x1+((float)sw/(float)Texture->w);
- float tex_coord_y2 = tex_coord_y1+((float)sh/(float)Texture->h);
- tex_coord_x1 *= Texture->bw;
- tex_coord_y1 *= Texture->bh;
- tex_coord_x2 *= Texture->bw;
- tex_coord_y2 *= Texture->bh;
- if (options & IMG_HFLIP){dx+=Texture->w; scale_x=-1;}
- if (options & IMG_VFLIP){dy+=Texture->h; scale_y=-1;}
- glLoadIdentity();
- glTranslatef(dx, dy, 0.0);
- if (scale_x!=1 && scale_y!=1){glScaled(scale_x, scale_y, 0);}
- if (rot!=0){
- int tmpw = Texture->w/2;
- int tmph = Texture->h/2;
- glTranslatef(tmpw, tmph, 0.0);
- glRotatef(rot, 0, 0, 1.0);
- glTranslatef(-tmpw, -tmph, 0.0);
- }
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- //additive blending - gray + gray = white
- if (options &= IMG_ADD_BLEND){glBlendFunc(GL_SRC_ALPHA, GL_ONE);}
- //regular alpha blending - gray + gray = gray
- else{glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);}
- //blit
- glColor4f(1.0,1.0,1.0,alpha);
- glBindTexture(GL_TEXTURE_2D, Texture->Texture_ID);
- glBegin(GL_QUADS);
- glTexCoord2f(tex_coord_x1,tex_coord_y1);
- glVertex2d(0, 0);
- glTexCoord2f(tex_coord_x2,tex_coord_y1);
- glVertex2d(sw, 0);
- glTexCoord2f(tex_coord_x2,tex_coord_y2);
- glVertex2d(sw, sh);
- glTexCoord2f(tex_coord_x1,tex_coord_y2);
- glVertex2d(0, sh);
- glEnd();
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
- glLoadIdentity();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement