Help: glReadPixels error on OS X

Hugo H <[email protected]> Thu, 23 May 2013 03:38:09 +0200
Newsgroups gmane.comp.python.opengl.user
Message-ID <CAE35mHVYf=KbMOtG5j9=_UrBaLL3xpTZonbSJgvnUzLWE3gvbg@mail.gmail.com>
Hello all,

I am facing an issue with using glReadPixels returning a <c_byte_Array>
object instead of the expected string.

Is this a bug ? Any idea how to get the pixel's value ?

Thank you in advance !
Greetz,

Hugo

——— details: ———

Here is the relevant part of my code:

> viewport = glGetIntegerv(GL_VIEWPORT)
> pixel = glReadPixels(cursorX, viewport[3]-cursorY, 1, 1, GL_RGB,
> GL_UNSIGNED_BYTE)


Using PyOpenGL 3.0.2, installed with Homebrew on OS X 10.8.3, I get the
following value for pixel:

<OpenGL.arrays.lists.c_byte_Array_1_Array_1_Array_3 object at 0x10ef57dd0>

The exact same code works perfectly on my Ubuntu 12.10-32bits system with
PyOpenGL 3.0.1, and returns a string of len(3) where each byte is one color
of the pixel.

The code I am using is a translation to Python of the following C tutorial:
http://www.lighthouse3d.com/opengl/picking/index.php3?color1

You will find my Python version attached for further examination.

------------------------------------------------------------------------------
Try New Relic Now & We'll Send You this Cool Shirt
New Relic is the only SaaS-based application performance monitoring service 
that delivers powerful full stack analytics. Optimize and monitor your
browser, app, & servers with just a few lines of code. Try New Relic
and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_may

_______________________________________________
PyOpenGL Homepage
http://pyopengl.sourceforge.net
_______________________________________________
PyOpenGL-Users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/pyopengl-users
glutsubwin.py (application/octet-stream, 4.4 KB)
#include <math.h>
#include <gl\glut.h>
#include <gl\gl.h>
#include <gl\glu.h>
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "render.h"
from render import *

#static camera cam;

#// Selection Buffer
#define SelBufferSize 512
SelBufferSize = 512

#static int mainWindow;
#static int border = 6,h=200,w=350;
border = 6
h=200
w=350

#// Picking Stuff //
#define RENDER                  1
RENDER = 1
#define SELECT                  2
SELECT = 2
#define BUFSIZE 1024
BUFSIZE = 1024
#GLuint selectBuf[BUFSIZE];
#GLint hits;
#int mode = RENDER;
mode = RENDER
#int cursorX,cursorY;


#//----------------------
#// Resizing
#//----------------------



#void changeSize(int w1, int h1) {
def changeSize(w1, h1):

    #float ratio;

    h = h1
    w = w1
    #// Prevent a divide by zero, when window is too short
    #// (you cant make a window of zero width).

    if(h == 0):
        h = 1

    ratio = 1.0 * w / h
    #// Reset the coordinate system before modifying
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()

    #// Set the viewport to be the entire window
    glViewport(0, 0, w, h)

    #// Set the clipping volume
    gluPerspective(45,ratio,0.1,1000)

    #// setting the camera now
    glMatrixMode(GL_MODELVIEW)
#}


#//---------------
#// Picking Stuff
#//---------------



#void processPick ()
def processPick():
#{
    #GLint viewport[4];
    #GLubyte pixel[3];

    #glGetIntegerv(GL_VIEWPORT, viewport);
    viewport = glGetIntegerv(GL_VIEWPORT)

    #glReadPixels(cursorX, viewport[3]-cursorY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);
    pixel = glReadPixels(cursorX, viewport[3]-cursorY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE)
    pixel = ord(pixel[0]), ord(pixel[1]), ord(pixel[2])

    #printf("%d %d %d\n",pixel[0],pixel[1],pixel[2]);
    print "%d %d %d\n" % (pixel[0],pixel[1],pixel[2])
    if (pixel[0] == 255):
        print "You picked the 1st snowman on the 1st row"
    elif (pixel[1] == 255):
        print "You picked the 1st snowman on the 2nd row"
    elif (pixel[2] == 255):
        print "You picked the 2nd snowman on the 1st row"
    elif (pixel[0] == 250):
        print "You picked the 2nd snowman on the 2nd row"
    else:
        print "You didn't click a snowman!"
    print "\n"

#}




#//-----------------
#// Rendering
#//-----------------




#void renderScene() {
def renderScene():
    global cam
    global mode

    glutSetWindow(mainWindow)

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    glLoadIdentity()


    gluLookAt(cam.pos[0],
              cam.pos[1],
              cam.pos[2],

              cam.lookAt[0],
              cam.lookAt[1],
              cam.lookAt[2],

              cam.lookUp[0],
              cam.lookUp[1],
              cam.lookUp[2])


    if (mode == SELECT):
        drawPickingMode()
    else:
        drawPickingMode()

    if (mode == SELECT):
        processPick()
        mode = RENDER
    else:
        glutSwapBuffers()
#}



#//-------------------
#// Keyboard and Mouse
#//-------------------


#void processNormalKeys(unsigned char key, int x, int y) {
def processNormalKeys(key, x, y):

    if (key == 27):
        quit()
        exit(0)
    else:
        processKeyboard(key, x, y)
#}




#void mouseStuff(int button, int state, int x, int y) {
def mouseStuff(button, state, x, y):

    global mode
    global cursorX
    global cursorY

    if (button != GLUT_LEFT_BUTTON or state != GLUT_DOWN):
        return

    cursorX = x
    cursorY = y
    mode = SELECT
#}





#//---------
#// Main
#//---------

#int main(int argc, char **argv)
def main(argc=None, argv=None):
#{

    global mainWindow
    global cam

    #glutInit(&argc, argv);
    glutInit()
    glutInitDisplayMode(GLUT_DEPTH  | GLUT_DOUBLE | GLUT_RGBA)
    glutInitWindowPosition(100, 100)
    glutInitWindowSize(w, h)
    mainWindow = glutCreateWindow("SnowMen from Lighthouse 3D")

    glutKeyboardFunc(processNormalKeys)
    glutReshapeFunc(changeSize)
    glutDisplayFunc(renderScene)
    glutMouseFunc(mouseStuff)
    glutIdleFunc(renderScene)


    initScene(argc, argv)
    cam = Camera()
    init(cam)


    glutMainLoop()

    return(0)
#}

if __name__ == '__main__':
    main()
render.py (application/octet-stream, 3.7 KB)
#include <math.h>
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
#include <stdio.h>
#include <stdlib.h>

#include "render.h"

#typedef struct cameras {
#   float pos[3];
#   float lookAt[3];
#   float lookUp[3];
#} camera;


class Camera(object):

    def __init__(self):
        self.pos = [0, 0, 0]
        self.lookAt = [0, 0, 0]
        self.lookUp = [0, 0, 0]

#static GLint snowman_display_list;


#void quit() {}
def quit():
    pass


#void processKeyboard(unsigned char key, int x, int y) {
def processKeyboard(key, x, y):
    #printf("key: %d\n",key);
    print "key: %d\n" % key
#}


#void picked(GLuint name, int sw) {
def picked(name, sw):
    #printf("my name = %d in %d\n",name,sw);
    print "my name = %d in %d\n" % (name, sw)
#}


#void init(camera *cam) {
def init(cam):

    cam.pos[0] = 1.5
    cam.pos[1] = 3.75
    cam.pos[2] = 3

    cam.lookAt[0] = 1.5
    cam.lookAt[1] = 1.75
    cam.lookAt[2] = 0

    cam.lookUp[0] = 0
    cam.lookUp[1] = 1
    cam.lookUp[2] = 0

#}


#void drawSnowMan() {
def drawSnowMan():



#// Draw Body
    glTranslatef(0.0 ,0.75, 0.0);
    glutSolidSphere(0.75,20,20);


#// Draw Head
    glTranslatef(0.0, 1.0, 0.0);
    glutSolidSphere(0.25,20,20);

#// Draw Eyes
    glPushMatrix();
    glColor3f(0.0,0.0,0.0);
    glTranslatef(0.05, 0.10, 0.18);
    glutSolidSphere(0.05,10,10);
    glTranslatef(-0.1, 0.0, 0.0);
    glutSolidSphere(0.05,10,10);
    glPopMatrix();

#// Draw Nose
    glColor3f(1.0, 0.5 , 0.5);
    glRotatef(0.0,1.0, 0.0, 0.0);
    glutSolidCone(0.08,0.5,10,2);
#}


#GLuint createDL() {
def createDL():
    #GLuint snowManDL;

    #// Create the id for the list
    snowManDL = glGenLists(1)

    glNewList(snowManDL, GL_COMPILE)
    #    drawSnowMan();
    drawSnowMan()
    glEndList()

    return snowManDL
#}


#void initScene(int argc, char **argv) {
def initScene(argc, argv):
    global snowman_display_list

    glEnable(GL_DEPTH_TEST)
    glEnable(GL_CULL_FACE)
    snowman_display_list = createDL()
#}



#void draw() {
def draw():

#// Draw ground
    glColor3f(0.9, 0.9, 0.9)
    glBegin(GL_QUADS)
    glVertex3f(-100.0, 0.0, -100.0)
    glVertex3f(-100.0, 0.0,  100.0)
    glVertex3f(100.0, 0.0,  100.0)
    glVertex3f(100.0, 0.0, -100.0)
    glEnd()

#// Draw 4 SnowMen

    glColor3f(1.0, 1.0, 1.0)

    #for(int i = 0; i < 2; i++)
    #    for(int j = 0; j < 2; j++) {
    for i in xrange(2):
        for j in xrange(2):
            glPushMatrix()
            glPushName(i*2+j)
            glTranslatef(i*3.0, 0, -j * 3.0)
            glColor3f(1.0, 1.0, 1.0)
            glCallList(snowman_display_list)
            glPopName()
            glPopMatrix()
        #}

#}



#void drawPickingMode() {
def drawPickingMode():

#// Draw 4 SnowMen


    glDisable(GL_DITHER)
    #for(int i = 0; i < 2; i++)
    #    for(int j = 0; j < 2; j++) {
    for i in xrange(2):
        for j in xrange(2):
            glPushMatrix()

            #switch (i*2+j) {
            #    case 0: glColor3ub(255,0,0);break;
            #    case 1: glColor3ub(0,255,0);break;
            #    case 2: glColor3ub(0,0,255);break;
            #    case 3: glColor3ub(130,0,130);break;
            #}

            if (i*2+j) == 0:
                glColor3ub(255, 0, 0)
            elif (i*2+j) == 1:
                glColor3ub(0, 255, 0)
            elif (i*2+j) == 2:
                glColor3ub(0, 0, 255)
            elif (i*2+j) == 3:
                glColor3ub(130, 0, 130)


            glTranslatef(i*3.0,0,-j * 3.0)
            glCallList(snowman_display_list)
            glPopMatrix()
        #}
    glEnable(GL_DITHER);
#}