/tags/main/aleph/Source_Files/RenderOther/OGL_Blitter.cpp

# · C++ · 140 lines · 88 code · 27 blank · 25 comment · 3 complexity · b67f4c43f77cd213972e920ca6c37705 MD5 · raw file

  1. /*
  2. Copyright (C) 2006 and beyond by Bungie Studios, Inc.
  3. and the "Aleph One" developers.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. This license is contained in the file "COPYING",
  13. which is included with this source code; it is available online at
  14. http://www.gnu.org/licenses/gpl.html
  15. OpenGL blitter
  16. written by Gregory Smith, 2006
  17. */
  18. #include "OGL_Blitter.h"
  19. const int OGL_Blitter::tile_size;
  20. OGL_Blitter::OGL_Blitter(const SDL_Surface& s, const SDL_Rect& dst, const SDL_Rect& ortho) : m_ortho(ortho)
  21. {
  22. x_scale = (s.w / dst.w);
  23. y_scale = (s.h / dst.h);
  24. x_offset = dst.x;
  25. y_offset = dst.y;
  26. // calculate how many rects we need
  27. int v_rects = ((s.h + tile_size -1) / tile_size);
  28. int h_rects = ((s.w + tile_size - 1) / tile_size);
  29. m_rects.resize(v_rects * h_rects);
  30. m_refs.resize(v_rects * h_rects);
  31. glGenTextures(v_rects * h_rects, &m_refs.front());
  32. SDL_Surface *t;
  33. #ifdef ALEPHONE_LITTLE_ENDIAN
  34. t = SDL_CreateRGBSurface(SDL_SWSURFACE, tile_size, tile_size, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
  35. #else
  36. t = SDL_CreateRGBSurface(SDL_SWSURFACE, tile_size, tile_size, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
  37. #endif
  38. glEnable(GL_TEXTURE_2D);
  39. int i = 0;
  40. for (int y = 0; y < v_rects; y++)
  41. {
  42. for (int x = 0; x < h_rects; x++)
  43. {
  44. m_rects[i].x = x * tile_size;
  45. m_rects[i].y = y * tile_size;
  46. m_rects[i].w = std::min(tile_size, s.w - x * tile_size);
  47. m_rects[i].h = std::min(tile_size, s.h - y * tile_size);
  48. SDL_BlitSurface(const_cast<SDL_Surface *>(&s), &m_rects[i], t, NULL);
  49. glBindTexture(GL_TEXTURE_2D, m_refs[i]);
  50. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  51. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  52. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  53. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  54. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tile_size, tile_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, t->pixels);
  55. i++;
  56. }
  57. }
  58. SDL_FreeSurface(t);
  59. }
  60. OGL_Blitter::~OGL_Blitter()
  61. {
  62. glDeleteTextures(m_refs.size(), &m_refs.front());
  63. m_refs.clear();
  64. m_rects.clear();
  65. }
  66. void OGL_Blitter::SetupMatrix()
  67. {
  68. glPushAttrib(GL_ALL_ATTRIB_BITS);
  69. // disable everything but alpha blending
  70. glDisable(GL_CULL_FACE);
  71. glDisable(GL_DEPTH_TEST);
  72. glDisable(GL_ALPHA_TEST);
  73. glEnable(GL_BLEND);
  74. glDisable(GL_FOG);
  75. glDisable(GL_SCISSOR_TEST);
  76. glDisable(GL_STENCIL_TEST);
  77. glMatrixMode(GL_PROJECTION);
  78. glPushMatrix();
  79. glLoadIdentity();
  80. glMatrixMode(GL_MODELVIEW);
  81. glPushMatrix();
  82. glLoadIdentity();
  83. // transform ortho into screen co-ordinates
  84. gluOrtho2D(m_ortho.x, m_ortho.x + m_ortho.w, m_ortho.y + m_ortho.h, m_ortho.y);
  85. }
  86. void OGL_Blitter::Draw()
  87. {
  88. for (int i = 0; i < m_rects.size(); i++)
  89. {
  90. glBindTexture(GL_TEXTURE_2D, m_refs[i]);
  91. glColor3ub(255, 255, 255);
  92. glBegin(GL_QUADS);
  93. GLdouble VScale = (double) m_rects[i].w / (double) tile_size;
  94. GLdouble UScale = (double) m_rects[i].h / (double) tile_size;
  95. glTexCoord2f(0.0, 0.0); glVertex3f(m_rects[i].x + x_offset, m_rects[i].y + y_offset, 0);
  96. glTexCoord2f(VScale, 0.0); glVertex3f(m_rects[i].x + x_offset + m_rects[i].w * x_scale, m_rects[i].y + y_offset, 0);
  97. glTexCoord2f(VScale, UScale); glVertex3f(m_rects[i].x + x_offset + m_rects[i].w * x_scale, m_rects[i].y + y_offset + m_rects[i].h * y_scale, 0);
  98. glTexCoord2f(0.0, UScale); glVertex3f(m_rects[i].x + x_offset, m_rects[i].y + y_offset + m_rects[i].h * y_scale, 0);
  99. glEnd();
  100. }
  101. }
  102. void OGL_Blitter::RestoreMatrix()
  103. {
  104. glPopMatrix();
  105. glMatrixMode(GL_PROJECTION);
  106. glPopMatrix();
  107. glPopAttrib();
  108. }