macroquad icon indicating copy to clipboard operation
macroquad copied to clipboard

How to set GL_REPEAT or TextureWrap::Repeat on texture

Open tirithen opened this issue 4 years ago • 2 comments

I want to render an endlessly repeating texture with x/y offset as a ground/background texture, but I cannot seem to find a way to pass the GL_REPEAT setting to the texture from the higher level load_texture call.

In miniquad it looks like there is a TextureWrap::Repeat enum value that could be applied to the TextureParams struct (https://github.com/not-fl3/miniquad/blob/master/src/graphics/texture.rs#L91) but to do that in macroquad the get_context function would need to be public.

Are there any way of exposing the TextureParams/TextureWrap structs all the way up to macroquads load_texture or similar more high level functions?

If I can get help with defining how the API should look on the top level I can create a pull request adding the in-between code.

tirithen avatar Dec 11 '21 08:12 tirithen

repeat/wrap is not yet implemented :( I believe there should be a set_wrap function just like set_filter

not-fl3 avatar Dec 11 '21 14:12 not-fl3

I have implemented set_wrap in a merge request following the set_filter method (https://github.com/not-fl3/macroquad/pull/336). That part was fairly easy, but I then got stuck on the problem that there is no way to set a drawing size that is larger than the size of the texture when using draw_texture_ex so therefore the image has no chance of repeating.

Probably there might also be other issues that I have not yet realized. If I can get some more pointers I can try to implement some more pieces for this with the goal to use this for a repeated "ground" texture in a project I'm working on. I have yet to learn much more about OpenGL, but I really enjoy using this library, lets see how it goes.

tirithen avatar Dec 11 '21 22:12 tirithen

This is something I noticed was missing as well. Its not a huge deal as I can still set the wrap mode using miniquad but it would be nice to have the function in macroquad. The below code is how I set the wrapping mode using miniquad.

let tex = load_texture("").await.unwrap();

let gl = unsafe { get_internal_gl() };
let ctx = gl.quad_context;

ctx.texture_set_wrap(tex.raw_miniquad_id(), miniquad::TextureWrap::Repeat, miniquad::TextureWrap::Repeat);

@tirithen

I then got stuck on the problem that there is no way to set a drawing size that is larger than the size of the texture when using draw_texture_ex so therefore the image has no chance of repeating.

This is resolved if you use a shader like below.

Fragment Shader

#version 100

varying lowp vec2 uv;

uniform sampler2D color_texture;
uniform highp vec2 repeat;

void main(){
    gl_FragColor = texture2D(color_texture, uv * repeat);
}

Vertex

#version 100

attribute vec3 position;
attribute vec2 texcoord;

varying lowp vec2 uv;

uniform mat4 Model;
uniform mat4 Projection;

void main() {
    gl_Position = Projection * Model * vec4(position, 1);
    uv = texcoord;
}

After loading the material and setting the uniform to something like (2, 2) you can then draw a rectangle and set it to what ever size you want. Setting repeat to (1., 1.) will make it so it doesn't repeat, so, it should be higher then (1., 1.) if you want it to repeat.

let color_repeat = load_material(
        ShaderSource::Glsl { 
            vertex: include_str!("../shaders/color_repeat.vert"),
            fragment: include_str!("../shaders/color_repeat.frag"),
        },
        
        MaterialParams{
            uniforms: vec![("repeat".to_string(), UniformType::Float2)],
            textures: vec!["color_texture".to_string()],
            ..Default::default()
        }

    ).unwrap();

color_repeat.set_uniform("repeat", vec2(2., 2.));
color_repeat.set_texture("color_texture", tex.clone());


loop{

    gl_use_material(&color_repeat);
    draw_rectangle(0., 0., 1024., 1024., WHITE);

    gl_use_default_material();

    next_frame().await;
}

NHodgesVFX avatar Dec 29 '23 17:12 NHodgesVFX

Thanks for the guidance! Currently when doing game experiments I mainly use bevy nowadays. But hopefully this is is helpful got anyone else trying to draw repeating textures! Macroquad has such an great and accessible API, but still I remember the much steeper learning curve when needing to use GLSL shaders directly with it. So great with every guide on the more complex topics for anyone else that might need to use GLSL shaders in macroquad projects, thanks!

tirithen avatar Dec 29 '23 19:12 tirithen