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); }
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); }
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); }
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); }
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; }
const vec4& vec4::norm(void) { mcemaths_norm_3_4(*this); return *this; }