0

私はpython / PyOpenGLで作業していますが、呼び出しは基本的にOpenGL自体に直接マッピングされるため、どちらかを知っている人に助けを求めています.

私は自分でファセットに分解した大きな 3D システムを持っています。コードでの私の最初の試みは次のようになりました。

from OpenGL.GL import *

def render(facets):
  for facet in facets:
    glColor( facet['color'] )
    glBegin(GL_TRIANGLES)
    for v in facet['vertices']:
      glVertex(v)
    glEnd()

つまり、一度に 1 つずつ Python オブジェクトを実行し、それぞれ個別に描画しました。レンダリングされる色は、三角形の表面の色として、ファセットごと、つまり三角形ごとに設定されました。

この方法でファセットを生成するコードをデバッグしたので、次のようにネイティブの OpenGL リストを使用して、ファセットをより高速にレンダリングしたいと考えました (pyglet のソース スニペットに基づく)。

def build_compiled_gllist(vertices, facets):
  """this time, the vertices must be specified globally, and referenced by
  indices in order to use the list paradigm. vertices is a list of 3-vectors, and
  facets are dicts containing 'normal' (a 3-vector) 'vertices' (indices to the 
  other argument) and 'color' (the color the triangle should be)."""

  # first flatten out the arrays:
  vertices = [x for point in vertices for x in point]
  normals = [x for facet in facets for x in facet['normal']]
  indices = [i for facet in facets for i in facet['vertices']]
  colors = [x for facet in facets for x in facet['color']]

  # then convert to OpenGL / ctypes arrays:
  vertices = (GLfloat * len(vertices))(*vertices)
  normals = (GLfloat * len(normals))(*normals)
  indices = (GLuint * len(indices))(*indices)
  colors = (GLfloat * len(colors))(*colors)

  # finally, build the list:
  list = glGenLists(1)
  glNewList(list, GL_COMPILE)

  glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
  glEnableClientState(GL_VERTEX_ARRAY)
  glEnableClientState(GL_NORMAL_ARRAY)
  glEnableClientState(GL_COLOR_ARRAY)
  glVertexPointer(3, GL_FLOAT, 0, vertices)
  glNormalPointer(GL_FLOAT, 0, normals)
  glColorPointer(3, GL_FLOAT, 0, colors)
  glDrawElements(GL_TRIANGLES, len(indices), GL_UNSIGNED_INT, indices)
  glPopClientAttrib()

  glEndList()

  return list

def run_gl_render(render_list):
  """trivial render function"""
  glCallList(render_list)

しかし、私の色は完全に間違っています。ファセットはオブジェクトにグループ化され、オブジェクト内ではすべてのファセットの色が同じである必要があります。代わりに、それらは完全にランダムに見えます。

他の例を見ると、この色の配列は面ごとではなく頂点ごとのようです。それはどのように理にかなっていますか?頂点は定義上レンダリングできないポイントです。ファセットはレンダリングされるものであり、色を持つものです! 私のシステムのすべての頂点は、2 つの facet-collections/object 間で共有されるため、その名前には 2 つの色が必要です。

このデータがどのように構造化されているかを明確にしてください。使用しているモデルを明らかに誤解しています。

4

1 に答える 1

3

はい、色は頂点ごとに指定されます。シェードモデルによっては、使用できる色は1つだけですが、各頂点には色が付けられます。置き換えるとコードが機能するはずです

colors = [x for facet in facets for x in facet['color']]

colors = [x for facet in facets for x in facet['color']*3]

各頂点の色を複製します。通常のデータが面ごとの場合は、通常のデータに対して同じことを行う必要があります。また、色と通常の値は、インデックスではなく、頂点の引数と一致する必要があることにも注意してください。

ちなみに、元のコードを使用してディスプレイリストを作成することはできます。つまり、それは完全に有効です

def compile_object(facets):
  displist = glGenLists(1)
  glNewList(displist, GL_COMPILE)
  # You can call glColor inside of glBegin/glEnd, so I moved them
  # outside the loop, which might improve performance somewhat
  glBegin(GL_TRIANGLES)
  for facet in facets:
    glColor( facet['color'] )
    for v in facet['vertices']:
      glVertex(v)
  glEnd()
  glEndList()
  return displist

これらのチュートリアルをお試しください

于 2013-01-15T17:16:03.883 に答える