예제 #1
0
파일: fxaa.cpp 프로젝트: junhuac/ryzomcore
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);*/
	}
}
예제 #2
0
// *********************************************************
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;
			}
		}
	}
}