Legacy GM Objects not affected by shader.

VerdeBoss

Member
Hi,

As you can see I'm new here,
and this is my first post.

Recently, I'm making a "First Person Click-and-Point" game, specifically FNAF.
I want certain objects to NOT be affected by the shader, which is the Panorama(3d curve).


Is there any way how to make a shader object that affects the parts behind it(similar to CTF's Perspective object) or make a custom surface?

If so,
Thanks!
 

Simon Gust

Member
you know how there are the functions shader_set and shader_reset. Anything drawn inbetween those function are affected by the shader, Everything after or before is not.
So basically set the shader, draw everything that needs the 3d curve, reset the shader draw everything that does not need a 3d curve.
 

Simon Gust

Member
Code:
with (OBJECTA) draw_self();

shader_set(SHADER);

with (OBJECTB) draw_self();

shader_reset();

with (OBJECTC) draw_self();
In this example of pseudo code, only OBJECTB is affected by the shader. the with statements can also be replaced with normal draw code. It would be only for when you draw objects.
 

Bingdom

Googledom
For future reference, the manual is a good resource for learning.

If you want to find something to do with shaders, searching "Game maker shaders" will bring you to the manual.
 
Last edited:

VerdeBoss

Member
Code:
with (OBJECTA) draw_self();

shader_set(SHADER);

with (OBJECTB) draw_self();

shader_reset();

with (OBJECTC) draw_self();
In this example of pseudo code, only OBJECTB is affected by the shader. the with statements can also be replaced with normal draw code. It would be only for when you draw objects.
Great!

It works!
Since it's on Draw GUI it draws on the screen not the object itself.
Now, I want a CLICKABLE object to not be affected.
any way how to do it?
 

Simon Gust

Member
Great!

It works!
Since it's on Draw GUI it draws on the screen not the object itself.
Now, I want a CLICKABLE object to not be affected.
any way how to do it?
If this object is also a GUI thing then you have to just draw it after you reset the shader. If it isn't on the GUI it shouldn't be affected by the shader unless you aren't resetting the shader.
 

VerdeBoss

Member
If this object is also a GUI thing then you have to just draw it after you reset the shader. If it isn't on the GUI it shouldn't be affected by the shader unless you aren't resetting the shader.
I found a easy way how.

It says that you must create a surface and apply shader to that surface
but I don't know how to make a surface and add the shader into it.
 
B

Badger

Guest
It says that you must create a surface and apply shader to that surface
but I don't know how to make a surface and add the shader into it.
Code:
//create event=========
 yourSurface=-1; // I am initializing a variable for the surface that we will create
 
//draw event=========
if(!surface_exists(yourSurface)){  // Here we are checking if a surface exists that is named "yourSurface"
 yourSurface=surface_create(64,64); //If "yourSurface" DOESN'T exist, then we create it. yourSurface is 64x64 pixels
 surface_set_target(yourSurface); //This tells Game Maker that we want to draw on the surface
 draw_clear_alpha(c_black,0);//This tells Game Maker to make the surface completely transparent
  //draw some stuff here EXAMPLE: draw_sprite(yourSprite,0,x,y);
 surface_reset_target();// This tells Game Maker that we are finished drawing to the surface
}

//To draw the surface with the shader:
 shader_set(yourShader);
  draw_surface(yourSurface,10,10);
 shader_reset();
To echo @Bingdom, use the manual. All of what I have typed here is explained thoroughly within it. The manual can be accessed online, or by pressing
F1 while in Game Maker Studio. Good Luck.
 

VerdeBoss

Member
Code:
//create event=========
 yourSurface=-1; // I am initializing a variable for the surface that we will create
 
//draw event=========
if(!surface_exists(yourSurface)){  // Here we are checking if a surface exists that is named "yourSurface"
 yourSurface=surface_create(64,64); //If "yourSurface" DOESN'T exist, then we create it. yourSurface is 64x64 pixels
 surface_set_target(yourSurface); //This tells Game Maker that we want to draw on the surface
 draw_clear_alpha(c_black,0);//This tells Game Maker to make the surface completely transparent
  //draw some stuff here EXAMPLE: draw_sprite(yourSprite,0,x,y);
 surface_reset_target();// This tells Game Maker that we are finished drawing to the surface
}

//To draw the surface with the shader:
 shader_set(yourShader);
  draw_surface(yourSurface,10,10);
 shader_reset();
To echo @Bingdom, use the manual. All of what I have typed here is explained thoroughly within it. The manual can be accessed online, or by pressing
F1 while in Game Maker Studio. Good Luck.
There, I made my surface.
but the shader won't work, it consists of drawing in the view not the whole surface.
I want it to affect only to the surface created, like I want it to behave like application_surface using Draw GUI.
However, If I use draw GUI on the surface I made instead of the application_surface..
The surface will stay stuck on the screen because GUI.

I wish I could show you the gifs
but they're too large.
 

VerdeBoss

Member
Ok,
I need this code to be modified by something else
but this method is killing the texture memory (for me)
Code:
//create
surf = -1
scroll = 0

//draw
surf=surface_create(1280, 721);
 surface_set_target(surf);
 draw_clear_alpha(c_black,0);
draw_background(bg_fnaf,scroll,0); //"scroll" means the movement of the background sprite
 surface_reset_target()

//draw gui
shader_set(shd_test);
draw_surface(surf,0,0);
shader_reset();
 surface_reset_target()
 
You need only create the surface if it doesn't exist already.

Right now, you are creating a new surface every frame in the draw event. ( and overwriting the variable that already indexing a surface, which is giving you the memory leak. )

You have left out the code for checking if the surface already exists.

@Badger already gave you the example using:

Draw Event
Code:
 if ( !surface_exists(surf) )
{
    ...insert your surface creation code here...
}

...insert your surface drawing code here...
 

VerdeBoss

Member
You need only create the surface if it doesn't exist already.

Right now, you are creating a new surface every frame in the draw event. ( and overwriting the variable that already indexing a surface, which is giving you the memory leak. )

You have left out the code for checking if the surface already exists.

@Badger already gave you the example using:

Draw Event
Code:
 if ( !surface_exists(surf) )
{
    ...insert your surface creation code here...
}

...insert your surface drawing code here...
I know that it is keep drawing of surfaces forever.
The reason I didn't add "if surface_exists" because the image won't move since it only happens one time, not forever.
 
The reason I didn't add "if surface_exists" because the image won't move since it only happens one time, not forever.
From what you are saying, it seems you don't understand surfaces (or managing dynamic resources) properly yet.

Read the following documentation on Surfaces and the surface_exist() function until you understand why you need the surface_exists() function in your code.

http://docs.yoyogames.com/index.html?page=source/dadiospice/002_reference/surfaces/index.html
http://docs.yoyogames.com/index.htm...ce/002_reference/surfaces/surface_exists.html

It's quite difficult to offer a proper solution, as its not clear exactly what you want.

Why are you drawing this in the Draw GUI Event if you want the surface to be in the background?

You should be drawing the surface using the shader first, before anything else, in the Draw Event.

Now, I want a CLICKABLE object to not be affected.
If you followed all the above posts advice, the only thing that should be affected by the shader is the background surface.

If you want a clickable object to not be affected by the shader, just make one as normal and have it draw after the background is drawn and you have reset the shader.
 

VerdeBoss

Member
From what you are saying, it seems you don't understand surfaces (or managing dynamic resources) properly yet.

Read the following documentation on Surfaces and the surface_exist() function until you understand why you need the surface_exists() function in your code.

http://docs.yoyogames.com/index.html?page=source/dadiospice/002_reference/surfaces/index.html
http://docs.yoyogames.com/index.htm...ce/002_reference/surfaces/surface_exists.html
the shader.
So, how do I draw the world on the surface and make it movable?
Do, I actually need to use views?
Code:
//draw event=========
if(!surface_exists(yourSurface)){  //if no surface, makes one
//draw some stuff here EXAMPLE: draw_sprite(yourSprite,0,x,y);
}
//after the surface is created you cannot mess around the creating surface code above.
else
{
//draw the surface and shader
//Something to make the background move instead of drawing the background here.
}
is exactly like pasting stuff in a piece of paper.
 
I used drawing part of surface, applied the shader in, and when you set any random object number greater than the shader objects depth number, that random object won't get affected by the shader.
All right. I just asked to make sure anyone else having the same problem will be able to come to this topic and find the answer. Glad you were able to get it working!
 

TheEliteD

Member
I used drawing part of surface, applied the shader in, and when you set any random object number greater than the shader objects depth number, that random object won't get affected by the shader.
Can you post the code, please? Or can you at least explain how to do that? I have the exact same problem. I don't want my buttons getting affected by the shader but I really do not know anything about shaders or surfaces for that matter.
 

TailBit

Member
Can you post the code, please? Or can you at least explain how to do that? I have the exact same problem. I don't want my buttons getting affected by the shader but I really do not know anything about shaders or surfaces for that matter.
Hm, if your control object is on top of the room's instance order list, then it should be enough to (draw background first if it should be unaffected by shader) have its draw event just start the shader, other draw events then draws, then draw gui starts and you have it turn shader off.. then the other draw guis follows.

Would that work without any extra surface?
 
Top