// --------------------------------------------------------------------------- void CBuilderZone::render (const NLMISC::CVector &viewMin, const NLMISC::CVector &viewMax) { sint32 i, zoneSelected; DWORD backgroundColor = GetSysColor (COLOR_WINDOW); // Reset the cache for (i = 0; i < (CACHE_RENDER_SIZE); ++i) { _CacheRender[i].VB.setNumVertices (0); _CacheRender[i].PB.setNumIndexes (0); _CacheRender[i].Used = false; } // Select all blocks visible float minx = floorf(viewMin.x/_Display->_CellSize)*_Display->_CellSize; float miny = floorf(viewMin.y/_Display->_CellSize)*_Display->_CellSize; float maxx = ceilf(viewMax.x/_Display->_CellSize)*_Display->_CellSize; float maxy = ceilf(viewMax.y/_Display->_CellSize)*_Display->_CellSize; CVector pos1, pos2, pos3, pos4; CUV uvMin, uvMax; sint32 x, y; ITexture *pTexture; while (minx < maxx) { miny = floorf(viewMin.y/_Display->_CellSize)*_Display->_CellSize; while (miny < maxy) { x = (sint32)floor(minx / _Display->_CellSize); y = (sint32)floor(miny / _Display->_CellSize); i = 0; string sZone = STRING_OUT_OF_BOUND; zoneSelected = 0; for (i = 0; i < (sint32)_ZoneRegions.size(); ++i) { const string &rSZone = getDocument ()->getZoneRegion (i).getName (x, y); if ((sZone == STRING_OUT_OF_BOUND) && (rSZone == STRING_UNUSED)) { sZone = STRING_UNUSED; zoneSelected = i; } if ((rSZone != STRING_OUT_OF_BOUND) && (rSZone != STRING_UNUSED)) { sZone = rSZone; zoneSelected = i; } } CZoneBankElement *pZBE = _ZoneBank.getElementByZoneName (sZone); if (pZBE == NULL) pTexture = _DataBase.getTexture (sZone, 0, 0, uvMin, uvMax); else pTexture = _DataBase.getTexture (sZone, getDocument ()->getZoneRegion (zoneSelected).getPosX(x, y), getDocument ()->getZoneRegion (zoneSelected).getPosY(x, y), uvMin, uvMax); // Look if already existing texture exists in the cache for (i = 0; i < (CACHE_RENDER_SIZE); ++i) if (_CacheRender[i].Used) if (_CacheRender[i].Mat.getTexture(0) == pTexture) break; if (i == (CACHE_RENDER_SIZE)) { // Use a new CacheRender slot for (i = 0; i < (CACHE_RENDER_SIZE); ++i) if (!_CacheRender[i].Used) break; nlassert(i<(CACHE_RENDER_SIZE)); _CacheRender[i].Used = true; _CacheRender[i].Mat.setTexture (0, pTexture); } pos1.x = (minx-viewMin.x)/(viewMax.x-viewMin.x); pos1.y = 0.0f; pos1.z = (miny-viewMin.y)/(viewMax.y-viewMin.y); pos2.x = (_Display->_CellSize+minx-viewMin.x)/(viewMax.x-viewMin.x); pos2.y = 0.0f; pos2.z = (miny-viewMin.y)/(viewMax.y-viewMin.y); pos3.x = (_Display->_CellSize+minx-viewMin.x)/(viewMax.x-viewMin.x); pos3.y = 0.0f; pos3.z = (_Display->_CellSize+miny-viewMin.y)/(viewMax.y-viewMin.y); pos4.x = (minx-viewMin.x)/(viewMax.x-viewMin.x); pos4.y = 0.0f; pos4.z = (_Display->_CellSize+miny-viewMin.y)/(viewMax.y-viewMin.y); uint32 nBasePt = _CacheRender[i].VB.getNumVertices(); _CacheRender[i].VB.setNumVertices (nBasePt+4); CVertexBufferReadWrite vba; _CacheRender[i].VB.lock (vba); vba.setVertexCoord (nBasePt+0, pos1); vba.setVertexCoord (nBasePt+1, pos2); vba.setVertexCoord (nBasePt+2, pos3); vba.setVertexCoord (nBasePt+3, pos4); uint32 nBaseTri = _CacheRender[i].PB.getNumIndexes (); _CacheRender[i].PB.setNumIndexes (nBaseTri+6); CIndexBufferReadWrite iba; _CacheRender[i].PB.lock (iba); iba.setTri (nBaseTri+0, nBasePt+0, nBasePt+1, nBasePt+2); iba.setTri (nBaseTri+3, nBasePt+0, nBasePt+2, nBasePt+3); if ((zoneSelected>=0)&&(zoneSelected<(sint32)_ZoneRegions.size())) { const CZoneRegion *pBZR = &(getDocument ()->getZoneRegion (zoneSelected)); if (pBZR->getFlip (x, y) == 1) { float rTmp = uvMin.U; uvMin.U = uvMax.U; uvMax.U = rTmp; } vba.setTexCoord (nBasePt+(pBZR->getRot (x, y)+0)%4, 0, CUV(uvMin.U, uvMin.V)); vba.setTexCoord (nBasePt+(pBZR->getRot (x, y)+1)%4, 0, CUV(uvMax.U, uvMin.V)); vba.setTexCoord (nBasePt+(pBZR->getRot (x, y)+2)%4, 0, CUV(uvMax.U, uvMax.V)); vba.setTexCoord (nBasePt+(pBZR->getRot (x, y)+3)%4, 0, CUV(uvMin.U, uvMax.V)); } else { vba.setTexCoord (nBasePt+0, 0, CUV(uvMin.U, uvMin.V)); vba.setTexCoord (nBasePt+1, 0, CUV(uvMax.U, uvMin.V)); vba.setTexCoord (nBasePt+2, 0, CUV(uvMax.U, uvMax.V)); vba.setTexCoord (nBasePt+3, 0, CUV(uvMin.U, uvMax.V)); } NLMISC::CRGBA color; if ((zoneSelected>=0)&&(zoneSelected<(sint32)_ZoneRegions.size())) { if (getZoneMask(x,y)) color = NLMISC::CRGBA(255, 255, 255, 255); else color = NLMISC::CRGBA(127, 127, 127, 255); } else color = NLMISC::CRGBA(255, 255, 255, 255); if (pTexture == NULL) color = _Display->_BackgroundColor; vba.setColor (nBasePt+0, color); vba.setColor (nBasePt+1, color); vba.setColor (nBasePt+2, color); vba.setColor (nBasePt+3, color); miny += _Display->_CellSize; } minx += _Display->_CellSize; } //MessageBox(NULL, "CBuilderZone::render", "3", MB_OK); if (DontUse3D) return; // Flush the cache to the screen CMatrix mtx; mtx.identity(); CNELU::Driver->setupViewport (CViewport()); CNELU::Driver->setupViewMatrix (mtx); CNELU::Driver->setupModelMatrix (mtx); CNELU::Driver->setFrustum (0.f, 1.f, 0.f, 1.f, -1.f, 1.f, false); //MessageBox(NULL, "CBuilderZone::render", "4", MB_OK); for (i = 0; i < (CACHE_RENDER_SIZE); ++i) if (_CacheRender[i].Used) { // Render with driver CNELU::Driver->activeVertexBuffer (_CacheRender[i].VB); CNELU::Driver->activeIndexBuffer (_CacheRender[i].PB); CNELU::Driver->renderTriangles (_CacheRender[i].Mat, 0, _CacheRender[i].PB.getNumIndexes()/3); } }
void CDeform2d::doDeform(const TPoint2DVect &surf, IDriver *drv, IPerturbUV *uvp) { nlassert(uvp); typedef CQuadEffect::TPoint2DVect TPoint2DVect; TPoint2DVect dest; CQuadEffect::processPoly(surf, (float) _XGranularity, (float) _YGranularity, dest); uint realWidth = NLMISC::raiseToNextPowerOf2(_Width); uint realHeight= NLMISC::raiseToNextPowerOf2(_Height); // draw the poly contour /*for (uint k = 0; k < dest.size(); ++k) { CDRU::drawLine(dest[k].x, dest[k].y, dest[(k + 1) % dest.size()].x, dest[(k + 1) % dest.size()].y, *drv, CRGBA::Red); }*/ static CMaterial mat; mat.setDoubleSided(true); mat.setLighting(false); mat.setZFunc(CMaterial::always); /* mat.setColor(CRGBA::Red); mat.texEnvOpRGB(0, CMaterial::Add); */ static CVertexBuffer vb; vb.setName("CDeform2d"); vb.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag); drv->setFrustum(0, (float) _Width, 0, (float) _Height, -1, 1, false); drv->setupViewMatrix(CMatrix::Identity); drv->setupModelMatrix(CMatrix::Identity); const float iDu = 1.f / _Width; const float iDv = 1.f / _Height; const float widthRatio = _Width / (float) realWidth; const float heightRatio = _Height / (float) realHeight; float u, u2, v; float du, dv; TPoint2DVect::const_iterator it; // get back datas from frame buffer for (it = dest.begin(); it != dest.end(); ++it) { // todo hulud use the new render to texture interface // drv->copyFrameBufferToTexture(_Tex, 0, (uint32) it->x,(uint32) it->y, (uint32) it->x, (uint32) it->y, _XGranularity, _YGranularity); } /** setup the whole vertex buffer * we don't share vertices here, as we work with unaligned quads */ vb.setNumVertices((uint32)dest.size() << 2); mat.setTexture(0, _Tex); { CVertexBufferReadWrite vba; vb.lock (vba); uint k = 0; // current index in the vertex buffer for (it = dest.begin(); it != dest.end(); ++it, k += 4) { // \todo optimize this by a direct access to the vertex buffer (if needed) // blit data to frame buffer and apply deformations vba.setVertexCoord(k, NLMISC::CVector(it->x, 0, it->y)); vba.setVertexCoord(k + 1, NLMISC::CVector(it->x + _XGranularity, 0, it->y)); vba.setVertexCoord(k + 2, NLMISC::CVector(it->x + _XGranularity, 0, it->y + _YGranularity)); vba.setVertexCoord(k + 3, NLMISC::CVector(it->x , 0, it->y + _YGranularity)); // perturbation of the uv coordinates u = it->x * iDu; v = it->y * iDv; uvp->perturbUV(u, v, du, dv); vba.setTexCoord(k, 0, (u + du) * widthRatio, (v + dv) * heightRatio ); u2 = (it->x + _XGranularity) * iDu; uvp->perturbUV(u2, v, du, dv); vba.setTexCoord(k + 1, 0, (u2 + du) * widthRatio, (v + dv) * heightRatio ); v = (it->y + _YGranularity) * iDv; uvp->perturbUV(u2, v, du, dv); vba.setTexCoord(k + 2, 0, (u2 + du) * widthRatio, (v + dv) * heightRatio ); uvp->perturbUV(u, v, du, dv); vba.setTexCoord(k + 3, 0, (u + du) * widthRatio, (v + dv) * heightRatio ); } } drv->activeVertexBuffer(vb); drv->renderRawQuads(mat, 0, (uint32)dest.size()); }