c2cf4dfa9fd7f92312413c50c5d1f244b4346c25
[blender.git] / source / blender / gpu / intern / gpu_draw.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2005 Blender Foundation.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): Brecht Van Lommel.
29  *
30  * ***** END GPL LICENSE BLOCK *****
31  */
32
33 #include <string.h>
34
35 #include "GL/glew.h"
36
37 #include "BLI_math.h"
38
39 #include "DNA_image_types.h"
40 #include "DNA_lamp_types.h"
41 #include "DNA_material_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_modifier_types.h"
44 #include "DNA_node_types.h"
45 #include "DNA_object_types.h"
46 #include "DNA_scene_types.h"
47 #include "DNA_smoke_types.h"
48 #include "DNA_userdef_types.h"
49 #include "DNA_view3d_types.h"
50
51 #include "MEM_guardedalloc.h"
52
53 #include "IMB_imbuf.h"
54 #include "IMB_imbuf_types.h"
55
56 #include "BKE_bmfont.h"
57 #include "BKE_global.h"
58 #include "BKE_image.h"
59 #include "BKE_main.h"
60 #include "BKE_material.h"
61 #include "BKE_node.h"
62 #include "BKE_object.h"
63 #include "BKE_utildefines.h"
64
65 #include "GPU_extensions.h"
66 #include "GPU_material.h"
67 #include "GPU_draw.h"
68
69 #include "smoke_API.h"
70
71 /* These are some obscure rendering functions shared between the
72  * game engine and the blender, in this module to avoid duplicaten
73  * and abstract them away from the rest a bit */
74
75 /* Text Rendering */
76
77 static void gpu_mcol(unsigned int ucol)
78 {
79         /* mcol order is swapped */
80         char *cp= (char *)&ucol;
81         glColor3ub(cp[3], cp[2], cp[1]);
82 }
83
84 void GPU_render_text(MTFace *tface, int mode,
85         const char *textstr, int textlen, unsigned int *col,
86         float *v1, float *v2, float *v3, float *v4, int glattrib)
87 {
88         if ((mode & TF_BMFONT) && (textlen>0) && tface->tpage) {
89                 Image* ima = (Image*)tface->tpage;
90                 int index, character;
91                 float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance;
92                 float advance_tab;
93                 
94                 /* multiline */
95                 float line_start= 0.0f, line_height;
96                 
97                 if (v4)
98                         line_height= MAX4(v1[1], v2[1], v3[1], v4[2]) - MIN4(v1[1], v2[1], v3[1], v4[2]);
99                 else
100                         line_height= MAX3(v1[1], v2[1], v3[1]) - MIN3(v1[1], v2[1], v3[1]);
101                 line_height *= 1.2; /* could be an option? */
102                 /* end multiline */
103
104                 
105                 /* color has been set */
106                 if (tface->mode & TF_OBCOL)
107                         col= NULL;
108                 else if (!col)
109                         glColor3f(1.0f, 1.0f, 1.0f);
110
111                 glPushMatrix();
112                 
113                 /* get the tab width */
114                 matrixGlyph((ImBuf *)ima->ibufs.first, ' ', & centerx, &centery,
115                         &sizex, &sizey, &transx, &transy, &movex, &movey, &advance);
116                 
117                 advance_tab= advance * 4; /* tab width could also be an option */
118                 
119                 
120                 for (index = 0; index < textlen; index++) {
121                         float uv[4][2];
122
123                         // lets calculate offset stuff
124                         character = textstr[index];
125                         
126                         if (character=='\n') {
127                                 glTranslatef(line_start, -line_height, 0.0);
128                                 line_start = 0.0f;
129                                 continue;
130                         }
131                         else if (character=='\t') {
132                                 glTranslatef(advance_tab, 0.0, 0.0);
133                                 line_start -= advance_tab; /* so we can go back to the start of the line */
134                                 continue;
135                                 
136                         }
137                         
138                         // space starts at offset 1
139                         // character = character - ' ' + 1;
140                         matrixGlyph((ImBuf *)ima->ibufs.first, character, & centerx, &centery,
141                                 &sizex, &sizey, &transx, &transy, &movex, &movey, &advance);
142
143                         uv[0][0] = (tface->uv[0][0] - centerx) * sizex + transx;
144                         uv[0][1] = (tface->uv[0][1] - centery) * sizey + transy;
145                         uv[1][0] = (tface->uv[1][0] - centerx) * sizex + transx;
146                         uv[1][1] = (tface->uv[1][1] - centery) * sizey + transy;
147                         uv[2][0] = (tface->uv[2][0] - centerx) * sizex + transx;
148                         uv[2][1] = (tface->uv[2][1] - centery) * sizey + transy;
149                         
150                         glBegin(GL_POLYGON);
151                         if(glattrib >= 0) glVertexAttrib2fvARB(glattrib, uv[0]);
152                         else glTexCoord2fv(uv[0]);
153                         if(col) gpu_mcol(col[0]);
154                         glVertex3f(sizex * v1[0] + movex, sizey * v1[1] + movey, v1[2]);
155                         
156                         if(glattrib >= 0) glVertexAttrib2fvARB(glattrib, uv[1]);
157                         else glTexCoord2fv(uv[1]);
158                         if(col) gpu_mcol(col[1]);
159                         glVertex3f(sizex * v2[0] + movex, sizey * v2[1] + movey, v2[2]);
160
161                         if(glattrib >= 0) glVertexAttrib2fvARB(glattrib, uv[2]);
162                         else glTexCoord2fv(uv[2]);
163                         if(col) gpu_mcol(col[2]);
164                         glVertex3f(sizex * v3[0] + movex, sizey * v3[1] + movey, v3[2]);
165
166                         if(v4) {
167                                 uv[3][0] = (tface->uv[3][0] - centerx) * sizex + transx;
168                                 uv[3][1] = (tface->uv[3][1] - centery) * sizey + transy;
169
170                                 if(glattrib >= 0) glVertexAttrib2fvARB(glattrib, uv[3]);
171                                 else glTexCoord2fv(uv[3]);
172                                 if(col) gpu_mcol(col[3]);
173                                 glVertex3f(sizex * v4[0] + movex, sizey * v4[1] + movey, v4[2]);
174                         }
175                         glEnd();
176
177                         glTranslatef(advance, 0.0, 0.0);
178                         line_start -= advance; /* so we can go back to the start of the line */
179                 }
180                 glPopMatrix();
181         }
182 }
183
184 /* Checking powers of two for images since opengl 1.x requires it */
185
186 static int is_pow2(int num)
187 {
188         /* (n&(n-1)) zeros the least significant bit of n */
189         return ((num)&(num-1))==0;
190 }
191
192 static int smaller_pow2(int num)
193 {
194         while (!is_pow2(num))
195                 num= num&(num-1);
196
197         return num;     
198 }
199
200 static int is_pow2_limit(int num)
201 {
202         /* take texture clamping into account */
203
204         /* XXX: texturepaint not global!
205            if (G.f & G_TEXTUREPAINT)
206            return 1;*/
207
208         if (U.glreslimit != 0 && num > U.glreslimit)
209                 return 0;
210
211         return ((num)&(num-1))==0;
212 }
213
214 static int smaller_pow2_limit(int num)
215 {
216         /* XXX: texturepaint not global!
217            if (G.f & G_TEXTUREPAINT)
218            return 1;*/
219         
220         /* take texture clamping into account */
221         if (U.glreslimit != 0 && num > U.glreslimit)
222                 return U.glreslimit;
223
224         return smaller_pow2(num);
225 }
226
227 /* Current OpenGL state caching for GPU_set_tpage */
228
229 static struct GPUTextureState {
230         int curtile, tile;
231         int curtilemode, tilemode;
232         int curtileXRep, tileXRep;
233         int curtileYRep, tileYRep;
234         Image *ima, *curima;
235
236         int domipmap, linearmipmap;
237
238         int alphamode;
239         MTFace *lasttface;
240 } GTS = {0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 1, 0, -1, NULL};
241
242 /* Mipmap settings */
243
244 void GPU_set_mipmap(int mipmap)
245 {
246         if (GTS.domipmap != (mipmap != 0)) {
247                 GPU_free_images();
248                 GTS.domipmap = mipmap != 0;
249         }
250 }
251
252 void GPU_set_linear_mipmap(int linear)
253 {
254         if (GTS.linearmipmap != (linear != 0)) {
255                 GPU_free_images();
256                 GTS.linearmipmap = linear != 0;
257         }
258 }
259
260 static int gpu_get_mipmap(void)
261 {
262         return GTS.domipmap;
263 }
264
265 static GLenum gpu_get_mipmap_filter(int mag)
266 {
267         /* linearmipmap is off by default *when mipmapping is off,
268          * use unfiltered display */
269         if(mag) {
270                 if(GTS.linearmipmap || GTS.domipmap)
271                         return GL_LINEAR;
272                 else
273                         return GL_NEAREST;
274         }
275         else {
276                 if(GTS.linearmipmap)
277                         return GL_LINEAR_MIPMAP_LINEAR;
278                 else if(GTS.domipmap)
279                         return GL_LINEAR_MIPMAP_NEAREST;
280                 else
281                         return GL_NEAREST;
282         }
283 }
284
285 /* Set OpenGL state for an MTFace */
286
287 static void gpu_make_repbind(Image *ima)
288 {
289         ImBuf *ibuf;
290         
291         ibuf = BKE_image_get_ibuf(ima, NULL);
292         if(ibuf==NULL)
293                 return;
294
295         if(ima->repbind) {
296                 glDeleteTextures(ima->totbind, (GLuint *)ima->repbind);
297                 MEM_freeN(ima->repbind);
298                 ima->repbind= 0;
299                 ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
300         }
301
302         ima->totbind= ima->xrep*ima->yrep;
303
304         if(ima->totbind>1)
305                 ima->repbind= MEM_callocN(sizeof(int)*ima->totbind, "repbind");
306 }
307
308 static void gpu_clear_tpage()
309 {
310         if(GTS.lasttface==0)
311                 return;
312         
313         GTS.lasttface= 0;
314         GTS.curtile= 0;
315         GTS.curima= 0;
316         if(GTS.curtilemode!=0) {
317                 glMatrixMode(GL_TEXTURE);
318                 glLoadIdentity();
319                 glMatrixMode(GL_MODELVIEW);
320         }
321         GTS.curtilemode= 0;
322         GTS.curtileXRep=0;
323         GTS.curtileYRep=0;
324         GTS.alphamode= -1;
325         
326         glDisable(GL_BLEND);
327         glDisable(GL_TEXTURE_2D);
328         glDisable(GL_TEXTURE_GEN_S);
329         glDisable(GL_TEXTURE_GEN_T);
330         glDisable(GL_ALPHA_TEST);
331 }
332
333 static void gpu_set_blend_mode(GPUBlendMode blendmode)
334 {
335         if(blendmode == GPU_BLEND_SOLID) {
336                 glDisable(GL_BLEND);
337                 glDisable(GL_ALPHA_TEST);
338                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
339         }
340         else if(blendmode==GPU_BLEND_ADD) {
341                 glEnable(GL_BLEND);
342                 glBlendFunc(GL_ONE, GL_ONE);
343                 glDisable(GL_ALPHA_TEST);
344         }
345         else if(blendmode==GPU_BLEND_ALPHA) {
346                 glEnable(GL_BLEND);
347                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
348                 
349                 /* if U.glalphaclip == 1.0, some cards go bonkers...
350                  * turn off alpha test in this case */
351
352                 /* added after 2.45 to clip alpha */
353                 if(U.glalphaclip == 1.0) {
354                         glDisable(GL_ALPHA_TEST);
355                 }
356                 else {
357                         glEnable(GL_ALPHA_TEST);
358                         glAlphaFunc(GL_GREATER, U.glalphaclip);
359                 }
360         }
361         else if(blendmode==GPU_BLEND_CLIP) {
362                 glDisable(GL_BLEND); 
363                 glEnable(GL_ALPHA_TEST);
364                 glAlphaFunc(GL_GREATER, 0.5f);
365         }
366 }
367
368 static void gpu_verify_alpha_mode(MTFace *tface)
369 {
370         /* verify alpha blending modes */
371         if(GTS.alphamode == tface->transp)
372                 return;
373
374         gpu_set_blend_mode(tface->transp);
375         GTS.alphamode= tface->transp;
376 }
377
378 static void gpu_verify_reflection(Image *ima)
379 {
380         if (ima && (ima->flag & IMA_REFLECT)) {
381                 /* enable reflection mapping */
382                 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
383                 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
384
385                 glEnable(GL_TEXTURE_GEN_S);
386                 glEnable(GL_TEXTURE_GEN_T);
387         }
388         else {
389                 /* disable reflection mapping */
390                 glDisable(GL_TEXTURE_GEN_S);
391                 glDisable(GL_TEXTURE_GEN_T);
392         }
393 }
394
395 int GPU_verify_image(Image *ima, int tftile, int tfmode, int compare, int mipmap)
396 {
397         ImBuf *ibuf = NULL;
398         unsigned int *bind = NULL;
399         int rectw, recth, tpx=0, tpy=0, y;
400         unsigned int *rectrow, *tilerectrow;
401         unsigned int *tilerect= NULL, *scalerect= NULL, *rect= NULL;
402         short texwindx, texwindy, texwinsx, texwinsy;
403
404         /* initialize tile mode and number of repeats */
405         GTS.ima = ima;
406         GTS.tilemode= (ima && (ima->tpageflag & (IMA_TILES|IMA_TWINANIM)));
407         GTS.tileXRep = 0;
408         GTS.tileYRep = 0;
409
410         /* setting current tile according to frame */
411         if(ima && (ima->tpageflag & IMA_TWINANIM))
412                 GTS.tile= ima->lastframe;
413         else
414                 GTS.tile= tftile;
415
416         GTS.tile = MAX2(0, GTS.tile);
417
418         if(ima) {
419                 GTS.tileXRep = ima->xrep;
420                 GTS.tileYRep = ima->yrep;
421         }
422
423         /* if same image & tile, we're done */
424         if(compare && ima == GTS.curima && GTS.curtile == GTS.tile &&
425            GTS.tilemode == GTS.curtilemode && GTS.curtileXRep == GTS.tileXRep &&
426            GTS.curtileYRep == GTS.tileYRep)
427                 return (ima!=0);
428
429         /* if tiling mode or repeat changed, change texture matrix to fit */
430         if(GTS.tilemode!=GTS.curtilemode || GTS.curtileXRep!=GTS.tileXRep ||
431            GTS.curtileYRep != GTS.tileYRep) {
432
433                 glMatrixMode(GL_TEXTURE);
434                 glLoadIdentity();
435
436                 if(ima && (ima->tpageflag & IMA_TILES))
437                         glScalef(ima->xrep, ima->yrep, 1.0);
438
439                 glMatrixMode(GL_MODELVIEW);
440         }
441
442         /* check if we have a valid image */
443         if(ima==NULL || ima->ok==0)
444                 return 0;
445
446         /* check if we have a valid image buffer */
447         ibuf= BKE_image_get_ibuf(ima, NULL);
448
449         if(ibuf==NULL)
450                 return 0;
451
452         /* ensure we have a char buffer and not only float */
453         if ((ibuf->rect==NULL) && ibuf->rect_float)
454                 IMB_rect_from_float(ibuf);
455
456         if(GTS.tilemode) {
457                 /* tiled mode */
458                 if(ima->repbind==0) gpu_make_repbind(ima);
459                 if(GTS.tile>=ima->totbind) GTS.tile= 0;
460                 
461                 /* this happens when you change repeat buttons */
462                 if(ima->repbind) bind= &ima->repbind[GTS.tile];
463                 else bind= &ima->bindcode;
464                 
465                 if(*bind==0) {
466                         
467                         texwindx= ibuf->x/ima->xrep;
468                         texwindy= ibuf->y/ima->yrep;
469                         
470                         if(GTS.tile>=ima->xrep*ima->yrep)
471                                 GTS.tile= ima->xrep*ima->yrep-1;
472         
473                         texwinsy= GTS.tile / ima->xrep;
474                         texwinsx= GTS.tile - texwinsy*ima->xrep;
475         
476                         texwinsx*= texwindx;
477                         texwinsy*= texwindy;
478         
479                         tpx= texwindx;
480                         tpy= texwindy;
481
482                         rect= ibuf->rect + texwinsy*ibuf->x + texwinsx;
483                 }
484         }
485         else {
486                 /* regular image mode */
487                 bind= &ima->bindcode;
488                 
489                 if(*bind==0) {
490                         tpx= ibuf->x;
491                         tpy= ibuf->y;
492                         rect= ibuf->rect;
493                 }
494         }
495
496         if(*bind != 0) {
497                 /* enable opengl drawing with textures */
498                 glBindTexture(GL_TEXTURE_2D, *bind);
499                 return *bind;
500         }
501
502         rectw = tpx;
503         recth = tpy;
504
505         /* for tiles, copy only part of image into buffer */
506         if (GTS.tilemode) {
507                 tilerect= MEM_mallocN(rectw*recth*sizeof(*tilerect), "tilerect");
508
509                 for (y=0; y<recth; y++) {
510                         rectrow= &rect[y*ibuf->x];
511                         tilerectrow= &tilerect[y*rectw];
512                                 
513                         memcpy(tilerectrow, rectrow, tpx*sizeof(*rectrow));
514                 }
515                         
516                 rect= tilerect;
517         }
518
519         /* scale if not a power of two */
520         if (!mipmap && (!is_pow2_limit(rectw) || !is_pow2_limit(recth))) {
521                 rectw= smaller_pow2_limit(rectw);
522                 recth= smaller_pow2_limit(recth);
523                 
524                 scalerect= MEM_mallocN(rectw*recth*sizeof(*scalerect), "scalerect");
525                 gluScaleImage(GL_RGBA, tpx, tpy, GL_UNSIGNED_BYTE, rect, rectw, recth, GL_UNSIGNED_BYTE, scalerect);
526                 rect= scalerect;
527         }
528
529         /* create image */
530         glGenTextures(1, (GLuint *)bind);
531         glBindTexture( GL_TEXTURE_2D, *bind);
532
533         if (!(gpu_get_mipmap() && mipmap)) {
534                 glTexImage2D(GL_TEXTURE_2D, 0,  GL_RGBA,  rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
535                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
536                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
537         }
538         else {
539                 gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect);
540                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
541                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
542
543                 ima->tpageflag |= IMA_MIPMAP_COMPLETE;
544         }
545
546         /* set to modulate with vertex color */
547         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
548                 
549         /* clean up */
550         if (tilerect)
551                 MEM_freeN(tilerect);
552         if (scalerect)
553                 MEM_freeN(scalerect);
554
555         return *bind;
556 }
557
558 static void gpu_verify_repeat(Image *ima)
559 {
560         /* set either clamp or repeat in X/Y */
561         if (ima->tpageflag & IMA_CLAMP_U)
562            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
563         else
564                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
565
566         if (ima->tpageflag & IMA_CLAMP_V)
567                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
568         else
569                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
570 }
571
572 int GPU_set_tpage(MTFace *tface, int mipmap)
573 {
574         Image *ima;
575         
576         /* check if we need to clear the state */
577         if(tface==0) {
578                 gpu_clear_tpage();
579                 return 0;
580         }
581
582         ima= tface->tpage;
583         GTS.lasttface= tface;
584
585         gpu_verify_alpha_mode(tface);
586         gpu_verify_reflection(ima);
587
588         if(GPU_verify_image(ima, tface->tile, tface->mode, 1, mipmap)) {
589                 GTS.curtile= GTS.tile;
590                 GTS.curima= GTS.ima;
591                 GTS.curtilemode= GTS.tilemode;
592                 GTS.curtileXRep = GTS.tileXRep;
593                 GTS.curtileYRep = GTS.tileYRep;
594
595                 glEnable(GL_TEXTURE_2D);
596         }
597         else {
598                 glDisable(GL_TEXTURE_2D);
599                 
600                 GTS.curtile= 0;
601                 GTS.curima= 0;
602                 GTS.curtilemode= 0;
603                 GTS.curtileXRep = 0;
604                 GTS.curtileYRep = 0;
605
606                 return 0;
607         }
608         
609         gpu_verify_repeat(ima);
610         
611         /* Did this get lost in the image recode? */
612         /* tag_image_time(ima);*/
613
614         return 1;
615 }
616
617 /* these two functions are called on entering and exiting texture paint mode,
618    temporary disabling/enabling mipmapping on all images for quick texture
619    updates with glTexSubImage2D. images that didn't change don't have to be
620    re-uploaded to OpenGL */
621 void GPU_paint_set_mipmap(int mipmap)
622 {
623         Image* ima;
624         
625         if(!GTS.domipmap)
626                 return;
627
628         if(mipmap) {
629                 for(ima=G.main->image.first; ima; ima=ima->id.next) {
630                         if(ima->bindcode) {
631                                 if(ima->tpageflag & IMA_MIPMAP_COMPLETE) {
632                                         glBindTexture(GL_TEXTURE_2D, ima->bindcode);
633                                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
634                                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
635                                 }
636                                 else
637                                         GPU_free_image(ima);
638                         }
639                 }
640
641         }
642         else {
643                 for(ima=G.main->image.first; ima; ima=ima->id.next) {
644                         if(ima->bindcode) {
645                                 glBindTexture(GL_TEXTURE_2D, ima->bindcode);
646                                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
647                                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
648                         }
649                 }
650         }
651 }
652
653 void GPU_paint_update_image(Image *ima, int x, int y, int w, int h, int mipmap)
654 {
655         ImBuf *ibuf;
656         
657         ibuf = BKE_image_get_ibuf(ima, NULL);
658         
659         if (ima->repbind || (gpu_get_mipmap() && mipmap) || !ima->bindcode || !ibuf ||
660                 (!is_pow2(ibuf->x) || !is_pow2(ibuf->y)) ||
661                 (w == 0) || (h == 0)) {
662                 /* these cases require full reload still */
663                 GPU_free_image(ima);
664         }
665         else {
666                 /* for the special case, we can do a partial update
667                  * which is much quicker for painting */
668                 GLint row_length, skip_pixels, skip_rows;
669
670                 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length);
671                 glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skip_pixels);
672                 glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skip_rows);
673
674                 if ((ibuf->rect==NULL) && ibuf->rect_float)
675                         IMB_rect_from_float(ibuf);
676
677                 glBindTexture(GL_TEXTURE_2D, ima->bindcode);
678
679                 glPixelStorei(GL_UNPACK_ROW_LENGTH, ibuf->x);
680                 glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
681                 glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
682
683                 glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
684                         GL_UNSIGNED_BYTE, ibuf->rect);
685
686                 glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
687                 glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
688                 glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows);
689
690                 if(ima->tpageflag & IMA_MIPMAP_COMPLETE)
691                         ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
692         }
693 }
694
695 void GPU_update_images_framechange(void)
696 {
697         Image *ima;
698         
699         for(ima=G.main->image.first; ima; ima=ima->id.next) {
700                 if(ima->tpageflag & IMA_TWINANIM) {
701                         if(ima->twend >= ima->xrep*ima->yrep)
702                                 ima->twend= ima->xrep*ima->yrep-1;
703                 
704                         /* check: is bindcode not in the array? free. (to do) */
705                         
706                         ima->lastframe++;
707                         if(ima->lastframe > ima->twend)
708                                 ima->lastframe= ima->twsta;
709                 }
710         }
711 }
712
713 int GPU_update_image_time(Image *ima, double time)
714 {
715         int     inc = 0;
716         float   diff;
717         int     newframe;
718
719         if (!ima)
720                 return 0;
721
722         if (ima->lastupdate<0)
723                 ima->lastupdate = 0;
724
725         if (ima->lastupdate>time)
726                 ima->lastupdate=(float)time;
727
728         if(ima->tpageflag & IMA_TWINANIM) {
729                 if(ima->twend >= ima->xrep*ima->yrep) ima->twend= ima->xrep*ima->yrep-1;
730                 
731                 /* check: is the bindcode not in the array? Then free. (still to do) */
732                 
733                 diff = (float)(time-ima->lastupdate);
734                 inc = (int)(diff*(float)ima->animspeed);
735
736                 ima->lastupdate+=((float)inc/(float)ima->animspeed);
737
738                 newframe = ima->lastframe+inc;
739
740                 if(newframe > (int)ima->twend) {
741                         if(ima->twend-ima->twsta != 0)
742                                 newframe = (int)ima->twsta-1 + (newframe-ima->twend)%(ima->twend-ima->twsta);
743                         else
744                                 newframe = ima->twsta;
745                 }
746
747                 ima->lastframe = newframe;
748         }
749
750         return inc;
751 }
752
753
754 void GPU_free_smoke(SmokeModifierData *smd)
755 {
756         if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain)
757         {
758                 if(smd->domain->tex)
759                         GPU_texture_free(smd->domain->tex);
760                 smd->domain->tex = NULL;
761
762                 if(smd->domain->tex_shadow)
763                         GPU_texture_free(smd->domain->tex_shadow);
764                 smd->domain->tex_shadow = NULL;
765         }
766 }
767
768 void GPU_create_smoke(SmokeModifierData *smd, int highres)
769 {
770         if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain && !smd->domain->tex && !highres)
771                 smd->domain->tex = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smoke_get_density(smd->domain->fluid));
772         else if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain && !smd->domain->tex && highres)
773                 smd->domain->tex = GPU_texture_create_3D(smd->domain->res_wt[0], smd->domain->res_wt[1], smd->domain->res_wt[2], smoke_turbulence_get_density(smd->domain->wt));
774
775         smd->domain->tex_shadow = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smd->domain->shadow);
776 }
777
778 void GPU_free_image(Image *ima)
779 {
780         /* free regular image binding */
781         if(ima->bindcode) {
782                 glDeleteTextures(1, (GLuint *)&ima->bindcode);
783                 ima->bindcode= 0;
784                 ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
785         }
786
787         /* free glsl image binding */
788         if(ima->gputexture) {
789                 GPU_texture_free(ima->gputexture);
790                 ima->gputexture= NULL;
791         }
792
793         /* free repeated image binding */
794         if(ima->repbind) {
795                 glDeleteTextures(ima->totbind, (GLuint *)ima->repbind);
796         
797                 MEM_freeN(ima->repbind);
798                 ima->repbind= NULL;
799                 ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
800         }
801 }
802
803 void GPU_free_images(void)
804 {
805         Image* ima;
806
807         if(G.main)
808                 for(ima=G.main->image.first; ima; ima=ima->id.next)
809                         GPU_free_image(ima);
810 }
811
812 /* OpenGL Materials */
813
814 #define FIXEDMAT        8
815
816 /* OpenGL state caching for materials */
817
818 static struct GPUMaterialState {
819         float (*matbuf)[2][4];
820         float matbuf_fixed[FIXEDMAT][2][4];
821         int totmat;
822
823         Material **gmatbuf;
824         Material *gmatbuf_fixed[FIXEDMAT];
825         Material *gboundmat;
826         Object *gob;
827         Scene *gscene;
828         int glay;
829         float (*gviewmat)[4];
830         float (*gviewinv)[4];
831
832         GPUBlendMode *blendmode;
833         GPUBlendMode blendmode_fixed[FIXEDMAT];
834         int alphapass;
835
836         int lastmatnr, lastretval;
837         GPUBlendMode lastblendmode;
838 } GMS = {NULL};
839
840 Material *gpu_active_node_material(Material *ma)
841 {
842         if(ma && ma->use_nodes && ma->nodetree) {
843                 bNode *node= nodeGetActiveID(ma->nodetree, ID_MA);
844
845                 if(node)
846                         return (Material *)node->id;
847                 else
848                         return NULL;
849         }
850
851         return ma;
852 }
853
854 void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, Object *ob, int glsl, int *do_alpha_pass)
855 {
856         extern Material defmaterial; /* from material.c */
857         Material *ma;
858         GPUMaterial *gpumat;
859         GPUBlendMode blendmode;
860         int a;
861         int gamma = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
862         
863         /* initialize state */
864         memset(&GMS, 0, sizeof(GMS));
865         GMS.lastmatnr = -1;
866         GMS.lastretval = -1;
867         GMS.lastblendmode = GPU_BLEND_SOLID;
868
869         GMS.gob = ob;
870         GMS.gscene = scene;
871         GMS.totmat= ob->totcol+1; /* materials start from 1, default material is 0 */
872         GMS.glay= v3d->lay;
873         GMS.gviewmat= rv3d->viewmat;
874         GMS.gviewinv= rv3d->viewinv;
875
876         GMS.alphapass = (v3d && v3d->transp);
877         if(do_alpha_pass)
878                 *do_alpha_pass = 0;
879         
880         if(GMS.totmat > FIXEDMAT) {
881                 GMS.matbuf= MEM_callocN(sizeof(*GMS.matbuf)*GMS.totmat, "GMS.matbuf");
882                 GMS.gmatbuf= MEM_callocN(sizeof(*GMS.gmatbuf)*GMS.totmat, "GMS.matbuf");
883                 GMS.blendmode= MEM_callocN(sizeof(*GMS.blendmode)*GMS.totmat, "GMS.matbuf");
884         }
885         else {
886                 GMS.matbuf= GMS.matbuf_fixed;
887                 GMS.gmatbuf= GMS.gmatbuf_fixed;
888                 GMS.blendmode= GMS.blendmode_fixed;
889         }
890
891         /* no materials assigned? */
892         if(ob->totcol==0) {
893                 GMS.matbuf[0][0][0]= (defmaterial.ref+defmaterial.emit)*defmaterial.r;
894                 GMS.matbuf[0][0][1]= (defmaterial.ref+defmaterial.emit)*defmaterial.g;
895                 GMS.matbuf[0][0][2]= (defmaterial.ref+defmaterial.emit)*defmaterial.b;
896                 GMS.matbuf[0][0][3]= 1.0;
897
898                 GMS.matbuf[0][1][0]= defmaterial.spec*defmaterial.specr;
899                 GMS.matbuf[0][1][1]= defmaterial.spec*defmaterial.specg;
900                 GMS.matbuf[0][1][2]= defmaterial.spec*defmaterial.specb;
901                 GMS.matbuf[0][1][3]= 1.0;
902                 
903                 /* do material 1 too, for displists! */
904                 QUATCOPY(GMS.matbuf[1][0], GMS.matbuf[0][0]);
905                 QUATCOPY(GMS.matbuf[1][1], GMS.matbuf[0][1]);
906
907                 if(glsl) {
908                         GMS.gmatbuf[0]= &defmaterial;
909                         GPU_material_from_blender(GMS.gscene, &defmaterial);
910                 }
911
912                 GMS.blendmode[0]= GPU_BLEND_SOLID;
913         }
914         
915         /* setup materials */
916         for(a=1; a<=ob->totcol; a++) {
917                 /* find a suitable material */
918                 ma= give_current_material(ob, a);
919                 if(!glsl) ma= gpu_active_node_material(ma);
920                 if(ma==NULL) ma= &defmaterial;
921
922                 /* create glsl material if requested */
923                 gpumat = (glsl)? GPU_material_from_blender(GMS.gscene, ma): NULL;
924
925                 if(gpumat) {
926                         /* do glsl only if creating it succeed, else fallback */
927                         GMS.gmatbuf[a]= ma;
928                         blendmode = GPU_material_blend_mode(gpumat, ob->col);
929                 }
930                 else {
931                         /* fixed function opengl materials */
932                         if (ma->mode & MA_SHLESS) {
933                                 GMS.matbuf[a][0][0]= ma->r;
934                                 GMS.matbuf[a][0][1]= ma->g;
935                                 GMS.matbuf[a][0][2]= ma->b;
936                                 if(gamma) linearrgb_to_srgb_v3_v3(&GMS.matbuf[a][0][0], &GMS.matbuf[a][0][0]);
937                         } else {
938                                 GMS.matbuf[a][0][0]= (ma->ref+ma->emit)*ma->r;
939                                 GMS.matbuf[a][0][1]= (ma->ref+ma->emit)*ma->g;
940                                 GMS.matbuf[a][0][2]= (ma->ref+ma->emit)*ma->b;
941
942                                 GMS.matbuf[a][1][0]= ma->spec*ma->specr;
943                                 GMS.matbuf[a][1][1]= ma->spec*ma->specg;
944                                 GMS.matbuf[a][1][2]= ma->spec*ma->specb;
945                                 GMS.matbuf[a][1][3]= 1.0;
946                                 
947                                 if(gamma) {
948                                         linearrgb_to_srgb_v3_v3(&GMS.matbuf[a][0][0], &GMS.matbuf[a][0][0]);
949                                         linearrgb_to_srgb_v3_v3(&GMS.matbuf[a][1][0], &GMS.matbuf[a][1][0]);
950                                 }
951                         }
952
953                         blendmode = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
954                         if(do_alpha_pass && GMS.alphapass)
955                                 GMS.matbuf[a][0][3]= ma->alpha;
956                         else
957                                 GMS.matbuf[a][0][3]= 1.0f;
958                 }
959
960                 /* setting do_alpha_pass = 1 indicates this object needs to be
961                  * drawn in a second alpha pass for improved blending */
962                 if(do_alpha_pass) {
963                         GMS.blendmode[a]= blendmode;
964                         if(ELEM(blendmode, GPU_BLEND_ALPHA, GPU_BLEND_ADD) && !GMS.alphapass)
965                                 *do_alpha_pass= 1;
966                 }
967         }
968
969         /* let's start with a clean state */
970         GPU_disable_material();
971 }
972
973 int GPU_enable_material(int nr, void *attribs)
974 {
975         extern Material defmaterial; /* from material.c */
976         GPUVertexAttribs *gattribs = attribs;
977         GPUMaterial *gpumat;
978         GPUBlendMode blendmode;
979
980         /* no GPU_begin_object_materials, use default material */
981         if(!GMS.matbuf) {
982                 float diff[4], spec[4];
983
984                 memset(&GMS, 0, sizeof(GMS));
985
986                 diff[0]= (defmaterial.ref+defmaterial.emit)*defmaterial.r;
987                 diff[1]= (defmaterial.ref+defmaterial.emit)*defmaterial.g;
988                 diff[2]= (defmaterial.ref+defmaterial.emit)*defmaterial.b;
989                 diff[3]= 1.0;
990
991                 spec[0]= defmaterial.spec*defmaterial.specr;
992                 spec[1]= defmaterial.spec*defmaterial.specg;
993                 spec[2]= defmaterial.spec*defmaterial.specb;
994                 spec[3]= 1.0;
995
996                 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff);
997                 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
998
999                 return 0;
1000         }
1001
1002         /* prevent index to use un-initialized array items */
1003         if(nr>=GMS.totmat)
1004                 nr= 0;
1005
1006         if(gattribs)
1007                 memset(gattribs, 0, sizeof(*gattribs));
1008
1009         /* keep current material */
1010         if(nr==GMS.lastmatnr)
1011                 return GMS.lastretval;
1012
1013         /* unbind glsl material */
1014         if(GMS.gboundmat) {
1015                 if(GMS.alphapass) glDepthMask(0);
1016                 GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat));
1017                 GMS.gboundmat= NULL;
1018         }
1019
1020         /* draw materials with alpha in alpha pass */
1021         GMS.lastmatnr = nr;
1022         GMS.lastretval = ELEM(GMS.blendmode[nr], GPU_BLEND_SOLID, GPU_BLEND_CLIP);
1023         if(GMS.alphapass)
1024                 GMS.lastretval = !GMS.lastretval;
1025
1026         if(GMS.lastretval) {
1027                 if(gattribs && GMS.gmatbuf[nr]) {
1028                         /* bind glsl material and get attributes */
1029                         Material *mat = GMS.gmatbuf[nr];
1030
1031                         gpumat = GPU_material_from_blender(GMS.gscene, mat);
1032                         GPU_material_vertex_attributes(gpumat, gattribs);
1033                         GPU_material_bind(gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT));
1034                         GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gviewinv, GMS.gob->col);
1035                         GMS.gboundmat= mat;
1036
1037                         if(GMS.alphapass) glDepthMask(1);
1038                 }
1039                 else {
1040                         /* or do fixed function opengl material */
1041                         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, GMS.matbuf[nr][0]);
1042                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, GMS.matbuf[nr][1]);
1043                 }
1044
1045                 /* set (alpha) blending mode */
1046                 blendmode = (GMS.alphapass)? GPU_BLEND_ALPHA: GPU_BLEND_SOLID;
1047                 GPU_set_material_blend_mode(blendmode);
1048         }
1049
1050         return GMS.lastretval;
1051 }
1052
1053 void GPU_set_material_blend_mode(int blendmode)
1054 {
1055         if(GMS.lastblendmode == blendmode)
1056                 return;
1057         
1058         gpu_set_blend_mode(blendmode);
1059         GMS.lastblendmode = blendmode;
1060 }
1061
1062 int GPU_get_material_blend_mode(void)
1063 {
1064         return GMS.lastblendmode;
1065 }
1066
1067 void GPU_disable_material(void)
1068 {
1069         GMS.lastmatnr= -1;
1070         GMS.lastretval= 1;
1071
1072         if(GMS.gboundmat) {
1073                 if(GMS.alphapass) glDepthMask(0);
1074                 GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat));
1075                 GMS.gboundmat= NULL;
1076         }
1077
1078         GPU_set_material_blend_mode(GPU_BLEND_SOLID);
1079 }
1080
1081 void GPU_end_object_materials(void)
1082 {
1083         GPU_disable_material();
1084
1085         if(GMS.matbuf && GMS.matbuf != GMS.matbuf_fixed) {
1086                 MEM_freeN(GMS.matbuf);
1087                 MEM_freeN(GMS.gmatbuf);
1088                 MEM_freeN(GMS.blendmode);
1089         }
1090
1091         GMS.matbuf= NULL;
1092         GMS.gmatbuf= NULL;
1093         GMS.blendmode= NULL;
1094 }
1095
1096 /* Lights */
1097
1098 int GPU_default_lights(void)
1099 {
1100         int a, count = 0;
1101         
1102         /* initialize */
1103         if(U.light[0].flag==0 && U.light[1].flag==0 && U.light[2].flag==0) {
1104                 U.light[0].flag= 1;
1105                 U.light[0].vec[0]= -0.3; U.light[0].vec[1]= 0.3; U.light[0].vec[2]= 0.9;
1106                 U.light[0].col[0]= 0.8; U.light[0].col[1]= 0.8; U.light[0].col[2]= 0.8;
1107                 U.light[0].spec[0]= 0.5; U.light[0].spec[1]= 0.5; U.light[0].spec[2]= 0.5;
1108                 U.light[0].spec[3]= 1.0;
1109                 
1110                 U.light[1].flag= 0;
1111                 U.light[1].vec[0]= 0.5; U.light[1].vec[1]= 0.5; U.light[1].vec[2]= 0.1;
1112                 U.light[1].col[0]= 0.4; U.light[1].col[1]= 0.4; U.light[1].col[2]= 0.8;
1113                 U.light[1].spec[0]= 0.3; U.light[1].spec[1]= 0.3; U.light[1].spec[2]= 0.5;
1114                 U.light[1].spec[3]= 1.0;
1115         
1116                 U.light[2].flag= 0;
1117                 U.light[2].vec[0]= 0.3; U.light[2].vec[1]= -0.3; U.light[2].vec[2]= -0.2;
1118                 U.light[2].col[0]= 0.8; U.light[2].col[1]= 0.5; U.light[2].col[2]= 0.4;
1119                 U.light[2].spec[0]= 0.5; U.light[2].spec[1]= 0.4; U.light[2].spec[2]= 0.3;
1120                 U.light[2].spec[3]= 1.0;
1121         }
1122
1123         glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
1124
1125         glLightfv(GL_LIGHT0, GL_POSITION, U.light[0].vec); 
1126         glLightfv(GL_LIGHT0, GL_DIFFUSE, U.light[0].col); 
1127         glLightfv(GL_LIGHT0, GL_SPECULAR, U.light[0].spec); 
1128
1129         glLightfv(GL_LIGHT1, GL_POSITION, U.light[1].vec); 
1130         glLightfv(GL_LIGHT1, GL_DIFFUSE, U.light[1].col); 
1131         glLightfv(GL_LIGHT1, GL_SPECULAR, U.light[1].spec); 
1132
1133         glLightfv(GL_LIGHT2, GL_POSITION, U.light[2].vec); 
1134         glLightfv(GL_LIGHT2, GL_DIFFUSE, U.light[2].col); 
1135         glLightfv(GL_LIGHT2, GL_SPECULAR, U.light[2].spec); 
1136
1137         for(a=0; a<8; a++) {
1138                 if(a<3) {
1139                         if(U.light[a].flag) {
1140                                 glEnable(GL_LIGHT0+a);
1141                                 count++;
1142                         }
1143                         else
1144                                 glDisable(GL_LIGHT0+a);
1145                         
1146                         // clear stuff from other opengl lamp usage
1147                         glLightf(GL_LIGHT0+a, GL_SPOT_CUTOFF, 180.0);
1148                         glLightf(GL_LIGHT0+a, GL_CONSTANT_ATTENUATION, 1.0);
1149                         glLightf(GL_LIGHT0+a, GL_LINEAR_ATTENUATION, 0.0);
1150                 }
1151                 else
1152                         glDisable(GL_LIGHT0+a);
1153         }
1154         
1155         glDisable(GL_LIGHTING);
1156
1157         glDisable(GL_COLOR_MATERIAL);
1158
1159         return count;
1160 }
1161
1162 int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[][4], int ortho)
1163 {
1164         Base *base;
1165         Lamp *la;
1166         int count;
1167         float position[4], direction[4], energy[4];
1168         
1169         /* disable all lights */
1170         for(count=0; count<8; count++)
1171                 glDisable(GL_LIGHT0+count);
1172         
1173         /* view direction for specular is not compute correct by default in
1174          * opengl, so we set the settings ourselfs */
1175         glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, (ortho)? GL_FALSE: GL_TRUE);
1176
1177         count= 0;
1178         
1179         for(base=scene->base.first; base; base=base->next) {
1180                 if(base->object->type!=OB_LAMP)
1181                         continue;
1182
1183                 if(!(base->lay & lay) || !(base->lay & ob->lay))
1184                         continue;
1185
1186                 la= base->object->data;
1187                 
1188                 /* setup lamp transform */
1189                 glPushMatrix();
1190                 glLoadMatrixf((float *)viewmat);
1191                 
1192                 where_is_object_simul(scene, base->object);
1193                 
1194                 if(la->type==LA_SUN) {
1195                         /* sun lamp */
1196                         VECCOPY(direction, base->object->obmat[2]);
1197                         direction[3]= 0.0;
1198
1199                         glLightfv(GL_LIGHT0+count, GL_POSITION, direction); 
1200                 }
1201                 else {
1202                         /* other lamps with attenuation */
1203                         VECCOPY(position, base->object->obmat[3]);
1204                         position[3]= 1.0f;
1205
1206                         glLightfv(GL_LIGHT0+count, GL_POSITION, position); 
1207                         glLightf(GL_LIGHT0+count, GL_CONSTANT_ATTENUATION, 1.0);
1208                         glLightf(GL_LIGHT0+count, GL_LINEAR_ATTENUATION, la->att1/la->dist);
1209                         glLightf(GL_LIGHT0+count, GL_QUADRATIC_ATTENUATION, la->att2/(la->dist*la->dist));
1210                         
1211                         if(la->type==LA_SPOT) {
1212                                 /* spot lamp */
1213                                 direction[0]= -base->object->obmat[2][0];
1214                                 direction[1]= -base->object->obmat[2][1];
1215                                 direction[2]= -base->object->obmat[2][2];
1216                                 glLightfv(GL_LIGHT0+count, GL_SPOT_DIRECTION, direction);
1217                                 glLightf(GL_LIGHT0+count, GL_SPOT_CUTOFF, la->spotsize/2.0);
1218                                 glLightf(GL_LIGHT0+count, GL_SPOT_EXPONENT, 128.0*la->spotblend);
1219                         }
1220                         else
1221                                 glLightf(GL_LIGHT0+count, GL_SPOT_CUTOFF, 180.0);
1222                 }
1223                 
1224                 /* setup energy */
1225                 energy[0]= la->energy*la->r;
1226                 energy[1]= la->energy*la->g;
1227                 energy[2]= la->energy*la->b;
1228                 energy[3]= 1.0;
1229
1230                 glLightfv(GL_LIGHT0+count, GL_DIFFUSE, energy); 
1231                 glLightfv(GL_LIGHT0+count, GL_SPECULAR, energy);
1232                 glEnable(GL_LIGHT0+count);
1233                 
1234                 glPopMatrix();                                  
1235                 
1236                 count++;
1237                 if(count==8)
1238                         break;
1239         }
1240
1241         return count;
1242 }
1243
1244 /* Default OpenGL State */
1245
1246 void GPU_state_init(void)
1247 {
1248         /* also called when doing opengl rendering and in the game engine */
1249         float mat_ambient[] = { 0.0, 0.0, 0.0, 0.0 };
1250         float mat_specular[] = { 0.5, 0.5, 0.5, 1.0 };
1251         float mat_shininess[] = { 35.0 };
1252         int a, x, y;
1253         GLubyte pat[32*32];
1254         const GLubyte *patc= pat;
1255         
1256         glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
1257         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_specular);
1258         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
1259         glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
1260
1261         GPU_default_lights();
1262         
1263         glDepthFunc(GL_LEQUAL);
1264         /* scaling matrices */
1265         glEnable(GL_NORMALIZE);
1266
1267         glShadeModel(GL_FLAT);
1268
1269         glDisable(GL_ALPHA_TEST);
1270         glDisable(GL_BLEND);
1271         glDisable(GL_DEPTH_TEST);
1272         glDisable(GL_FOG);
1273         glDisable(GL_LIGHTING);
1274         glDisable(GL_LOGIC_OP);
1275         glDisable(GL_STENCIL_TEST);
1276         glDisable(GL_TEXTURE_1D);
1277         glDisable(GL_TEXTURE_2D);
1278
1279         /* default on, disable/enable should be local per function */
1280         glEnableClientState(GL_VERTEX_ARRAY);
1281         glEnableClientState(GL_NORMAL_ARRAY);
1282         
1283         glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
1284         glPixelTransferi(GL_RED_SCALE, 1);
1285         glPixelTransferi(GL_RED_BIAS, 0);
1286         glPixelTransferi(GL_GREEN_SCALE, 1);
1287         glPixelTransferi(GL_GREEN_BIAS, 0);
1288         glPixelTransferi(GL_BLUE_SCALE, 1);
1289         glPixelTransferi(GL_BLUE_BIAS, 0);
1290         glPixelTransferi(GL_ALPHA_SCALE, 1);
1291         glPixelTransferi(GL_ALPHA_BIAS, 0);
1292         
1293         glPixelTransferi(GL_DEPTH_BIAS, 0);
1294         glPixelTransferi(GL_DEPTH_SCALE, 1);
1295         glDepthRange(0.0, 1.0);
1296         
1297         a= 0;
1298         for(x=0; x<32; x++) {
1299                 for(y=0; y<4; y++) {
1300                         if( (x) & 1) pat[a++]= 0x88;
1301                         else pat[a++]= 0x22;
1302                 }
1303         }
1304         
1305         glPolygonStipple(patc);
1306
1307         glMatrixMode(GL_TEXTURE);
1308         glLoadIdentity();
1309         glMatrixMode(GL_MODELVIEW);
1310
1311         glFrontFace(GL_CCW);
1312         glCullFace(GL_BACK);
1313         glDisable(GL_CULL_FACE);
1314 }
1315