1 // GnashTexture.cpp: GnashImage class used for OpenGL rendering
3 // Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
4 // Free Software Foundation, Inc.
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "GnashTexture.h"
41 static inline bool gl_do_check_error(int report
)
44 bool is_error
= false;
45 while ((error
= glGetError()) != GL_NO_ERROR
) {
47 log_error(_("glError: %s caught\n"), gluErrorString(error
));
53 static inline void gl_purge_errors(void)
58 static inline bool gl_check_error(void)
60 return gl_do_check_error(1);
63 // glGetIntegerv() wrapper
64 static bool gl_get_param(GLenum param
, unsigned int *pval
)
69 glGetIntegerv(param
, &val
);
77 // Check for GLX extensions (TFP, FBO)
78 static bool check_extension(const char *name
, const char *ext
)
83 if (name
== nullptr || ext
== nullptr)
86 end
= ext
+ strlen(ext
);
87 name_len
= strlen(name
);
89 n
= strcspn(ext
, " ");
90 if (n
== name_len
&& strncmp(name
, ext
, n
) == 0)
97 GnashTextureFormat::GnashTextureFormat(image::ImageType type
)
100 case image::TYPE_RGB
:
101 _internal_format
= GL_RGB
;
104 case image::TYPE_RGBA
:
105 _internal_format
= GL_RGBA
;
114 GnashTexture::GnashTexture(unsigned int width
, unsigned int height
,
115 image::ImageType type
)
123 D(bug("GnashTexture::GnashTexture()\n"));
128 GnashTexture::~GnashTexture()
130 D(bug("GnashTexture::~GnashTexture()\n"));
133 glDeleteTextures(1, &_texture
);
138 bool GnashTexture::init()
140 // XXX: we only support NPOT textures
141 const char *gl_extensions
= (const char *)glGetString(GL_EXTENSIONS
);
142 if (!check_extension("GL_ARB_texture_non_power_of_two", gl_extensions
))
147 if (_width
== 0 || _height
== 0)
150 glGenTextures(1, &_texture
);
155 glDeleteTextures(1, &_texture
);
159 glPixelStorei(GL_UNPACK_ALIGNMENT
, internal_format() == GL_RGBA
? 4 : 1);
160 glTexImage2D(GL_TEXTURE_2D
, 0, internal_format(), _width
, _height
, 0,
161 format(), GL_UNSIGNED_BYTE
, nullptr);
166 // Bind texture, preserve previous texture state
167 bool GnashTexture::bind()
169 TextureState
* const ts
= &_texture_state
;
172 ts
->was_enabled
= glIsEnabled(GL_TEXTURE_2D
);
174 if (!ts
->was_enabled
)
175 glEnable(GL_TEXTURE_2D
);
176 else if (gl_get_param(GL_TEXTURE_BINDING_2D
, &ts
->old_texture
))
177 ts
->was_bound
= _texture
== ts
->old_texture
;
181 if (!ts
->was_bound
) {
183 glBindTexture(GL_TEXTURE_2D
, _texture
);
184 if (gl_check_error())
188 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
189 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
190 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
191 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
195 // Release texture, restore previous texture state
196 void GnashTexture::release()
198 TextureState
* const ts
= &_texture_state
;
199 if (!ts
->was_bound
&& ts
->old_texture
)
200 glBindTexture(GL_TEXTURE_2D
, ts
->old_texture
);
201 if (!ts
->was_enabled
)
202 glDisable(GL_TEXTURE_2D
);
206 // Update texture with data
207 void GnashTexture::update(const std::uint8_t *data
)
209 D(bug("GnashTexture::update(): data %p, size %dx%d\n", data
, _width
, _height
));
212 glTexSubImage2D(GL_TEXTURE_2D
, 0,
213 0, 0, _width
, _height
,
214 format(), GL_UNSIGNED_BYTE
, data
);