File: OldStyleRenderer.py

package info (click to toggle)
pycollada 0.6-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,936 kB
  • sloc: python: 17,667; makefile: 98
file content (194 lines) | stat: -rw-r--r-- 8,945 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#!/usr/bin/env python

from __future__ import print_function
from __future__ import absolute_import

import collada
import numpy
import pyglet
from pyglet.gl import *
import ctypes
from . import glutils


class OldStyleRenderer: 

    def __init__(self, dae, window):
        self.dae = dae
        self.window = window
        # to calculate model boundary
        self.z_max = -100000.0
        self.z_min = 100000.0
        self.textures = {}

        glShadeModel(GL_SMOOTH) # Enable Smooth Shading
        glClearColor(0.0, 0.0, 0.0, 0.5) # Black Background
        glClearDepth(1.0) # Depth Buffer Setup
        glEnable(GL_DEPTH_TEST) # Enables Depth Testing
        glDepthFunc(GL_LEQUAL) # The Type Of Depth Testing To Do
        
        glEnable(GL_MULTISAMPLE);

        glEnable(GL_LIGHTING)
        glEnable(GL_LIGHT0)
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
        glCullFace(GL_BACK)

        glEnable(GL_TEXTURE_2D) # Enable Texture Mapping
        # glEnable(GL_TEXTURE_RECTANGLE_ARB) # Enable Texture Mapping
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)

        # create one display list
        print('Creating display list...')
        print('It could take some time. Please be patient :-) .')
        self.displist = glGenLists(1)
        # compile the display list, store a triangle in it
        glNewList(self.displist, GL_COMPILE)
        self.drawPrimitives()
        glEndList()
        print('done. Ready to render.')

    def drawPrimitives(self):
        glBegin(GL_TRIANGLES)
        
        if self.dae.scene is not None:
            for geom in self.dae.scene.objects('geometry'):
                for prim in geom.primitives():
                    mat = prim.material
                    diff_color = (GLfloat * 4)(*(0.3,0.3,0.3,0.0))
                    spec_color = None 
                    shininess = None
                    amb_color = None
                    tex_id = None
                    for prop in mat.effect.supported:
                        value = getattr(mat.effect, prop)
                        # it can be a float, a color (tuple) or a Map
                        # ( a texture )
                        if isinstance(value, collada.material.Map):
                            colladaimage = value.sampler.surface.image
                            # Accessing this attribute forces the
                            # loading of the image using PIL if
                            # available. Unless it is already loaded.
                            img = colladaimage.pilimage
                            if img: # can read and PIL available
                                # See if we already have texture for this image
                                if colladaimage.id in self.textures:
                                    tex_id = self.textures[colladaimage.id]
                                else:
                                    # If not - create new texture
                                    try:
                                        # get image meta-data
                                        # (dimensions) and data
                                        (ix, iy, tex_data) = (img.size[0], img.size[1], img.tostring("raw", "RGBA", 0, -1))
                                    except SystemError:
                                        # has no alpha channel,
                                        # synthesize one
                                        (ix, iy, tex_data) = (img.size[0], img.size[1], img.tostring("raw", "RGBX", 0, -1))
                                    # generate a texture ID
                                    tid = GLuint()
                                    glGenTextures(1, ctypes.byref(tid))
                                    tex_id = tid.value
                                    # make it current
                                    glBindTexture(GL_TEXTURE_2D, tex_id)
                                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
                                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
                                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
                                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
                                    #glPixelStorei(GL_UNPACK_ALIGNMENT, 4)
                                    # copy the texture into the
                                    # current texture ID
                                    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data)

                                    self.textures[colladaimage.id] = tex_id
                            else:
                                print('  %s = Texture %s: (not available)'%(
                                    prop, colladaimage.id))
                        else:
                            if prop == 'diffuse' and value is not None:
                                diff_color = (GLfloat * 4)(*value)
                            elif prop == 'specular' and value is not None:
                                spec_color = (GLfloat * 4)(*value)
                            elif prop == 'ambient' and value is not None:
                                amb_color = (GLfloat * 4)(*value)
                            elif prop == 'shininess' and value is not None:
                                shininess = value

                    # use primitive-specific ways to get triangles
                    prim_type = type(prim).__name__
                    if prim_type == 'BoundTriangleSet':
                        triangles = prim
                    elif prim_type == 'BoundPolylist':
                        triangles = prim.triangleset()
                    else:
                        print('Unsupported mesh used:', prim_type)
                        triangles = []

                    if tex_id is not None:
                        glBindTexture(GL_TEXTURE_2D, tex_id)
                    else:
                        glBindTexture(GL_TEXTURE_2D, 0)


                    # add triangles to the display list
                    for t in triangles:
                        nidx = 0
                        if tex_id is not None and len(t.texcoords) > 0:
                            texcoords = t.texcoords[0]
                        else:
                            texcoords = None

                        for vidx in t.indices:
                            if diff_color is not None:
                                glMaterialfv(GL_FRONT, GL_DIFFUSE, diff_color)
                            if spec_color is not None:
                                glMaterialfv(GL_FRONT, GL_SPECULAR, spec_color)
                            if amb_color is not None:
                                glMaterialfv(GL_FRONT, GL_AMBIENT, amb_color)
                            if shininess is not None:
                                glMaterialfv(GL_FRONT, GL_SHININESS, (GLfloat * 1)(shininess))

                            # if not t.normals is None:
                            glNormal3fv((GLfloat * 3)(*t.normals[nidx]))
                            if texcoords is not None:
                                glTexCoord2fv((GLfloat * 2)(*texcoords[nidx]))

                            nidx += 1

                            v = prim.vertex[vidx]
                            glVertex3fv((GLfloat * 3)(*v))

                            # calculate max and min Z coordinate
                            if v[2] > self.z_max:
                                self.z_max = v[2]
                            elif v[2] < self.z_min:
                                self.z_min = v[2]
        glutils.getGLError()
        glEnd()


    def render(self, rotate_x, rotate_y, rotate_z):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glMatrixMode(GL_PROJECTION) # Select The Projection Matrix
        glLoadIdentity() # Reset The Projection Matrix
        if self.window.height == 0: # Calculate The Aspect Ratio Of The Window
            gluPerspective(100, self.window.width, 1.0, 5000.0)
        else:
            gluPerspective(100, self.window.width / self.window.height, 1.0, 5000.0)
        glMatrixMode(GL_MODELVIEW) # Select The Model View Matrix
        glLoadIdentity()
        z_offset = self.z_min - (self.z_max - self.z_min) * 3
        light_pos = (GLfloat * 3)(100.0, 100.0, 100.0 * -z_offset)
        glLightfv(GL_LIGHT0, GL_POSITION, light_pos)
        glTranslatef(0, 0, z_offset)
        glRotatef(rotate_x, 1.0, 0.0, 0.0)
        glRotatef(rotate_y, 0.0, 1.0, 0.0)
        glRotatef(rotate_z, 0.0, 0.0, 1.0)
        
        # draw the display list
        glCallList(self.displist)


    def cleanup(self):
        print('Renderer cleaning up')
        glDeleteLists(self.displist, 1)