glDrawPixels и проблемы с numpy

Я пытаюсь визуализировать набор Мандельброта, используя numpy и OpenGL. Однако у меня проблемы с отрисовкой кода, то есть glDrawPixels.

Когда я рисую с помощью glDrawPixels, я получаю что-то черное и все в беспорядке, но при использовании более медленного метода glBegin и glEnd я получаю правильный результат. Код:

#!/usr/bin/env python3  

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

from pylab import *
from numpy import *
from time import clock

w,h = 80,60
eps = 2
max_iter = 30

def draw():
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    t = clock()
    print("Being calculation")

    x = linspace(-1.5, 0.5, w)
    y = linspace(-1,1,h)
    a, b = meshgrid(x,y)
    M = (a + 1j*b).T
    Alive = ones((w,h), dtype=bool)
    C = M.copy()
    esc = max_iter * ones((w,h), dtype=int32)

    for k in range(max_iter):
        M[Alive] = square(M[Alive]) + C[Alive]
        esc[logical_and(Alive, abs(M) > eps)] = k
        Alive = abs(M) < eps

    colorsMap = array([0x8B0000FF, 0xA52A2AFF, 0xB22222FF, 0xDC143CFF, 0xFF0000FF, 0xFF6347FF, 0xFF7F50FF, 0xCD5C5CFF, 0xF08080FF, 0xE9967AFF, 0xFA8072FF, 0xFFA07AFF, 0xFF4500FF, 0xFF8C00FF, 0xFFA500FF, 0xFFD700FF, 0xB8860BFF, 0xDAA520FF, 0xEEE8AAFF, 0xBDB76BFF, 0xF0E68CFF, 0x808000FF, 0xFFFF00FF, 0x9ACD32FF, 0x556B2FFF, 0x6B8E23FF, 0x7CFC00FF, 0x7FFF00FF, 0xADFF2FFF, 0x006400FF, 0x008000FF, 0x228B22FF, 0x00FF00FF, 0x32CD32FF, 0x90EE90FF, 0x98FB98FF, 0x8FBC8FFF, 0x00FA9AFF, 0x00FF7FFF, 0x2E8B57FF, 0x66CDAAFF, 0x3CB371FF, 0x20B2AAFF, 0x2F4F4FFF, 0x008080FF, 0x008B8BFF, 0x00FFFFFF, 0x00FFFFFF, 0xE0FFFFFF, 0x00CED1FF, 0x40E0D0FF, 0x48D1CCFF, 0xAFEEEEFF, 0x7FFFD4FF, 0xB0E0E6FF, 0x5F9EA0FF, 0x4682B4FF, 0x6495EDFF, 0x00BFFFFF, 0x1E90FFFF, 0xADD8E6FF, 0x87CEEBFF, 0x87CEFAFF, 0x191970FF, 0x000080FF, 0x00008BFF, 0x0000CDFF, 0x0000FFFF, 0x4169E1FF, 0x8A2BE2FF, 0x4B0082FF, 0x483D8BFF, 0x6A5ACDFF, 0x7B68EEFF, 0x9370DBFF, 0x8B008BFF, 0x9400D3FF, 0x9932CCFF, 0xBA55D3FF, 0x800080FF, 0xD8BFD8FF, 0xDDA0DDFF, 0xEE82EEFF, 0xFF00FFFF, 0xDA70D6FF, 0xC71585FF, 0xDB7093FF, 0xFF1493FF, 0xFF69B4FF, 0xFFB6C1FF, 0xFFC0CBFF, 0xFAEBD7FF, 0xF5F5DCFF, 0xFFE4C4FF, 0xFFEBCDFF, 0xF5DEB3FF, 0xFFF8DCFF, 0xFFFACDFF, 0xFAFAD2FF, 0xFFFFE0FF, 0x8B4513FF, 0xA0522DFF, 0xD2691EFF, 0xCD853FFF, 0xF4A460FF, 0xDEB887FF, 0xD2B48CFF, 0xBC8F8FFF, 0xFFE4B5FF, 0xFFDEADFF, 0xFFDAB9FF, 0xFFE4E1FF, 0xFFF0F5FF, 0xFAF0E6FF, 0xFDF5E6FF, 0xFFEFD5FF, 0xFFF5EEFF, 0xF5FFFAFF, 0x708090FF, 0x778899FF, 0xB0C4DEFF, 0xE6E6FAFF, 0xFFFAF0FF, 0xF0F8FFFF, 0xF8F8FFFF, 0xF0FFF0FF, 0xFFFFF0FF, 0xF0FFFFFF, 0xFFFAFAFF], dtype=uint32)

    cmap = zeros((w,h), dtype=uint32)

    for k in range(max_iter):
        cmap[esc == k] = colorsMap[k]


    print("Finish Calculation: {:.2f}".format(clock() - t))
    t = clock()
    print("Begin Drawing")

    if True: #Change for effect
        glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, cmap.data)
    else:
        #Primite drawing numpy array
        def transform(cl):
            r = ((cl >> 24) & 0xFF) / 256.0
            b = ((cl >> 16) & 0xFF) / 256.0
            g = ((cl >>  8) & 0xFF) / 256.0
            return (r,b,g)

        glBegin(GL_POINTS)
        for y in range(0,h):
            for x in range(0,w):
                glColor3f(*transform(cmap[x,y]))
                glVertex2i(x,y)
        glEnd()
    glFlush()
    print("Finish drawing:     {:.2f}".format(clock() - t))

def idle():
    glutPostRedisplay()

def reshape(width, height):
    global w,h
    w,h =width, height

    glViewport(0, 0, width, height)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluOrtho2D(0, width, height, 0)
    glClearColor( 1., 1., 1., 0.)
    glClear( GL_COLOR_BUFFER_BIT )
    glPointSize(1.0)
    glColor3f(0., 0., 0.)

glutInit(sys.argv)
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
glutInitWindowSize(w,h)
glutInitWindowPosition(100,100)

glutCreateWindow("Fraktali")
glutReshapeFunc(reshape)
glutDisplayFunc(draw)

glutMainLoop()

person nmiculinic    schedule 30.05.2015    source источник


Ответы (1)


glDrawPixels () ожидает данные в порядке строк («растровое сканирование»), тогда как мой массив был в порядке столбцов. Не знал, что именно так numpy сохраняет данные в памяти. Это решило проблему:

    glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ascontiguousarray(cmap.transpose()).data)

Спасибо пользователю GClements на форуме openGL.

person nmiculinic    schedule 31.05.2015