Пример #1
0
	void PS_Mesh::_update(Particle * p)
	{
		Float3 Position = p->Position;
		if (mParent->IsLocalSpace())
			Position.TransformA(mParent->GetParent()->GetWorldTM());

		mMesh->SetPosition(Position);
		mMesh->SetOpacity(p->Color.a);
		mMesh->SetRotationEx(p->Rotation);
		mMesh->SetScale(p->Size);
		mMesh->_updateTM();

		int blendMode = mParent->GetBlendMode();

		for (int i = 0; i < mMesh->GetSubMeshCount(); ++i)
		{
			SubMesh * submesh = mMesh->GetSubMesh(i);
			Material * mtl = submesh->GetMaterial();
			
			mtl->diffuse = Float3(p->Color.r, p->Color.g, p->Color.b);
			if (mParent->_getTexture() != NULL)
			{
				mtl->maps[eMapType::DIFFUSE] = mParent->_getTexture();
			}

			if (mParent->GetShaderEnable())
			{
				mtl->depthMode = eDepthMode::N_LESS_EQUAL;

				if (blendMode == PS_BlendMode::ADD)
				{
					mtl->blendMode = eBlendMode::ADD;
				}
				else if (blendMode == PS_BlendMode::ALPHA_BLEND)
				{
					mtl->blendMode = eBlendMode::ALPHA_BLEND;
				}
				else if (blendMode == PS_BlendMode::COLOR_BLEND)
				{
					mtl->blendMode = eBlendMode::COLOR_BLEND;
				}
				else
				{
					mtl->blendMode = eBlendMode::OPACITY;
					mtl->depthMode = eDepthMode::LESS_EQUAL;
				}

				submesh->SetShaderFX(mParent->_getShaderFX());
				submesh->SetRenderCallBack(eRenderCallBack::SHADER, mParent->GetShader().c_ptr());
			}
		}
	}
Пример #2
0
	void MeshGroup::_genMesh(const Array<Mesh *> & arr, int first, int last, bool hasLightingColor)
	{
		MeshSourcePtr source = arr[0]->GetSource();
		Mesh * mesh = new Mesh;

		for (int i = 0; i < source->GetMeshBufferCount(); ++i)
		{
			SubMesh * submesh = mesh->NewSubMesh();
			VertexBufferPtr srcVB = source->GetMeshBuffer(i)->GetRenderOp()->vertexBuffers[0];
			IndexBufferPtr srcIB = source->GetMeshBuffer(i)->GetRenderOp()->indexBuffer;
			int p_offset = source->GetMeshBuffer(i)->GetRenderOp()->vertexDeclarations[0].GetElementOffset(eVertexSemantic::POSITION);
			int n_offset = source->GetMeshBuffer(i)->GetRenderOp()->vertexDeclarations[0].GetElementOffset(eVertexSemantic::NORMAL);
			int stride = srcVB->GetStride();

			VertexBufferPtr vb = HWBufferManager::Instance()->NewVertexBuffer(stride, srcVB->GetCount() * (last - first));
			
			const char * v_src = (const char *)srcVB->Lock(eLockFlag::READ);
			char * v_dest = (char *)vb->Lock(eLockFlag::WRITE);
			for (int j = first; j < last; ++j)
			{
				const Mat4 & worldTM = arr[j]->GetWorldTM();
				bool hasScale = arr[j]->GetWorldScale() != Float3(1, 1, 1);

				for (int k = 0; k < srcVB->GetCount(); ++k)
				{
					memcpy(v_dest, v_src, stride);

					Float3 * position = (Float3 *)(v_dest + p_offset);
					position->TransformA(worldTM);
					
					if (n_offset != -1)
					{
						Float3 * normal = (Float3 *)(v_dest + n_offset);
						normal->TransformN(worldTM);

						if (hasScale)
						{
							normal->Normalize();
						}
					}

					v_dest += stride;
					v_src += stride;
				}
			}
			vb->Unlock();
			srcVB->Unlock();

			IndexBufferPtr ib = HWBufferManager::Instance()->NewIndexBuffer(srcIB->GetCount() * (last - first));

			int startVertex = 0;
			const short * i_src = (const short *)srcIB->Lock(eLockFlag::READ);
			char * i_dest = (char *)ib->Lock(eLockFlag::WRITE);
			for (int j = first; j < last; ++j)
			{
				for (int k = 0; k < srcIB->GetCount(); ++k)
				{
					*i_dest++ = (*i_src++) + startVertex;
				}

				startVertex += srcVB->GetCount();
			}
			ib->Unlock();
			srcIB->Unlock();
			
			submesh->GetRenderOp()->vertexDeclarations[0] = source->GetMeshBuffer(i)->GetRenderOp()->vertexDeclarations[0];
			submesh->GetRenderOp()->vertexBuffers[0] = vb;
			submesh->GetRenderOp()->indexBuffer = ib;
			submesh->GetRenderOp()->primCount = ib->GetCount() / 3;
			submesh->GetRenderOp()->primType = ePrimType::TRIANGLE_LIST;

			if (hasLightingColor)
			{
				int count = submesh->GetRenderOp()->vertexBuffers[0]->GetCount();
				submesh->GetRenderOp()->vertexDeclarations[LIGHTING_COLOR_STREAM].AddElement(eVertexSemantic::LIGHTING_COLOR, eVertexType::UBYTE4);
				submesh->GetRenderOp()->vertexBuffers[LIGHTING_COLOR_STREAM] = HWBufferManager::Instance()->NewVertexBuffer(4, count);

				Array<Rgba32> lightColors;
				Rgba32 * data = (Rgba32 *)submesh->GetRenderOp()->vertexBuffers[LIGHTING_COLOR_STREAM]->Lock(eLockFlag::WRITE);
				for (int j = first; j < last; ++j)
				{
					arr[j]->GetLightingColor(lightColors);
					d_assert (lightColors.Size() > 0);

					memcpy(data, &lightColors[0], 4 * count);

					startVertex += count;
					lightColors.Clear();
				}
				submesh->GetRenderOp()->vertexBuffers[LIGHTING_COLOR_STREAM]->Unlock();
			}

			*submesh->GetMaterial() = *source->GetMeshBuffer(i)->GetMaterial();

			submesh->SetMeshShader(source->GetMeshBuffer(i)->GetShader());
		}

		mesh->SetSLMode(hasLightingColor ? eStaticLightingMode::LIGHTING_COLOR : eStaticLightingMode::NONE);

		mMeshes.PushBack(mesh);
	}
Пример #3
0
	Mesh * PS_MeshSet::_createClinder()
	{
		Float3 offset = mCenter;
		int rings = mRings;
		float radius = mRadius;
		float height = mHeight;

		if (rings < 1)
			return NULL;

		Mesh * pMesh = new Mesh;
		SubMesh * sm = pMesh->NewSubMesh();

		int iVertexCount = (rings + 1) * 2;
		int iIndexCount = rings * 6;
		int iPrimCount = iIndexCount / 3;

		d_assert(iIndexCount < 65536);

		sm->GetRenderOp()->vertexDeclarations[0].AddElement(eVertexSemantic::POSITION, eVertexType::FLOAT3);
		sm->GetRenderOp()->vertexDeclarations[0].AddElement(eVertexSemantic::TEXCOORD0, eVertexType::FLOAT2);

		VertexBufferPtr buffer = HWBufferManager::Instance()->NewVertexBuffer(20, iVertexCount);

		float * vert = (float *)buffer->Lock(eLockFlag::WRITE);
		{
			float r_step = (2 * PI / rings);
			float u_step = 1 / (float)rings;
			float x, z, rads;

			for (int i = 0; i <= rings; ++i)
			{
				rads = i * r_step;

				Math::SinCos(rads, z, x);

				x *= radius;
				z *= radius;

				*vert++ = x + offset.x;
				*vert++ = 0 + offset.y;
				*vert++ = z + offset.z;
				*vert++ = i * u_step;
				*vert++ = 1;

				*vert++ = x + offset.x;
				*vert++ = height + offset.y;
				*vert++ = z + offset.z;
				*vert++ = i * u_step;
				*vert++ = 0;
			}
		}
		buffer->Unlock();

		IndexBufferPtr ibuffer = HWBufferManager::Instance()->NewIndexBuffer(iIndexCount);
		short * indices = (short *)ibuffer->Lock(eLockFlag::WRITE);
		{
			for (short i = 0; i < rings; ++i)
			{
				int j = i * 2;

				*indices++ = j;
				*indices++ = j + 1;
				*indices++ = j + 2;

				*indices++ = j + 2;
				*indices++ = j + 1;
				*indices++ = j + 3;
			}
		}
		ibuffer->Unlock();

		sm->GetRenderOp()->vertexBuffers[0] = buffer;
		sm->GetRenderOp()->indexBuffer = ibuffer;
		sm->GetRenderOp()->primType = ePrimType::TRIANGLE_LIST;
		sm->GetRenderOp()->primCount = iPrimCount;

		sm->GetMaterial()->cullMode = eCullMode::NONE;
		sm->GetMaterial()->maps[eMapType::DIFFUSE] = RenderHelper::Instance()->GetWhiteTexture();

		pMesh->SetLocalAabb(Aabb(Float3(-radius, 0, -radius) + offset, Float3(radius, height, radius) + offset));

		return pMesh;
	}
Пример #4
0
	Mesh * PS_MeshSet::_createCone(bool up)
	{
		Float3 offset = mCenter;
		int rings = (mRings + 3) / 4;
		int segments = mSegments;
		float radius = mRadius;
		float height = mHeight;

		if (rings < 1)
			return NULL;

		Mesh * pMesh = new Mesh;
		SubMesh * sm = pMesh->NewSubMesh();

		float h1 = up ? 0 : height;
		float h2 = up ? height : 0;

		int iVertexCount = 1 + (rings * 4 + 1);
		int iIndexCount = rings * 4 * 3;
		int iPrimCount = iIndexCount / 3;

		d_assert(iIndexCount < 65536);

		sm->GetRenderOp()->vertexDeclarations[0].AddElement(eVertexSemantic::POSITION, eVertexType::FLOAT3);
		sm->GetRenderOp()->vertexDeclarations[0].AddElement(eVertexSemantic::TEXCOORD0, eVertexType::FLOAT2);

		VertexBufferPtr buffer = HWBufferManager::Instance()->NewVertexBuffer(20, iVertexCount);

		float * vert = (float *)buffer->Lock(eLockFlag::WRITE);
		{
			float r_step = (PI2 / (rings * 4));
			float d_step = (radius * 2 / rings);
			float u_step = 1 / (float)rings;
			float v_step = u_step;
			float x, z;
			float rads = -PI * 0.25f;

			*vert++ = 0 + offset.x;
			*vert++ = h1 + offset.x;
			*vert++ = 0 + offset.z;
			*vert++ = 0.5f;
			*vert++ = 0.5f;

			// top
			for (int i = 0; i <= rings; ++i)
			{
				Math::SinCos(rads, z, x);

				x *= radius;
				z *= radius;

				*vert++ = x + offset.x;
				*vert++ = h2 + offset.y;
				*vert++ = z + offset.z;
				*vert++ = i * u_step;
				*vert++ = 0;

				rads += r_step;
			}

			// right
			for (int i = 1; i <= rings; ++i)
			{
				Math::SinCos(rads, z, x);

				x *= radius;
				z *= radius;

				*vert++ = x + offset.x;
				*vert++ = h2 + offset.y;
				*vert++ = z + offset.z;
				*vert++ = 1;
				*vert++ = i * v_step;

				rads += r_step;
			}

			// bottom
			for (int i = 1; i <= rings; ++i)
			{
				Math::SinCos(rads, z, x);

				x *= radius;
				z *= radius;

				*vert++ = x + offset.x;
				*vert++ = h2 + offset.y;
				*vert++ = z + offset.z;
				*vert++ = 1 - i * u_step;
				*vert++ = 1;

				rads += r_step;
			}

			// left
			for (int i = 1; i <= rings; ++i)
			{
				Math::SinCos(rads, z, x);

				x *= radius;
				z *= radius;

				*vert++ = x + offset.x;
				*vert++ = h2 + offset.y;
				*vert++ = z + offset.z;
				*vert++ = 0;
				*vert++ = 1 - i * u_step;

				rads += r_step;
			}
		}
		buffer->Unlock();

		IndexBufferPtr ibuffer = HWBufferManager::Instance()->NewIndexBuffer(iIndexCount);
		short * indices = (short *)ibuffer->Lock(eLockFlag::WRITE);
		{
			for (short i = 0; i < rings * 4; ++i)
			{
				*indices++ = i + 1;
				*indices++ = 0;
				*indices++ = i + 2;
			}
		}
		ibuffer->Unlock();

		sm->GetRenderOp()->vertexBuffers[0] = buffer;
		sm->GetRenderOp()->indexBuffer = ibuffer;
		sm->GetRenderOp()->primType = ePrimType::TRIANGLE_LIST;
		sm->GetRenderOp()->primCount = iPrimCount;

		sm->GetMaterial()->cullMode = eCullMode::NONE;
		sm->GetMaterial()->maps[eMapType::DIFFUSE] = RenderHelper::Instance()->GetWhiteTexture();

		pMesh->SetLocalAabb(Aabb(Float3(-radius, 0, -radius) + offset, Float3(radius, height, radius) + offset));

		return pMesh;
	}
Пример #5
0
	Mesh * PS_MeshSet::_createSphere()
	{
		Float3 offset = mCenter;
		int rings = mRings;
		int segments = mSegments;
		float radius = mRadius;

		if (rings < 1 || segments < 1)
			return NULL;

		Mesh * pMesh = new Mesh;
		SubMesh * sm = pMesh->NewSubMesh();

		int iVertexCount = (rings + 1) * (segments + 1);
		int iIndexCount = rings * segments * 6;
		int iPrimCount = iIndexCount / 3;

		d_assert(iIndexCount < 65536);

		sm->GetRenderOp()->vertexDeclarations[0].AddElement(eVertexSemantic::POSITION, eVertexType::FLOAT3);
		sm->GetRenderOp()->vertexDeclarations[0].AddElement(eVertexSemantic::TEXCOORD0, eVertexType::FLOAT2);

		VertexBufferPtr buffer = HWBufferManager::Instance()->NewVertexBuffer(20, iVertexCount);

		float * vert = (float *)buffer->Lock(eLockFlag::WRITE);
		{
			float fTileRingAngle = (PI / rings);
			float fTileSegAngle = (PI * 2 / segments);
			float u_step = 1 / (float)rings;
			float v_step = 1 / (float)segments;
			float r;
			short i, j;
			Float3 pos;

			for (i = 0; i <= rings; ++i)
			{
				r = radius * Math::Sin(i * fTileRingAngle);
				pos.y = radius * Math::Cos(i * fTileRingAngle);

				for (j = 0; j <= segments; ++j)
				{
					pos.x = r * Math::Cos(j * fTileSegAngle);
					pos.z = r * Math::Sin(j * fTileSegAngle);

					*vert++ = pos.x + offset.x;
					*vert++ = pos.y + offset.y;
					*vert++ = pos.z + offset.z;
					*vert++ = i * u_step;
					*vert++ = j * v_step;
				}

			}
		}
		buffer->Unlock();

		IndexBufferPtr ibuffer = HWBufferManager::Instance()->NewIndexBuffer(iIndexCount);
		short * indices = (short *)ibuffer->Lock(eLockFlag::WRITE);
		{
			short row = 0, row_n = 0;
			short i, j;

			for (i = 0; i < rings; ++i)
			{
				row_n = row + segments + 1;

				for (j = 0; j < segments; ++j)
				{
					*indices++ = row + j;
					*indices++ = row + j + 1;
					*indices++ = row_n + j;

					*indices++ = row_n + j;
					*indices++ = row + j + 1;
					*indices++ = row_n + j + 1;
				}

				row += segments + 1;
			}
		}
		ibuffer->Unlock();

		sm->GetRenderOp()->vertexBuffers[0] = buffer;
		sm->GetRenderOp()->indexBuffer = ibuffer;
		sm->GetRenderOp()->primCount = iPrimCount;
		sm->GetRenderOp()->primType= ePrimType::TRIANGLE_LIST;

		sm->GetMaterial()->maps[eMapType::DIFFUSE] = RenderHelper::Instance()->GetWhiteTexture();

		pMesh->SetLocalAabb(Aabb(Float3(-radius, -radius, -radius) + offset, Float3(radius, radius, radius) + offset));

		return pMesh;
	}