]> git.tdb.fi Git - libs/gl.git/blob - source/texunit.cpp
Better state tracking for bound objects
[libs/gl.git] / source / texunit.cpp
1 #include <stdexcept>
2 #include <msp/gl/extensions/arb_multitexture.h>
3 #include <msp/gl/extensions/arb_vertex_shader.h>
4 #include "gl.h"
5 #include "texunit.h"
6
7 using namespace std;
8
9 namespace Msp {
10 namespace GL {
11
12 vector<TexUnit> TexUnit::units;
13 TexUnit *TexUnit::cur_unit = 0;
14
15 TexUnit::TexUnit():
16         texture(0),
17         texenv(0)
18 {
19         fill(texgen, texgen+4, static_cast<const TexGen *>(0));
20 }
21
22 bool TexUnit::set_texture(const Texture *tex)
23 {
24         bool result = (tex!=texture);
25         texture = tex;
26         return result;
27 }
28
29 bool TexUnit::set_texenv(const TexEnv *env)
30 {
31         bool result = (texenv!=env);
32         texenv = env;
33         return result;
34 }
35
36 bool TexUnit::set_texgen(unsigned i, const TexGen *gen)
37 {
38         if(i>=4)
39                 throw out_of_range("TexUnit::set_texgen");
40         bool result = (texgen[i]!=gen);
41         texgen[i] = gen;
42         return result;
43 }
44
45 const TexGen *TexUnit::get_texgen(unsigned i)
46 {
47         if(i>=4)
48                 throw out_of_range("TexUnit::get_texgen");
49         return texgen[i];
50 }
51
52 void TexUnit::bind()
53 {
54         if(cur_unit!=this && (cur_unit || index))
55                 glActiveTexture(GL_TEXTURE0+index);
56         cur_unit = this;
57 }
58
59 unsigned TexUnit::get_n_units()
60 {
61         static int count = -1;
62         if(count<0)
63         {
64                 if(ARB_vertex_shader)
65                         glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &count);
66                 else if(ARB_multitexture)
67                         glGetIntegerv(GL_MAX_TEXTURE_UNITS, &count);
68                 else
69                         count = 1;
70         }
71         return count;
72 }
73
74 TexUnit &TexUnit::get_unit(unsigned n)
75 {
76         if(n>0)
77                 static Require _req(ARB_multitexture);
78         if(n>=get_n_units())
79                 throw out_of_range("TexUnit::get_unit");
80
81         if(units.size()<=n)
82         {
83                 unsigned i = units.size();
84                 units.resize(n+1);
85                 for(; i<units.size(); ++i)
86                         units[i].index = i;
87         }
88
89         return units[n];
90 }
91
92 TexUnit &TexUnit::current()
93 {
94         if(!cur_unit)
95                 get_unit(0).bind();
96         return *cur_unit;
97 }
98
99 TexUnit *TexUnit::find_unit(const Texture *tex)
100 {
101         for(vector<TexUnit>::iterator i=units.begin(); i!=units.end(); ++i)
102                 if(i->texture==tex)
103                         return &*i;
104         return 0;
105 }
106
107 TexUnit *TexUnit::find_unit(const TexEnv *env)
108 {
109         for(vector<TexUnit>::iterator i=units.begin(); i!=units.end(); ++i)
110                 if(i->texenv==env)
111                         return &*i;
112         return 0;
113 }
114
115 } // namespace GL
116 } // namespace Msp