Class: GlimR::Texture
- Inherits:
-
SceneObject
- Object
- SceneObject
- GlimR::Texture
- Defined in:
- lib/glimr/renderer/texture.rb
Overview
A Texture is a wrapper around an OpenGL texture object. It generates a texture id when it is first used.
To load a texture from an image file, use Texture.load(image_filename) or Texture#load(image_filename).
The #width and #height of a texture refer to the dimensions of the loaded image, while the #bound of a texture is the closest containing power of two for the image dimensions (as in, the texture dimensions are a power of two square, inside which the image is stamped.)
The #mode of a texture is GL::TEXTURE_2D. If feeling particularly adventurous, extend the class to do rectangular textures, non-power-of-two textures, 1D and 3D textures.
Uses SDL, Imlib2, or RMagick to load images. If you have none of these, trying to load texture images will fail.
Instance Attribute Summary collapse
-
#bound ⇒ Object
Returns the smallest power of two that is larger or equal to the larger of width and height.
-
#filename ⇒ Object
readonly
Returns the value of attribute filename.
-
#height ⇒ Object
Returns the value of attribute height.
-
#mode ⇒ Object
Returns the value of attribute mode.
-
#pixels ⇒ Object
Returns the value of attribute pixels.
-
#tex_id ⇒ Object
readonly
Returns the value of attribute tex_id.
-
#width ⇒ Object
Returns the value of attribute width.
Attributes inherited from SceneObject
#children, #drawables, #mtime, #parent, #viewport
Attributes included from EventListener
#event_listeners, #listener_count
Class Method Summary collapse
-
.load(filename) ⇒ Object
Creates a new Texture from the given image filename.
Instance Method Summary collapse
-
#absolute_texture ⇒ Object
The collapsed texture for a texture is the texture itself.
-
#apply ⇒ Object
Bind tex_id as the OpenGL texture and upload the texture if it has been changed since last use.
- #default_config ⇒ Object
-
#finish ⇒ Object
Deletes the OpenGL texture object.
-
#initialize(*a, &b) ⇒ Texture
constructor
A new instance of Texture.
- #inspect ⇒ Object
-
#load(filename) ⇒ Object
Loads the image filename into the texture.
-
#pop_state ⇒ Object
Pops the GL attrib stack.
- #power_of_two?(n) ⇒ Boolean
-
#push_state ⇒ Object
Pushes GL::TEXTURE_BIT to attrib stack.
-
#replace!(other) ⇒ Object
Replace main instance variables with the other’s.
-
#upload_texture ⇒ Object
Uploads the texture to OpenGL.
Methods inherited from SceneObject
#<<, #absolute_geometry, #absolute_material, #absolute_shader, #absolute_transform, #absolute_transform_for_drawing, #add_drawables, #attach, #clone, #detach, #detach_self, #remove_drawables, #render, #replace_node, #root, #touch!, #visible
Methods included from EventListener
#add_event_listener, #decrement_listener_count, #dispatch_event, #event_root, #increment_listener_count, #method_missing, #multicast_event, #process_event, #remove_event_listener
Constructor Details
#initialize(*a, &b) ⇒ Texture
Returns a new instance of Texture.
62 63 64 65 |
# File 'lib/glimr/renderer/texture.rb', line 62 def initialize(*a, &b) @tex_id = [] super end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class GlimR::EventListener
Instance Attribute Details
#bound ⇒ Object
Returns the smallest power of two that is larger or equal to the larger of width and height.
167 168 169 |
# File 'lib/glimr/renderer/texture.rb', line 167 def bound @bound end |
#filename ⇒ Object (readonly)
Returns the value of attribute filename.
46 47 48 |
# File 'lib/glimr/renderer/texture.rb', line 46 def filename @filename end |
#height ⇒ Object
Returns the value of attribute height.
45 46 47 |
# File 'lib/glimr/renderer/texture.rb', line 45 def height @height end |
#mode ⇒ Object
Returns the value of attribute mode.
45 46 47 |
# File 'lib/glimr/renderer/texture.rb', line 45 def mode @mode end |
#pixels ⇒ Object
Returns the value of attribute pixels.
45 46 47 |
# File 'lib/glimr/renderer/texture.rb', line 45 def pixels @pixels end |
#tex_id ⇒ Object (readonly)
Returns the value of attribute tex_id.
46 47 48 |
# File 'lib/glimr/renderer/texture.rb', line 46 def tex_id @tex_id end |
#width ⇒ Object
Returns the value of attribute width.
45 46 47 |
# File 'lib/glimr/renderer/texture.rb', line 45 def width @width end |
Class Method Details
.load(filename) ⇒ Object
Creates a new Texture from the given image filename.
56 57 58 59 60 |
# File 'lib/glimr/renderer/texture.rb', line 56 def self.load(filename) t = new t.load(filename) t end |
Instance Method Details
#absolute_texture ⇒ Object
The collapsed texture for a texture is the texture itself.
68 69 70 |
# File 'lib/glimr/renderer/texture.rb', line 68 def absolute_texture self end |
#apply ⇒ Object
Bind tex_id as the OpenGL texture and upload the texture if it has been changed since last use.
121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/glimr/renderer/texture.rb', line 121 def apply return unless pixels Enable(mode) if not @tex_id[0] @tex_id[0] = GenTextures(1)[0] push_state BindTexture(mode, @tex_id[0]) upload_texture pop_state end BindTexture(mode, @tex_id[0]) upload_texture if @changed end |
#default_config ⇒ Object
48 49 50 51 52 53 |
# File 'lib/glimr/renderer/texture.rb', line 48 def default_config super.merge( :mode => TEXTURE_2D, :width => 0, :height => 0 ) end |
#finish ⇒ Object
Deletes the OpenGL texture object.
114 115 116 117 |
# File 'lib/glimr/renderer/texture.rb', line 114 def finish DeleteTextures(@tex_id) @tex_id.clear end |
#inspect ⇒ Object
233 234 235 |
# File 'lib/glimr/renderer/texture.rb', line 233 def inspect "#<#{self.class.name}:#{hash}:TEXID#@tex_id:FILE:#@filename:MODE#@mode:W#@width:H#@height:B#@bound>" end |
#load(filename) ⇒ Object
Loads the image filename into the texture.
73 74 75 76 77 78 79 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 109 110 111 |
# File 'lib/glimr/renderer/texture.rb', line 73 def load(filename) if $sdl surf = SDL::Surface.load(filename.to_s) if surf.bpp < 32 rmask = 0xff000000 gmask = 0x00ff0000 bmask = 0x0000ff00 amask = 0x000000ff image = SDL::Surface.new( SDL::SWSURFACE|SDL::SRCALPHA, surf.w, surf.h, 32, amask,bmask,gmask,rmask) image.put(surf,0,0) else image = surf end w = image.w h = image.h px = image.pixels elsif $imlib image = Imlib2::Image.load(filename.to_s) w = image.width h = image.height px = image.data.gsub(/(.)(.)(.)(.)/, '\2\3\4\1') elsif $rmagick image = Magick::Image.read(filename.to_s).first w = image.width h = image.height px = image.to_blob{|i| i.format = "RGBA" i.depth = 8 } end @filename = filename self.mode = TEXTURE_2D self.width = w.to_i self.height = h.to_i self.pixels = px + "" end |
#pop_state ⇒ Object
Pops the GL attrib stack.
160 161 162 |
# File 'lib/glimr/renderer/texture.rb', line 160 def pop_state PopAttrib() end |
#power_of_two?(n) ⇒ Boolean
135 136 137 |
# File 'lib/glimr/renderer/texture.rb', line 135 def power_of_two?(n) (n & (n - 1) == 0) end |
#push_state ⇒ Object
Pushes GL::TEXTURE_BIT to attrib stack.
155 156 157 |
# File 'lib/glimr/renderer/texture.rb', line 155 def push_state PushAttrib(TEXTURE_BIT) end |
#replace!(other) ⇒ Object
Replace main instance variables with the other’s. Namely: @tex_id, @bound, @bound_pixels, @width, @height, @pixels, @changed, @mode.
Use this to swap a texture for another when you want to preserve the rest of the state.
But beware, the current texture is lost unless you copy it somewhere else first.
E.g.
t = Texture.load 'foo.jpg'
backup = Texture.new
backup.replace! deep_texture_node
deep_texture_node.replace! t
219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/glimr/renderer/texture.rb', line 219 def replace!(other) @tex_id = other.tex_id @bound = other.instance_variable_get(:@bound) @bound_pixels = other.instance_variable_get(:@bound_pixels) @width = other.instance_variable_get(:@width) @height = other.instance_variable_get(:@height) @pixels = other.instance_variable_get(:@pixels) @changed = other.instance_variable_get(:@changed) @mode = other.instance_variable_get(:@mode) self end |
#upload_texture ⇒ Object
Uploads the texture to OpenGL. Uses TexImage2D if the texture dimensions have changed since last upload, otherwise uses TexSubImage2D.
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/glimr/renderer/texture.rb', line 180 def upload_texture if !@bound @bound = self.bound @bound_pixels = "\000"*(4*@bound*@bound) TexImage2D( mode, 0, 4, @bound, @bound, 0, RGBA, UNSIGNED_BYTE, @bound_pixels ) end TexSubImage2D( mode, 0, 0, 0, width, height, RGBA, UNSIGNED_BYTE, pixels ) TexParameteri(mode, TEXTURE_WRAP_S, CLAMP) TexParameteri(mode, TEXTURE_WRAP_T, CLAMP) TexParameteri(mode, TEXTURE_MIN_FILTER, LINEAR) TexParameteri(mode, TEXTURE_MAG_FILTER, LINEAR) @changed = false end |