다수의 정점 (점군과 비슷 함)을 플롯하려고합니다.OpenGL에서 500+ 정점 위치를 업데이트하려고하면 읽기 액세스 위반이 발생합니까?
동시에 VBO를 사용하고 Numpy 배열을 GLSL 프로그램에 전달하고 정점 위치를 애니메이션하는 방법을 배우려고합니다. WindowsError: exception: access violation reading 0x0999B000
때로는 (무작위로) 작동하고 난 그냥 궁금했다 :
나는 내가 일반적으로 오류가 발생 (500)를 통해 나는 array_size
매개 변수 아무것도 설정하는 방법 큰 제한하고 있지만 일부 진전을 생각한다 내가 메모리를 할당하거나 배열을 버퍼링하는 방식에 실수를하고 있습니까?
메모를 추가하기 만하면 앞으로는 2500+ 정점 위치를 한 번에 업데이트하려고합니다. 어떻게하면 가능할 수 있는지 궁금해하고 있었습니까?
#!/bin/env python
# coding: utf-8
import time
import numpy as np
from textwrap import dedent
from OpenGL.GL import *
from OpenGL.GL.shaders import compileShader, compileProgram
import pygame
from pygame.locals import *
##############################################################################
# OpenGL funcs
##############################################################################
buffers=None
shader = None
def init_gl():
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE) #allow the program to specify the point size
global shader, buffers
vertex_shader = compileShader(dedent('''
uniform mat4 Projection = mat4(1);
uniform mat4 ModelView = mat4(1);
varying out vec3 _color;
void main() {
_color = gl_Color;
gl_Position = Projection * ModelView * gl_ModelViewProjectionMatrix * gl_Vertex;
vec3 ndc = gl_Position.xyz/gl_Position.w ; // perspective divide.
float zDist = 1.0-ndc.z ; // 1 is close (right up in your face,)
// 0 is far (at the far plane)
gl_PointSize = 25*zDist ; // between 0 and 50 now.
}
'''), GL_VERTEX_SHADER)
fragment_shader = compileShader(dedent('''
in vec3 _color;
void main() {
gl_FragColor = vec4(_color, 1.0); //gl_Color;
}
'''), GL_FRAGMENT_SHADER)
shader = compileProgram(vertex_shader, fragment_shader)
buffers=create_vbo()
yaw=0
pitch=0
def draw():
global yaw, pitch
glClear(GL_COLOR_BUFFER_BIT)# | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
yaw+=0.39
pitch+=0.27
glTranslatef(0.0, 0.0, 0.0)
glRotatef(yaw, 0, 1, 0)
glRotatef(pitch, 1, 0, 0)
setPoints()
glFlush()
##############################################################################
# vertices
##############################################################################
array_size = 1000
scale = 0.15
#create dataset https://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html
theta = np.linspace(-4 * np.pi, 4 * np.pi, array_size)
z = np.linspace(-2, 2, array_size)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
vertices = np.dstack((x,y,z)) * scale
colors = np.tile(np.array([0.0, 1.0, 0.0]), (array_size,1)) #a bunch of green vertices
indices=np.arange(array_size)
def create_vbo():
buffers = glGenBuffers(3)
glBindBuffer(GL_ARRAY_BUFFER, buffers[0])
glBufferData(GL_ARRAY_BUFFER,
vertices.nbytes, # byte size
(ctypes.c_float*len(vertices.flat))(*vertices.flat),
GL_STREAM_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, buffers[1])
glBufferData(GL_ARRAY_BUFFER,
colors.nbytes, # byte size
(ctypes.c_float*len(colors.flat))(*colors.flat),
GL_STATIC_DRAW)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2])
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
indices.nbytes, # byte size
(ctypes.c_uint*len(indices.flat))(*indices.flat),
GL_STATIC_DRAW)
return buffers
def draw_vbo():
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glVertexPointer(3, GL_FLOAT, 0, None);
glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
glColorPointer(3, GL_FLOAT, 0, None);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2]);
glDrawElements(GL_POINTS, indices.size, GL_UNSIGNED_INT, None);
glDisableClientState(GL_COLOR_ARRAY)
glDisableClientState(GL_VERTEX_ARRAY);
def setPoints():
global shader
glUseProgram(shader)
draw_vbo()
projection = np.array([#the matrix generated captured while using HTC Vive
[ 0.75752085, 0. , 0. , 0.],
[ 0. , 0.68160856, 0. , 0.],
[ 0.05516453, -0.00299519, -1.00040019, -1.],
[ 0. , 0. , -0.20008004, 0.]
])
modelview = np.array([#the matrix generated captured while using HTC Vive
[ 0.99030989, 0.04490654, 0.13141415, 0.],
[-0.01430531, 0.9742285 , -0.22510922, 0.],
[-0.13813627, 0.22104797, 0.9654305 , 0.],
[-0.12975544, -0.9294402 , -1.06236947, 1.]
])
glUniformMatrix4fv(glGetUniformLocation(shader, "Projection"), 1, False, projection)
glUniformMatrix4fv(glGetUniformLocation(shader, "ModelView"), 1, False, modelview)
glUseProgram(0)
##############################################################################
if __name__ == '__main__':
pygame.init()
pygame.display.set_mode((800, 600), HWSURFACE|OPENGL|DOUBLEBUF)
init_gl()
start_time = time.time()
while time.time() - start_time < 5: #5 second animation
draw()
pygame.display.flip()
[업데이트]
나는 내가 제대로 내 NumPy와 배열의 데이터 유형을 캐스팅하지 않은 깨달았을 때 나는 내 자신의 질문에 대답했다 생각합니다. 그래서 내가 그들을 만들 때 내 배열에 .astype()
을 추가하여 내가 보여 애니메이션 :
vertices = (np.dstack((x,y,z)) * scale).astype(np.float32)
colors = (np.tile(np.array([0.0, 1.0, 0.0]), (array_size,1))).astype(np.float32) #a bunch of green vertices
indices = np.arange(array_size).astype(np.uint32)
을 위해 2000 + 버텍스를 얻을 수 있었다 그리고 여기에 고정 된 예는있다 :
#!/bin/env python
# coding: utf-8
import time
import numpy as np
from textwrap import dedent
from OpenGL.GL import *
from OpenGL.GL.shaders import compileShader, compileProgram
import pygame
from pygame.locals import *
##############################################################################
# OpenGL funcs
##############################################################################
buffers=None
shader = None
def init_gl():
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE) #allow the program to specify the point size
global shader, buffers
vertex_shader = compileShader(dedent('''
uniform mat4 Projection = mat4(1);
uniform mat4 ModelView = mat4(1);
varying out vec3 _color;
void main() {
_color = gl_Color;
gl_Position = Projection * ModelView * gl_ModelViewProjectionMatrix * gl_Vertex;
vec3 ndc = gl_Position.xyz/gl_Position.w ; // perspective divide.
float zDist = 1.0-ndc.z ; // 1 is close (right up in your face,)
// 0 is far (at the far plane)
gl_PointSize = 25*zDist ; // between 0 and 50 now.
}
'''), GL_VERTEX_SHADER)
fragment_shader = compileShader(dedent('''
in vec3 _color;
void main() {
gl_FragColor = vec4(_color, 1.0); //gl_Color;
}
'''), GL_FRAGMENT_SHADER)
shader = compileProgram(vertex_shader, fragment_shader)
buffers=create_vbo()
yaw=0
pitch=0
def draw():
global yaw, pitch
glClear(GL_COLOR_BUFFER_BIT)# | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
yaw+=0.39
pitch+=0.27
glTranslatef(0.0, 0.0, 0.0)
glRotatef(yaw, 0, 1, 0)
glRotatef(pitch, 1, 0, 0)
setPoints()
glFlush()
##############################################################################
# vertices
##############################################################################
array_size = 2000
scale = 0.15
#create dataset https://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html
theta = np.linspace(-4 * np.pi, 4 * np.pi, array_size)
z = np.linspace(-2, 2, array_size)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
vertices = (np.dstack((x,y,z)) * scale).astype(np.float32)
colors = (np.tile(np.array([0.0, 1.0, 0.0]), (array_size,1))).astype(np.float32) #a bunch of green vertices
indices = np.arange(array_size).astype(np.uint)
def create_vbo():
buffers = glGenBuffers(3)
glBindBuffer(GL_ARRAY_BUFFER, buffers[0])
glBufferData(GL_ARRAY_BUFFER,
vertices.nbytes, # byte size
(ctypes.c_float*len(vertices.flat))(*vertices.flat),
GL_STREAM_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, buffers[1])
glBufferData(GL_ARRAY_BUFFER,
colors.nbytes, # byte size
(ctypes.c_float*len(colors.flat))(*colors.flat),
GL_STATIC_DRAW)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2])
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
indices.nbytes, # byte size
(ctypes.c_uint*len(indices.flat))(*indices.flat),
GL_STATIC_DRAW)
return buffers
def draw_vbo():
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glVertexPointer(3, GL_FLOAT, 0, None);
glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
glColorPointer(3, GL_FLOAT, 0, None);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2]);
glDrawElements(GL_POINTS, indices.size, GL_UNSIGNED_INT, None);
glDisableClientState(GL_COLOR_ARRAY)
glDisableClientState(GL_VERTEX_ARRAY);
def setPoints():
global shader
glUseProgram(shader)
draw_vbo()
projection = np.array([#the matrix generated captured while using HTC Vive
[ 0.75752085, 0. , 0. , 0.],
[ 0. , 0.68160856, 0. , 0.],
[ 0.05516453, -0.00299519, -1.00040019, -1.],
[ 0. , 0. , -0.20008004, 0.]
])
modelview = np.array([#the matrix generated captured while using HTC Vive
[ 0.99030989, 0.04490654, 0.13141415, 0.],
[-0.01430531, 0.9742285 , -0.22510922, 0.],
[-0.13813627, 0.22104797, 0.9654305 , 0.],
[-0.12975544, -0.9294402 , -1.06236947, 1.]
])
glUniformMatrix4fv(glGetUniformLocation(shader, "Projection"), 1, False, projection)
glUniformMatrix4fv(glGetUniformLocation(shader, "ModelView"), 1, False, modelview)
glUseProgram(0)
##############################################################################
if __name__ == '__main__':
pygame.init()
pygame.display.set_mode((800, 600), HWSURFACE|OPENGL|DOUBLEBUF)
init_gl()
start_time = time.time()
while time.time() - start_time < 5: #5 second animation
draw()
pygame.display.flip()
답변 해 주셔서 감사합니다. 나는 또한 이것을 목격했다 (당신이 이것을 타이핑하는 것처럼)! 내 게시물을 개정 된 코드로 업데이트했으며 제안한대로 정확하게 수정했습니다. 나는 이것을 잘 설명하고 원래의 문제를 해결하기 때문에 이것을 답으로 받아 들일 것입니다. – Logic1
여러분을 환영합니다! 또한 자신에게 답을 똑같이 찾는 당신을위한 소품! :) – Vallentin