//////////////////////////////////////////////////////////////////////////////// // Scorched3D (c) 2000-2003 // // This file is part of Scorched3D. // // Scorched3D is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // Scorched3D is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Scorched3D; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include ShadowMap::ShadowMap() : size_(256), sizeSq_(256 *256), shadowCount_(0) { shadowBytes_ = new GLubyte[sizeSq_]; memset(shadowBytes_, 255, sizeSq_); shadowTexture_.create(shadowBytes_, size_, size_, 1, 4, GL_LUMINANCE, false); } ShadowMap::~ShadowMap() { delete [] shadowBytes_; } void ShadowMap::setTexture() { shadowCount_ = 0; // Set the shadow map texture shadowTexture_.draw(true); if (!GLStateExtension::getNoTexSubImage()) { // Update with the contents from the stored bytes glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size_, size_, GL_LUMINANCE, GL_UNSIGNED_BYTE, shadowBytes_); // Reset the stored bytes memset(shadowBytes_, 255, sizeSq_); // Debuging stripe //for (int i=0; igetNoShadows()) return; int mapWidth = ScorchedClient::instance()->getLandscapeMaps().getGroundMaps().getMapWidth(); int mapHeight = ScorchedClient::instance()->getLandscapeMaps().getGroundMaps().getMapHeight(); float sx = mapx * size_ / float(mapWidth); float sy = mapy * size_ / float(mapHeight); float sw = mapw * size_ / float(mapWidth); // Make sure the size is scaled if (sx < 0 || sx >= size_ || sy < 0 || sy >= size_) { return; } shadowCount_++; const GLubyte minNum = 64; int decrement = int(opacity * 200.0f); float halfW = sw / 2.0f; float minX = sx - halfW; float minY = sy - halfW; float maxX = sx + halfW; float maxY = sy + halfW; minX = MAX(minX, 0.0f); minY = MAX(minY, 0.0f); maxX = MIN(maxX, size_ - 1.0f); maxY = MIN(maxY, size_ - 1.0f); int iSize = int(size_); int xStart = int(minX); int yStart = int(minY); int xWidth = int(maxX - minX); int yWidth = int(maxY - minY); int yInc = size_ - xWidth; if (xWidth <= 0 || yWidth <= 0) return; if (circle) { static float sintable[100]; static bool sintablemade = false; if (!sintablemade) { sintablemade = true; float degMult = 0.0314f; for (int i=0; i<100; i++) { float deg = float(i) * degMult; sintable[i] = sinf(deg); } } GLubyte *start = &shadowBytes_[(yStart * iSize) + xStart]; for (int y=0; y decrement + minNum) (*start) -= (GLubyte) (decrement); else (*start = minNum); } start+=xWidth - (halfSize + x); } } else { GLubyte *start = &shadowBytes_[(yStart * iSize) + xStart]; for (int y=0; y decrement + minNum) (*start) -= (GLubyte) decrement; else (*start = minNum); } } } }