31 #include "util/structures/rect.h"
32 #include "video/imagemanager.h"
33 #include "video/sdl/sdlimage.h"
34 #include "video/renderbackend.h"
35 #include "video/opengl/renderbackendopengl.h"
40 GLImage::GLImage(IResourceLoader* loader):
48 GLImage::GLImage(
const std::string& name, IResourceLoader* loader):
56 GLImage::GLImage(SDL_Surface* surface):
64 GLImage::GLImage(
const std::string& name, SDL_Surface* surface):
72 GLImage::GLImage(
const uint8_t* data, uint32_t width, uint32_t height):
73 Image(data, width, height),
81 GLImage::GLImage(
const std::string& name,
const uint8_t* data, uint32_t width, uint32_t height):
82 Image(name, data, width, height),
103 void GLImage::resetGlimage() {
109 m_colorkey = RenderBackend::instance()->getColorKey();
112 void GLImage::cleanup() {
115 glDeleteTextures(1, &m_texId);
118 m_compressed =
false;
121 m_tex_coords[0] = m_tex_coords[1] =
122 m_tex_coords[2] = m_tex_coords[3] = 0.0f;
132 assert(target != m_surface);
135 if (rect.
right() < 0 || rect.
x >
static_cast<int32_t
>(target->w) ||
136 rect.
bottom() < 0 || rect.
y >
static_cast<int32_t
>(target->h)) {
142 }
else if (m_shared) {
149 void GLImage::generateGLTexture() {
156 const uint32_t width = m_surface->w;
157 const uint32_t height = m_surface->h;
161 if(GLEE_ARB_texture_non_power_of_two && RenderBackend::instance()->isNPOTEnabled()) {
162 m_chunk_size_w = width;
163 m_chunk_size_h = height;
172 m_tex_coords[0] = m_tex_coords[1] = 0.0f;
173 m_tex_coords[2] =
static_cast<float>(m_surface->w%m_chunk_size_w) / static_cast<float>(m_chunk_size_w);
174 m_tex_coords[3] =
static_cast<float>(m_surface->h%m_chunk_size_h) / static_cast<float>(m_chunk_size_h);
176 if (m_tex_coords[2] == 0.0f){
177 m_tex_coords[2] = 1.0f;
180 if (m_tex_coords[3] == 0.0f){
181 m_tex_coords[3] = 1.0f;
184 uint8_t* data =
static_cast<uint8_t*
>(m_surface->pixels);
185 int32_t pitch = m_surface->pitch;
190 glGenTextures(1, &m_texId);
192 static_cast<RenderBackendOpenGL*
>(RenderBackend::instance())->bindTexture(m_texId);
194 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
195 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
197 GLint internalFormat = GL_RGBA8;
198 if(GLEE_ARB_texture_compression && RenderBackend::instance()->isImageCompressingEnabled()) {
199 internalFormat = GL_COMPRESSED_RGBA;
202 m_compressed =
false;
205 SDL_Surface* target = RenderBackend::instance()->getRenderTargetSurface();
206 int32_t bpp_target = target->format->BitsPerPixel;
207 int32_t bpp_source = m_surface->format->BitsPerPixel;
209 if (bpp_target == 16 && bpp_source == 32) {
210 uint16_t* oglbuffer =
new uint16_t[m_chunk_size_w * m_chunk_size_h];
211 memset(oglbuffer, 0x00, m_chunk_size_w*m_chunk_size_h*
sizeof(uint16_t));
213 for (uint32_t y = 0; y < height; ++y) {
214 for (uint32_t x = 0; x < width; ++x) {
215 uint32_t pos = (y * pitch) + (x * 4);
217 uint8_t r = data[pos + 0];
218 uint8_t g = data[pos + 1];
219 uint8_t b = data[pos + 2];
220 uint8_t a = data[pos + 3];
222 if (RenderBackend::instance()->isColorKeyEnabled()) {
224 if (r == m_colorkey.r && g == m_colorkey.g && b == m_colorkey.b) {
229 oglbuffer[(y*m_chunk_size_w) + x] = ((r >> 4) << 12) |
237 internalFormat = GL_RGBA4;
241 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, m_chunk_size_w, m_chunk_size_h,
242 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, oglbuffer);
248 if(GLEE_ARB_texture_non_power_of_two && RenderBackend::instance()->isNPOTEnabled()) {
249 if(RenderBackend::instance()->isColorKeyEnabled()) {
250 uint8_t* oglbuffer =
new uint8_t[width * height * 4];
251 memcpy(oglbuffer, data, width * height * 4 *
sizeof(uint8_t));
253 for (uint32_t y = 0; y < height; ++y) {
254 for (uint32_t x = 0; x < width * 4; x += 4) {
255 uint32_t gid = x + y * width;
257 uint8_t r = oglbuffer[gid + 0];
258 uint8_t g = oglbuffer[gid + 1];
259 uint8_t b = oglbuffer[gid + 2];
260 uint8_t a = oglbuffer[gid + 3];
263 if (r == m_colorkey.r && g == m_colorkey.g && b == m_colorkey.b) {
264 oglbuffer[gid + 3] = 0;
270 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, m_chunk_size_w, m_chunk_size_h,
271 0, GL_RGBA, GL_UNSIGNED_BYTE, oglbuffer);
276 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, m_chunk_size_w, m_chunk_size_h,
277 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
281 uint32_t* oglbuffer =
new uint32_t[m_chunk_size_w * m_chunk_size_h];
282 memset(oglbuffer, 0x00, m_chunk_size_w*m_chunk_size_h*
sizeof(uint32_t));
284 for (uint32_t y = 0; y < height; ++y) {
285 for (uint32_t x = 0; x < width; ++x) {
286 uint32_t pos = (y * pitch) + (x * 4);
288 uint8_t a = data[pos + 3];
289 uint8_t b = data[pos + 2];
290 uint8_t g = data[pos + 1];
291 uint8_t r = data[pos + 0];
293 if (RenderBackend::instance()->isColorKeyEnabled()) {
295 if (r == m_colorkey.r && g == m_colorkey.g && b == m_colorkey.b) {
300 oglbuffer[(y*m_chunk_size_w) + x] = r | (g << 8) | (b << 16) | (a<<24);
305 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, m_chunk_size_w, m_chunk_size_h,
306 0, GL_RGBA, GL_UNSIGNED_BYTE, static_cast<GLvoid*>(oglbuffer));
312 void GLImage::generateGLSharedTexture(
const GLImage* shared,
const Rect& region) {
313 uint32_t width = shared->getWidth();
314 uint32_t height = shared->getHeight();
316 if(!GLEE_ARB_texture_non_power_of_two || !RenderBackend::instance()->isNPOTEnabled()) {
321 m_tex_coords[0] =
static_cast<GLfloat
>(region.x) / static_cast<GLfloat>(width);
322 m_tex_coords[1] =
static_cast<GLfloat
>(region.y) / static_cast<GLfloat>(height);
323 m_tex_coords[2] =
static_cast<GLfloat
>(region.x + region.w) / static_cast<GLfloat>(width);
324 m_tex_coords[3] =
static_cast<GLfloat
>(region.y + region.h) / static_cast<GLfloat>(height);
331 m_texId = img->m_texId;
333 m_subimagerect = region;
334 m_atlas_img = shared;
335 m_surface = m_shared_img->m_surface;
336 m_compressed = m_shared_img->m_compressed;
337 m_atlas_name = m_shared_img->getName();
340 generateGLSharedTexture(img, region);
343 setState(IResource::RES_LOADED);
349 }
else if (m_shared) {
354 void GLImage::validateShared() {
356 if (m_shared_img->m_texId && m_shared_img->m_texId == m_texId) {
360 if (m_shared_img->getState() == IResource::RES_NOT_LOADED) {
361 m_shared_img->load();
362 m_shared_img->generateGLTexture();
365 m_texId = m_shared_img->m_texId;
366 m_surface = m_shared_img->m_surface;
367 m_compressed = m_shared_img->m_compressed;
368 generateGLSharedTexture(m_shared_img, m_subimagerect);
376 glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, img->getWidth(), img->getHeight(),
377 GL_RGBA, GL_UNSIGNED_BYTE, img->getSurface()->pixels);
381 void GLImage::load() {
385 if (!ImageManager::instance()->exists(m_atlas_name)) {
386 ImagePtr newAtlas = ImageManager::instance()->create(m_atlas_name);
388 m_atlas_img = newAtlas;
393 if (m_shared_img->m_surface != m_surface || m_texId != m_shared_img->m_texId) {
394 m_texId = m_shared_img->m_texId;
395 m_surface = m_shared_img->m_surface;
396 m_compressed = m_shared_img->m_compressed;
398 generateGLSharedTexture(m_shared_img, m_subimagerect);
401 m_state = IResource::RES_LOADED;
407 void GLImage::free() {
409 m_state = IResource::RES_NOT_LOADED;
412 GLuint GLImage::getTexId()
const {
416 const GLfloat* GLImage::getTexCoords()
const {