sfml3.rb

Class: SFML::Shader

Inherits:
Object
  • Object
show all
Defined in:
ext/graphics/shader.c,
ext/graphics/shader.c

Overview

A GLSL vertex/geometry/fragment shader program, uploaded to the GPU and carried on RenderState#shader.

The set_*_array methods below are generated from a shared macro (see ext/graphics/shader.c) and documented here directly since the macro hides their function bodies from the doc-comment scanner.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.available? ⇒ Boolean

Returns true if shaders are supported.

Returns:

  • (Boolean)

Returns:

  • (Boolean) —

    whether the system supports shaders at all



180
181
182
# File 'ext/graphics/shader.c', line 180

static VALUE Shader_is_available(VALUE klass) {
    return BOOL2RB(sfShader_isAvailable());
}

.from_file(vertex) ⇒ Shader .from_file(vertex, fragment) ⇒ Shader .from_file(vertex, fragment, geometry) ⇒ Shader

Compiles a shader from GLSL source file paths. Any of the three may be nil to skip that stage.

Overloads:

Returns:

Raises:

  • (RuntimeError) —

    if compilation fails



81
82
83
84
85
86
87
88
89
# File 'ext/graphics/shader.c', line 81

static VALUE Shader_from_file(int argc, VALUE* argv, VALUE klass) {
    VALUE rb_vertex, rb_fragment, rb_geometry;

    rb_scan_args(argc, argv, "12", &rb_vertex, &rb_fragment, &rb_geometry);

    return Shader_wrap(klass, sfShader_createFromFile(StringValueCStr(rb_vertex),
                                                      Shader_optional_cstr(rb_geometry),
                                                      Shader_optional_cstr(rb_fragment)));
}

.from_memory(vertex) ⇒ Shader .from_memory(vertex, fragment) ⇒ Shader .from_memory(vertex, fragment, geometry) ⇒ Shader

Compiles a shader from GLSL source Strings. Any of the three may be nil to skip that stage.

Overloads:

  • .from_memory(vertex) ⇒ Shader

    Returns:

  • .from_memory(vertex, fragment) ⇒ Shader

    Returns:

  • .from_memory(vertex, fragment, geometry) ⇒ Shader

    Returns:

Returns:

Raises:

  • (RuntimeError) —

    if compilation fails



102
103
104
105
106
107
108
109
110
# File 'ext/graphics/shader.c', line 102

static VALUE Shader_from_memory(int argc, VALUE* argv, VALUE klass) {
    VALUE rb_vertex, rb_fragment, rb_geometry;

    rb_scan_args(argc, argv, "12", &rb_vertex, &rb_fragment, &rb_geometry);

    return Shader_wrap(klass, sfShader_createFromMemory(Shader_optional_cstr(rb_vertex),
                                                        Shader_optional_cstr(rb_geometry),
                                                        Shader_optional_cstr(rb_fragment)));
}

.from_stream(vertex) ⇒ Shader .from_stream(vertex, fragment) ⇒ Shader .from_stream(vertex, fragment, geometry) ⇒ Shader

Compiles a shader from GLSL source read through InputStream objects. Any of the three may be nil to skip that stage.

Overloads:

  • .from_stream(vertex) ⇒ Shader

    Returns:

  • .from_stream(vertex, fragment) ⇒ Shader

    Returns:

  • .from_stream(vertex, fragment, geometry) ⇒ Shader

    Returns:

Returns:

Raises:

  • (RuntimeError) —

    if compilation fails



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'ext/graphics/shader.c', line 123

static VALUE Shader_from_stream(int argc, VALUE* argv, VALUE klass) {
    VALUE rb_vertex, rb_fragment, rb_geometry;
    VALUE holder_vertex = Qnil, holder_fragment = Qnil, holder_geometry = Qnil;
    sfInputStream* vertex = NULL;
    sfInputStream* fragment = NULL;
    sfInputStream* geometry = NULL;

    rb_scan_args(argc, argv, "12", &rb_vertex, &rb_fragment, &rb_geometry);

    if (!NIL_P(rb_vertex)) {
        vertex = input_stream_from_rb(rb_vertex, &holder_vertex);
    }

    if (!NIL_P(rb_fragment)) {
        fragment = input_stream_from_rb(rb_fragment, &holder_fragment);
    }

    if (!NIL_P(rb_geometry)) {
        geometry = input_stream_from_rb(rb_geometry, &holder_geometry);
    }

    (void)holder_vertex;
    (void)holder_fragment;
    (void)holder_geometry;

    return Shader_wrap(klass, sfShader_createFromStream(vertex, geometry, fragment));
}

.geometry_available? ⇒ Boolean

Returns true if geometry shaders are supported.

Returns:

  • (Boolean)

Returns:

  • (Boolean) —

    whether the system supports geometry shaders



191
192
193
# File 'ext/graphics/shader.c', line 191

static VALUE Shader_is_geometry_available(VALUE klass) {
    return BOOL2RB(sfShader_isGeometryAvailable());
}

Instance Method Details

#bind ⇒ self

Activates this shader for rendering. Pass a RenderState carrying it to Target#draw instead of calling this directly, unless drawing raw OpenGL.

Returns:

  • (self)

Returns:

  • (self)


168
169
170
171
# File 'ext/graphics/shader.c', line 168

static VALUE Shader_bind(VALUE self) {
    sfShader_bind(Get_Shader_Struct(self));
    return self;
}

#native_handle ⇒ Integer

Returns the underlying OpenGL handle.

Returns:

  • (Integer)

Returns:

  • (Integer) —

    the underlying OpenGL program handle



157
158
159
# File 'ext/graphics/shader.c', line 157

static VALUE Shader_get_native_handle(VALUE self) {
    return UINT2NUM(sfShader_getNativeHandle(Get_Shader_Struct(self)));
}

#set_bool(name, x) ⇒ self

Sets the name uniform to a boolean.

Returns:

  • (self)

Returns:

  • (self)


240
241
242
243
244
245
246
247
# File 'ext/graphics/shader.c', line 240

static VALUE Shader_set_bool(VALUE self, VALUE rb_name, VALUE rb_x) {
    char name[256];

    Shader_name(rb_name, name, sizeof(name));
    sfShader_setBoolUniform((sfShader*)Get_Shader_Struct(self), name, RTEST(rb_x));

    return self;
}

#set_bvec2(name, vector) ⇒ self

vector is a 2-element Array.

Returns:

  • (self)

Returns:

  • (self)

Raises:

  • (ArgumentError) —

    if vector has fewer than 2 elements



466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
# File 'ext/graphics/shader.c', line 466

static VALUE Shader_set_bvec2(VALUE self, VALUE rb_name, VALUE rb_vector) {
    char name[256];
    VALUE array = rb_convert_type(rb_vector, T_ARRAY, "Array", "to_ary");

    Shader_name(rb_name, name, sizeof(name));

    if (RARRAY_LEN(array) < 2) {
        raise_invalid_array_length(2);
    }

    sfShader_setBvec2Uniform(
        (sfShader*)Get_Shader_Struct(self), name,
        (sfGlslBvec2){RTEST(rb_ary_entry(array, 0)), RTEST(rb_ary_entry(array, 1))});

    return self;
}

#set_bvec3(name, vector) ⇒ self

vector is a 3-element Array.

Returns:

  • (self)

Returns:

  • (self)

Raises:

  • (ArgumentError) —

    if vector has fewer than 3 elements



491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
# File 'ext/graphics/shader.c', line 491

static VALUE Shader_set_bvec3(VALUE self, VALUE rb_name, VALUE rb_vector) {
    char name[256];
    VALUE array = rb_convert_type(rb_vector, T_ARRAY, "Array", "to_ary");

    Shader_name(rb_name, name, sizeof(name));

    if (RARRAY_LEN(array) < 3) {
        raise_invalid_array_length(3);
    }

    sfShader_setBvec3Uniform((sfShader*)Get_Shader_Struct(self), name,
                             (sfGlslBvec3){RTEST(rb_ary_entry(array, 0)),
                                           RTEST(rb_ary_entry(array, 1)),
                                           RTEST(rb_ary_entry(array, 2))});

    return self;
}

#set_bvec4(name, vector) ⇒ self

vector is a 4-element Array.

Returns:

  • (self)

Returns:

  • (self)

Raises:

  • (ArgumentError) —

    if vector has fewer than 4 elements



517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
# File 'ext/graphics/shader.c', line 517

static VALUE Shader_set_bvec4(VALUE self, VALUE rb_name, VALUE rb_vector) {
    char name[256];
    VALUE array = rb_convert_type(rb_vector, T_ARRAY, "Array", "to_ary");

    Shader_name(rb_name, name, sizeof(name));

    if (RARRAY_LEN(array) < 4) {
        raise_invalid_array_length(4);
    }

    sfShader_setBvec4Uniform(
        (sfShader*)Get_Shader_Struct(self), name,
        (sfGlslBvec4){RTEST(rb_ary_entry(array, 0)), RTEST(rb_ary_entry(array, 1)),
                      RTEST(rb_ary_entry(array, 2)), RTEST(rb_ary_entry(array, 3))});

    return self;
}

#set_color(name, color) ⇒ self

Sets a vec4 uniform from color (a Color), normalized to the 0..1 range.

Returns:

  • (self)

Returns:

  • (self)


257
258
259
260
261
262
263
264
# File 'ext/graphics/shader.c', line 257

static VALUE Shader_set_color(VALUE self, VALUE rb_name, VALUE rb_color) {
    char name[256];

    Shader_name(rb_name, name, sizeof(name));
    sfShader_setColorUniform((sfShader*)Get_Shader_Struct(self), name, color_from_rb(rb_color));

    return self;
}

#set_current_texture(name) ⇒ self

Binds the target's own currently-bound texture (CSFML's "current texture" special value) to the sampler uniform name.

Returns:

  • (self)

Returns:

  • (self)


653
654
655
656
657
658
659
660
# File 'ext/graphics/shader.c', line 653

static VALUE Shader_set_current_texture(VALUE self, VALUE rb_name) {
    char name[256];

    Shader_name(rb_name, name, sizeof(name));
    sfShader_setCurrentTextureUniform((sfShader*)Get_Shader_Struct(self), name);

    return self;
}

#set_float(name, x) ⇒ self

Sets the name uniform to a single Float.

Returns:

  • (self)

Returns:

  • (self)


208
209
210
211
212
213
214
215
# File 'ext/graphics/shader.c', line 208

static VALUE Shader_set_float(VALUE self, VALUE rb_name, VALUE rb_x) {
    char name[256];

    Shader_name(rb_name, name, sizeof(name));
    sfShader_setFloatUniform((sfShader*)Get_Shader_Struct(self), name, NUM2DBL(rb_x));

    return self;
}

#set_float_array(name, values) ⇒ self

Sets the name uniform to an Array of Floats.

Returns:

  • (self)

#set_int(name, x) ⇒ self

Sets the name uniform to a single Integer.

Returns:

  • (self)

Returns:

  • (self)


224
225
226
227
228
229
230
231
# File 'ext/graphics/shader.c', line 224

static VALUE Shader_set_int(VALUE self, VALUE rb_name, VALUE rb_x) {
    char name[256];

    Shader_name(rb_name, name, sizeof(name));
    sfShader_setIntUniform((sfShader*)Get_Shader_Struct(self), name, NUM2INT(rb_x));

    return self;
}

#set_int_color(name, color) ⇒ self

Sets an ivec4 uniform from color (a Color), in the 0..255 range.

Returns:

  • (self)

Returns:

  • (self)


273
274
275
276
277
278
279
280
# File 'ext/graphics/shader.c', line 273

static VALUE Shader_set_int_color(VALUE self, VALUE rb_name, VALUE rb_color) {
    char name[256];

    Shader_name(rb_name, name, sizeof(name));
    sfShader_setIntColorUniform((sfShader*)Get_Shader_Struct(self), name, color_from_rb(rb_color));

    return self;
}

#set_ivec2(name, vector) ⇒ self

Sets the name uniform to a Vector2 of Integers.

Returns:

  • (self)

Returns:

  • (self)


390
391
392
393
394
395
396
397
398
399
# File 'ext/graphics/shader.c', line 390

static VALUE Shader_set_ivec2(VALUE self, VALUE rb_name, VALUE rb_vector) {
    char name[256];
    sfVector2f vec = vec2f_from_rb(rb_vector);

    Shader_name(rb_name, name, sizeof(name));
    sfShader_setIvec2Uniform((sfShader*)Get_Shader_Struct(self), name,
                             (sfGlslIvec2){(int)vec.x, (int)vec.y});

    return self;
}

#set_ivec3(name, vector) ⇒ self

vector is a 3-element Array.

Returns:

  • (self)

Returns:

  • (self)

Raises:

  • (ArgumentError) —

    if vector has fewer than 3 elements



409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
# File 'ext/graphics/shader.c', line 409

static VALUE Shader_set_ivec3(VALUE self, VALUE rb_name, VALUE rb_vector) {
    char name[256];
    VALUE array = rb_convert_type(rb_vector, T_ARRAY, "Array", "to_ary");
    sfGlslIvec3 vector;

    Shader_name(rb_name, name, sizeof(name));

    if (RARRAY_LEN(array) < 3) {
        raise_invalid_array_length(3);
    }

    vector.x = NUM2INT(rb_ary_entry(array, 0));
    vector.y = NUM2INT(rb_ary_entry(array, 1));
    vector.z = NUM2INT(rb_ary_entry(array, 2));

    sfShader_setIvec3Uniform((sfShader*)Get_Shader_Struct(self), name, vector);

    return self;
}

#set_ivec4(name, vector) ⇒ self

vector is a 4-element Array.

Returns:

  • (self)

Returns:

  • (self)

Raises:

  • (ArgumentError) —

    if vector has fewer than 4 elements



437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
# File 'ext/graphics/shader.c', line 437

static VALUE Shader_set_ivec4(VALUE self, VALUE rb_name, VALUE rb_vector) {
    char name[256];
    VALUE array = rb_convert_type(rb_vector, T_ARRAY, "Array", "to_ary");
    sfGlslIvec4 vector;

    Shader_name(rb_name, name, sizeof(name));

    if (RARRAY_LEN(array) < 4) {
        raise_invalid_array_length(4);
    }

    vector.x = NUM2INT(rb_ary_entry(array, 0));
    vector.y = NUM2INT(rb_ary_entry(array, 1));
    vector.z = NUM2INT(rb_ary_entry(array, 2));
    vector.w = NUM2INT(rb_ary_entry(array, 3));

    sfShader_setIvec4Uniform((sfShader*)Get_Shader_Struct(self), name, vector);

    return self;
}

#set_mat3(name, matrix) ⇒ self

matrix is a 9-element Array.

Returns:

  • (self)

Returns:

  • (self)

Raises:

  • (ArgumentError) —

    if matrix has fewer than 9 elements



543
544
545
546
547
548
549
550
551
552
# File 'ext/graphics/shader.c', line 543

static VALUE Shader_set_mat3(VALUE self, VALUE rb_name, VALUE rb_matrix) {
    char name[256];
    sfGlslMat3 matrix = glsl_mat3_from_rb(rb_matrix);

    Shader_name(rb_name, name, sizeof(name));

    sfShader_setMat3Uniform((sfShader*)Get_Shader_Struct(self), name, &matrix);

    return self;
}

#set_mat3_array(name, values) ⇒ self

values is an Array of 9-element Arrays.

Returns:

  • (self)

#set_mat4(name, matrix) ⇒ self

matrix is a 16-element Array.

Returns:

  • (self)

Returns:

  • (self)

Raises:

  • (ArgumentError) —

    if matrix has fewer than 16 elements



562
563
564
565
566
567
568
569
570
571
# File 'ext/graphics/shader.c', line 562

static VALUE Shader_set_mat4(VALUE self, VALUE rb_name, VALUE rb_matrix) {
    char name[256];
    sfGlslMat4 matrix = glsl_mat4_from_rb(rb_matrix);

    Shader_name(rb_name, name, sizeof(name));

    sfShader_setMat4Uniform((sfShader*)Get_Shader_Struct(self), name, &matrix);

    return self;
}

#set_mat4_array(name, values) ⇒ self

values is an Array of 16-element Arrays.

Returns:

  • (self)

#set_texture(name, texture) ⇒ Texture

SFML keeps and re-binds a pointer to texture internally (rather than copying it) for as long as the shader may use it; this binding keeps a reference alongside it so the Texture can't be GC'd out from under the shader. CSFML's C API unconditionally dereferences the texture argument, so unlike most other uniform setters here, nil is not accepted.

Returns:

Returns:

Raises:

  • (ArgumentError) —

    if texture is not a Texture

#set_uniform(name, value) ⇒ self #uniform=(name, value) ⇒ self

Sets the uniform name, dispatching to the appropriate set_* method based on +value+'s class: Color, Texture, Vector2, Vector3, true/false, Integer, Float, or an Array (dispatched by length: 2 -> vec2, 3 -> vec3, 4 -> vec4, 9 -> mat3, 16 -> mat4).

Overloads:

  • #set_uniform(name, value) ⇒ self

    Returns:

    • (self)
  • #uniform=(name, value) ⇒ self

    Returns:

    • (self)

Returns:

  • (self)

Raises:

  • (ArgumentError) —

    if +value+'s class/length isn't recognized



674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
# File 'ext/graphics/shader.c', line 674

static VALUE Shader_set_uniform(VALUE self, VALUE rb_name, VALUE rb_value) {
    if (rb_obj_is_kind_of(rb_value, Get_Klass_Color())) {
        return Shader_set_color(self, rb_name, rb_value);
    }

    if (rb_obj_is_kind_of(rb_value, Get_Klass_Texture())) {
        return Shader_set_texture(self, rb_name, rb_value);
    }

    if (rb_obj_is_kind_of(rb_value, Get_Klass_Vector2())) {
        return Shader_set_vec2(self, rb_name, rb_value);
    }

    if (rb_obj_is_kind_of(rb_value, Get_Klass_Vector3())) {
        return Shader_set_vec3(self, rb_name, rb_value);
    }

    if (rb_value == Qtrue || rb_value == Qfalse) {
        return Shader_set_bool(self, rb_name, rb_value);
    }

    if (RB_INTEGER_TYPE_P(rb_value)) {
        return Shader_set_int(self, rb_name, rb_value);
    }

    if (RB_FLOAT_TYPE_P(rb_value)) {
        return Shader_set_float(self, rb_name, rb_value);
    }

    if (RB_TYPE_P(rb_value, T_ARRAY)) {
        long length = RARRAY_LEN(rb_value);

        if (length == 2) {
            return Shader_set_vec2(self, rb_name, rb_value);
        }

        if (length == 3) {
            return Shader_set_vec3(self, rb_name, rb_value);
        }

        if (length == 4) {
            return Shader_set_vec4(self, rb_name, rb_value);
        }

        if (length == 9) {
            return Shader_set_mat3(self, rb_name, rb_value);
        }

        if (length == 16) {
            return Shader_set_mat4(self, rb_name, rb_value);
        }
    }

    rb_raise(rb_eArgError, "unsupported shader uniform value");
    return self;
}

#set_vec2(name, vector) ⇒ self

Sets the name uniform to a Vector2.

Returns:

  • (self)

Returns:

  • (self)


289
290
291
292
293
294
295
296
# File 'ext/graphics/shader.c', line 289

static VALUE Shader_set_vec2(VALUE self, VALUE rb_name, VALUE rb_vector) {
    char name[256];

    Shader_name(rb_name, name, sizeof(name));
    sfShader_setVec2Uniform((sfShader*)Get_Shader_Struct(self), name, vec2f_from_rb(rb_vector));

    return self;
}

#set_vec2_array(name, values) ⇒ self

Sets the name uniform to an Array of Vector2 values.

Returns:

  • (self)

#set_vec3(name, vector) ⇒ self

Sets the name uniform to a Vector3.

Returns:

  • (self)

Returns:

  • (self)


305
306
307
308
309
310
311
312
# File 'ext/graphics/shader.c', line 305

static VALUE Shader_set_vec3(VALUE self, VALUE rb_name, VALUE rb_vector) {
    char name[256];

    Shader_name(rb_name, name, sizeof(name));
    sfShader_setVec3Uniform((sfShader*)Get_Shader_Struct(self), name, vec3f_from_rb(rb_vector));

    return self;
}

#set_vec3_array(name, values) ⇒ self

Sets the name uniform to an Array of Vector3 values.

Returns:

  • (self)

#set_vec4(name, vector) ⇒ self

vector is a 4-element Array.

Returns:

  • (self)

Returns:

  • (self)

Raises:

  • (ArgumentError) —

    if vector has fewer than 4 elements



372
373
374
375
376
377
378
379
380
381
# File 'ext/graphics/shader.c', line 372

static VALUE Shader_set_vec4(VALUE self, VALUE rb_name, VALUE rb_vector) {
    char name[256];
    sfGlslVec4 vector = glsl_vec4_from_rb(rb_vector);

    Shader_name(rb_name, name, sizeof(name));

    sfShader_setVec4Uniform((sfShader*)Get_Shader_Struct(self), name, vector);

    return self;
}

#set_vec4_array(name, values) ⇒ self

values is an Array of 4-element Arrays.

Returns:

  • (self)

#set_uniform(name, value) ⇒ self #uniform=(name, value) ⇒ self

Sets the uniform name, dispatching to the appropriate set_* method based on +value+'s class: Color, Texture, Vector2, Vector3, true/false, Integer, Float, or an Array (dispatched by length: 2 -> vec2, 3 -> vec3, 4 -> vec4, 9 -> mat3, 16 -> mat4).

Overloads:

  • #set_uniform(name, value) ⇒ self

    Returns:

    • (self)
  • #uniform=(name, value) ⇒ self

    Returns:

    • (self)

Returns:

  • (self)

Raises:

  • (ArgumentError) —

    if +value+'s class/length isn't recognized



674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
# File 'ext/graphics/shader.c', line 674

static VALUE Shader_set_uniform(VALUE self, VALUE rb_name, VALUE rb_value) {
    if (rb_obj_is_kind_of(rb_value, Get_Klass_Color())) {
        return Shader_set_color(self, rb_name, rb_value);
    }

    if (rb_obj_is_kind_of(rb_value, Get_Klass_Texture())) {
        return Shader_set_texture(self, rb_name, rb_value);
    }

    if (rb_obj_is_kind_of(rb_value, Get_Klass_Vector2())) {
        return Shader_set_vec2(self, rb_name, rb_value);
    }

    if (rb_obj_is_kind_of(rb_value, Get_Klass_Vector3())) {
        return Shader_set_vec3(self, rb_name, rb_value);
    }

    if (rb_value == Qtrue || rb_value == Qfalse) {
        return Shader_set_bool(self, rb_name, rb_value);
    }

    if (RB_INTEGER_TYPE_P(rb_value)) {
        return Shader_set_int(self, rb_name, rb_value);
    }

    if (RB_FLOAT_TYPE_P(rb_value)) {
        return Shader_set_float(self, rb_name, rb_value);
    }

    if (RB_TYPE_P(rb_value, T_ARRAY)) {
        long length = RARRAY_LEN(rb_value);

        if (length == 2) {
            return Shader_set_vec2(self, rb_name, rb_value);
        }

        if (length == 3) {
            return Shader_set_vec3(self, rb_name, rb_value);
        }

        if (length == 4) {
            return Shader_set_vec4(self, rb_name, rb_value);
        }

        if (length == 9) {
            return Shader_set_mat3(self, rb_name, rb_value);
        }

        if (length == 16) {
            return Shader_set_mat4(self, rb_name, rb_value);
        }
    }

    rb_raise(rb_eArgError, "unsupported shader uniform value");
    return self;
}