PDA

View Full Version : Problems with glDrawPixels and numpy arrays with pyOpenGl



lpp___
05-30-2015, 12:45 PM
I'm trying to visualize mandelbrot set using numpy and OpenGL. However I have problems in drawing code, that is glDrawPixels.

When I draw using glDrawPixels I get something black and all messed up, but when using slower method of glBegin & glEnd I get the correct result. Code:



#!/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 = 800,600
eps = 2
max_iter = 16
u = (-1.5, 0.5)
v = (-1,1)

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)

def draw():
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

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

x = linspace(u[0], u[1], w)
y = linspace(v[0], v[1], h)
a, b = meshgrid(x,y)
M = (a + 1j*b).T
Alive = ones((w,h), dtype=bool)

### Mandelbrot | Julia picker
## Mandelbrot
# C = M.copy()

## Julia
C = (0.32 + 0.043j) * ones(M.shape, dtype=complex128)

### End picker

esc = max_iter * ones((w,h), dtype=int32)

for k in range(max_iter):
M[Alive] = square(M[Alive]) + C[Alive]
MD = real(M)**2 + imag(M)**2
esc[logical_and(Alive, MD > eps*eps)] = k
Alive = MD <= eps*eps


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 False: #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()

GClements
05-30-2015, 03:31 PM
When I draw using glDrawPixels I get something black and all messed up, but when using slower method of glBegin & glEnd I get the correct result.
There are two issues with your code. First, the glDrawPixels() version doesn't call glFlush(), which may result in the call not executing. Second, glDrawPixels() expects the data in row-major ("raster scan") order, whereas your array is in column-major order. Use np.ascontiguousarray(cmap.transpose()) instead of just cmap (or, preferably, change the shape of cmap from (w,h) to (h,w)).

lpp___
05-31-2015, 03:23 AM
Thank you, this solved the problem.