3

openGL で約 50k-60k のポイントを視覚化する必要がありますが、それらをすべて印刷することができましたが、回転を使用すると、フレームごとにすべてのデータを印刷するだけなので、回転ごとに非常に時間がかかります。すべてのデータを一度印刷し、データのインポートをフリーズして、画像を保持しながら処理を停止する方法はありますか?

def PointClouds(pcd_files): #pcd_file
   glBegin(GL_POINTS)
   for i in pcd_files:
       pc = pypcd.PointCloud.from_path(i)
       number_of_points = pc.get_metadata().get('points')
       z = pc.pc_data['z']
       x = pc.pc_data['x']
       y = pc.pc_data['y']
       for j in range(number_of_points):
           glVertex3f(x[j], y[j], z[j])
   glEnd()

主なものは次のとおりです。

files = glob.glob(os.getcwd() + "\\" + PCD_OutPutDirectory + "\*.pcd")

pygame.init()
display = (1700, 1000)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
gluPerspective(50, (display[0] / display[1]), 0.1, 5000)
glTranslatef(0, 0, -1000)
Clock = pygame.time.Clock()
while True:
    Clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
    glRotatef(2, 1, 1, 3)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    PointClouds(files)
    pygame.display.flip()

すべてのポイントを印刷しますが、各回転の間にすべてのポイントを超えて再度印刷します.60k以上のポイントがあるため、各回転の間に時間がかかりすぎます. ポイントを一度だけ読み取り、回転ではなく画像をフリーズする必要があります。助けてくれてありがとう

4

1 に答える 1

3

ボトルネックは for ループとglBegin/glEndシーケンスです。データはフレームごとにファイルから読み取られます。glBegin/glEndシーケンスと固定関数マトリックス スタックを使用した描画は、何十年も前から非推奨になっていることに注意してください。起動時にファイルを 1 回読み取り、Vertex Buffer Objectを作成します。(最先端のレンダリング方法については、Vertex SpecificationShaderの詳細を参照してください。)

既存のコードに最も近い解決策は、クライアント側の機能glEnableClientStateと固定関数属性を使用することですglVertexPointer。このソリューションでは、シェーダー プログラムは必要ありません。以下では、 PyOpenGL
を使用していると仮定します。

頂点座標を配列にロードする

def LoadVertices(pcd_files):
    vertices = []
    for i in pcd_files:
       pc = pypcd.PointCloud.from_path(i)
       number_of_points = pc.get_metadata().get('points')
       z = pc.pc_data['z']
       x = pc.pc_data['x']
       y = pc.pc_data['y']
       for j in range(number_of_points):
           vertices += [x[j], y[j], z[j]]
    return vertices

頂点バッファ オブジェクトを作成し、バッファ オブジェクトのデータ ストアを作成して初期化します。

import ctypes
def CreateBuffer(vertices):
    bufferdata = (ctypes.c_float*len(vertices))(*vertices) # float buffer
    buffersize = len(vertices)*4                           # buffer size in bytes 

    vbo = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glBufferData(GL_ARRAY_BUFFER, buffersize, bufferdata, GL_STATIC_DRAW) 
    glBindBuffer(GL_ARRAY_BUFFER, 0)
    return vbo

バッファからPoint プリミティブを描画できる関数を作成します。

def DrawBuffer(vbo, noOfVertices):
    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glEnableClientState(GL_VERTEX_ARRAY)
    glVertexPointer(3, GL_FLOAT, 0, None)

    glDrawArrays(GL_POINTS, 0, noOfVertices)

    glDisableClientState(GL_VERTEX_ARRAY)
    glBindBuffer(GL_ARRAY_BUFFER, 0)

プログラムで次の関数を使用します。

files = glob.glob(os.getcwd() + "\\" + PCD_OutPutDirectory + "\*.pcd")

pygame.init()
display = (1700, 1000)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)

vArray    = LoadVertices(files)
noPoints  = len(vArray) // 3
bufferObj = CreateBuffer(vArray)

gluPerspective(50, (display[0] / display[1]), 0.1, 5000)
glTranslatef(0, 0, -1000)
Clock = pygame.time.Clock()
while True:
    Clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
    glRotatef(2, 1, 1, 3)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    DrawBuffer(bufferObj, noPoints)

    pygame.display.flip()

各ポイントに個別の色を追加したい場合、頂点とその属性は座標だけで構成されているだけでなく、 RGB カラー(x, y, z)も必要であるため、各属性タプルは 3 つではなく 6 つのコンポーネントで構成されています。 (x, y, z, r, g, b)

固定機能の色属性は、クライアントの状態によって有効にする必要がありますGL_COLOR_ARRAY。で指定された属性を追加しますglColorPointer

各属性タプルのサイズは 24 バイトです。これは、タプルが 6 つのコンポーネントで構成(x, y, z, r, g, b)され、各コンポーネントのサイズが 4 バイトであるためです (これは のサイズですfloat)。このサイズは、それぞれの 3 番目のパラメータ ( ) に
渡す必要があります。srideglVertexPointerglColorPointer

名前付きバッファ オブジェクトがバインドされている場合、glVertexPointerそれぞれの最後のパラメータはglColorPointer、バッファ オブジェクトのバッファ ストアへのバイト オフセットとして扱われます。オフセットは、属性の最初のコンポーネントまでのバイト数です。オフセットが 0 の
場合は、属性タプルの最初のコンポーネントであるためです。オフセットが 3*4=12 バイトの場合は、3 つの座標の後にあり、各コンポーネントのサイズが 4 であるためです。最後のパラメーターの型はポインターであるため、オフセットをキャストする必要があります(例: )。この python 組み込みライブラリをインポートする必要があります。オフセットが 0 の場合、 の代わりに を使用できます。glVertexPointer(x, y, z)glColorPointer(r, g, b)(x, y, z)ctypes.c_void_pctypes.c_void_p(3*4)ctypesNonectypes.c_void_p(0)

頂点属性の仕様は次のようになります。

glBindBuffer(GL_ARRAY_BUFFER, vbo)

stride = 6*4 # (24 bates) : [x, y, z, r, g, b] * sizeof(float)

glEnableClientState(GL_VERTEX_ARRAY)
glVertexPointer(3, GL_FLOAT, stride, None)

glEnableClientState(GL_COLOR_ARRAY)
offset = 3*4 # (12 bytes) : the rgb color starts after the 3 coordinates x, y, z 
glColorPointer(3, GL_FLOAT, stride, ctypes.c_void_p(offset))

すべて一緒に:

import ctypes 

def LoadVertices(pcd_files):
    attributes = []
    for i in pcd_files:
       pc = pypcd.PointCloud.from_path(i)
       number_of_points = pc.get_metadata().get('points')
       z = pc.pc_data['z']
       x = pc.pc_data['x']
       y = pc.pc_data['y']
       r = # set the RGB color data here
       g =
       b = 
       for j in range(number_of_points):
           attributes += [x[j], y[j], z[j], r[j], g[j], b[j]]
    return attributes

def CreateBuffer(attributes):
    bufferdata = (ctypes.c_float*len(attributes))(*attributes) # float buffer
    buffersize = len(attributes)*4                             # buffer size in bytes 

    vbo = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glBufferData(GL_ARRAY_BUFFER, buffersize, bufferdata, GL_STATIC_DRAW) 
    glBindBuffer(GL_ARRAY_BUFFER, 0)
    return vbo

def DrawBuffer(vbo, noOfVertices):
    glBindBuffer(GL_ARRAY_BUFFER, vbo)

    stride = 6*4 # (24 bates) : [x, y, z, r, g, b] * sizeof(float)

    glEnableClientState(GL_VERTEX_ARRAY)
    glVertexPointer(3, GL_FLOAT, stride, None)

    glEnableClientState(GL_COLOR_ARRAY)
    offset = 3*4 # (12 bytes) : the rgb color starts after the 3 coordinates x, y, z 
    glColorPointer(3, GL_FLOAT, stride, ctypes.c_void_p(offset))

    glDrawArrays(GL_POINTS, 0, noOfVertices)

    glDisableClientState(GL_VERTEX_ARRAY)
    glDisableClientState(GL_COLOR_ARRAY)
    glBindBuffer(GL_ARRAY_BUFFER, 0)
files = glob.glob(os.getcwd() + "\\" + PCD_OutPutDirectory + "\*.pcd")

pygame.init()
display = (800, 600)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)

vArray    = LoadVertices(files)
noPoints  = len(vArray) // 6  # 6 components per attribute tuple
bufferObj = CreateBuffer(vArray)

gluPerspective(50, (display[0] / display[1]), 0.1, 5000)
glTranslatef(0, 0, -1000)
Clock = pygame.time.Clock()
while True:
    Clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
    glRotatef(2, 1, 1, 3)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    DrawBuffer(bufferObj, noPoints)

    pygame.display.flip()
于 2019-06-27T15:50:57.277 に答える