Class: Nuklear::Renderer
- Inherits:
-
Object
- Object
- Nuklear::Renderer
- Defined in:
- lib/nuklear/renderer.rb,
lib/nuklear/renderer/opengl24.rb,
ext/nuklear/nkrb_renderer.c,
ext/nuklear_renderer_opengl2/nuklear_renderer_opengl2.c,
ext/nuklear_renderer_opengl4/nuklear_renderer_opengl4.c
Overview
This base class provides a pure-Ruby renderer implementation for Nuklear. Importantly, it doesn’t actually draw anything. Instead it provides a generic renderer implementation where subclasses need only override the #draw method to draw something.
In most cases, subclasses will also have to override #initialize to set up one-time state (e.g. compiling shaders), and also #render to set up per-frame state (e.g. activating shaders). In both cases, subclasses should call ‘super`.
Defined Under Namespace
Constant Summary collapse
- Vertex =
Fiddle::Importer.struct [ 'float position[3]', 'float uv[3]', 'unsigned char color[4]' ]
Instance Attribute Summary collapse
-
#commands ⇒ Object
readonly
Nuklear::Buffer containing command data.
-
#context ⇒ Object
readonly
Nuklear::Context for this renderer.
-
#convert_config ⇒ Object
Returns the configuration necessary for converting a Nuklear rendering pass into a renderer-specific one.
- #drawable_size ⇒ Object
-
#null_texture_handle ⇒ Object
Assign the handle for a 1x1 white texture to this accessor.
-
#vertex_indices ⇒ Object
readonly
Nuklear::Buffer containing vertex index data.
-
#vertices ⇒ Object
readonly
Nuklear::Buffer containing vertex data.
-
#window_size ⇒ Object
Returns the value of attribute window_size.
Class Method Summary collapse
Instance Method Summary collapse
-
#draw(cmd) ⇒ Object
Called for each Nuklear draw command, numerous times per render pass.
-
#initialize ⇒ Renderer
constructor
For all renderer implementations, override #initialize to set up your initial state (e.g. compiling shaders) and call ‘super`.
- #nk_convert(rcontext) ⇒ Object
- #nk_draw_foreach(rcontext) ⇒ Object
-
#render(context) ⇒ Object
Called at the start of a render pass.
Constructor Details
#initialize ⇒ Renderer
For all renderer implementations, override #initialize to set up your initial state (e.g. compiling shaders) and call ‘super`.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/nuklear/renderer.rb', line 49 def initialize @commands = Nuklear::Buffer.new @vertices = Nuklear::Buffer.new @vertex_indices = Nuklear::Buffer.new @window_size = [640, 480] @drawable_size = nil @null_texture_handle = 0 @convert_config = { vertex_layout: [ [:position, :float, Vertex.offsetof('position')], [:texcoord, :float, Vertex.offsetof('uv')], [:color, :r8g8b8a8, Vertex.offsetof('color')] ], vertex_size: Vertex.size, vertex_alignment: Vertex.alignment, null: null_texture_handle, circle_segment_count: 22, curve_segment_count: 22, arc_segment_count: 22, global_alpha: 1.0, shape_aa: true, line_aa: true } end |
Instance Attribute Details
#commands ⇒ Object (readonly)
Nuklear::Buffer containing command data
36 37 38 |
# File 'lib/nuklear/renderer.rb', line 36 def commands @commands end |
#context ⇒ Object (readonly)
Nuklear::Context for this renderer
39 40 41 |
# File 'lib/nuklear/renderer.rb', line 39 def context @context end |
#convert_config ⇒ Object
Returns the configuration necessary for converting a Nuklear rendering pass into a renderer-specific one. This data can be changed at run-time; it is not cached.
21 22 23 |
# File 'lib/nuklear/renderer.rb', line 21 def convert_config @convert_config end |
#drawable_size ⇒ Object
79 80 81 |
# File 'lib/nuklear/renderer.rb', line 79 def drawable_size @drawable_size || window_size end |
#null_texture_handle ⇒ Object
Assign the handle for a 1x1 white texture to this accessor. It doesn’t matter what format this takes, (GL texture ID, memory address of texture data, etc), as long as the renderer can decode this into a usable result when it’s passed back to it later on.
27 28 29 |
# File 'lib/nuklear/renderer.rb', line 27 def null_texture_handle @null_texture_handle end |
#vertex_indices ⇒ Object (readonly)
Nuklear::Buffer containing vertex index data
33 34 35 |
# File 'lib/nuklear/renderer.rb', line 33 def vertex_indices @vertex_indices end |
#vertices ⇒ Object (readonly)
Nuklear::Buffer containing vertex data
30 31 32 |
# File 'lib/nuklear/renderer.rb', line 30 def vertices @vertices end |
#window_size ⇒ Object
Returns the value of attribute window_size.
15 16 17 |
# File 'lib/nuklear/renderer.rb', line 15 def window_size @window_size end |
Class Method Details
.renderer_class ⇒ Object
3 4 5 6 7 8 9 10 11 |
# File 'lib/nuklear/renderer/opengl24.rb', line 3 def self.renderer_class if SDL2::GL.get_attribute(SDL2::GL::CONTEXT_MAJOR_VERSION) > 2 require 'nuklear_renderer_opengl4' Nuklear::Renderer::OpenGL4 else require 'nuklear_renderer_opengl2' Nuklear::Renderer::OpenGL2 end end |
Instance Method Details
#draw(cmd) ⇒ Object
Called for each Nuklear draw command, numerous times per render pass. Renderers should override this method to actually draw something, but keep this method as lightweight as possible.
‘element_count`: The number of elements to be drawn. `clip_rect`: An array containing the x, y, width and height
(in that order) of the region to be drawn to.
‘texture_handle`: The handle of a texture to be drawn. See
#null_texture_handle.
‘offset`: The number of elements already drawn, not including the
current command.
103 104 105 |
# File 'lib/nuklear/renderer.rb', line 103 def draw(cmd) end |
#nk_convert(rcontext) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'ext/nuklear/nkrb_renderer.c', line 36
VALUE nkrb_renderer_convert(VALUE self, VALUE rcontext) {
struct nk_context *context = NULL;
struct nk_buffer *commands = NULL;
struct nk_buffer *vertices = NULL;
struct nk_buffer *indices = NULL;
Data_Get_Struct(rcontext, struct nk_context, context);
Data_Get_Struct(rb_funcall(self, rb_intern("commands"), 0), struct nk_buffer, commands);
Data_Get_Struct(rb_funcall(self, rb_intern("vertices"), 0), struct nk_buffer, vertices);
Data_Get_Struct(rb_funcall(self, rb_intern("vertex_indices"), 0), struct nk_buffer, indices);
VALUE rconfig = rb_funcall(self, rb_intern("convert_config"), 0);
VALUE rvertex_layout = rb_hash_aref(rconfig, ID2SYM(rb_intern("vertex_layout")));
struct nk_convert_config config;
struct nk_draw_vertex_layout_element *vertex_layout = alloca((RARRAY_LEN(rvertex_layout) + 1) * sizeof(struct nk_draw_vertex_layout_element));
for (int i = 0; i < RARRAY_LEN(rvertex_layout); i++) {
VALUE rlayout = RARRAY_AREF(rvertex_layout, i);
vertex_layout[i].attribute = rb2nk_attribute(RARRAY_AREF(rlayout, 0));
vertex_layout[i].format = rb2nk_format(RARRAY_AREF(rlayout, 1));
vertex_layout[i].offset = FIX2INT(RARRAY_AREF(rlayout, 2));
}
vertex_layout[RARRAY_LEN(rvertex_layout)].attribute = NK_VERTEX_LAYOUT_END;
memset(&config, 0, sizeof(config));
config.vertex_layout = vertex_layout;
config.vertex_size = FIX2INT(rb_hash_aref(rconfig, ID2SYM(rb_intern("vertex_size"))));
config.vertex_alignment = FIX2INT(rb_hash_aref(rconfig, ID2SYM(rb_intern("vertex_alignment"))));
config.null.texture = (nk_handle) (void *) NUM2ULL(rb_hash_aref(rconfig, ID2SYM(rb_intern("null"))));
config.circle_segment_count = NUM2UINT(rb_hash_aref(rconfig, ID2SYM(rb_intern("circle_segment_count"))));
config.curve_segment_count = NUM2UINT(rb_hash_aref(rconfig, ID2SYM(rb_intern("curve_segment_count"))));
config.arc_segment_count = NUM2UINT(rb_hash_aref(rconfig, ID2SYM(rb_intern("arc_segment_count"))));
config.global_alpha = (float) NUM2DBL(rb_hash_aref(rconfig, ID2SYM(rb_intern("global_alpha"))));
config.shape_AA = RTEST(rb_hash_aref(rconfig, ID2SYM(rb_intern("shape_aa")))) ? NK_ANTI_ALIASING_ON : NK_ANTI_ALIASING_OFF;
config.line_AA = RTEST(rb_hash_aref(rconfig, ID2SYM(rb_intern("line_aa")))) ? NK_ANTI_ALIASING_ON : NK_ANTI_ALIASING_OFF;
// all that for this
nk_flags result = nk_convert(context, commands, vertices, indices, &config);
switch(result) {
case NK_CONVERT_SUCCESS: break; // OK
case NK_CONVERT_INVALID_PARAM: rb_raise(rb_eRuntimeError, "Nuklear error: INVALID_PARAM");
case NK_CONVERT_COMMAND_BUFFER_FULL: rb_raise(rb_eRuntimeError, "Nuklear error: COMMAND_BUFFER_FULL");
case NK_CONVERT_VERTEX_BUFFER_FULL: rb_raise(rb_eRuntimeError, "Nuklear error: VERTEX_BUFFER_FULL");
case NK_CONVERT_ELEMENT_BUFFER_FULL: rb_raise(rb_eRuntimeError, "Nuklear error: ELEMENT_BUFFER_FULL");
default: rb_raise(rb_eRuntimeError, "Nuklear error: %d (unknown)", result);
}
return self;
}
|
#nk_draw_foreach(rcontext) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'ext/nuklear/nkrb_renderer.c', line 80
VALUE nkrb_renderer_draw_foreach(VALUE self, VALUE rcontext) {
struct nk_context *context = NULL;
struct nk_buffer *commands = NULL;
Data_Get_Struct(rcontext, struct nk_context, context);
Data_Get_Struct(rb_funcall(self, rb_intern("commands"), 0), struct nk_buffer, commands);
/* convert from command queue into draw list and draw to screen */
const struct nk_draw_command *cmd;
// const nk_draw_index *offset = NULL;
/* iterate over and execute each draw command */
int offset = 0;
nk_draw_foreach(cmd, context, commands) {
if (!cmd->elem_count) continue;
VALUE rcmd = rb_hash_new();
VALUE rclip_rect = rb_ary_new2(4);
rb_ary_store(rclip_rect, 0, DBL2NUM(cmd->clip_rect.x));
rb_ary_store(rclip_rect, 1, DBL2NUM(cmd->clip_rect.y));
rb_ary_store(rclip_rect, 2, DBL2NUM(cmd->clip_rect.w));
rb_ary_store(rclip_rect, 3, DBL2NUM(cmd->clip_rect.h));
rb_hash_aset(rcmd, ID2SYM(rb_intern("element_count")), INT2NUM(cmd->elem_count));
rb_hash_aset(rcmd, ID2SYM(rb_intern("texture_handle")), ULL2NUM((unsigned long long) cmd->texture.ptr));
rb_hash_aset(rcmd, ID2SYM(rb_intern("clip_rect")), rclip_rect);
rb_hash_aset(rcmd, ID2SYM(rb_intern("offset")), INT2NUM(offset));
rb_yield(rcmd);
offset += cmd->elem_count;
}
return self;
}
|
#render(context) ⇒ Object
Called at the start of a render pass. Renderers may wish to override this method to apply once-per-frame state updates. They should call ‘super` when they are ready to proceed.
86 87 88 89 |
# File 'lib/nuklear/renderer.rb', line 86 def render(context) nk_convert(context) nk_draw_foreach(context) { |command| draw(command) } end |