2017-04-11 7 views
0

私は多数の頂点をプロットしようとしています(点群に似ています)。OpenGLで500+頂点の位置を更新しようとすると、読み取りアクセス違反が発生しますか?

同時に、VBOを使用してNumpy配列をGLSLプログラムに渡し、頂点の位置をアニメーション化する方法も学びたいと考えています。 WindowsError: exception: access violation reading 0x0999B000

時にはそれが(ランダムに)動作している場合、私はちょうど思っていた:私はいくつかの進歩を遂げていると思います

は、しかし、私は一般的にエラーが発生し、私は500の上にarray_sizeパラメータ、何を設定することができますどのように大規模に制限されていますメモリを割り当てる方法や配列をバッファする方法を間違えていますか?

メモを追加するだけで、将来は2500+頂点の位置を一度に更新したいと考えています。それをどうすればできるのだろうと思っていましたか?

array_size = 100

#!/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() 

[UPDATE]

私は私が正しく私の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+ Vertsのを取得するために管理し、ここに固定された例でいる:

#!/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() 

答えて

2

問題があることです全体としてdtypeは指定されていないため、dtypeとしてfloat64が選択されています。

print(vertices.dtype) 
print(colors.dtype) 
print(indices.dtype) 

これは"float32", "float32", "uint32"と表示されます。しかし、それは"float64", "float64", "int32"を印刷します。

この問題は、データが2倍のサイズになってしまうことです。 glBufferData()と呼ぶと、datasizeには、実際に何を実際に与えているのかと比べて2倍になっているということになります。あなたのドライバは、あなたがそれを与えたデータの範囲外のデータを読み取ろうとしているので、access violation reading 0x0999B000をトリガーするものです


それを修正する最も簡単な方法は、頂点を設定した後、次の操作を行うために、次のようになります。

vertices = vertices.astype(np.float32) 
colors = colors.astype(np.float32) 
indices = indices.astype(np.uint32) 

今、あなたはあなたのRAMとVRAM許す限り多くの頂点を追加することができます!verticesglBufferData()を呼び出す前に、以下を追加し、将来の頭痛から自分を救うために


最後に:

assert vertices.dtype == np.float32 

同様にcolorsindicesのためにそう(代わりにnp.uint32を使用します)。

これは、データ型が目的のデータ型以外の場合は、アサーションをトリガします。 2 未満の指標については


-1あなたがint32uint32を使用するかどうかの変更をすることはありません。しかし、予想されるタイプにするのが賢明かもしれません。したがって、将来自分自身を誤って身を乗り越えることは避けてください。 あなたはおそらくその量の索引や他の誰かにその問題には触れません。しかし、申し訳ありませんよりも安全です。

+0

ありがとうございました。私もこれを見つけました(あなたがこれを打ち込んでいるのと同じように)!私は改訂コードで自分の投稿を更新しました。それはあなたの提案通りです。私はこれを答えとして受け入れます。なぜならそれはきれいに記述的で、元の問題を解決するからです。 – Logic1

+0

あなたはようこそ!同じように自分自身で答えを見つけるためにあなたにも小道具! :) – Vallentin

関連する問題