]> git.tdb.fi Git - libs/gl.git/blob - source/texture.cpp
Remove support for texture borders
[libs/gl.git] / source / texture.cpp
1 /* $Id$
2
3 This file is part of libmspgl
4 Copyright © 2007  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include "except.h"
9 #include "texture.h"
10 #include "texunit.h"
11
12 using namespace std;
13
14 namespace Msp {
15 namespace GL {
16
17 istream &operator>>(istream &in, TextureFilter &tf)
18 {
19         string str;
20         in>>str;
21
22         if(str=="NEAREST")
23                 tf = NEAREST;
24         else if(str=="LINEAR")
25                 tf = LINEAR;
26         else if(str=="NEAREST_MIPMAP_NEAREST")
27                 tf = NEAREST_MIPMAP_NEAREST;
28         else if(str=="NEAREST_MIPMAP_LINEAR")
29                 tf = NEAREST_MIPMAP_LINEAR;
30         else if(str=="LINEAR_MIPMAP_NEAREST")
31                 tf = LINEAR_MIPMAP_NEAREST;
32         else if(str=="LINEAR_MIPMAP_LINEAR")
33                 tf = LINEAR_MIPMAP_LINEAR;
34         else
35                 in.setstate(ios_base::failbit);
36
37         return in;
38 }
39
40
41 Texture::Texture(GLenum t):
42         target(t),
43         min_filter(NEAREST_MIPMAP_LINEAR),
44         mag_filter(LINEAR),
45         wrap_s(REPEAT),
46         wrap_t(REPEAT),
47         wrap_r(REPEAT),
48         gen_mipmap(false),
49         compare(false),
50         cmp_func(LEQUAL),
51         dirty_params(0)
52 {
53         glGenTextures(1, &id);
54 }
55
56 Texture::~Texture()
57 {
58         glDeleteTextures(1, &id);
59 }
60
61 void Texture::update_parameter(int mask) const
62 {
63         if(current()==this)
64         {
65                 if(mask&MIN_FILTER)
66                         glTexParameteri(target, GL_TEXTURE_MIN_FILTER, min_filter);
67                 if(mask&MAG_FILTER)
68                         glTexParameteri(target, GL_TEXTURE_MAG_FILTER, mag_filter);
69                 if(mask&WRAP_S)
70                         glTexParameteri(target, GL_TEXTURE_WRAP_S, wrap_s);
71                 if(mask&WRAP_T)
72                         glTexParameteri(target, GL_TEXTURE_WRAP_T, wrap_t);
73                 if(mask&WRAP_R)
74                         glTexParameteri(target, GL_TEXTURE_WRAP_R, wrap_r);
75                 if(mask&GENERATE_MIPMAP)
76                         glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, gen_mipmap);
77                 if(mask&COMPARE)
78                         glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, (compare ? GL_COMPARE_R_TO_TEXTURE : GL_NONE));
79                 if(mask&COMPARE_FUNC)
80                         glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, cmp_func);
81         }
82         else
83                 dirty_params |= mask;
84 }
85
86 void Texture::set_min_filter(TextureFilter f)
87 {
88         min_filter = f;
89         update_parameter(MIN_FILTER);
90 }
91
92 void Texture::set_mag_filter(TextureFilter f)
93 {
94         mag_filter = f;
95         update_parameter(MAG_FILTER);
96 }
97
98 void Texture::set_wrap(TextureWrap w)
99 {
100         set_wrap_s(w);
101         set_wrap_t(w);
102         set_wrap_r(w);
103 }
104
105 void Texture::set_wrap_s(TextureWrap w)
106 {
107         wrap_s = w;
108         update_parameter(WRAP_S);
109 }
110
111 void Texture::set_wrap_t(TextureWrap w)
112 {
113         wrap_t = w;
114         update_parameter(WRAP_T);
115 }
116
117 void Texture::set_wrap_r(TextureWrap w)
118 {
119         wrap_r = w;
120         update_parameter(WRAP_R);
121 }
122
123 void Texture::set_generate_mipmap(bool gm)
124 {
125         gen_mipmap = gm;
126         update_parameter(GENERATE_MIPMAP);
127 }
128
129 void Texture::set_compare_enabled(bool c)
130 {
131         compare = c;
132         update_parameter(COMPARE);
133 }
134
135 void Texture::set_compare_func(Predicate f)
136 {
137         cmp_func = f;
138         update_parameter(COMPARE_FUNC);
139 }
140
141 void Texture::bind() const
142 {
143         if(!target)
144                 throw InvalidState("Attempt to bind a texture without target (should never happen)");
145
146         const Texture *cur = TexUnit::current().get_texture();
147         if(cur!=this)
148         {
149                 if(cur && cur->target!=target)
150                         glDisable(cur->target);
151                 if(!cur || cur->target!=target)
152                         glEnable(target);
153
154                 glBindTexture(target, id);
155                 TexUnit::current().set_texture(this);
156
157                 if(dirty_params)
158                 {
159                         update_parameter(dirty_params);
160                         dirty_params = 0;
161                 }
162         }
163 }
164
165 void Texture::bind_to(unsigned i) const
166 {
167         TexUnit::activate(i);
168         bind();
169 }
170
171 const Texture *Texture::current()
172 {
173         return TexUnit::current().get_texture();
174 }
175
176 void Texture::unbind()
177 {
178         const Texture *cur = TexUnit::current().get_texture();
179         if(!cur)
180                 return;
181
182         glBindTexture(cur->target, 0);
183         glDisable(cur->target);
184         TexUnit::current().set_texture(0);
185 }
186
187 void Texture::unbind_from(unsigned i)
188 {
189         TexUnit::activate(i);
190         unbind();
191 }
192
193
194 Texture::Loader::Loader(Texture &t):
195         DataFile::ObjectLoader<Texture>(t)
196 {
197         add("min_filter", &Loader::min_filter);
198         add("mag_filter", &Loader::mag_filter);
199         add("generate_mipmap", &Loader::generate_mipmap);
200 }
201
202 void Texture::Loader::min_filter(TextureFilter f)
203 {
204         obj.set_min_filter(f);
205 }
206
207 void Texture::Loader::mag_filter(TextureFilter f)
208 {
209         obj.set_mag_filter(f);
210 }
211
212 void Texture::Loader::generate_mipmap(bool gm)
213 {
214         obj.set_generate_mipmap(gm);
215 }
216
217 } // namespace GL
218 } // namespace Msp