• Hey! Guest! The 39th GMC Jam will take place between November 26th, 12:00 UTC and November 30th, 12:00 UTC. Why not join in! Click here to find out more!

can you not use shaders with draw_sprite_pos()?

bsabiston

Member
I am trying to add some shading effects to sprites which I'm drawing with the draw_sprite_pos. But even after setting the shader in the draw function, it seems to have no effect. The sprites just draw normally. Can I not use shaders with the draw_sprite_pos function?

EDIT: I switched over to using vertex buffers, and it STILL doesn't appear to be using the shader. I use shaders elsewhere in my game, for another object, and they work OK. I don't get why this one isn't working...
 
Last edited:

bsabiston

Member
Okay let's see. I have a room with one object in it, and the object is supposed to draw the view. For some reason it shows up on the layer list garbled, like this.

https://imgur.com/a/NG4p9WQ

Not sure if it is related.

My shader uses two uniforms which I get like this in the object's creation code:

dungeon_alpha = shader_get_uniform(shd_dungeon, "dungeon_alpha")
dungeon_uv = shader_get_uniform(shd_dungeon, "dungeon_uv")​


So in the object's draw function I draw a bunch of pseudo-3d tiles, like for a first-person retro dungeon. I was using draw_sprite_pos, and I switched to using vertex buffers thinking that draw_sprite_pos would not work with shaders.
This is how I call it with draw_sprite_pos:

shader_set( shd_dungeon );
shader_set_uniform_f(dungeon_uv,argument0.uv_left, argument0.uv_right)
shader_set_uniform_f(dungeon_alpha,argument1)
draw_sprite_pos(argument0.sprite_index,0, argument0.x1,argument0.y1,argument0.x2,argument0.y2,argument0.x3,argument0.y3,argument0.x4,argument0.y4,argument1)
shader_reset()​


And this is how I do it with shaders:
argument0.x1 = argument1
argument0.y1 = argument2
argument0.x2 = argument3
argument0.y2 = argument4
argument0.x3 = argument5
argument0.y3 = argument6
argument0.x4 = argument7
argument0.y4 = argument8

argument0.vbuff = vertex_create_buffer();
vertex_begin(argument0.vbuff, argument0.format);

// triangle 1
vertex_position(argument0.vbuff, argument0.x1,argument0.y1);
vertex_texcoord(argument0.vbuff, argument0.uv_left, argument0.uv_top);
vertex_color(argument0.vbuff, c_white, 1);


vertex_position(argument0.vbuff, argument0.x2,argument0.y2);
vertex_texcoord(argument0.vbuff, argument0.uv_right, argument0.uv_top);
vertex_color(argument0.vbuff, c_white, 1);


vertex_position(argument0.vbuff, argument0.x4,argument0.y4);
vertex_texcoord(argument0.vbuff, argument0.uv_left, argument0.uv_bottom);
vertex_color(argument0.vbuff, c_white, 1);


// triangle 2
vertex_position(argument0.vbuff, argument0.x2,argument0.y2);
vertex_texcoord(argument0.vbuff, argument0.uv_right, argument0.uv_top);
vertex_color(argument0.vbuff, c_white, 1);

vertex_position(argument0.vbuff, argument0.x3,argument0.y3);
vertex_texcoord(argument0.vbuff, argument0.uv_right, argument0.uv_bottom);
vertex_color(argument0.vbuff, c_white, 1);


vertex_position(argument0.vbuff,argument0.x4,argument0.y4);
vertex_texcoord(argument0.vbuff, argument0.uv_left, argument0.uv_bottom);
vertex_color(argument0.vbuff, c_white, 1);

vertex_end(argument0.vbuff)

shader_set( shd_dungeon );
shader_set_uniform_f(dungeon_uv,argument0.uv_left, argument0.uv_right)
shader_set_uniform_f(dungeon_alpha,argument1)
vertex_submit(argument0.vbuff, pr_trianglelist, argument0.tex);
shader_reset()

The graphics show up the same for both of these methods -- they show up as if I wasn't using a shader.
Here's my shader. Just to try to get it working I am just returning c_white for now. It doesn't do it. It just acts like it is not using the shader at all.

// vertex shader =============================================================
attribute vec2 in_Position;
attribute vec2 in_TextureCoord;
attribute vec4 in_Colour;

varying vec2 v_vTexcoord;

void main() {
vec4 object_space_pos = vec4( in_Position.x, in_Position.y, 0.0, 1.0);
gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;

v_vTexcoord = in_TextureCoord;
}​


// fragment shader =============================================================
varying vec2 v_vTexcoord;
//varying vec4 v_vColour;

uniform vec2 dungeon_alpha;
uniform vec2 dungeon_uv;

void main() {
float r = (v_vTexcoord.x - dungeon_uv[0]) / (dungeon_uv[1] - dungeon_uv[0]);
float dim = dungeon_alpha;//mix(dungeon_alphas[0],dungeon_alphas[1],r);

gl_FragColor = vec4(1.0,1.0,1.0,1.0); // texture2D( gm_BaseTexture, v_vTexcoord )*0.25; // commented out just to see if shader is even being called - it is not
}​




Any ideas?
 

bsabiston

Member
Ah! It returns 0. Thanks!
That documentation says the game will crash if you try to use an uncompiled shader, but apparently that doesn't always happen.

The problem was the line where I set the float 'dim' to a vec2 value. I had commented out the correct line when trying to debug, and introduced a new error in the process...
 

icuurd12b42

TMC Founder
GMC Elder
what the deal with this code?
argument0.x1 = argument1
argument0.y1 = argument2
argument0.x2 = argument3
argument0.y2 = argument4
argument0.x3 = argument5
argument0.y3 = argument6
argument0.x4 = argument7
argument0.y4 = argument8

argument0.vbuff = vertex_create_buffer();

Ya should really shove the arguments in local variable so we can grasp what you are doing...

also I dont see you deleting the vertex buffer.

about the uvs....
Be aware that the engine will remap the uv for you to match the location of the image on the texture page.... the texture returned by sprite_get_texture is not the texture page but some value the engine knows to extrapolate more detail as to the image and it's actual location on the tpage (I assume)....
if you define a vertex buffer for a drawing of a sprite for example, you define the 6 vertices to create 2 triangles specifying that the color extracted from the source image be from uv 0,0 to uv 1,1. if you draw a sprite that is located on the texture page that is from uv .4,.4 to .6,.6, your shader will see the v_vTexcoord values ranged from .4,.4 to .6,.6 even though you defined the vertices for go from 0,0 to 1,1...


upload_2018-7-21_14-29-10.png

If the math in the shader is depending on the uvs to be from 0,0 to 1,1, you would need to remap this, you can pass the sprite_get_uvs array to a vec4 uniform via shader_set_uniform_f_array

You can bypass the need for this by forcing your sprite to be on its own texture page, either with the use for 3d check box or by setting the sprite to use its own unique texture group.

upload_2018-7-21_14-37-1.png

note for the remapping to wordk with sprite_get_uvs your texture group must have the no cropping option set
upload_2018-7-21_14-38-22.png
 
Last edited:

bsabiston

Member
Thanks but maybe it wasn't clear from my earlier post -- the problem is fixed, it was just that trying to set float dim to a vec2. Thanks for suggesting shader_is_compiled().

Thanks also for reminding me to delete the vertex buffers. I assumed they would be deleted when I reassigned the variable, but maybe they aren't.
 
Last edited:
Top