Jump to content


jimn346

Member Since 13 Apr 2009
Offline Last Active Mar 17 2013 06:26 PM

Topics I've Started

Surface Glows

23 September 2011 - 03:19 AM

I am attempting to write a script that can make a glow effect out of a surface, and I have a script that should work, but it doesn't. It draws the hard radius but not the soft one. I based it off Tiby312's sprite effects found here.

NOTE: This code is not intended to add an effect to the surface but create a new surface containing only the effect.
Example: Posted Image

EDIT: I figured out the problem, but I haven't found a solution. The alpha for the soft radius is not being calculated correctly.

//surface_effect_from_surface(surface, xscale, yscale, color, alpha, hardradius, softradius)
//By Tiby312
//Modified by jimn346

//Initialize the variables.
var surface, width, height, newsurf, softradius, alpha, xscale, yscale, color, hardradius, tempsurf;

//Set the arguments to the variables.
surface = argument0;
xscale = argument1;
yscale = argument2;
color = argument3;
alpha = argument4;
hardradius = argument5 + 1;
softradius = argument6;

//Set the width and height of the drawing board.
width = (surface_get_width(surface) * xscale) + ((softradius + hardradius) * 2) + 2;
height = (surface_get_height(surface) * yscale) + ((softradius + hardradius) * 2) + 2;

//Create the new surface.
newsurf = surface_create(width, height);

//Start drawing on the new surface.
surface_set_target(newsurf);

//Set the drawing board to clear white.
draw_clear_alpha(c_white, 0);

//Turn d3d fog on so that the image drawn is just white.
d3d_set_fog(true, c_white, 0, 0);

//Turn on additive blending so the new alpha values won't replace the old ones, but instead blend with them.
draw_set_blend_mode(bm_add);

//Draw the hard radius.
var blurinc;
blurinc = hardradius + 10;
for(ii = 0; ii < hardradius; ii += 1;)
{
    for(i = 0; i < 360; i += 360 / blurinc;)
    {
        draw_surface_ext(surface, lengthdir_x(ii, i), - lengthdir_y(ii, i), xscale, yscale, 0, c_white, 1);
    }
}

//Draw the soft radius.
var blurrad, blurinc, alpha, tempalpha;
blurrad = hardradius + softradius;
blurinc = softradius + hardradius + 10;
tempalpha = 1 / blurinc;
for(ii = hardradius; ii < blurrad; ii += 1;)
{
    for(i = 0; i < 360; i += 360 / blurinc;)
    {
        draw_surface_ext(surface, lengthdir_x(ii, i), - lengthdir_y(ii, i), xscale, yscale, 0, c_white, tempalpha);
    }
}

//Turn fog off.
d3d_set_fog(false, 0, 0, 0);

//Turn off additive blending so that the new image will replace the old one and images will be drawn to the screen normally.
draw_set_blend_mode(bm_normal);

//Create a temporary surface for editing.
tempsurf = surface_create(width, height);

//Start drawing on the temporary surface.
surface_set_target(tempsurf);

//Duplicate the previous surface to this one in the correct alpha and color.
draw_surface_ext(newsurf, 0, 0, 1, 1, 0, color, alpha);

//Start drawing on the new surface.
surface_set_target(newsurf);

//Set the drawing board to a transparent version of the final color.
draw_clear_alpha(color, 0);

//Draw the duplicated surface back onto the original.
draw_surface_ext(tempsurf, 0, 0, 1, 1, 0, c_white, 1);

//Set drawing to be on the screen.
surface_reset_target();

//Delete the temporary surface.
surface_free(tempsurf);

//Return the ID of the new surface.
return newsurf;

Old code:
Spoiler

Realtime Surface Alpha Mask

15 August 2011 - 07:44 PM

It is a well known fact that transparent or semitransparent pixels drawn onto a surface replace the alpha value instead of blending it (much like the option in GM's image editor to "blend" or "replace" for those who don't understand). It seems the only way to fix this is to use another surface as an alpha mask (I have tried all possible combinations for blend modes and none correct the alpha), but this seems impossible with the standard, black-and-white, "alpha = brightness" masks. I could make the surface a sprite and use "sprite_set_alpha_from_sprite" and turn it into a surface again, but that wouldn't work in realtime. I've seen somewhere that you can use a surface as an alpha mask if you use clear alpha black as 100% alpha and 100% alpha black as transparent and then draw that on the other surface with bm_subtract (it may have been a different blend mode), and that would work, but the alpha mask is being created in game, and I can't make it with the correct alpha (in other words, I can apply an existing alpha mask, but I can't correctly create one to correspond with the original surface). So that others can understand, I'm making a drawing program and need to find a way to make the brush work properly.

GM8.1 Has Slower FPS?

23 July 2011 - 03:39 AM

This isn't really mathematical, but this seems like the best place to put this because it doesn't have to do with code and the community forum says "Discussions about GameMaker itself should now take place in the new GM general discussion forums." and the GM general discussion forum doesn't exist.

I was creating a program in GM8.1 with the room speed set at 60. It isn't an extremely heavy program, but it only ran at 30 FPS. I converted it to a GMK and used GM8.0 to run it and it ran at the full 60 FPS. This is consistent. What would cause GM8.1 to be slower than 8.0?

Media Player DLL

10 June 2011 - 08:34 PM

I'm attempting to make a program that saves a single frame from a video file as an image and can also save all frames of a video as images. The problem I'm having is finding the frames per second of a video so I can save each frame individually without skipping frames or saving frames more than once. I need to set the room speed to the speed of the video, but I need to find the video FPS first. This clearly requires a script that manually finds the FPS from the file or a DLL. I would prefer a DLL, but a script would work fine too. Another solution would be a DLL that allows you to save a specified frame from a video and check the number of frames in a video. This would actually be better than the first solution.

I also need a media player DLL that can pause a video. I found many, but they all had broken links.

Drawing a List of Sprites in a Wrapping Grid

15 May 2011 - 07:09 PM

For an item screen, I am trying to draw a list of items (using sprites). It works, but the list is out of order. I read my script and figured out why (the x and y increase in the same manner, so it it diagonal), but I don't know how to fix it. This is my code (for the time being, the values in the ds list are the same as their indexes).
if menu=1 {
  draw_background(tempback,view_xview,view_yview);
  draw_set_alpha(.5);
  draw_rectangle(-8,-8,room_width+8,room_height+8,0);
  draw_set_alpha(1);
  draw_background(bkg_itemback,view_xview+(view_wview-208)/2,view_yview+(view_hview-133)/2)
  for(i=0; i<ds_list_size(item_have); i+=1;) {
    draw_sprite(spr_items,ds_list_find_value(item_have,i),view_xview+(view_wview-208)/2+1+36*(i+1-4*(floor((i+1)/4)-((i+1)/4=floor((i+1)/4))))+5,view_yview+(view_hview-133)/2-5+24*(i+1-3*(floor((i+1)/3)-((i+1)/3=floor((i+1)/3))))+2);
    if ds_list_find_value(item_have,i)=item[0] {
      draw_sprite(spr_itemset,0,view_xview+(view_wview-208)/2+1+36*(i+1-4*(floor((i+1)/4)-((i+1)/4=floor((i+1)/4)))),view_yview+(view_hview-133)/2-5+24*(i+1-3*(floor((i+1)/3)-((i+1)/3=floor((i+1)/3)))));
      };
    if ds_list_find_value(item_have,i)=item[1] {
      draw_sprite(spr_itemset,1,view_xview+(view_wview-208)/2+1+36*(i+1-4*(floor((i+1)/4)-((i+1)/4=floor((i+1)/4)))),view_yview+(view_hview-133)/2-5+24*(i+1-3*(floor((i+1)/3)-((i+1)/3=floor((i+1)/3)))));
      };
    if ds_list_find_value(item_have,i)=item[2] {
      draw_sprite(spr_itemset,2,view_xview+(view_wview-208)/2+1+36*(i+1-4*(floor((i+1)/4)-((i+1)/4=floor((i+1)/4)))),view_yview+(view_hview-133)/2-5+24*(i+1-3*(floor((i+1)/3)-((i+1)/3=floor((i+1)/3)))));
      };
    };
  };

This is the order of the images in the sprite.
Posted Image

This it appears on the screen.
Posted Image