CFXAA::CFXAA(NL3D::UDriver *driver) : m_Driver(driver), m_PP(NULL), m_VP(NULL), m_Width(~0), m_Height(~0) { nldebug("3D: Create FXAA"); CDriverUser *dru = static_cast<CDriverUser *>(driver); NL3D::IDriver *drv = (dru)->getDriver(); if (drv->supportBloomEffect() && drv->supportNonPowerOfTwoTextures()) { m_PP = new CPixelProgram(); // arbfp1 { IProgram::CSource *source = new IProgram::CSource(); source->Features.MaterialFlags = CProgramFeatures::TextureStages; source->Profile = IProgram::arbfp1; source->setSourcePtr(a_arbfp1); m_PP->addSource(source); } // ps_2_0 { IProgram::CSource *source = new IProgram::CSource(); source->Features.MaterialFlags = CProgramFeatures::TextureStages; source->Profile = IProgram::ps_2_0; source->setSourcePtr(a_ps_2_0); m_PP->addSource(source); } if (!drv->compilePixelProgram(m_PP)) { nlwarning("3D: No supported pixel program for FXAA effect"); delete m_PP; m_PP = NULL; } else { nldebug("3D: FXAA pixel program available"); } } if (!m_PP) { return; } // create vp { m_VP = new CVertexProgram(); // nelvp { IProgram::CSource *source = new IProgram::CSource(); source->Features.MaterialFlags = CProgramFeatures::TextureStages; source->Profile = IProgram::nelvp; source->setSourcePtr(a_nelvp); m_VP->addSource(source); } if (!drv->compileVertexProgram(m_VP)) { nlwarning("3D: No supported vertex program for FXAA effect"); delete m_VP; m_VP = NULL; delete m_PP; m_PP = NULL; } else { nldebug("3D: FXAA vertex program available"); } } if (!m_VP) { return; } // create material and vb { m_Mat = m_Driver->createMaterial(); m_Mat.initUnlit(); m_Mat.setColor(CRGBA::White); m_Mat.setBlend (false); m_Mat.setAlphaTest (false); NL3D::CMaterial *mat = m_Mat.getObjectPtr(); mat->setShader(NL3D::CMaterial::Normal); mat->setBlendFunc(CMaterial::one, CMaterial::zero); mat->setZWrite(false); mat->setZFunc(CMaterial::always); mat->setDoubleSided(true); m_QuadUV.V0 = CVector(0.f, 0.f, 0.5f); m_QuadUV.V1 = CVector(1.f, 0.f, 0.5f); m_QuadUV.V2 = CVector(1.f, 1.f, 0.5f); m_QuadUV.V3 = CVector(0.f, 1.f, 0.5f); /*if (drv->textureCoordinateAlternativeMode()) { m_QuadUV.Uv0 = CUV(0.f, 1.f); m_QuadUV.Uv1 = CUV(1.f, 1.f); m_QuadUV.Uv2 = CUV(1.f, 0.f); m_QuadUV.Uv3 = CUV(0.f, 0.f); } else {*/ m_QuadUV.Uv0 = CUV(0.f, 0.f); m_QuadUV.Uv1 = CUV(1.f, 0.f); m_QuadUV.Uv2 = CUV(1.f, 1.f); m_QuadUV.Uv3 = CUV(0.f, 1.f); /*}*/ /*CVertexBuffer &vb = m_VB; vb.clearValueEx(); vb.addValueEx(CVertexBuffer::Position, CVertexBuffer::Float3); vb.addValueEx(CVertexBuffer::TexCoord0, CVertexBuffer::Float2); vb.addValueEx(CVertexBuffer::TexCoord1, CVertexBuffer::Float4); vb.initEx(); vb.setPreferredMemory(CVertexBuffer::RAMVolatile, false); vb.setNumVertices(4);*/ } }
// ********************************************************* void CPrimRender::onUpdate(CGroupMap &worldMap) { //H_AUTO(R2_CPrimRender_onUpdate) nlassert(_AddedToWorldMap); if (!_Look.VertexLook.WorldMapTexture.empty()) { nlassert(_Vertices.size() == _WorldMapVertices.size()); } static std::vector<sint32> px; static std::vector<sint32> py; px.resize(_Vertices.size()); py.resize(_Vertices.size()); for(uint k = 0; k < _Vertices.size(); ++k) { worldMap.worldToWindowSnapped(px[k], py[k], _Vertices[k]); if (!_WorldMapVertices.empty()) { _WorldMapVertices[k]->setX(px[k]); _WorldMapVertices[k]->setY(py[k]); _WorldMapVertices[k]->updateCoords(); } } if (_WorldMapPoly) { if (_Look.Shape == CPrimLook::ClosedPolyLine) { _WorldMapPoly->setActive(_Active); /*static volatile bool test1 = false; const CVector2f &origin = test1 ? worldMap.getWorldOffset() : CVector2f::Null; CVector2f ref0(0.f, 0.f); CVector2f ref1(1000.f, 1000.f); ref0 += origin; ref1 += origin; worldMap.worldToWindow(ref0, ref0); worldMap.worldToWindow(ref1, ref1); CMatrix polyMatrix; float scaleX = (ref1.x - ref0.x) * 0.001f; float scaleY = (ref1.y - ref0.y) * 0.001f; polyMatrix.setRot(CVector(scaleX, 0.f, 0.f), CVector(0.f, scaleY, 0.f), CVector::Null); polyMatrix.setPos(CVector(ref0.x - scaleX * origin.x, ref0.y - scaleY * origin.y, 0.f)); */ _WorldMapPoly->setVertices(_Vertices); //_WorldMapPoly->setMatrix(polyMatrix); //_WorldMapPoly->touch(); /* static volatile bool dumpPoly = false; if (dumpPoly) { nlwarning("================"); const std::vector<CVector> &verts = _WorldMapPoly->getVertices(); for(uint k = 0; k < verts.size(); ++k) { CVector pos = _WorldMapPoly->getMatrix() * verts[k]; nlwarning("vert %d = (%.1f, %.1f, %.1f)", (int) k , pos.x, pos.y, pos.z); } dumpPoly = false; }*/ } else { _WorldMapPoly->setActive(false); } } for(uint k = 0; k < _WorldMapEdges.size(); ++k) { uint startIndex = _Look.Shape == CPrimLook::Star ? 0 : k; CVector2f start((float) px[startIndex], (float) py[startIndex]); uint nextIndex = (k + 1) % _Vertices.size(); CVector2f end((float) px[nextIndex], (float) py[nextIndex]); _WorldMapEdges[k]->setQuad(start, end, _Look.EdgeLook.WorldMapWidth); _WorldMapEdges[k]->setFiltered(_Look.EdgeLook.WorldMapFiltered); _WorldMapEdges[k]->updateCoords(); // float length = (end - start).norm(); if (_CustomWorldMapEdgeUVMatrix.On) { CUV uvs[4]; CVector startUV = _CustomWorldMapEdgeUVMatrix.Matrix * _Vertices[startIndex]; CVector endUV = _CustomWorldMapEdgeUVMatrix.Matrix * _Vertices[nextIndex]; static uint index0 = 0; static uint index1 = 3; static uint index2 = 2; static uint index3 = 1; uvs[index0] = uvs[index1] = CUV(startUV.x, startUV.y); uvs[index2] = uvs[index3] = CUV(endUV.x, endUV.y); _WorldMapEdges[k]->setCustomUVs(uvs); } else { switch(_Look.EdgeLook.WorldMapWrapMode) { case CEdgeLook::Scaled: _WorldMapEdges[k]->setPattern(0.f, 1.f, CCtrlQuad::Repeat); break; case CEdgeLook::Repeat: _WorldMapEdges[k]->setPattern(0.f, _InvWorldTextureWidth * _Look.EdgeLook.WorldMapUScale * length, CCtrlQuad::Repeat); break; case CEdgeLook::Centered: _WorldMapEdges[k]->setPattern(0.5f - 0.5f * length * _InvWorldTextureWidth * _Look.EdgeLook.WorldMapUScale, 0.5f + 0.5f * length * _InvWorldTextureWidth * _Look.EdgeLook.WorldMapUScale, CCtrlQuad::Clamp); break; default: nlassert(0); break; } } } }