Not logged inGosu Forums
Forum back to libgosu.org Help Search Register Login
Up Topic Gosu / Gosu Exchange / A more stable OpenGL ruby implementation ?
- - By bestguigui Date 2013-06-22 08:31
Hi all ! It's been a long time !

I have an annoying problem which causes an OpenGL error when I'm drawing something in 3D using the deprecated way of immediate drawing (glBegin...glEnd).
For an unknown reason, when I'm using variables to draw, in something like :

glBegin(GL_QUADS)
  glVertex3f(0.0, 0.0, 0.0)
  glVertex3f(@width, 0.0, 0.0)
  glVertex3f(@width, @height, 0.0)
  glVertex3f(0.0, @height, 0.0)
glEnd

the program happens to crash with an OpenGL error exception. It's not something that happens anytime, but really sometimes... I read a lot about it, it seems to be the exception that OpenGL throws when you're doing another OpenGL call inside the glBegin...glEnd block. I'm not sure about this, but it seems that using a variable in Ruby OpenGL is sometimes considered as calling another OpenGL function.

I never had this problem when I used OpenGL in a C or C++ environnement, and this crash does not even occur everytime I launch my program.

I tried to intercept it using a begin rescue structure, which makes the program running quite nice with a rare black "splash" screen with a 1 frame duration, then the scene is back to normal. Sometimes (even more rare) the program still crashes.

This is really a pain ! Since this is totally random, I don't think my way of coding this drawing is in cause. Since Ruby OpenGL is not that used, I can't find any help and trust me : I looked into it a lot.

Can someone help me with this ?

Thanks a lot !
Guigui
Parent - - By jlnr (dev) Date 2013-06-22 09:49
Can you log these variables every time before you feed them into glVertex3f? I wouldn't be surprised if the OpenGL gem causes errors and crashes when you accidentally pass nil in, or some other value that it doesn't expect.
Parent - By bestguigui Date 2013-06-22 10:01 Edited 2013-06-22 11:56
I'll try. The hard issue here is to reproduce this problem, as it seems random like I said earlier. I'll try to create this context is a smaller program and report here, thanks for this idea it might actually be the problem ;)

EDIT : I tried to use a nil value directly, I get this error :  `glVertex3f': no implicit conversion to float from nil (TypeError)
which is not the GL::Error I usually get with the "bug" (GL_INVALID_OPERATION).

Maybe it's time for me to use Vertex Arrays instead... Seems to work quite good.

EDIT 2 : if it can be useful to anybody or if something seems odd, here is my first OBJ FILE loader using vertex arrays. It only supports one texture and no color, because I needed that and nothing more.

require "scanf"

class GLTexture
  def initialize(p_win, filename)
    filename.is_a?(Gosu::Image) ? gosu_image = filename : gosu_image = Gosu::Image.new(p_win, filename, true)
    array_of_pixels = gosu_image.to_blob
    @texture_id = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, @texture_id[0])
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, gosu_image.width, gosu_image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, array_of_pixels)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    gosu_image = nil
  end

  def get_id
    return @texture_id[0]
  end
end

class ObjModel
  def initialize(filename)
    @v, @vt, @vn = Array.new, Array.new, Array.new
    v, vt, vn = Array.new, Array.new, Array.new
    File.open(filename).readlines.each do |line|
      if line.include?("v  ")
        v << line.chomp.scanf("v  %f %f %f")
      elsif line.include?("vt  ")
        vt << line.chomp.scanf("vt  %f %f %f")
        vt.last[1] = 1.0 - vt.last[1] # vertical mirror fix
      elsif line.include?("vn  ")
        vn << line.chomp.scanf("vn  %f %f %f")
      elsif line.include?("f ")
        t = line.chomp.scanf("f %d/%d/%d %d/%d/%d %d/%d/%d")
        @v += v[t[0] - 1]; @v += v[t[3] - 1]; @v += v[t[6] - 1]
        @vt += vt[t[1] - 1]; @vt += vt[t[4] - 1]; @vt += vt[t[7] - 1]
        @vn += vn[t[2] - 1]; @vn += vn[t[5] - 1]; @vn += vn[t[8] - 1]
      end
    end
  end
 
  def draw(texture)
    glBindTexture(GL_TEXTURE_2D, texture.get_id)
    glEnableClientState(GL_VERTEX_ARRAY)
    glEnableClientState(GL_TEXTURE_COORD_ARRAY)
    glEnableClientState(GL_NORMAL_ARRAY)
    glVertexPointer(3, GL_FLOAT, 0, @v)
    glTexCoordPointer(3, GL_FLOAT, 0, @vt)
    glNormalPointer(GL_FLOAT, 0, @vn)
    glDrawArrays(GL_TRIANGLES, 0, @v.size / 3)
  end
end
Up Topic Gosu / Gosu Exchange / A more stable OpenGL ruby implementation ?

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill