// --------------------------------------------------------------------------- void CBuilderZone::displayGrid (const NLMISC::CVector &viewMin, const NLMISC::CVector &viewMax) { // Select all blocks visible float rMinX = floorf (viewMin.x / _Display->_CellSize)*_Display->_CellSize; float rMinY = floorf (viewMin.y / _Display->_CellSize)*_Display->_CellSize; float rMaxX = ceilf (viewMax.x / _Display->_CellSize)*_Display->_CellSize; float rMaxY = ceilf (viewMax.y / _Display->_CellSize)*_Display->_CellSize; sint32 nMinX = (sint32)floor (rMinX / _Display->_CellSize); sint32 nMinY = (sint32)floor (rMinY / _Display->_CellSize); sint32 nMaxX = (sint32)floor (rMaxX / _Display->_CellSize); sint32 nMaxY = (sint32)floor (rMaxY / _Display->_CellSize); static vector<uint8> vBars; sint32 nBarsW = (nMaxX-nMinX)+1; sint32 nBarsH = (nMaxY-nMinY)+1; vBars.resize (nBarsW*nBarsH); sint32 x, y, i, j, zoneSelected; for (i = 0; i < nBarsW*nBarsH; ++i) vBars[i] = 0; for (y = nMinY; y <= nMaxY; ++y) for (x = nMinX; x <= nMaxX; ++x) { 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; } } //const string &sZone = _ZoneRegion.getName (x, y); CZoneBankElement *pZBE = _ZoneBank.getElementByZoneName (sZone); if (pZBE != NULL) if ((pZBE->getSizeX() > 1) || (pZBE->getSizeY() > 1)) { const CZoneRegion *pSelected = &(getDocument ()->getZoneRegion (zoneSelected)); sint32 sizeX = pZBE->getSizeX(), sizeY = pZBE->getSizeY(); sint32 posX = pSelected->getPosX (x, y), posY = pSelected->getPosY (x, y); uint8 rot = pSelected->getRot (x, y); uint8 flip = pSelected->getFlip (x, y); sint32 deltaX, deltaY; if (flip == 0) { switch (rot) { case 0: deltaX = -posX; deltaY = -posY; break; case 1: deltaX = -(sizeY-1-posY); deltaY = -posX; break; case 2: deltaX = -(sizeX-1-posX); deltaY = -(sizeY-1-posY); break; case 3: deltaX = -posY; deltaY = -(sizeX-1-posX); break; } } else { switch (rot) { case 0: deltaX = -(sizeX-1-posX); deltaY = -posY; break; case 1: deltaX = -(sizeY-1-posY); deltaY = -(sizeX-1-posX); break; case 2: deltaX = -posX; deltaY = -(sizeY-1-posY); break; case 3: deltaX = -posY; deltaY = -posX; break; } } static SPiece sMask; sMask.Tab.resize (sizeX*sizeY); for(i = 0; i < sizeX*sizeY; ++i) sMask.Tab[i] = pZBE->getMask()[i]; sMask.w = sizeX; sMask.h = sizeY; sMask.rotFlip (rot, flip); for (j = 0; j < sMask.h; ++j) for (i = 0; i < sMask.w; ++i) if (sMask.Tab[i+j*sMask.w]) { if (((x+deltaX+i-nMinX)>=0) && ((x+deltaX+i-nMinX)<nBarsW) && ((y+deltaY+j-nMinY)>=0) && ((y+deltaY+j-nMinY)<nBarsH)) { if ((i > 0) && (sMask.Tab[i-1+j*sMask.w])) vBars[x+deltaX+i-nMinX + (y+deltaY+j-nMinY)*nBarsW] |= 1; if ((j > 0) && (sMask.Tab[i+(j-1)*sMask.w])) vBars[x+deltaX+i-nMinX + (y+deltaY+j-nMinY)*nBarsW] |= 2; } } } } CVertexBuffer VB; CIndexBuffer PB; CMaterial Mat; Mat.initUnlit (); Mat.setBlend (false); VB.setVertexFormat (CVertexBuffer::PositionFlag); VB.setNumVertices ((nBarsW+1)*(nBarsH+1)); CVertexBufferReadWrite vba; VB.lock (vba); for (y = nMinY; y <= nMaxY+1; ++y) for (x = nMinX; x <= nMaxX+1; ++x) { CVector pos; pos.x = (x*_Display->_CellSize - viewMin.x)/(viewMax.x-viewMin.x); pos.y = 0.0f; pos.z = (y*_Display->_CellSize - viewMin.y)/(viewMax.y-viewMin.y); vba.setVertexCoord (x-nMinX+(y-nMinY)*(nBarsW+1), pos); } PB.setNumIndexes (nBarsW*nBarsH*2*2); CIndexBufferReadWrite iba; PB.lock (iba); uint32 nNbLine = 0; for (y = 0; y < nBarsH; ++y) for (x = 0; x < nBarsW; ++x) { // Vertical Line ? if ((vBars[x+y*nBarsW] & 1) == 0) { iba.setLine (nNbLine*2, x+y*(nBarsW+1), x+(y+1)*(nBarsW+1)); ++nNbLine; } // Horizontal Line ? if ((vBars[x+y*nBarsW] & 2) == 0) { iba.setLine (nNbLine*2, x+y*(nBarsW+1), (x+1)+y*(nBarsW+1)); ++nNbLine; } } iba.unlock(); PB.setNumIndexes (nNbLine*2); if (DontUse3D) return; // Render with driver CMatrix mtx; mtx.identity(); vba.unlock(); 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); CNELU::Driver->activeVertexBuffer (VB); CNELU::Driver->activeIndexBuffer (PB); CNELU::Driver->renderLines (Mat, 0, PB.getNumIndexes()/2); }
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()); }
// --------------------------------------------------------------------------- void CBuilderZone::renderTransition (const NLMISC::CVector &viewMin, const NLMISC::CVector &viewMax) { // Selected ? if (_ZoneRegionSelected != -1) { // Select all blocks visible float rMinX = floorf (viewMin.x / _Display->_CellSize)*_Display->_CellSize; float rMinY = floorf (viewMin.y / _Display->_CellSize)*_Display->_CellSize; float rMaxX = ceilf (viewMax.x / _Display->_CellSize)*_Display->_CellSize; float rMaxY = ceilf (viewMax.y / _Display->_CellSize)*_Display->_CellSize; sint32 nMinX = (sint32)floor (rMinX / _Display->_CellSize); sint32 nMinY = (sint32)floor (rMinY / _Display->_CellSize); sint32 nMaxX = (sint32)floor (rMaxX / _Display->_CellSize); sint32 nMaxY = (sint32)floor (rMaxY / _Display->_CellSize); CVertexBuffer VB , VBSel; CIndexBuffer PB, PBSel; CMaterial Mat, MatSel; Mat.initUnlit (); Mat.setBlend (false); MatSel.initUnlit (); MatSel.setBlend (false); MatSel.setColor(NLMISC::CRGBA(255,0,0,0)); VB.setVertexFormat (CVertexBuffer::PositionFlag); VB.reserve ((nMaxX-nMinX+1)*(nMaxY-nMinY+1)*4*2); VBSel.setVertexFormat (CVertexBuffer::PositionFlag); VBSel.reserve ((nMaxX-nMinX+1)*(nMaxY-nMinY+1)*4*2); CVertexBufferReadWrite vba; VB.lock (vba); CVertexBufferReadWrite vbaSel; VBSel.lock (vbaSel); sint32 nVertCount = 0; sint32 nVertCountSel = 0; sint32 x, y, k; CVector worldPos, screenPos; for (y = nMinY; y <= nMaxY; ++y) for (x = nMinX; x <= nMaxX; ++x) { const CZoneRegion *pBZR = &(getDocument ()->getZoneRegion (_ZoneRegionSelected)); uint8 ceUp = pBZR->getCutEdge (x, y, 0); uint8 ceLeft = pBZR->getCutEdge (x, y, 2); if ((ceUp > 0) && (ceUp < 3)) for (k = 0; k < 2; ++k) { if (ceUp == 1) worldPos.x = x * _Display->_CellSize + 3.0f * _Display->_CellSize / 12.0f; else worldPos.x = x * _Display->_CellSize + 7.0f * _Display->_CellSize / 12.0f; worldPos.y = (y+1)*_Display->_CellSize + _Display->_CellSize / 12.0f; worldPos.z = 0; // World -> Screen conversion screenPos.x = (worldPos.x - viewMin.x) / (viewMax.x - viewMin.x); screenPos.y = 0.0f; screenPos.z = (worldPos.y - viewMin.y) / (viewMax.y - viewMin.y); if (k == 0) { vba.setVertexCoord (nVertCount, screenPos); ++nVertCount; } else { vbaSel.setVertexCoord (nVertCountSel, screenPos); ++nVertCountSel; } worldPos.y = (y+1)*_Display->_CellSize - _Display->_CellSize / 12.0f; screenPos.z = (worldPos.y - viewMin.y) / (viewMax.y - viewMin.y); if (k == 0) { vba.setVertexCoord (nVertCount, screenPos); ++nVertCount; } else { vbaSel.setVertexCoord (nVertCountSel, screenPos); ++nVertCountSel; } if (ceUp == 1) worldPos.x = x * _Display->_CellSize + 5.0f * _Display->_CellSize / 12.0f; else worldPos.x = x * _Display->_CellSize + 9.0f * _Display->_CellSize / 12.0f; screenPos.x = (worldPos.x - viewMin.x) / (viewMax.x - viewMin.x); if (k == 0) { vba.setVertexCoord (nVertCount, screenPos); ++nVertCount; } else { vbaSel.setVertexCoord (nVertCountSel, screenPos); ++nVertCountSel; } worldPos.y = (y+1)*_Display->_CellSize + _Display->_CellSize / 12.0f; screenPos.z = (worldPos.y - viewMin.y) / (viewMax.y - viewMin.y); if (k == 0) { vba.setVertexCoord (nVertCount, screenPos); ++nVertCount; } else { vbaSel.setVertexCoord (nVertCountSel, screenPos); ++nVertCountSel; } ceUp = 3 - ceUp; } if ((ceLeft > 0) && (ceLeft < 3)) for (k = 0; k < 2; ++k) { worldPos.x = x * _Display->_CellSize - _Display->_CellSize / 12.0f; if (ceLeft == 1) worldPos.y = y * _Display->_CellSize + 3.0f * _Display->_CellSize / 12.0f; else worldPos.y = y * _Display->_CellSize + 7.0f * _Display->_CellSize / 12.0f; worldPos.z = 0; // World -> Screen conversion screenPos.x = (worldPos.x - viewMin.x) / (viewMax.x - viewMin.x); screenPos.y = 0.0f; screenPos.z = (worldPos.y - viewMin.y) / (viewMax.y - viewMin.y); if (k == 0) { vba.setVertexCoord (nVertCount, screenPos); ++nVertCount; } else { vbaSel.setVertexCoord (nVertCountSel, screenPos); ++nVertCountSel; } worldPos.x = x * _Display->_CellSize + _Display->_CellSize / 12.0f; screenPos.x = (worldPos.x - viewMin.x) / (viewMax.x - viewMin.x); if (k == 0) { vba.setVertexCoord (nVertCount, screenPos); ++nVertCount; } else { vbaSel.setVertexCoord (nVertCountSel, screenPos); ++nVertCountSel; } if (ceLeft == 1) worldPos.y = y * _Display->_CellSize + 5.0f * _Display->_CellSize / 12.0f; else worldPos.y = y * _Display->_CellSize + 9.0f * _Display->_CellSize / 12.0f; screenPos.z = (worldPos.y - viewMin.y) / (viewMax.y - viewMin.y); if (k == 0) { vba.setVertexCoord (nVertCount, screenPos); ++nVertCount; } else { vbaSel.setVertexCoord (nVertCountSel, screenPos); ++nVertCountSel; } worldPos.x = x * _Display->_CellSize - _Display->_CellSize / 12.0f; screenPos.x = (worldPos.x - viewMin.x) / (viewMax.x - viewMin.x); if (k == 0) { vba.setVertexCoord (nVertCount, screenPos); ++nVertCount; } else { vbaSel.setVertexCoord (nVertCountSel, screenPos); ++nVertCountSel; } ceLeft = 3 - ceLeft; } } vba.unlock(); VB.setNumVertices (nVertCount); PB.setNumIndexes (nVertCount*2); CIndexBufferReadWrite iba; PB.lock (iba); for (x = 0; x < (nVertCount/4); ++x) { iba.setLine (x*4+0, x*4+0, x*4+1); iba.setLine (x*4+1, x*4+1, x*4+2); iba.setLine (x*4+2, x*4+2, x*4+3); iba.setLine (x*4+3, x*4+3, x*4+0); } iba.unlock(); vbaSel.unlock(); VBSel.setNumVertices (nVertCountSel); PBSel.setNumIndexes (nVertCountSel*2); CIndexBufferReadWrite ibaSel; PBSel.lock (ibaSel); for (x = 0; x < (nVertCountSel/4); ++x) { ibaSel.setLine (x*4+0, x*4+0, x*4+1); ibaSel.setLine (x*4+1, x*4+1, x*4+2); ibaSel.setLine (x*4+2, x*4+2, x*4+3); ibaSel.setLine (x*4+3, x*4+3, x*4+0); } ibaSel.unlock(); if (DontUse3D) return; // Render 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); CNELU::Driver->activeVertexBuffer (VB); CNELU::Driver->activeIndexBuffer (PB); CNELU::Driver->renderLines (Mat, 0, PB.getNumIndexes()/2); CNELU::Driver->activeVertexBuffer (VBSel); CNELU::Driver->activeIndexBuffer (PBSel); CNELU::Driver->renderLines (MatSel, 0, PBSel.getNumIndexes()/2); } }
/*********************************************************\ displayOrientation() \*********************************************************/ void displayOrientation() { float x = 0.9f*4.f/3.f; float y = 0.1f; float radius = 0.015f; // Triangle CMaterial mat; mat.initUnlit(); mat.setSrcBlend(CMaterial::srcalpha); mat.setDstBlend(CMaterial::invsrcalpha); mat.setBlend(true); CVertexBuffer vb; vb.setVertexFormat (CVertexBuffer::PositionFlag); vb.setNumVertices (7); { CVertexBufferReadWrite vba; vb.lock(vba); // tri vba.setVertexCoord (0, CVector (-radius, 0, 0)); vba.setVertexCoord (1, CVector (radius, 0, 0)); vba.setVertexCoord (2, CVector (0, 0, 3*radius)); // quad vba.setVertexCoord (3, CVector (-radius, 0, -radius)); vba.setVertexCoord (4, CVector (radius, 0, -radius)); vba.setVertexCoord (5, CVector (radius, 0, radius)); vba.setVertexCoord (6, CVector (-radius, 0, radius)); } CNELU::Driver->activeVertexBuffer(vb); CIndexBuffer pbTri; pbTri.setNumIndexes (3); { CIndexBufferReadWrite iba; pbTri.lock (iba); iba.setTri (0, 0, 1, 2); } CIndexBuffer pbQuad; pbQuad.setNumIndexes (6); { CIndexBufferReadWrite iba; pbQuad.lock(iba); iba.setTri (0, 3, 4, 5); iba.setTri (3, 5, 6, 3); } CNELU::Driver->setFrustum (0.f, 4.f/3.f, 0.f, 1.f, -1.f, 1.f, false); CMatrix mtx; mtx.identity(); CNELU::Driver->setupViewMatrix (mtx); mat.setColor(CRGBA(50,255,255,150)); // up mtx.identity(); mtx.translate(CVector(x,0,y)); mtx.rotateY(MoveListener.getRotZ() ); mtx.translate(CVector(0,0,radius)); CNELU::Driver->setupModelMatrix (mtx); CNELU::Driver->activeVertexBuffer(vb); CNELU::Driver->activeIndexBuffer(pbTri); CNELU::Driver->renderTriangles(mat, 0, pbTri.getNumIndexes()/3); mat.setColor(CRGBA(50,50,255,150)); // down mtx.identity(); mtx.translate(CVector(x,0,y)); mtx.rotateY(MoveListener.getRotZ() + (float)Pi); mtx.translate(CVector(0,0,radius)); CNELU::Driver->setupModelMatrix (mtx); CNELU::Driver->renderTriangles(mat, 0, pbTri.getNumIndexes()/3); // left mtx.identity(); mtx.translate(CVector(x,0,y)); mtx.rotateY(MoveListener.getRotZ() - (float)Pi/2); mtx.translate(CVector(0,0,radius)); CNELU::Driver->setupModelMatrix (mtx); CNELU::Driver->renderTriangles(mat, 0, pbTri.getNumIndexes()/3); // right mtx.identity(); mtx.translate(CVector(x,0,y)); mtx.rotateY(MoveListener.getRotZ() + (float)Pi/2); mtx.translate(CVector(0,0,radius)); CNELU::Driver->setupModelMatrix (mtx); CNELU::Driver->renderTriangles(mat, 0, pbTri.getNumIndexes()/3); // center mtx.identity(); mtx.translate(CVector(x,0,y)); mtx.rotateY(MoveListener.getRotZ()); CNELU::Driver->setupModelMatrix (mtx); CNELU::Driver->activeIndexBuffer(pbQuad); CNELU::Driver->renderTriangles(mat, 0, pbQuad.getNumIndexes()/3); }