ENIGMA Forums
General fluff => General ENIGMA => Topic started by: Lemon Pie on April 26, 2012, 08:37:30 pm
-
I made a project in Game Maker that would draw a Mandelbrot Set fractal (depending on a few parameters). I ported the project to ENIGMA to test speeds of ENIGMA vs GM.
Visually this is what happened :o
(http://i48.tinypic.com/5pmjb.png)
(ENIGMA on the left, Game Maker on the right)
Speed-wise I got a 10-30 times increase in ENIGMA over GM :D
I was able to render a fractal in ENIGMA at 50 iterations per x,y coordinate about 10 times in the time it took for GM.
Anyways.. :v:
I can't wait to see how far the ENIGMA project goes! Great work so far guys! (Y)
The Mandelbrot Set script in GML for anyone who may want it:
////////////////////////////
//Mandelbrot set algorithm//
////////////////////////////
draw_set_color(c_black) //sets drawing color to black
draw_rectangle(0,0,room_width,room_height,false) //draws 'background'
screen_refresh(); //refreshes screen
xx = 0; //starting x point
yy = 0; //starting y point
Iteration = global._Iterations; //Maximum Iterations (Number of times it will redraw)
MinReal = global._MinReal; //Minimum Real Number (Smallest, Negative)
MaxReal = global._MaxReal; //Maximum Real Number (Largest, Positive)
MinIm = global._MinImaginary; //Minimum Imaginary (Smallest Imaginary, Negative)
MaxIm = MinIm+(MaxReal-MinReal)*room_height/room_width;
//Maximum Imaginary (Largest Imaginary, Depends on Others)
RealFac = (MaxReal-MinReal)/(room_width-1); //Real factor
ImFac = (MaxIm-MinIm)/(room_height-1); //Imaginary Factor
cReal = MinReal + xx *RealFac; //C real start value
cIm = MinIm - yy * ImFac; //C Imaginary start value
for (yy = 0; yy <room_height; yy+=1)
{
cIm = MaxIm-yy*ImFac; //New C Imaginary value
for(xx = 0; xx<room_width; xx+=1)
{
cReal = MinReal+xx*RealFac; //New C Real value
zReal = cReal; //Z Real value
zIm = cIm; //Z Imaginary value
isTrue = true;
for (i=0; i<Iteration; i+=1)
{
zR2 = sqr(zReal); //New z[Real]^2
zIm2 = sqr(zIm); //New z[Imaginary]^2
if (zR2+zIm2>4) //if the 2 numbers are inside the fractal's limits
{
isTrue = false; //sets isTrue to false
if argument0 = true //if you want to draw a background color
{
draw_set_color(make_color_hsv(zR2*(5*i),0,i*10)) //makes a color
draw_point(xx,yy) //draws the color at the point
}
break;
}
zIm = 2*zReal*zIm+cIm; //New z[Imaginary]^2
zReal = zR2-zIm2+cReal; //New z[Real]^2
}
if (isTrue) //if the point should draw
{
if argument1 = true //if you want to draw inside the fractal image
{ //makes a pretty color for the inside of the fractal
draw_set_color(make_color_rgb(abs((i*zR2)*255),abs((i*zIm2)*255),abs((i+zR2*zIm2)*255)))
}
else draw_set_color(c_white) //else the color is white
draw_point(xx,yy) //draws a pixel at XX,YY w/ color
}
}
screen_refresh(); //refreshes the screen so you can see the fractal creating itself
//Putting the refresh here is faster than after a pixel is drawn.
sleep(1); //sleeps for 1 millisecond. Allows you to
//keep control of the window while drawing in GM
}
keyboard_wait();
-
There's some more games on the EDC if you want to test the speed of GM vs ENIGMA. These two are good:
http://enigma-dev.org/edc/games.php?game=4
http://enigma-dev.org/edc/games.php?game=26
-
Why does it look interlaced?
-
The same reason ray trace demo from EDC look interlaced. I suspect it was flashing (like switching between the lines) right? I never could of figure out why this happened. I thought it was because of buffer switching during screen_refresh() but I am not sure. Anyway, as surfaces are in, you could probably use those to eliminate these problems.
edit: Just tried the code. Have the same problem. I fixed it by using surfaces and screen_redraw().
SwapBuffers(enigma::window_hDC); (on win) is the cause of the problem and I don't think you can easily fix it.
edit2: Its something to do with WM_ERASEBKGND message and OnEraseBkgnd. If they are overwritten then it could fix it (hell if I know how to overwrite them).
-
It is because of buffer switching. Half of the lines are painted on the front buffer, half on the back. Just draw it all in one go. :P
Perhaps we could use for an option to disable double buffering...
At any rate, it's nice to see someone able to get the project running without hassle. :)
Also, you could speed this up more by placing it in draw_primitive_begin(pr_pointlist)/draw_primitive_end(), and using draw_vertex() instead of draw_point().
-
But linux also has double buffering and you don't see this interlacing. I also thought it was something to do with double buffering (like half a year ago when I clearly mentioned this problem), but googling makes me to believe its something to do with windows and WM_ERASEBKGND. Its apparently a common problem with gl on windows.
edit: Also, OP if you used data types that are in ENIGMA, then you should be able to speed it up even more. Like putting int in front of some variables.