我正在使用Numba为我的内核和OpenGL(下面的代码)创建一个Python手电筒应用程序。它非常接近完成,但是当我运行它时,我遇到错误,glEnd错误1280.代码运行时的终端输出也在下面。我无法弄清楚究竟是什么导致了这个问题,并帮助缩小它将是非常有帮助的。
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL.ARB.vertex_buffer_object import *
from OpenGL.GL.ARB.pixel_buffer_object import *
import numpy as np
import sys
import pycuda.gl as cuda_gl
import pycuda.driver as cuda_driver
import math
from numba import jit, cuda as nbcuda
W = 600
H = 600
loc = np.array([W/2, H/2], dtype = 'float32')
dragMode = False
TX = 32
TY = 32
pbo, tex, pycuda_pbo, distanceKernel = [None] * 4
class ExternalMemory(object):
"""
Provide an externally managed memory.
Interface requirement: __cuda_memory__, device_ctypes_pointer, _cuda_memize_
"""
__cuda_memory__ = True
def __init__(self, ptr, size):
self.device_ctypes_pointer = ctypes.c_void_p(ptr)
self._cuda_memsize_ = size
def render():
global pycuda_pbo, pbo
assert pbo is not None
pycuda_pbo.unregister()
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, long(pbo))
pycuda_pbo = cuda_gl.BufferObject(long(pbo))
pbo_mapping = pycuda_pbo.map()
source_ptr = ExternalMemory(pbo_mapping.device_ptr(), W*H * 4)
d_out = nbcuda.devicearray.DeviceNDArray(shape = W*H * 4,
strides = (1,),
dtype = np.dtype('uint8'),
gpu_data = source_ptr)
blockSize = (TX, TY)
gridSize = ((W + TX - 1)/TX, (H + TY - 1)/TY)
distanceKernel[gridSize, blockSize](d_out, W, H, loc)
cuda_driver.Context.synchronize()
pbo_mapping.unmap()
glBindTexture(GL_TEXTURE_2D, tex)
def drawTexture():
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, W, H, 0, GL_RGBA, GL_UNSIGNED_BYTE, None)
glEnable(GL_TEXTURE_2D)
glBegin(GL_TEXTURE_2D)
glBegin(GL_QUADS)
glTexCoord2f(0.0, 0.0); glVertex2f(0,0)
glTexCoord2f(0.0, 1.0); glVertex2f(0,H)
glTexCoord2f(1.0, 1.0); glVertex2f(W,H)
glTexCoord2f(1.0, 0.0); glVertex2f(W,0)
glEnd()
glDisable(GL_TEXTURE_2D)
def display():
render()
drawTexture()
glutSwapBuffers()
def create_PBO():
global pbo, pycuda_pbo
data = np.zeros((W*H,4), dtype = 'uint8')
pbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, pbo)
glBufferData(GL_ARRAY_BUFFER, data, GL_DYNAMIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, 0)
pycuda_pbo = cuda_gl.BufferObject(long(pbo))
def create_texture():
global tex
tex = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, tex)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
def exitfunc():
glBindBuffer(GL_ARRAY_BUFFER, long(pbo))
glDeleteBuffers(1, long(pbo));
glBindBuffer(GL_ARRAY_BUFFER, 0)
pbo = None
glDeleteTextures(tex);
tex = None
def keyboard(key, x, y):
if key == '\033': #\033 is escape key
exit()
elif key == 'a':
dragMode = not dragMode
elif key == 27:
exit()
glutPostRedisplay()
def mouseMove(x, y):
if dragMode == True:
loc[0] = x
loc[1] = y
glutPostRedisplay()
def mouseDrag(x, y):
if dragMode == False:
loc[0] = x
loc[1] = y
glutPostRedisplay()
def handleSpecialKeypress(key, x, y):
if key == GLUT_KEY_LEFT:
loc[0] -= DELTA
if key == GLUT_KEY_RIGHT:
loc[0] += DELTA
if key == GLUT_KEY_UP:
loc[1] -= DELTA
if key == GLUT_KEY_DOWN:
loc[1] += DELTA
glutPostRedisplay()
def printInstructions():
print "flashlight instructions"
print "a: toggle mouse tracking mode"
print "arrow keys: move ref location"
print "esc: close graphics window"
def main():
global cuda_gl, cuda_driver, distanceKernel
printInstructions();
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE)
glutCreateWindow("flashlight: distance image display app")
gluOrtho2D(0, W, H, 0)
glutDisplayFunc(display)
glutKeyboardFunc(keyboard)
glutSpecialFunc(handleSpecialKeypress)
glutPassiveMotionFunc(mouseMove)
glutMotionFunc(mouseDrag)
create_texture()
#Sets up GL interop
import pycuda.gl.autoinit
import pycuda.gl
cuda_gl = pycuda.gl
cuda_driver = pycuda.driver
# force compilation here
@nbcuda.jit(device = True)
def clip(n):
if n > 255:
n = 255
elif n < 0:
n = 0
return n
@nbcuda.jit("(uint8[::1], int32, int32, float32[::1])")
def distanceKernel(d_out, w, h, pos):
c = nbcuda.blockIdx.x*nbcuda.blockDim.x + nbcuda.threadIdx.x
r = nbcuda.blockIdx.y*nbcuda.blockDim.y + nbcuda.threadIdx.y
i = (r*w + c) * 4
if c >= w or r >= h:
return
d = math.sqrt((c - pos[0]) * (c - pos[0]) + (r - pos[1]) * (r - pos[1]))
intensity = clip(255 - d)
d_out[i] = intensity
d_out[i+1] = intensity
d_out[i+2] = 0
d_out[i+3] = 255
create_PBO()
glutMainLoop()
atexit(exitfunc)
main()
这是终端在OpenGL运行时吐出的内容
flashlight instructions
a: toggle mouse tracking mode
arrow keys: move ref location
esc: close graphics window
cuInit
cuDeviceGetCount
cuDeviceGetCount
cuDeviceGet
cuGLCtxCreate
cuCtxGetDevice
cuGLRegisterBufferObject
cuGLUnregisterBufferObject
cuGLRegisterBufferObject
cuGLMapBufferObject
cuCtxSynchronize
cuGLUnmapBufferObject
Traceback (most recent call last):
File "_ctypes/callbacks.c", line 314, in 'calling callback function'
File "stackcode.py", line 80, in display
drawTexture()
File "stackcode.py", line 75, in drawTexture
glEnd()
File "latebind.pyx", line 44, in OpenGL_accelerate.latebind.Curry.__call__ (src/latebind.c:1201)
File "/home/uchytilc/anaconda2/lib/python2.7/site-packages/OpenGL/GL/exceptional.py", line 46, in glEnd
return baseFunction( )
File "/home/uchytilc/anaconda2/lib/python2.7/site-packages/OpenGL/platform/baseplatform.py", line 402, in __call__
return self( *args, **named )
File "errorchecker.pyx", line 53, in OpenGL_accelerate.errorchecker._ErrorChecker.glCheckError (src/errorchecker.c:1218)
OpenGL.error.GLError: GLError(
err = 1280,
description = 'invalid enumerant',
baseOperation = glEnd,
cArguments = ()
)
cuCtxPopCurrent
cuCtxPushCurrent
cuGLUnregisterBufferObject
cuGLUnregisterBufferObject failed with code 1
PyCUDA WARNING: a clean-up operation failed (dead context maybe?)
cuGLUnregisterBufferObject failed: invalid argument
cuCtxPopCurrent
cuCtxPushCurrent
cuCtxDetach
答案 0 :(得分:1)