예제 #1
0
void FP_SingleColour::process(const FragmentProcessorInput* input, FragmentProcessorOutput* output) const
{
	const PROCDATA_SINGLECOLOUR* inData = (const PROCDATA_SINGLECOLOUR*)input->user;

	float shadowFactor = PuresoftSamplerProjection::get(m_shadowTex, inData->shadowcoord);

	ALIGN16 float L[4];
	mcemaths_sub_3_4(L, m_lightPos, inData->worldPos);
	mcemaths_norm_3_4(L);

	ALIGN16 float E[4];
	mcemaths_sub_3_4(E, m_cameraPos, inData->worldPos);
	mcemaths_norm_3_4(E);

	ALIGN16 float H[4];
	mcemaths_add_3_4(H, E, L);
	mcemaths_norm_3_4(H);


	enum {LAMBERT, SPECULAR};
	ALIGN16 float factors[4];

	factors[LAMBERT] = mcemaths_dot_3_4(L, inData->normal);

	float yawOfLight = (float)acos(mcemaths_dot_3_4(L, m_lightDir));
	factors[LAMBERT] *= yawOfLight < fieldOfLight ? 1.0f : (float)opt_pow(cos(yawOfLight - fieldOfLight), 150);

	factors[SPECULAR] = opt_pow(mcemaths_dot_3_4(H, inData->normal), (unsigned int)*m_specularExponent);

	mcemaths_clamp_3_4(factors, 0, 1.0f);

	ALIGN16 float outputColour[4];
	mcemaths_quatcpy(outputColour, m_diffuse);
	mcemaths_mul_3_4(outputColour, factors[LAMBERT]);

	ALIGN16 float specularColour[4];
	mcemaths_quatcpy(specularColour, m_diffuse);
	mcemaths_mulvec_3_4(specularColour, m_specularColour);
	mcemaths_mul_3_4(specularColour, factors[SPECULAR]);

	ALIGN16 float ambientColour[4];
	mcemaths_quatcpy(ambientColour, m_diffuse);
	mcemaths_mulvec_3_4(ambientColour, m_ambient);

	mcemaths_add_3_4_ip(outputColour, specularColour);
	mcemaths_mul_3_4(outputColour, shadowFactor);
	mcemaths_add_3_4_ip(outputColour, ambientColour);
	mcemaths_clamp_3_4(outputColour, 0, 1.0f);

	mcemaths_mul_3_4(outputColour, 255.0f);

	PURESOFTBGRA bytesColour;
	bytesColour.elems.r = (unsigned char)outputColour[2];
	bytesColour.elems.g = (unsigned char)outputColour[1];
	bytesColour.elems.b = (unsigned char)outputColour[0];
	bytesColour.elems.a = 0;

	output->write4(0, &bytesColour);
}
예제 #2
0
파일: testproc.cpp 프로젝트: FMX/Puresoft3D
void FP_DiffuseOnly::process(const FragmentProcessorInput* input, FragmentProcessorOutput* output) const
{
	PURESOFTBGRA bytesColour;
	ALIGN16 float outputColour[4], ambiemtColour[4];

	const PROCDATA_DIFFUSEONLY* inData = (const PROCDATA_DIFFUSEONLY*)input->user;

	float shadowFactor = PuresoftSamplerProjection::get(m_shadowTex, inData->shadowcoord);

	PuresoftSampler2D::get4(m_diffuseTex, inData->texcoord[0], inData->texcoord[1], &bytesColour);
	outputColour[0] = bytesColour.elems.b;
	outputColour[1] = bytesColour.elems.g;
	outputColour[2] = bytesColour.elems.r;
	outputColour[3] = bytesColour.elems.a;

	mcemaths_quatcpy(ambiemtColour, outputColour);
	mcemaths_mulvec_3_4(ambiemtColour, m_ambient);

	ALIGN16 float L[4];
	mcemaths_sub_3_4(L, m_lightPos, inData->worldPos);
	mcemaths_norm_3_4(L);

	ALIGN16 float E[4];
	mcemaths_sub_3_4(E, m_cameraPos, inData->worldPos);
	mcemaths_norm_3_4(E);

	ALIGN16 float H[4];
	mcemaths_add_3_4(H, E, L);
	mcemaths_norm_3_4(H);

	enum {LAMBERT, SPECULAR};
	ALIGN16 float factors[4];

	factors[LAMBERT] = mcemaths_dot_3_4(L, inData->normal);

	float yawOfLight = acos(mcemaths_dot_3_4(L, m_lightDir));
	factors[LAMBERT] *= yawOfLight < fieldOfLight ? 1.0f : opt_pow(cos(yawOfLight - fieldOfLight), 150);

	factors[SPECULAR] = opt_pow(mcemaths_dot_3_4(H, inData->normal), (unsigned int)*m_specularExponent);

	mcemaths_clamp_3_4(factors, 0, 1.0f);

	mcemaths_mul_3_4(outputColour, (factors[LAMBERT] + factors[SPECULAR]) * shadowFactor);
	mcemaths_add_3_4_ip(outputColour, ambiemtColour);
	mcemaths_clamp_3_4(outputColour, 0, 255.0f);

	bytesColour.elems.r = (unsigned char)outputColour[2];
	bytesColour.elems.g = (unsigned char)outputColour[1];
	bytesColour.elems.b = (unsigned char)outputColour[0];
	bytesColour.elems.a = 0;

	output->write4(0, &bytesColour);
}
예제 #3
0
void FP_Cloud::process(const FragmentProcessorInput* input, FragmentProcessorOutput* output) const
{
	ALIGN16 float cloudColour[4];
	PURESOFTBGRA textureColour;
	const PROCDATA_CLOUD* inData = (const PROCDATA_CLOUD*)input->user;

	PuresoftSampler2D::get4(m_diffuseTex, inData->texcoord[0], inData->texcoord[1], &textureColour);

	cloudColour[0] = 255.0f;
	cloudColour[1] = 255.0f;
	cloudColour[2] = 255.0f;
	cloudColour[3] = textureColour.elems.r;

	float shadowFactor = PuresoftSamplerProjection::get(m_shadowTex, inData->shadowcoord);

	ALIGN16 float L[4];
	mcemaths_sub_3_4(L, m_lightPos, inData->worldPos);
	float distance = mcemaths_len_3_4(L);
	mcemaths_div_3_4(L, distance);

	ALIGN16 float E[4];
	mcemaths_sub_3_4(E, m_cameraPos, inData->worldPos);
	mcemaths_norm_3_4(E);
	ALIGN16 float H[4];
	mcemaths_add_3_4(H, E, L);
	mcemaths_norm_3_4(H);

	float lambert = 2.0f * mcemaths_dot_3_4(L, inData->normal);

	mcemaths_mul_3(cloudColour, lambert * shadowFactor);

	__asm{
		movaps		xmm0,	[cloudColour]
		cvtps2dq	xmm0,	xmm0
		packusdw	xmm0,	xmm0
		packuswb	xmm0,	xmm0
		movss		[cloudColour], xmm0
	}

	output->write4(0, cloudColour);
}
예제 #4
0
void FP_Satellite::process(const FragmentProcessorInput* input, FragmentProcessorOutput* output) const
{
	ALIGN16 float outputColour[4];
	ALIGN16 float bumpNormal[4];
	PURESOFTBGRA bytesColour;

	const PROCDATA_PLANET* inData = (const PROCDATA_PLANET*)input->user;

	PuresoftSampler2D::get4(m_diffuseTex, inData->texcoord[0], inData->texcoord[1], &bytesColour);
	outputColour[0] = bytesColour.elems.b;
	outputColour[1] = bytesColour.elems.g;
	outputColour[2] = bytesColour.elems.r;
	outputColour[3] = bytesColour.elems.a;

	PuresoftSampler2D::get4(m_bumpTex, inData->texcoord[0], inData->texcoord[1], &bytesColour);
	bumpNormal[0] = bytesColour.elems.r;
	bumpNormal[1] = bytesColour.elems.g;
	bumpNormal[2] = bytesColour.elems.b;
	bumpNormal[3] = 0;

	float shadowFactor = PuresoftSamplerProjection::get(m_shadowTex, inData->shadowcoord);

	mcemaths_div_3_4(bumpNormal, 255.0f);
	mcemaths_mul_3_4(bumpNormal, 2.0f);
	mcemaths_sub_4by1(bumpNormal, 1.0f);

	ALIGN16 float tbn[16];
	mcemaths_make_tbn(tbn, inData->tangent, inData->binormal, inData->normal);

	mcemaths_transform_m4v4_ip(bumpNormal, tbn);
	mcemaths_norm_3_4(bumpNormal);

	ALIGN16 float L[4];
	mcemaths_sub_3_4(L, m_lightPos, inData->worldPos);
	float distance = mcemaths_len_3_4(L);
	mcemaths_div_3_4(L, distance);

	ALIGN16 float E[4];
	mcemaths_sub_3_4(E, m_cameraPos, inData->worldPos);
	mcemaths_norm_3_4(E);
	ALIGN16 float H[4];
	mcemaths_add_3_4(H, E, L);
	mcemaths_norm_3_4(H);

	float lambert = mcemaths_dot_3_4(L, bumpNormal);

	float specular = mcemaths_dot_3_4(H, bumpNormal);
	specular = specular < 0 ? 0 : specular;
	//specular = pow(specular, 50.0f);
	specular = opt_pow(specular, 50);

	mcemaths_add_1to4(outputColour, 255.0f * specular);

	mcemaths_mul_3_4(outputColour, lambert);

	mcemaths_mul_3_4(outputColour, shadowFactor);
	mcemaths_clamp_3_4(outputColour, 0, 255.0f);

	bytesColour.elems.r = (unsigned char)outputColour[2];
	bytesColour.elems.g = (unsigned char)outputColour[1];
	bytesColour.elems.b = (unsigned char)outputColour[0];
	bytesColour.elems.a = 0;

	output->write4(0, &bytesColour);
}
예제 #5
0
bool write_face(HOBJXIO hobjxio, const string& name, const faces& fcs, const obj_mesh_data& dat, const material& mtl)
{
	static vec4_coll vertices;
	static vec4_coll normals;
	static vec4_coll tangents;
	static vec2_coll texcoords;

	mesh_info mesh;
	mesh.num_indices = 0;
	mesh.indices = NULL;

	for(int i = 0; i < faces::MAX; i++)
	{
		const face& fc = fcs.face_data[i];
		// stat vertices
		mesh.num_vertices = 0;
		for(int i = 0; i < (int)fc.size(); i++)
			// 3 indices for 1 triangle, 4 for 2, 5 for 3, ... n indices for n-2 triangles make (n-2)*3 vertices
			mesh.num_vertices += (fc[i].vertIndices.size() - 2) * 3;

		if(0 == mesh.num_vertices)
			continue;

		// prepare container
		vertices.clear();
		normals.clear();
		tangents.clear();
		texcoords.clear();

		// for each facet
		for(int i = 0; i < (int)fc.size(); i++)
		{
			const facet& f = fc[i];
			// facet -> triangles
			for(int j = 1; j < (int)f.vertIndices.size() - 1; j++)
			{
				vertices.push_back(dat.vertices[f.vertIndices[    0]]);
				vertices.push_back(dat.vertices[f.vertIndices[    j]]);
				vertices.push_back(dat.vertices[f.vertIndices[j + 1]]);
			}
		}
		ATLASSERT(vertices.size() > 0);
		mesh.vertices = &vertices[0];

		// for each facet
		for(int i = 0; i < (int)fc.size(); i++)
		{
			const facet& f = fc[i];
			// facet -> triangles
			for(int j = 1; j < (int)f.normIndices.size() - 1; j++)
			{
				normals.push_back(dat.normals[f.normIndices[    0]]);
				normals.push_back(dat.normals[f.normIndices[    j]]);
				normals.push_back(dat.normals[f.normIndices[j + 1]]);
			}
		}

		// unlike vertices, normal data can be absent
		if(0 == normals.size()) // if normal not exists, we generate
		{
			for(int i = 0; i < (int)vertices.size(); i += 3)
			{
				const vec4& a = vertices[    i];
				const vec4& b = vertices[i + 1];
				const vec4& c = vertices[i + 2];
				vec4 edge1, edge2, n;
				mcemaths_sub_3_4(edge1, c, b);
				mcemaths_sub_3_4(edge2, a, b);
				mcemaths_cross_3(n, edge1, edge2);
				mcemaths_norm_3_4(n);
				normals.push_back(n);
				normals.push_back(n);
				normals.push_back(n);
			}
		}
		mesh.normals = &normals[0];
		mesh.has_normals = true;

		// for each facet
		for(int i = 0; i < (int)fc.size(); i++)
		{
			const facet& f = fc[i];
			// facet -> triangles
			for(int j = 1; j < (int)f.texIndices.size() - 1; j++)
			{
				texcoords.push_back(dat.texcoords[f.texIndices[    0]]);
				texcoords.push_back(dat.texcoords[f.texIndices[    j]]);
				texcoords.push_back(dat.texcoords[f.texIndices[j + 1]]);
			}
		}

 		mesh.texcoords = NULL;
 		mesh.tangents = NULL;
 		mesh.has_texcoords = mesh.has_tangents = false;
		if(texcoords.size() > 0) // unlike vertices, texture coordinate can also be absent
		{
			mesh.texcoords = &texcoords[0];
			mesh.has_texcoords = true;

			// if texcoords exist, generate tangents (save time for game initialization as much as possible)
 			for(int i = 0; i < (int)vertices.size(); i += 3)
 			{
 				const vec4&  a = vertices [    i];
 				const vec4&  b = vertices [i + 1];
 				const vec4&  c = vertices [i + 2];
				const vec2& ta2 = texcoords[    i];
				const vec2& tb2 = texcoords[i + 1];
				const vec2& tc2 = texcoords[i + 2];
				vec4 ta(ta2.x, ta2.y, 0, 0);
				vec4 tb(tb2.x, tb2.y, 0, 0);
				vec4 tc(tc2.x, tc2.y, 0, 0);
 				vec4 modvec1(0.0f), modvec4(0.0f), texvec1(0.0f), texvec4(0.0f);
 				mcemaths_sub_3_4(modvec1, c , a);
 				mcemaths_sub_3_4(modvec4, b , a);
 				mcemaths_sub_3_4(texvec1, tc, ta);
 				mcemaths_sub_3_4(texvec4, tb, ta);
 				mcemaths_mul_3_4(modvec1, texvec4.y);
 				mcemaths_mul_3_4(modvec4, texvec1.y);
 				mcemaths_sub_3_4_ip(modvec1, modvec4);
 				mcemaths_div_3_4(modvec1, texvec1.x * texvec4.y - texvec4.x * texvec1.y);
 				mcemaths_norm_3_4(modvec1);
 				tangents.push_back(modvec1);
 				tangents.push_back(modvec1);
 				tangents.push_back(modvec1);
 			}
			mesh.tangents = &tangents[0];
			mesh.has_tangents = true;
		}

		mesh.mesh_name = name;
		mesh.ambient_colour = vec4(mtl.ambientColour.x, mtl.ambientColour.y, mtl.ambientColour.z, 1.0f);
		mesh.diffuse_colour = vec4(mtl.diffuseColour.x, mtl.diffuseColour.y, mtl.diffuseColour.z, 1.0f);
		mesh.specular_colour = vec4(mtl.specularColour.x, mtl.specularColour.y, mtl.specularColour.z, 1.0f);
		mesh.specular_exponent = mtl.specularExponent;
		mesh.diffuse_file = mtl.diffuseFile;
		mesh.bump_file = mtl.bumpFile;
		mesh.spc_file = mtl.spcFile;
		mesh.spe_file = mtl.speFile;
		mesh.programme = mtl.programmeName;

		if(!write_mesh(hobjxio, mesh))
			return false;
	}

	return true;
}
예제 #6
0
const vec4& vec4::norm(void)
{
	mcemaths_norm_3_4(*this);
	return *this;
}