GMLscripts.com

Discuss and collaborate on GML scripts
Invert

You are not logged in.

#1 Re: Script Submission » Smooth color grid » 2009-12-19 17:40:24

I believe bm_add is functionally equivalent to _ext(bm_src_alpha,bm_one).

#3 Re: Script Submission » bezier4 » 2009-12-01 22:55:41

Depends. If you're calculating a series of points on one curve, you can precalculate some important stuff and use a different equation to save time.

Pseudocode, off the top of my head:

a = P3 - 3(P2 - P1) - P0
b = 3(P2 - 2P1 + P0)
c = 3(P1 - P0)

And then for any t on the the cubic curve B:

B(t) = ((a*t + b)*t + c)*t + P0

You should be able to confirm a, b, and c by multiplying out the equation you have above and then regrouping by powers of t instead of by point #.

But I've got something even better. This script will work for an arbitrary number of points (just specify the right degree) and works on pure add/sub/mult/div. A cubic call takes 0.02 milliseconds.

Expand/*
scr_bezier_point();

0 degree
1 t
n point
*/

var a, i, n, t, t1;

a = argument2;
i = 1;
n = 1;
t = 1;
t1 = 1-argument1;

repeat argument0 {
    n *= (argument0-i+1) / i;
    t *= argument1;
    a *= t1;
    a += argument[i+2] * n * t;
    i += 1;
    }
    
return a;

Bezier curves are crazy stuff. I came up with some equations for bezier-to-circle collision detection in April, and then this semester I wrote a paper on them to get credit for a calculus class. Booyah.

#4 Re: Script Submission » Scripts of fractions » 2009-11-24 16:21:18

How is 11.12 == 2 1/5? It's 278/25.

Which brings up something else. Just loop through 2 and 5, and you'll get the same answer. The other numbers are pointless.

Or, if you really want to go crazy, try something like this: http://homepage.smc.edu/kennedy_john/DEC2FRAC.PDF

#5 Re: GML Code Help » Blend Mode Fail » 2009-11-05 21:11:55

I recently ran into the FlatRedBall and Ice Cream XNA engines. And then there's Aziel. I'm kinda tempted to just jump ship on GM and move to an XNA engine if I want to do anything more graphically intensive than a Mario clone. Or possibly Torque2D/TorqueX.

#6 Re: GML Code Help » Blend Mode Fail » 2009-11-05 20:09:19

Good idea. Report:

UV hijinks: everything ... works fine. I think. Love the tiling example.

Gradient transition: Doesn't work at all. Higher contrast does nothing, higher % just makes the thing darker.
http://i307.photobucket.com/albums/nn29 … t103-1.png

Raster transform lighting: it seems to have trouble with the smearing.
http://i307.photobucket.com/albums/nn29 … t101-2.png
http://i307.photobucket.com/albums/nn29 … t102-1.png

The other light engine thing: the shadows get tinted funky colors.

screenshot100-3.png

This canvas/fingerpaint/bloody murder thing is actually something I'd forgotten about long before my move to Win7, so I'm not going to worry too much about fixing it, but the problem shows up in a lot of places where there's no easy substitute. It has, however, made me give more thought to some of my other ideas that don't use surfaces and stuff.

#7 Re: GML Creations » UV Hijinks - Smoke and Mirrors » 2009-11-05 12:15:55

I noticed that "problem" too with triangles, but I think it's meant to do that, so that shapes will all mesh correctly. Otherwise, if you drew 2 triangles/rectangles that share a side and give them an alpha value, there would be one line between them that gets drawn over twice, which would look pretty wack. And then people would be even more confused.

#8 Re: GML Code Help » Blend Mode Fail » 2009-11-03 18:44:26

Um ... ?

I presume you refer to the paint demo? But no part of it involves the color of eggshells, I'm afraid. Did you try RMB or MMB?

#9 Re: GML Code Help » Blend Mode Fail » 2009-11-03 15:26:59

xot wrote:

the standard bm_normal+surface bug

You've been talking to th15, haven't you? It's not a bug, it's a feature.

At least I don't think it's a bug. The way alpha changes on the destination when drawn to with bm_normal is logical and predictable. When he talks about NVIDIA bugs, I'm thinking it works as expected. I admit I don't have blending experience using other APIs. And whatever bugs he's seeing, maybe I'm not getting them. But I am using NVIDIA hardware and I haven't seen anything happen on this machine that couldn't be corrected logically. That's not to say that there aren't bugs in your DX10/11 drivers, I'd be surprised it there weren't.

Mmm, I disagree, but the effect is hard to pin down exactly. If a sprite has an alpha channel, and it gets drawn onto a surface that already has an image on it, the result should be a mix, right? But I've had problems in the past with the image underneath the sprite getting erased completely and replaced by the sprite, as if the blend mode was (bm_one,bm_zero) instead of bm_normal. Can't test the problem anymore, though, because everything's borked no matter what mode I use. I'd like to think it was my DX drivers, but in that case it should affect everything, unless GM uses an outdated blend mode method (GM6/7 is based on DX8, I recall) that no other programs use and has been corrupted in DX11, which I find unlikely.

xot wrote:

Now it's as if, when I use draw_set_blend_mode_ext(1,1), it fails just like bm_normal does.

Shouldn't that blend mode (bm_zero,bm_zero) set all channels to 0 (transparent black) in the destination?

My bad. I meant (bm_one,bm_one), and forgot that blend modes start at index 1, not 0.

xot wrote:

Hmmm. Blend mode (bm_zero,bm_src_alpha) should do this:


    Source            Destination            Resulting
    Pixels              Pixels                Pixels   
[u]
R = [0.97] * [0.00]  +  [0.97] * [0.75]    =  0.73
G = [0.25] * [0.00]  +  [0.25] * [0.75]    =  0.19    (#BA3054)
B = [0.44] * [0.00]  +  [0.44] * [0.75]    =  0.33
A = [0.75] * [0.00]  +  [0.75] * [0.75]    =  0.56

If alpha isn't changing, something definitely isn't working right. Unfortunately, there is no way to get the alpha of a pixel directly from the surface using something like surface_getpixel(), so it's hard to precisely verify these predictions.

That's correct. It's the idea from here: http://www.messy-mind.net/2007/2d-metaballs/

No, the alpha isn't changing . The colors themselves get multiplied by the alpha value (where alpha != 1), though, which is what makes the image I posted a funky mix of black and red.

#10 Re: Off Topic » Audience Participation: Interactivity vs Interpretation » 2009-10-31 11:56:46

Inspiring. Any meaning in the simple graphics is really all in our imagination - the flickering fluorescent tubes (4x1 white pixels), the snow (1x1), the water (3x1 pattern) - in comparison with high-def 3D graphics, which strive to show us all the exact details. The author has reduced the elements of mood to their simplest form - in the case of the flickering lights, glowing lines and a subtle effect on surrounding pixels. We see that and, although it bears little resemblance to the real thing, we know what it is and what it means.

#11 Re: GML Code Help » Blend Mode Fail » 2009-10-30 15:38:55

Interesting. I've actually never encountered the problem in your Test 1 or, for that matter, ever had any problems with leftover data on my surfaces. Maybe Vista/Dx10 fixed the problem?

At any rate, I'm afraid the script doesn't help. It's a problem that appeared specifically when I moved from Vista to 7. But thanks for the attempt, xot - I think I have a better idea what the problem is now. You know how drawing to a surface with bm_normal sometimes overwrites the alpha channel of the area underneath? Now it's as if, when I use draw_set_blend_mode_ext(1,1), it fails just like bm_normal does. However, it seems like draw_set_blend_mode_ext(1,5) is working just fine, which makes me think it's something like the surface's alpha level is being overwritten regardless of what blend mode is used. [Edit:] I'm using (1,5) in a variation of GearGOD's metaball effect, which multiplies a surface by itself 3 or 4 times . . . now that I think about it, it seems the alpha channel is also being ignored for this mode too, but it's harder to tell because the surface's alpha channel is just getting replaced by the alpha of a copy of itself - in other words, the alpha isn't changed at all, which in itself supports the hypothesis below. If it were working properly, the new alpha would be A1*A1/255.

Essentially, the blend mode is applied as normal to the RGB of the surface but not the A, and the blend mode for the alpha channel is always (bm_one,bm_zero), or something close.

Probably the standard bm_normal+surface bug and my bug are related.

#12 GML Code Help » Blend Mode Fail » 2009-10-29 23:18:00

RaiSoleil
Replies: 14

Just upgraded to Windows 7 and, inexplicably, Game Maker's blend modes aren't working. None of my blending-dependent scripts are acting as normal. I reinstalled GM7, yes. I can't tell if the problem is with Windows, GM, or Dx11 (my hardware only supports 10, but that shouldn't matter, afaik), but something's failed somewhere in the pipeline. I can't describe exactly how they're not working, but it seems to be limited to blend modes and alpha channels, which points the finger at DirectX. Google has nothing to say.

Any ideas how to get it working again?

Just as a test, please try this: Canvas Test. Sorry it's not a gmk, but it's the last known working version I think (decompile it if you want). RMB to squirt, MMB to spray, then LMB to push paint around. It looks like this for you, right? Well, it looks like this for me. Awful.

#13 Re: Script Submission » draw_polygon_inverted » 2009-10-05 11:04:35

Ah, intriguing idea. I'll need to fiddle with this some more . . . seems like it should mesh with my AA engine pretty well.

#14 Re: Script Submission » draw_polygon_inverted » 2009-10-04 17:16:06

Careful of the alpha there. When drawing to a surface, inverting with an alpha of 1 will flip the alpha channel too, which might not be what you want.

Also, pr_trianglefan only?

#15 Re: Script Submission » An alternative, flexible range_finder() script » 2009-08-03 23:59:35

Oi, sorry. I'd attempted to reformat the code to more closely match the standards; apparently I also borked some things in the process.

The whole with() section is an even worse drag on the script (30% to 40% slower) than I thought it would be, having edited it without retesting.  It either needs to be forced in the creation code for colliding objects or replaced with something better. The code you posted isn't very accurate if the origin isn't centered. However, it gave me the idea you see below - a *fraction* slower now closer to your code, and slightly faster now back to "slightly slower" (because I fail at variable referencing) than the point_distance(x0,y0,t.x,t.y)+t.sprite_radius by itself (surprisingly), but it doesn't require an instance variable and is much, much faster than the with() section.

And some things that don't seem to help speed things up at all, for reasons I can only attribute to GM's own idiosyncratic execution speeds:
- Setting precise collision checking to 0 for both collision_line()s
- Restricting the line to only collide with the last found target after a certain time - the if/else check countered any increase.

Expand{
    var x0, y0, lx, ly, d, t, t2, res;
    x0 = argument0;
    y0 = argument1;
    d = argument2;
    lx = lengthdir_x(1,argument3);
    ly = lengthdir_y(1,argument3);
    t2 = -4;

    res = argument7;
    if (res <= 0) res = 1;

    t = collision_line(x0,y0,x0+lx*d,y0+ly*d,argument4,argument5,argument6);

    if t {
        var x1, y1, td;
        d =  point_distance(x0,y0,mean(t.bbox_left,t.bbox_right),mean(t.bbox_top,t.bbox_bottom))+t.sprite_width+t.sprite_height;
        x1 = x0;
        y1 = y0;
        td = 0;
        
        while (d>res) {
            d *= 0.5;
            x1 += lx*d;
            y1 += ly*d;

            t = collision_line(x0,y0,x1,y1,argument4,argument5,argument6);

            if t {
                x1 = x0;
                y1 = y0;
                t2 = t;
            }
            else {
                x0 = x1;
                y0 = y1;
                td += d;
            } 
        }

        cx = x1+lx*res*0.5;
        cy = y1+ly*res*0.5;
        cd = td;
    }
    else {
        cx = argument0 + lx*d;
        cy = argument1 + ly*d;
        cd = d;
    }

    return t2;
}

[Edit:] switched out some code (faster now), split variable assignments

#16 Script Submission » An alternative, flexible range_finder() script » 2009-08-02 18:01:18

RaiSoleil
Replies: 2

After some discussion with icuurd12b42, I think I've cut this script down as much as I can. It preforms much the same function as range_finder except it finds the x, y, distance, and instance of collision as well as being faster. The biggest jump comes from that point_distance() idea of icuurd's, but to solve his inaccuracy problem I've made the script dependent on the variable sprite_radius, which holds the maximum distance from the origin to the four bbox points. Problem is, it either has to be pre-calculated in the instance or checked as below in the script, which wastes time. Furthermore, it's unlikely this radius check will work for all the possible sprite/mask transformations. An alternative, less local-variable-dependent solution would be preferable. So far all my ideas have either had loophole situations or slowed things down.

Speed-wise, the script is great; its execution time is dependent on the distance to the first object found by collision_line() instead of the total length. In comparison to range_finder, the script is up to twice as fast with nearby objects and a large (10000+) range; with a smaller range, the speed is still a noticeable percentage better. Testing 65536 beams of 65536 range in a room full of concave-shaped objects got about 0.062 to 0.065 ms per call on my computer. A resolution of 4 (~2px from perfect) got about 0.055 ms. A possible addition here is that once within a certain range (adjustable?), the script should only check its current target instance in collision_line() instead of all the objects of the given type.

Suggestions always appreciated. Including, perhaps, that I'm a little psyco over a few thousandths of a millisecond.

In other news, I did some testing of "x>>1" vs "x*0.5" vs "x/2". Apparently . . . division and multiplication are essentially the same speed. And since "x>>1" actually forces you to use "x = x>>1", bitshift ends up the slowest. Compared to "x = x/2", bitshift is almost as slow. Annoying.

Expand/*
**  Usage:
**      scr_collision_beam(x,y,range,dir,object,prec,notme,res)
**
**  Given:
**      x,y     position in room
**      range   farthest distance to check
**      dir     direction of beam in degrees
**      object  which instance or object to look for, or keyword all
**      prec    if true, use precise collision checking
**      notme   if true, ignore the calling instance
**      res     maximum deviation from perfect
**
**  Returns:
**      Instance id or -4 if none
**
**  Sets:
**      cx,cy   point of collision 
**      cd      distance to point of collision
**
**  Notes:
**      Computes answer in log2(first_found_distance)-log2(res) collision checks
**      Answer is within res/2 pixels of perfect
**      Creates local variable "sprite_radius" for the first collision_line() instance if it does not exist already
**
**  GMLScripts.com
*/

{
    var x0, y0, x1, y1, lx, ly, d, t, t2, td, res;
    x0 = argument0;
    y0 = argument1;
    x1 = x0;
    y1 = y0;
    d = argument2;
    lx = lengthdir_x(1,argument3);
    ly = lengthdir_y(1,argument3);
    t2 = -4;
    td = d;
    res = argument7;
    if (res <= 0) res = 1; 
    
    t = collision_line(x0,y0,x0+lx*d,y0+ly*d,argument4,argument5,argument6);
    
    if t {
        td = 0;
        with t { // Needs an alternative
            if !variable_local_exists(sprite_radius) {
                                sprite_radius = sqrt(sqr(max(bbox_right-sprite_xoffset-x,x+sprite_xoffset-bbox_left)) +
                                sqr(max(bbox_bottom-sprite_yoffset-y,y+sprite_yoffset-bbox_top)))*0.5;
            }
        }
        
        d = min(d,point_distance(x0,y0,t.x,t.y)+t.__sprite_radius);
        
        while (d>res) {
            // at what point should it switch to only checking one instance?
            // When it hasn't found a new instance in 3 checks? Or the last 3 (res?) checks of the loop?
            d *= 0.5;
            x1 += lx*d;
            y1 += ly*d;
            
            t = collision_line(x0,y0,x1,y1,argument4,argument5,argument6);
            
            if t {
                x1 = x0;
                y1 = y0;
                t2 = t;
            }
            else {
                x0 = x1;
                y0 = y1;
                td += d;
            }
        }
        
        cx = x1+lx*res*0.5;
        cy = y1+ly*res*0.5;
        cd = td;
    }
    else {
        cx = argument0 + lx*td;
        cy = argument1 + ly*td;
        cd = td;
    }
    
    return t2;
}

Board footer

Powered by FluxBB