source: src/materials/Textured.pym @ 1345:ff8ef9c6bbb7

Revision 1345:ff8ef9c6bbb7, 10.4 KB checked in by Arc Riley <arcriley@…>, 6 years ago (diff)

Happy New Year! (copyright string update)

Line 
1# PySoy's materials.Textured class
2#
3# Copyright (C) 2006,2007,2008,2009 PySoy Group
4#
5#  This program is free software; you can redistribute it and/or modify
6#  it under the terms of the GNU Affero General Public License as published
7#  by the Free Software Foundation, either version 3 of the License, or
8#  (at your option) any later version.
9#
10#  This program is distributed in the hope that it will be useful,
11#  but WITHOUT ANY WARRANTY; without even the implied warranty of
12#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13#  GNU Affero General Public License for more details.
14#
15#  You should have received a copy of the GNU Affero General Public License
16#  along with this program; if not, see http://www.gnu.org/licenses
17#
18# $Id: Textured.pym 1393 2008-12-31 23:51:25Z ArcRiley $
19
20cdef class Textured(Material) :
21  '''soy.materials.Textured
22
23    Textured materials support one or more basic textures in addition to the
24    standard Material colors (ambient, diffuse, specular, emission) which
25    are multiplied by the texture color to provide light-based shading.
26   
27    Currently .bumpmap .colormap and .glowmap are supported.
28  '''
29
30  ############################################################################
31  #
32  # Python functions
33  #
34
35  def __cinit__(self,
36                soy.colors.Color ambient=None,
37                soy.colors.Color diffuse=None,
38                soy.colors.Color specular=None,
39                soy.colors.Color emission=None,
40                float shininess=0.5,
41                soy.textures.Texture bumpmap=None,
42                soy.textures.Texture colormap=None,
43                soy.textures.Texture glowmap=None,
44                *args, **keywords) :
45    ######################################
46    #
47    # store the texture arguments
48    #
49    self._bumpmap  = bumpmap
50    self._colormap = colormap
51    self._glowmap  = glowmap
52    #
53    ######################################
54
55
56  ############################################################################
57  #
58  # Properties
59  #
60
61  property colormap :
62    '''soy.materials.Textured.colormap
63
64    When a texture is assigned to this property a colormap texture is rendered.
65
66    In OpenGL terms, this texture is set GL_MODULATE to the lit material color
67    which provides it's shading.  Textures with an alpha component will be
68    translucent to the material's lit color, so to achieve actual translucency
69    this material's colors (ambient/diffuse) must also be translucent.
70
71    Default is None (disabled).
72    '''
73   
74    def __get__(self) :
75      return self._colormap
76
77    def __set__(self, soy.textures.Texture _value) :
78      self._colormap = _value
79
80    def __del__(self) :
81      self._colormap = None
82
83
84  property glowmap :
85    '''soy.materials.Textured.glowmap
86
87    When a texture is assigned to this property a glowmap texture is rendered.
88
89    In OpenGL terms, this texture is set GL_ADD.
90
91    Default is None (disabled).
92    '''
93   
94    def __get__(self) :
95      return self._glowmap
96
97    def __set__(self, soy.textures.Texture _value) :
98      self._glowmap = _value
99
100    def __del__(self) :
101      self._glowmap = None
102
103
104  property bumpmap :
105    '''soy.materials.Textured.bumpmap
106
107    When a texture is assigned to this property a bumpmap texture is rendered.
108
109    This allows artists to add fine-grained detail to 3d objects or the give
110    otherwise smooth/flat surfaces a pattered appearance that changes with
111    the angle of light (shadows/highlights).
112
113    In OpenGL terms, this texture is a dot3 normal map in tangent-space which
114    is mapped to object space by combining it with a normalisation cubemap.
115
116    Default is None (disabled).
117    '''
118
119    def __get__(self) :
120      return self._bumpmap
121
122    def __set__(self, soy.textures.Texture _value) :
123      if _value._chans != 3 :
124        raise ValueError('bumpmaps must be RGB')
125      self._bumpmap = _value
126
127    def __del__(self) :
128      self._bumpmap = None
129
130
131  ############################################################################
132  #
133  # General C functions
134  #
135  cdef int _isTransparent(self) nogil :
136    #
137    # textures are only translucent to the colors, so if either lack
138    # translucency this check will return False
139    #
140    if self._colormap is not None and self._colormap._chans %2 == 1 :
141      return 0
142    if self._ambient._rgba[3] != 1.0 :
143      return 1
144    if self._diffuse._rgba[3] != 1.0 :
145      return 1
146    return 0
147
148
149  cdef int _needsTSLVs(self) nogil :
150    ######################################
151    #
152    # this material usually needs TSLV
153    #
154    return 1
155    #
156    ######################################
157
158
159  ############################################################################
160  #
161  # WindowLoop functions
162  #
163
164  cdef int _render(self, int _pass, float* _texcoords, float* _tslvs) nogil :
165    cdef int _i, _bump, _unit
166    _unit = 0
167    _bump = 0;
168    ######################################
169    #
170    # if there's no bumpmap, render it like a textured material
171    #
172    if self._bumpmap is None :
173      _pass += 1
174    else :
175      _bump = 1
176    #
177    ######################################
178    #
179    # this will only be true if _pass==0 and bumpmap is not None
180    #
181    if _pass == 0 :
182      ####################################
183      #
184      # Texture1 - the normalisation cubemap
185      #
186      gl.glActiveTexture(gl.GL_TEXTURE1)
187      gl.glClientActiveTexture(gl.GL_TEXTURE1)
188      gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY)
189      gl.glTexCoordPointer(3,  gl.GL_FLOAT,  0, _tslvs)
190      _normalisation_cube_map._enable()
191      gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_COMBINE)
192      gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_SOURCE0_RGB,  gl.GL_TEXTURE)
193      gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_SOURCE1_RGB,  gl.GL_PREVIOUS)
194      gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_COMBINE_RGB,  gl.GL_DOT3_RGB)
195      gl.glTexParameteri(gl.GL_TEXTURE_CUBE_MAP,
196                         gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
197      gl.glTexParameteri(gl.GL_TEXTURE_CUBE_MAP,
198                         gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
199      gl.glTexParameteri(gl.GL_TEXTURE_CUBE_MAP,
200                         gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE)
201      gl.glTexParameteri(gl.GL_TEXTURE_CUBE_MAP,
202                         gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE)
203      gl.glTexParameteri(gl.GL_TEXTURE_CUBE_MAP,
204                         gl.GL_TEXTURE_WRAP_R, gl.GL_CLAMP_TO_EDGE)
205      #
206      ####################################
207      #
208      # Texture0 - the dot3 normal map (bumpmap)
209      #
210      gl.glActiveTexture(gl.GL_TEXTURE0)
211      gl.glClientActiveTexture(gl.GL_TEXTURE0)
212      gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY)
213      gl.glTexCoordPointer(3,  gl.GL_FLOAT, 48, _texcoords)
214      self._bumpmap._enable()
215      gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_COMBINE)
216      gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_SOURCE0_RGB,      gl.GL_TEXTURE)
217      gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_COMBINE_RGB,      gl.GL_REPLACE)
218      #             
219      ####################################
220      #
221      # either return now and render 2-pass or play a trick
222      # no tricks yet
223      #
224      return 1
225      #     
226    ######################################
227    #
228    # Render non-bumpmap passes
229    #
230    if _pass == 1 :
231      if _bump :   
232        ##################################
233        #
234        # start by cleaning up from last pass
235        #
236        gl.glActiveTexture(gl.GL_TEXTURE1)
237        gl.glClientActiveTexture(gl.GL_TEXTURE1)
238        _normalisation_cube_map._disable()
239        gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY)
240        gl.glActiveTexture(gl.GL_TEXTURE0)
241        gl.glClientActiveTexture(gl.GL_TEXTURE0)
242        self._bumpmap._disable()
243        #
244        ##################################
245        #
246        # also setup blending for this pass
247        #
248        gl.glEnable(gl.GL_BLEND)
249        gl.glBlendFunc(gl.GL_DST_COLOR, gl.GL_ZERO)
250        gl.glEnable(gl.GL_POLYGON_OFFSET_FILL)
251        gl.glPolygonOffset(0,-2)
252        #
253      ####################################
254      #
255      # number of shades, currently just 0 or 1
256      #
257      if self._shades == 0 :
258        gl.glShadeModel(gl.GL_SMOOTH)
259      else :
260        gl.glShadeModel(gl.GL_FLAT)
261      #
262      ####################################
263      #
264      # lit material colors and settings
265      #
266      gl.glMaterialfv(gl.GL_FRONT, gl.GL_AMBIENT,   self._ambient._rgba)
267      gl.glMaterialfv(gl.GL_FRONT, gl.GL_DIFFUSE,   self._diffuse._rgba)
268      gl.glMaterialfv(gl.GL_FRONT, gl.GL_SPECULAR,  self._specular._rgba)
269      gl.glMaterialfv(gl.GL_FRONT, gl.GL_EMISSION,  self._emission._rgba)
270      gl.glMaterialf (gl.GL_FRONT, gl.GL_SHININESS, self._shininess)   
271      #
272      ####################################
273      #
274      # render the colormap
275      #
276      if self._colormap is not None :
277        gl.glActiveTexture(_texunits[_unit])
278        gl.glClientActiveTexture(_texunits[_unit])
279        gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY)
280        gl.glTexCoordPointer(3,  gl.GL_FLOAT, 48, _texcoords)
281        gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_MODULATE)
282        self._colormap._enable()
283        _unit += 1
284      #
285      ####################################
286      #
287      # render the glowmap
288      #
289      if self._glowmap is not None :
290        gl.glActiveTexture(_texunits[_unit])
291        gl.glClientActiveTexture(_texunits[_unit])
292        gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY)
293        gl.glTexCoordPointer(3,  gl.GL_FLOAT, 48, _texcoords)
294        gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_ADD)
295        gl.glEnable(gl.GL_BLEND)
296        gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE)
297        self._glowmap._enable()
298        _unit += 1
299      #
300      ####################################
301      #
302      # return 1
303      #
304      return 1
305    #
306    ######################################
307    #
308    # disable textures from last pass
309    #
310    else :
311      if _bump :
312        ##################################
313        #
314        # disable bump-blending
315        #
316        gl.glDisable(gl.GL_BLEND)
317        gl.glDisable(gl.GL_POLYGON_OFFSET_FILL)
318        gl.glPolygonOffset(0,0)
319        #
320      ####################################
321      #
322      _unit = 0
323      if self._colormap is not None :
324        gl.glActiveTexture(_texunits[_unit])
325        self._colormap._disable()
326        _unit += 1
327      if self._glowmap is not None :
328        gl.glActiveTexture(_texunits[_unit])
329        self._glowmap._disable()
330      return 0
331    #
332    ######################################
Note: See TracBrowser for help on using the repository browser.