向我解释,就像我是5:OpenGL 4.x渲染管道



我在opengl的停留时间里花了最后几个星期。尽管在一些较旧的NEHE示例之后,我没有问题,但从我阅读的所有内容中,OpenGL4都是完全不同的过程。而且我可以访问《红皮书》和《超级圣经》,但前者仍在提供旧版OpenGL呼叫,而后者使用自己的图书馆。两者都不有助于理解如何在项目中整理代码。例如,我目前的理解是Glu和Glut是遗产,不应用于OpenGL 4。

我可以很容易地为假设的模型空间生成顶点。我很难理解模型最终如何显示在我的屏幕上。我的尝试中约有95%的尝试最终出现黑色屏幕。

预先感谢。

这是一些代码:

# primatives.py
from collections import Iterable
from functools import reduce
import operator
import numpy as np
from exc import UnimplementedMethod
class Primative(object):
    SIZE = 1  # number of pixels on a default grid
    def __init__(self, point=None, *args, **kwargs):
        self.point = point if isinstance(point, Iterable) else [0, 0, 0]
        self.point = np.array(self.point, dtype=np.float32)
        scaler = [self.SIZE/2]*len(self.point)
        self.point = (self.point * scaler).tolist()
    @property
    def active(self):
        attr = "__active__"
        if not hasattr(self, attr):
            setattr(self, attr, False)
        return getattr(self, attr)
    @active.setter
    def active(self, value):
        attr = "__active__"
        if value in [True, False]:
            setattr(self, attr, value)
        return getattr(self, attr)
    @property
    def vertices(self):
        """Returns a simple list of calculated vertices"""
        clsname = self.__class__.__name__
        raise UnimplementedMethod(clsname)
    @property
    def dimension(self):
        return len(self.point)
    @property
    def scaler(self):
        attr = "__scaler__"
        if not hasattr(self, attr):
            size = self.SIZE / 2
            setattr(self, attr, [size]*self.dimension)
        return getattr(self, attr)
    @scaler.setter
    def scaler(self, *values):
        attr = "__scaler__"
        values = values[0] if len(values) == 1 else values
        if len(values) == 1 and len(values) != self.point:
            if isinstance(values, [int, float]):
                setattr(self, attr, [values]*self.dimension)
            elif isinstance(values, Iterable):
                data = [(v, i)
                        for v, i in zip(values, xrange(self.dimension))]
                value = [v for v, i in data]
                if len(value) != self.dimension:
                    raise ValueError
                setattr(self, attr, value)
    @property
    def translation(self):
        attr = "__transalation__"
        if not hasattr(self, attr):
            size = self.SIZE / 2
            setattr(self, attr, [size]*self.dimension)
        return getattr(self, attr)
    @translation.setter
    def transalation(self, *values):
        attr = "__transalation__"
        values = values[0] if len(values) == 1 else values
        if isinstance(values, (int, float)):
            setattr(self, attr, [values]*self.dimension)
        elif isinstance(values, Iterable):
            data = [(v, i)
                    for v, i in zip(values, xrange(self.dimension))]
            value = [v for v, i in data]
            if len(value) != self.dimension:
                raise ValueError
            setattr(self, attr, value)
    @property
    def rotation(self):
        """
        Rotation in radians
        """
        attr = "__rotation__"
        if not hasattr(self, attr):
            setattr(self, attr, [0]*self.dimension)
        return getattr(self, attr)
    @rotation.setter
    def rotation(self, *values):
        """
        Rotation in radians
        """
        attr = "__rotation__"
        values = values[0] if len(values) == 1 else values
        if isinstance(values, (int, float)):
            setattr(self, attr, [values]*self.dimension)
        elif isinstance(values, Iterable):
            data = [(v, i)
                    for v, i in zip(values, xrange(self.dimension))]
            value = [v for v, i in data]
            if len(value) != self.dimension:
                raise ValueError
            setattr(self, attr, value)
    @property
    def volume(self):
        clsname = self.__class__.__name__
        raise UnimplementedMethod(clsname)

class Cube(Primative):
    #       G           H
    #        * --------- *
    #       /|          /|
    #    C / |       D / |
    #     * --------- *  |
    #     |  * -------|- *
    #     | / E       | / F
    #     |/          |/
    #     * --------- *
    #      A           B
    @property
    def center_of_mass(self):
        """
        Uses density to calculate center of mass
        """
        return self.point
    @property
    def material(self):
        clsname = self.__class__.__name__
        raise UnimplementedMethod(clsname)
    @material.setter
    def material(self, value):
        clsname = self.__class__.__name__
        raise UnimplementedMethod(clsname)
    @property
    def mass(self):
        return self.material.density * self.volume
    @property
    def volume(self):
        func = operator.mul
        return reduce(func, self.scaler, 1)
    @property
    def normals(self):
        """
        computes the vertex normals
        """
        norm = []
        if len(self.point) == 1:
            norm = [
            # counter clockwise
            # x    (left hand rule)
            (-1),           # A
            (1)             # B
            ]
        elif len(self.point) == 2:
            norm = [  
            # counter clockwise
            # x, y    (left hand rule)
            (-1, -1),       # A
            (1, -1),        # B
            (1, 1),         # C
            (-1, 1)         # D
            ]
        elif len(self.point) == 3:
            norm = [
            # counter clockwise
            # x, y, z    (left hand rule)
            (-1, -1, 1),    # A 0
            (1, -1, 1),     # B 1
            (1, 1, 1),      # D 2
            (-1, 1, 1),     # C 3
            (-1, -1, -1),   # E 4
            (1, -1, -1),    # F 5
            (1, 1, -1),     # H 6
            (-1, 1, -1),    # G 7
            ]
        return norm
    @property
    def indices(self):
        indices = []
        if len(self.point) == 2:
            indices = [
                [[1, 0, 3], [2, 3, 1]],   # BAC CDB front
            ]
        elif len(self.point) == 3:
            indices = [
                [[1, 0, 3], [2, 3, 1]],  # BAC CDB front
                [[5, 1, 2], [2, 6, 5]],  # FBD DHF right
                [[4, 5, 6], [6, 7, 4]],  # EFH HGE back
                [[5, 4, 0], [0, 1, 5]],  # FEA ABF bottom
                [[0, 4, 7], [7, 3, 0]],  # AEG GCA left
                [[2, 3, 7], [7, 6, 2]],  # DCG GHD top
            ]
        return indices
    @property
    def nodes(self):
        normals = np.array(self.normals, dtype=np.float32)
        scaler = np.array(self.scaler, dtype=np.float32)
        nodes = normals * scaler
        return nodes.tolist()
    @property
    def vertices(self):
        verts = (n for node in self.nodes for n in node)
        return verts

和另一个:

# Voxel.py
from collections import Iterable
from time import time
import numpy as np
import pyglet
from pyglet.gl import *
from primatives import Cube
import materials

class Voxel(Cube):
    """
    Standard Voxel
    """
    def __init__(self, point=None, material=None):
        super(Voxel, self).__init__(point=point)
        if isinstance(material, materials.Material):
            self.material = material
        else:
            self.material = materials.stone
    def __str__(self):
        point = ", ".join(str(p) for p in self.point)
        material = self.material.name
        desc = "<Voxel [%s] (%s)>" % (material, point)
        return desc
    def __repr__(self):
        point = ", ".join(str(p) for p in self.point)
        material = self.material.name
        desc = "<Voxel %s(%s)>" % (material, point)
        return desc
    @property
    def material(self):
        attr = "__material__"
        if not hasattr(self, attr):
            setattr(self, attr, materials.ether)
        return getattr(self, attr)
    @material.setter
    def material(self, value):
        attr = "__material__"
        if value in materials.valid_materials:
            setattr(self, attr, value)
        return getattr(self, attr)

class Chunk(Cube):
    """
    A Chunk contains a specified number of Voxels.  Chunks are an
    optimization to manage voxels which do not change often.
    """
    NUMBER = 16
    NUMBER_OF_VOXELS_X = NUMBER
    NUMBER_OF_VOXELS_Y = NUMBER
    NUMBER_OF_VOXELS_Z = NUMBER
    def __init__(self, point=None):
        point = (0, 0, 0) if point is None else point
        super(Chunk, self).__init__(point=point)
        self.batch = pyglet.graphics.Batch()
        points = []
        x_scale = self.NUMBER_OF_VOXELS_X / 2
        y_scale = self.NUMBER_OF_VOXELS_Y / 2
        z_scale = self.NUMBER_OF_VOXELS_Z / 2
        self.rebuild_mesh = True
        if len(point) == 1:
            points = ((x,) for x in xrange(-x_scale, x_scale))
        elif len(point) == 2:
            points = ((x, y) 
                      for x in xrange(-x_scale, x_scale) 
                      for y in xrange(-y_scale, y_scale))
        elif len(point) == 3:
            points = ((x, y, z) 
                      for x in xrange(-x_scale, x_scale) 
                      for y in xrange(-y_scale, y_scale)
                      for z in xrange(-z_scale, z_scale))
        t = time()
        self.voxels = dict((point, Voxel(point)) for point in points)
        self.active_voxels = dict((p, v) 
                                  for p, v in self.voxels.iteritems()
                                  if v.active)
        self.inactive_voxels = dict((p, v) 
                                    for p, v in self.voxels.iteritems()
                                    if not v.active)
        print 'Setup Time: %s' % (time() - t)
    @property
    def material(self):
        return ether
    @material.setter
    def material(self, value):
        if value in materials.valid_materials:
            for voxel in self.voxels:
                if voxel.material != value:
                    voxel.material = value
                    self.rebuild_mesh = True
    @property
    def mesh(self):
        """
        Returns the verticies as defined by the Chunk's Voxels
        """
        attr = "__mesh__"
        if self.rebuild_mesh == True:
            self.mesh_vert_count = 0
            vertices = []
            t = time()
            for point, voxel in self.active_voxels.iteritems():
                if voxel.active is True:
                    vertices.extend(voxel.vertices)
                    num_verts_in_voxel = len(voxel.normals)
                    self.mesh_vert_count += num_verts_in_voxel
            print "Mesh Generation Time: %s" % time() - t
            vertices = tuple(vertices)
            setattr(self, attr, vertices)
            voxel_count = len(self.active_voxels)
            voxel_mesh = self.mesh
            count = self.mesh_vert_count
            group = None
            data = ('v3f/static', vertices)
            self.batch.add(count, self.mode, group, data)
        return getattr(self, attr)
    @property
    def center_of_mass(self):
        """
        Uses density to calculate center of mass.  This is probably only
        useful if the chunk represents an object.
        """
        center = self.point
        points = []
        for point, voxel in self.active_voxels.iteritems():
            mass = voxel.mass
            if mass > 0:
                point = [p*mass for p in point]
            points.append(point)
        points = np.array(points)
        means = []
        if points.any():
            for idx, val in enumerate(self.point):
                means.append(np.mean(points[:, idx]))
        if means:
            center = means
        return center
    def add(self, voxel):
        added = False
        point = None
        if isinstance(voxel, Voxel):
            point = voxel.point
        elif isinstance(voxel, Iterable):
            point = voxel
        if point in self.inactive_voxels.iterkeys():
            last = self.voxels[point]
            self.voxels[point] = voxel if isinstance(voxel, Voxel) else last
            self.voxels[point].active = True
            self.active_voxels[point] = self.voxels[point]
            self.inactive_voxels.pop(point)
            added = True
            self.rebuild_mesh = True
        return added
    def remove(self, voxel):
        removed = False
        point = None
        if isinstance(voxel, Voxel):
            point = voxel.point
        elif isinstance(voxel, Iterable):
            point = voxel
        if point in self.active_voxels.iterkeys():
            last = self.voxels[point]
            self.voxels[point] = voxel if isinstance(voxel, Voxel) else last
            self.voxels[point].active = False
            self.inactive_voxels[point] = self.voxels[point]
            self.active_voxels.pop(point)
            removed = True
            self.rebuild_mesh = True
        return removed
    def render(self):
        voxels = len(self.active_voxels)
        self.batch.draw()
        return voxels
if __name__ == "__main__":
    import pyglet
    from pyglet.gl import *
    class Window(pyglet.window.Window):
        def __init__(self, *args, **kwargs):
            super(Window, self).__init__(*args, **kwargs)
            vox_cnt = self.setup_scene()
            print 'Added: %s voxels' % (vox_cnt)
        def run(self):
            """wrapper to start the gui loop"""
            pyglet.app.run()
        def setup_scene(self):
            self.chunk = Chunk()
            cnt = 0
            t = time()
            for x in xrange(self.chunk.NUMBER_OF_VOXELS_X):
                for y in xrange(self.chunk.NUMBER_OF_VOXELS_Y):
                        self.chunk.add((x, y))
                        cnt += 1
            print "Setup Scene Time: %s" % (time() - t)
            return cnt
        def render_scene(self):
            y = h = self.height
            x = w = self.width
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            glMatrixMode(GL_PROJECTION)
            glLoadIdentity()
            # glEnable(GL_DEPTH_TEST)
            # glDepthFunc(GL_LESS)
            t = time()
            voxels_drawn = self.chunk.render()
            print 'Render Time: %s' % (time() - t)
            print 'Points Rendered %s' % voxels_drawn
            # array_len = len(self.vertex_data)
            # glDrawArrays(GL_TRIANGLES, 0, array_len)
        def on_draw(self, *args, **kwargs):
            self.render_scene()
    w = Window()
    w.run()

源分布中有示例,如果下载它们(链接到页面)。

您想看到的一个是在<top-dir>/examples/opengl.py中 - 对于圆环。如果您进行以下修改,您将有一个立方体。

# line 91:
cube.draw()  # previously torus.draw()
# line 178: replace the line with the below (GL_TRIANGLES for GL_QUADS)
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, indices)
# line 187:
cube = Cube(0.8)  # previously torus = Torus(1, 0.3, 50, 30)

# replace lines 125 through 166 with:
class Cube(object):
    Vertices =(0.,0.,0., 1.,0.,0., 0.,0.,1., 1.,0.,1.,
               0.,1.,0., 1.,1.,0., 0.,1.,1., 1.,1.,1.)
    def __init__(self, scale):
        # Create the vertex and normal arrays.
        indices = [0,1,3,2, 1,5,7,3, 5,4,6,7,
                   0,2,6,4, 0,4,5,1, 2,3,7,6]
        normals = [  0.0, -1.0,  0.0,
                     1.0,  0.0,  0.0,
                     0.0,  1.0,  0.0,
                    -1.0,  0.0,  0.0,
                     0.0,  0.0,  -1.0,
                     0.0,  0.0,   1.0]
        vertices = [scale * v for v in Cube.Vertices]
        vertices = (GLfloat * len(vertices))(*vertices)
        normals = (GLfloat * len(normals))(*normals)

我对Python的类包装器不了解,而且我已经有一段时间没有进行任何图形编程。但是我知道,您应该在硬件伙计们社区中搜索有关实际工作和内部词的合格答案谁可以创建VHDL GPU代码或编写低级驱动程序。他们知道确保其工作原理以及某些常见问题解释应该在其社区中可用。

基于该假设,这是一些谷歌搜索我的首先:

  1. OpenGL 4.4 API参考卡 - Page 7 - (在http://www.opengl.org上的顶级资源之间可用)显示一些简单的图片>图片(5岁?)渲染管道分为

    • 蓝色块指示各种缓冲区,这些缓冲液由OpenGL管道喂食或喂食
    • 绿色块指示固定功能阶段
    • 黄色块指示可编程阶段
  2. 震惊的沃尔顿 - DirectX与OpenGL辩论的回归指向130页的幻灯片,OpenGL如何解锁15X性能增长|NVIDIA博客。这两篇文章都属于AMD,Intel,NVIDIA,Game Developer Converence

我很久以前使用C,C ,Delphi的一些简单的OpenGL,我的建议是首先摆脱Python映射。寻找合适的班级图书馆,并提供良好的社区,只有之后您就知道您要寻找的东西。

以上是恕我直言的水,要在

中开始钓鱼

相关内容

  • 没有找到相关文章

最新更新