Table Of Contents

Previous topic

Model View Matrix

Next topic

Projection Matrix

This Page

Vertex Array

ここまではglVertexで三角形を描画してきたが、ここで配列からデータ投入して連続した三角形を描画する方法を導入する。 頂点データを格納した配列を頂点配列(VertexArray)と呼ぶ。

VertexArrayクラス

vertexarray

#!/usr/bin/python
# coding: utf-8

from OpenGL.GL import *

'''
頂点配列

====
属性
====
* 位置
'''
class VertexArray(object):
    def __init__(self, vertices):
        self.vertices=vertices

    def __str__(self):
        return "<VertexArray %d>" % len(self.vertices)

    def draw(self):
        # 位置属性
        glEnableClientState(GL_VERTEX_ARRAY)
        glVertexPointer(3, GL_FLOAT, 0, self.vertices)
        # 描画
        glDrawArrays(GL_TRIANGLES, 0, len(self.vertices))
        # 後始末
        glDisableClientState(GL_VERTEX_ARRAY)



'''
頂点配列

====
属性
====
* 位置
* UV
'''
class VertexArrayWithUV(object):
    def __init__(self, vertices, uvarray):
        self.vertices=vertices
        self.uvarray=uvarray

    def __str__(self):
        return "<VertexArrayWithUV %d>" % len(self.vertices)

    def draw(self):
        # 位置属性
        glEnableClientState(GL_VERTEX_ARRAY)
        glVertexPointer(3, GL_FLOAT, 0, self.vertices)
        # UV属性
        glEnableClientState(GL_TEXTURE_COORD_ARRAY)
        glTexCoordPointer(2, GL_FLOAT, 0, self.uvarray)
        # 描画
        glDrawArrays(GL_TRIANGLES, 0, len(self.vertices))
        # 後始末
        glDisableClientState(GL_TEXTURE_COORD_ARRAY)
        glDisableClientState(GL_VERTEX_ARRAY)


'''
インデックス参照頂点配列

====
属性
====
* 位置
'''
class IndexedVertexArray(object):
    def __init__(self, vertices, indices):
        self.vertices=vertices
        self.indices=indices

    def draw(self):
        # 位置属性
        glEnableClientState(GL_VERTEX_ARRAY)
        glVertexPointer(3, GL_FLOAT, 0, self.vertices)
        # indexによる描画
        glDrawElements(GL_TRIANGLES, len(self.indices),
                GL_UNSIGNED_INT, self.indices)
        # 後始末
        glDisableClientState(GL_VERTEX_ARRAY)


'''
インデックス参照頂点配列

====
属性
====
* 位置
* 色
'''
class IndexedVertexArrayWithColor(object):
    def __init__(self, vertices, colors, indices):
        self.vertices=vertices
        self.colors=colors
        self.indices=indices

    def draw(self):
        # 位置属性
        glEnableClientState(GL_VERTEX_ARRAY)
        glVertexPointer(3, GL_FLOAT, 0, self.vertices)
        # 色属性
        glEnableClientState(GL_COLOR_ARRAY)
        glColorPointer(3, GL_FLOAT, 0, self.colors)
        # indexによる描画
        glDrawElements(GL_TRIANGLES, len(self.indices),
                GL_UNSIGNED_INT, self.indices)
        # 後始末
        glDisableClientState(GL_COLOR_ARRAY)
        glDisableClientState(GL_VERTEX_ARRAY)

頂点配列の保持と描画はこれだけで、むしろ glBegin()~glVertex()~glEnd() の呼び出しよりシンプルなくらいになる。 問題は、如何にこの配列にデータを満たすのかということになる。

Vertex(頂点)

OpenGLの頂点について軽く説明。

OpenGLの頂点は、三次元空間上の座標をもった点で座標以外にも複数の属性を持つことができる。以下、各属性について

位置属性

必須の属性で(x, y, z, w)。三次元の同次座標表現(アフィン変換用)となっている。 モデルビュー座標を操作している間は、基本的にw=1なのでw値を意識する必要は無い。

透視投影で遠近感の処理をするときに、wが1以外になる。視点から遠い点ほどwが大きくなるように仕込んでから、wが1になるように(x, y, z, w)をわる(同時座標の正規化)ことで遠近感を表現することができる。

色属性

頂点カラー。隣の点と色が違う場合にグラデーションを作れる。

UV属性

UV座標。テクスチャを貼るときに使う。

頂点配列で立方体を作る

サンプルとして頂点配列で立方体を描画する。 立方体は、各面に2つずつ三角形が含まれるので12の三角形を含む。 glVertexだと36回呼び出しが必要となる(GL_TRIANGLESを使う場合)ところを、 頂点配列を使ってサクッと描画する。 面倒なところが、描画時から初期化時に移ることになる。

Cube.py

#!/usr/bin/python
# coding: utf8

from OpenGL.GL import *

import glut_ui
import glbase
import vertexarray


def createCube(size):
    return vertexarray.IndexedVertexArrayWithColor(
            vertices=[
                -size, -size, -size, # v0
                size, -size, -size, # v1
                size,  size, -size, # v2
                -size,  size, -size, # v3
                -size, -size,  size, # v4
                size, -size,  size, # v5
                size,  size,  size, # v6
                -size,  size,  size, # v7
                ],
            colors=[
                1, 0, 0, # v0の色
                0, 1, 0, # v1の色
                0, 0, 1, # v2の色
                1, 1, 1, # v3の色
                0, 1, 1, # v4の色
                1, 0, 1, # v5の色
                1, 1, 0, # v6の色
                0, 0, 0, # v7の色
                ],
            indices=[
                4, 5, 6, # triangle0の頂点index
                6, 7, 4, # triangle1の頂点index
                5, 1, 2, # triangle2の頂点index
                2, 6, 5, # triangle3の頂点index
                1, 0, 3, # triangle4の頂点index
                3, 2, 1, # triangle5の頂点index
                0, 4, 7, # triangle6の頂点index
                7, 3, 0, # triangle7の頂点index
                3, 7, 6, # triangle8の頂点index
                6, 2, 3, # triangle9の頂点index
                0, 1, 5, # triangle10の頂点index
                5, 4, 0, # triangle11の頂点index
            ])


if __name__=="__main__":
    import Rotation
    glut_ui.run(glbase.BaseController(Rotation.Rotation(), createCube(0.4)))
inserted by FC2 system