BrowserUk has asked for the wisdom of the Perl Monks concerning the following question:

Update: My bad. I was including an alpha value in the color array. Being used to perl sub just ignoring extra args whilst I worked out how to use aplha values in OpenGL. But XS subs aren't like perl subs, and the extra value causes the sub to print it's usage message and fail. :(

I finally got OpenGL built and installed and I'm just starting to play with it and I encountered a Perl problem that I haven't experienced before. I'm trying to call glColor3f() within a subroutine into which I'm passing an array ref containing the rgb values.

  1. My first attempt was: glColor3f( @$ref ); fails!

    But that (and all other failures) bellyaches Usage: OpenGL::glColor3f(red, green, blue) at...

  2. So then I tried hard coding the numbers:glColor3f( 1.0, 0.0, 0.0 ); works!
  3. So then I tried glColor3f( $ref->[ 0 ], $ref->[ 1 ], $ref->[ 2 ] ); works!
  4. Hm! Prototype problem? &glColor3f( @$ref ); Fails!
  5. Then I tried: glColor3f( @{ $ref }[ 0, 1, 2 ] ); works!
  6. Then I tried: glColor3f( map $_, @$ref ); fails!

Quick peruse of the xs source shows:

void glColor3f(red, green, blue) GLfloat red GLfloat green GLfloat blue

Which doesn't clarify what's going on. Can you?


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re: XS prototype (or not) problem?
by salva (Canon) on Jul 24, 2008 at 08:47 UTC
    what does prototype say about the function?
    use OpenGL; print prototype("OpenGL::glColor3f"), "\n";
    When the module is compiled, a OpenGL.c file is generated, can you post the code for the function wrapper?

    Also, how is the function registered in the interpreter? Look for a cv = newXS("OpenGL::glColor3f", ...) statement probably followed by sv_setpv((SV*)cv, "$$$") to set the prototype

Re: XS prototype (or not) problem?
by syphilis (Archbishop) on Jul 24, 2008 at 08:13 UTC
    glColor3f( @$ref ); fails!

    Can't reproduce the problem:
    C:\_32\comp\OpenGL>perl -MOpenGL -e "@x=1.0,0.0,0.0);$ref=\@x,OpenGL:: +glColor3f(@$ref)" C:\_32\comp\OpenGL>
    Which version of OpenGL ? (I have the upcoming 0.57 built from svn source - so it may be that an old problem has been fixed.)

    Cheers,
    Rob

      I don't get an error if I do that either, but (I think) that's because nothing has been initialised yet. Try this:

      #! perl -slw use strict; use OpenGL qw[ :all ]; print "Version: ", $OpenGL::VERSION; glutInit(); glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA + ); glutInitWindowSize( 1024, 768 ); my $main = glutCreateWindow( 'OGL1' ); glutDisplayFunc( \&render ); glutMainLoop(); sub render { glClearColor( 1, 1, 1, 1 ); glClear(GL_COLOR_BUFFER_BIT); drawPolygon( #### One too many arguments!!! (I'd added an alpha value) [ 1.0, 0.0, 0.0, 0.0 ], # red [ 0.25, 0.25, 0.25 ], [ 0.75, 0.25, 0.25 ], [ 0.75, 0.75, 0.25 ], [ 0.25, 0.75, 0.25 ], ); glutSwapBuffers(); } sub drawPolygon { glBegin(GL_POLYGON); ## glColor3f( @{ shift() }[ 0, 1, 2 ] ); ## Works glColor3f( @{ shift() } ); ## Fails glVertex3f( @$_ ) for @_; glEnd(); }

      Switch the comment card in drawPloygon to see it work.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        sub drawPolygon { glBegin(GL_POLYGON); ## glColor3f( @{ shift() }[ 0, 1, 2 ] ); ## Works glColor3f( @{ shift() } ); ## Fails glVertex3f( @$_ ) for @_; glEnd(); }
        In the call that works glColor3f() receives 3 arguments. In the call that fails glColor3f() receives 4 arguments - which rightly warrants a "Usage" error. The following rendition of sub drawPolygon works fine for me:
        sub drawPolygon { glBegin(GL_POLYGON); my $arg = shift; pop(@$arg); ## glColor3f( @{ shift() }[ 0, 1, 2 ] ); ## Works glColor3f( @{ $arg } ); glVertex3f( @$_ ) for @_; glEnd(); }
        Update: Duh, you'd already worked it out for yourself. I missed the "Solved" and didn't pay attention to the comments.

        Cheers,
        Rob
Re: XS prototype (or not) problem?
by cdarke (Prior) on Jul 24, 2008 at 07:59 UTC
    When you say "Fails!", how does it fail? What is the error message?
    You suspect a prototype issue, in the XS is there a PROTOTYPE statement?
      Maybe recompile with  #define GL_GLEXT_PROTOTYPES 0