1 /* 2 Copyright (c) 2013 yvt 3 4 This file is part of OpenSpades. 5 6 OpenSpades 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. 10 11 OpenSpades 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. 15 16 You should have received a copy of the GNU General Public License 17 along with OpenSpades. If not, see <http://www.gnu.org/licenses/>. 18 19 */ 20 21 #include "GLFlatMapRenderer.h" 22 #include <Client/GameMap.h> 23 #include <Core/Bitmap.h> 24 #include <Core/Debug.h> 25 #include "GLImage.h" 26 #include "GLRenderer.h" 27 28 namespace spades { 29 namespace draw { GLFlatMapRenderer(GLRenderer * r,client::GameMap * m)30 GLFlatMapRenderer::GLFlatMapRenderer(GLRenderer *r, client::GameMap *m) 31 : renderer(r), map(m) { 32 SPADES_MARK_FUNCTION(); 33 34 chunkRows = m->Height() >> ChunkBits; 35 chunkCols = m->Width() >> ChunkBits; 36 for (int i = 0; i < chunkRows * chunkCols; i++) 37 chunkInvalid.push_back(false); 38 39 Handle<Bitmap> bmp(GenerateBitmap(0, 0, m->Width(), m->Height()), false); 40 try { 41 image = static_cast<GLImage *>(renderer->CreateImage(bmp)); 42 } catch (...) { 43 throw; 44 } 45 46 image->Bind(IGLDevice::Texture2D); 47 IGLDevice *dev = renderer->GetGLDevice(); 48 dev->TexParamater(IGLDevice::Texture2D, IGLDevice::TextureMagFilter, 49 IGLDevice::Nearest); 50 dev->TexParamater(IGLDevice::Texture2D, IGLDevice::TextureMinFilter, 51 IGLDevice::Nearest); 52 } 53 ~GLFlatMapRenderer()54 GLFlatMapRenderer::~GLFlatMapRenderer() { image->Release(); } 55 GenerateBitmap(int mx,int my,int w,int h)56 Bitmap *GLFlatMapRenderer::GenerateBitmap(int mx, int my, int w, int h) { 57 SPADES_MARK_FUNCTION(); 58 Handle<Bitmap> bmp(new Bitmap(w, h), false); 59 try { 60 uint32_t *pixels = bmp->GetPixels(); 61 62 for (int y = 0; y < h; y++) { 63 for (int x = 0; x < w; x++) { 64 int px = mx + x, py = my + y; 65 for (int z = 0; z < 64; z++) { 66 if (map->IsSolid(px, py, z)) { 67 uint32_t col = map->GetColor(px, py, z); 68 col |= 0xff000000UL; 69 *pixels = col; 70 break; 71 } 72 } 73 pixels++; 74 } 75 } 76 } catch (...) { 77 throw; 78 } 79 return bmp.Unmanage(); 80 } 81 GameMapChanged(int x,int y,int z,client::GameMap * map)82 void GLFlatMapRenderer::GameMapChanged(int x, int y, int z, client::GameMap *map) { 83 if (map != this->map) 84 return; 85 86 SPAssert(x >= 0); 87 SPAssert(x < map->Width()); 88 SPAssert(y >= 0); 89 SPAssert(y < map->Height()); 90 SPAssert(z >= 0); 91 SPAssert(z < map->Depth()); 92 93 int chunkX = x >> ChunkBits; 94 int chunkY = y >> ChunkBits; 95 int chunkId = chunkX + chunkY * chunkCols; 96 SPAssert(chunkId >= 0); 97 SPAssert(chunkId < chunkCols * chunkRows); 98 chunkInvalid[chunkId] = true; 99 } 100 Draw(const AABB2 & dest,const AABB2 & src)101 void GLFlatMapRenderer::Draw(const AABB2 &dest, const AABB2 &src) { 102 SPADES_MARK_FUNCTION(); 103 104 // update chunks 105 for (size_t i = 0; i < chunkInvalid.size(); i++) { 106 if (!chunkInvalid[i]) 107 continue; 108 int chunkX = ((int)i) % chunkCols; 109 int chunkY = ((int)i) / chunkCols; 110 111 Handle<Bitmap> bmp( 112 GenerateBitmap(chunkX * ChunkSize, chunkY * ChunkSize, ChunkSize, ChunkSize), 113 false); 114 try { 115 image->SubImage(bmp, chunkX * ChunkSize, chunkY * ChunkSize); 116 } catch (...) { 117 throw; 118 } 119 chunkInvalid[i] = false; 120 } 121 122 renderer->DrawImage(image, dest, src); 123 } 124 } 125 } 126