TheExDeus
|
|
Posted on: September 25, 2010, 12:58:45 pm |
|
|
Joined: Apr 2008
Posts: 1860
|
Notice: These functions are not in GM. They are just additional functions that could be useful to add. What they do is that they tile a sprite over selected region (which is a rectangle with x1,y1 top left corner and x2,y2 bottom left). It automatically crops the image as needed and it works with any size sprite. They are based on GMLScripts script http://www.gmlscripts.com/script/draw_sprite_tiled_area by EyeGuy. Function: draw_sprite_tiled_area( int spr, int subimg, double x, double y, double x1, double y1, double x2, double y2); GSsprite.h: int draw_sprite_tiled_area(int spr,int subimg,double x,double y,double x1,double y1,double x2,double y2); GSsprite.cpp: int draw_sprite_tiled_area(int spr,int subimg,double x,double y,double x1,double y1,double x2,double y2) { enigma::sprite *spr2d = enigma::spritestructarray[spr]; if (!spr2d) return -1;
if (enigma::cur_bou_tha_noo_sho_eve_cha_eve != spr2d->texturearray[subimg % spr2d->subcount]) { glBindTexture(GL_TEXTURE_2D,spr2d->texturearray[subimg % spr2d->subcount]); enigma::cur_bou_tha_noo_sho_eve_cha_eve = spr2d->texturearray[subimg % spr2d->subcount]; }
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
glPushAttrib(GL_CURRENT_BIT); glColor4f(1,1,1,1);
const float tbx=spr2d->texbordx,tby=spr2d->texbordy; float sw,sh,i,j,jj,left,top,width,height,X,Y; sw = spr2d->width; sh = spr2d->height;
i = x1-(fmod(x1,sw) - fmod(x,sw)) - sw*(fmod(x1,sw)<fmod(x,sw)); j = y1-(fmod(y1,sh) - fmod(y,sh)) - sh*(fmod(y1,sh)<fmod(y,sh)); jj = j;
glBegin(GL_QUADS); for(i=i; i<=x2; i+=sw) { for(j=j; j<=y2; j+=sh) {
if(i <= x1) left = x1-i; else left = 0; X = i+left;
if(j <= y1) top = y1-j; else top = 0; Y = j+top;
if(x2 <= i+sw) width = ((sw)-(i+sw-x2)+1)-left; else width = sw-left;
if(y2 <= j+sh) height = ((sh)-(j+sh-y2)+1)-top; else height = sh-top;
glTexCoord2f(left/sw*tbx,top/sh*tby); glVertex2f(X,Y); glTexCoord2f((left+width)/sw*tbx,top/sh*tby); glVertex2f(X+width,Y); glTexCoord2f((left+width)/sw*tbx,(top+height)/sh*tby); glVertex2f(X+width,Y+height); glTexCoord2f(left/sw*tbx,(top+height)/sh*tby); glVertex2f(X,Y+height); } j = jj; } glEnd();
glPopAttrib(); return 0; } Function: draw_sprite_tiled_area_ext( int spr, int subimg, double x, double y, double x1, double y1, double x2, double y2, double xscale, double yscale, int color, double alpha); GSsprite.h: int draw_sprite_tiled_area_ext(int spr,int subimg,double x,double y,double x1,double y1,double x2,double y2, double xscale, double yscale, int color, double alpha); GSsprite.cpp: int draw_sprite_tiled_area_ext(int spr,int subimg,double x,double y,double x1,double y1,double x2,double y2, double xscale, double yscale, int color, double alpha) { enigma::sprite *spr2d = enigma::spritestructarray[spr]; if (!spr2d) return -1;
if (enigma::cur_bou_tha_noo_sho_eve_cha_eve != spr2d->texturearray[subimg % spr2d->subcount]) { glBindTexture(GL_TEXTURE_2D,spr2d->texturearray[subimg % spr2d->subcount]); enigma::cur_bou_tha_noo_sho_eve_cha_eve = spr2d->texturearray[subimg % spr2d->subcount]; }
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
glPushAttrib(GL_CURRENT_BIT); glColor4ub(__GETR(color),__GETG(color),__GETB(color),char(alpha*255));
const float tbx=spr2d->texbordx,tby=spr2d->texbordy; float sw,sh,i,j,jj,left,top,width,height,X,Y; sw = spr2d->width*xscale; sh = spr2d->height*yscale;
i = x1-(fmod(x1,sw) - fmod(x,sw)) - sw*(fmod(x1,sw)<fmod(x,sw)); j = y1-(fmod(y1,sh) - fmod(y,sh)) - sh*(fmod(y1,sh)<fmod(y,sh)); jj = j;
glBegin(GL_QUADS); for(i=i; i<=x2; i+=sw) { for(j=j; j<=y2; j+=sh) {
if(i <= x1) left = x1-i; else left = 0; X = i+left;
if(j <= y1) top = y1-j; else top = 0; Y = j+top;
if(x2 <= i+sw) width = ((sw)-(i+sw-x2)+1)-left; else width = sw-left;
if(y2 <= j+sh) height = ((sh)-(j+sh-y2)+1)-top; else height = sh-top;
glTexCoord2f(left/sw*tbx,top/sh*tby); glVertex2f(X,Y); glTexCoord2f((left+width)/sw*tbx,top/sh*tby); glVertex2f(X+width,Y); glTexCoord2f((left+width)/sw*tbx,(top+height)/sh*tby); glVertex2f(X+width,Y+height); glTexCoord2f(left/sw*tbx,(top+height)/sh*tby); glVertex2f(X,Y+height); } j = jj; } glEnd();
glPopAttrib(); return 0; } Added attachments show: First image: draw_sprite_tiled_area(sprite0,0,0,0,75,75,375,375); Second image: draw_sprite_tiled_area_ext(sprite0,0,0,0,75,75,375,375,0.5,0.5,c_yellow,0.7); You can see some artifacts when scaled down, but I guess it is normal.
|
|
« Last Edit: September 26, 2010, 08:57:04 am by HaRRiKiRi »
|
Logged
|
|
|
|
Josh @ Dreamland
|
|
Reply #1 Posted on: October 16, 2010, 01:38:32 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
I'm not sure what to do with the licensing for these. I can see these being useful, though. Is any license associated with them on that site?
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
TheExDeus
|
|
Reply #3 Posted on: October 16, 2010, 04:58:57 pm |
|
|
Joined: Apr 2008
Posts: 1860
|
They are free to use, modify and redistribute, so there is really no license involved. You don't even have to give credit, but you could if you were kind enough. I do understand the math behind all this, so I could make them from scratch, but they would look almost exactly like these. Its just that there are aren't so many ways to invent the wheel... I could make them more messy and less optimized if you want. Then they would be custom made for sure. And I am pretty sure these can't be optimized any more, because gmlscript.com usually hold only the most optimized code. Thou here we could change float to int, thus creating an (substantial?) speed increase, because I don't see why width, height or position should be decimal.. Thou you have made all positions and sizes in all functions floats for some reason. I know that GM allows x and y to be a decimal, but I don't get why. You cant have something 1.5 pixels from somewhere. Its a lot better if is 1 or 2 pixels. Hope you understand this post. It seems I have written a lot and said so little.
|
|
|
Logged
|
|
|
|
Josh @ Dreamland
|
|
Reply #4 Posted on: October 17, 2010, 08:23:37 am |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
Well, that's a mistake in itself. You could have the most outstandingly efficient piece of GML fathomable, and on the optimization scale, it'd be a steaming pile of shit and rusted bolts compared to the equivalent in a real language. Not just because GM's interpreter is slow, but because GM's pointerless, classless system makes you do all sorts of running around to get something simple done. Compare a C Brainfuck interpreter to a JavaScript one. There's no comparison.
But yes, your purpose is legal, then; as Ism said, it's just common courtesy to let him know we're using them. (Even though I don't find anything particularly insightful about his code, it's the idea that counts). But, seeing as that site is full of people taking such scripts and running with them without credit, I suppose it'd only be annoying if everyone that found use for them emailed him. So do what you like.
Anyway, yes, I'm a proponent of integral coordinates. Except one thing: All vars are double. To call your function, they are cast as int. You then invoke glTexCoord2f, casting them back to float.
I do the same thing; I've been waiting for someone to help me decide what to do about it. I think at this point swapping them all for 2i would be our best bet.
|
|
« Last Edit: October 17, 2010, 08:26:17 am by Josh @ Dreamland »
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
Josh @ Dreamland
|
|
Reply #6 Posted on: October 17, 2010, 12:43:33 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
Good point. Maybe I'll drop him a letter later.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
Brett
|
|
Reply #7 Posted on: October 19, 2010, 07:34:48 pm |
|
|
Location: Canada! Joined: Aug 2010
Posts: 25
|
Thou here we could change float to int, thus creating an (substantial?) speed increase, because I don't see why width, height or position should be decimal.. Thou you have made all positions and sizes in all functions floats for some reason. I know that GM allows x and y to be a decimal, but I don't get why. You cant have something 1.5 pixels from somewhere. Its a lot better if is 1 or 2 pixels.
GM allows X,Y to be decimals because you can modify the view so that those little differences matter. GM has 3D support, and all 2D functions work in 3D as well so the decimals matter when the view is transformed. [EDIT] Not sure if you can do this in OpenGL (I've only used DX) but you can get DX to do this automatically for you. Simply turn texture repeating on and then put a vertex at the 4 corners with texture cords changed. [/EDIT] [EDIT2] Something like this? (Never used OGL before, so it needs debugging) .H file int draw_sprite_tiled_area(int spr, double X, double Y, int x1, int y1, int x2, int y2); .CPP file //int spr, double x, double y, int x1, int y1, int x2, int y2 //Draws a rectangle between [x1,y1] and [x2,y2] with the sprite offset by X and Y (both 0-1) int draw_sprite_tiled_area(int spr, double X, double Y, int x1, int y1, int x2, int y2){ enigma::sprite *spr2d = enigma::spritestructarray[spr]; //Non existant sprite if (!spr2d) return -1; //Some error? No idea, but it is used in the above example too. if (enigma::cur_bou_tha_noo_sho_eve_cha_eve != spr2d->texturearray[subimg % spr2d->subcount]){ glBindTexture(GL_TEXTURE_2D,spr2d->texturearray[subimg % spr2d->subcount]); enigma::cur_bou_tha_noo_sho_eve_cha_eve = spr2d->texturearray[subimg % spr2d->subcount]; } const float tbx=spr2d->texbordx; const float tby=spr2d->texbordy; const float sw = spr2d->width; const float sh = spr2d->height; //Texture repeat ON glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); glPushAttrib(GL_CURRENT_BIT); glColor4f(1,1,1,1); //Draw the quad glBegin(GL_QUADS); glTexCoord2f(x1/sw*tbx+X,y1/sh*tby+Y); glVertex2f(x1,y1); glTexCoord2f(x2/sw*tbx+X,y1/sh*tby+Y); glVertex2f(x2,y1); glTexCoord2f(x2/sw*tbx+X,y2/sh*tby+Y); glVertex2f(x1,y2); glTexCoord2f(x1/sw*tbx+X,y2/sh*tby+Y); glVertex2f(x2,y2); //End drawing glEnd(); glPopAttrib(); return 0; } No credit required and No license attached - do whatever you want with it (if it works). Derived from the code above [/EDIT2]
|
|
« Last Edit: October 19, 2010, 08:25:55 pm by Brett »
|
Logged
|
GML Programmer Since 2005, C++ Programmer Since 2009
|
|
|
|
Josh @ Dreamland
|
|
Reply #9 Posted on: October 20, 2010, 08:07:51 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
Brett-- You are assuming all power-of-two textures. I see you multiplied tbx and tby by the necessary factor. Those variables, however, are only 1 (meaning the edge of the sprite) when the sprite is a power of two across both dimensions. I proposed such a fix after the check for each against 1, but no one has implemented it, yet.
Also, can you elaborate on a circumstance where doubles would be necessary for X and Y for the sake of accuracy? I'm not sure if a highly zoomed in view would produce such a case or not; can you test that for me? (I realize that many GL demonstrations have axises from -1 to 1, but I am not sure what GM's behavior would be in that case.)
RetroX-- No good reason. Originally I was using floats for x and y, but then I changed to doubles, and now I'm using int. I never updated the code, though, because I was waiting for someone like Brett to justify why they should be doubles.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
|