void csMeshGeneratorGeometry::SetFadeParams (csMGGeom& geom, float opaqueDist, float scale) { float fadeInM, fadeInN, fadeOutM, fadeOutN; float max_opaque_dist = csMin (this->max_opaque_dist, opaqueDist); float max_draw_dist = csMin (total_max_dist, (fabsf (scale) > EPSILON ? 1.0f/scale : 0) + opaqueDist); float min_fade_dist = min_opaque_dist-min_draw_dist; if (fabsf (min_fade_dist) > EPSILON) { fadeInM = 1.0f/(min_fade_dist); fadeInN = -min_draw_dist * fadeInM; } else { fadeInM = 0; fadeInN = 1; } float max_fade_dist = max_opaque_dist-max_draw_dist; if (fabsf (max_fade_dist) > EPSILON) { fadeOutM = 1.0f/(max_fade_dist); fadeOutN = -max_opaque_dist*fadeOutM + 1; } else { fadeOutM = 0; fadeOutN = 1; } geom.fadeInfoVar->SetValue (csVector4 (fadeInM, fadeInN, fadeOutM, fadeOutN)); }
static void PerspectiveScreen (const csVector3& v, csVector2& p, const CS::Math::Matrix4& camProj, float hw, float hh) { csVector4 v_proj (camProj * csVector4 (v, 1)); p.x = (v_proj.x / v_proj.w + 1.0f) * hw; p.y = (v_proj.y / v_proj.w + 1.0f) * hh; }
static void Perspective (const csVector3& v, csVector2& p, const CS::Math::Matrix4& proj, int screenWidth, int screenHeight) { csVector4 v_proj (proj * csVector4 (v, 1)); float inv_w = 1.0f/v_proj.w; p.x = (v_proj.x * inv_w + 1) * screenWidth/2; p.y = (v_proj.y * inv_w + 1) * screenHeight/2; }
static float LightAttnCLQ (float squaredDistance, const csVector4& c) { /** * CLQ, Constant Linear Quadratic: * * 1 / (constant1 + constant2*distance + constant3*distance^2) */ return c * csVector4 (1, sqrtf(squaredDistance), squaredDistance, 0); }
uint csFlareHalo::AddComponent ( float pos, float w, float h, uint mode, iMaterialWrapper *image) { csFlareComponent *comp = new csFlareComponent; comp->next = 0; if (components == 0) components = comp; else last->next = comp; last = comp; comp->color = csVector4 (1,1,1,1); comp->position = pos; comp->width = w; comp->height = h; comp->mixmode = mode; comp->image = image; if (comp->image) comp->image->IncRef (); return cmp_cnt++; }
void csPortalContainer::DrawOnePortal ( csPortal* po, const csPoly2D& poly, const csReversibleTransform& movtrans, iRenderView *rview, const csPlane3& camera_plane) { iGraphics3D* g3d = rview->GetGraphics3D (); // is_this_fog is true if this sector is fogged. bool is_this_fog = rview->GetThisSector ()->HasFog (); // If we have fog or the portal is z-filled we need to keep the // camera plane because recursive rendering may cause it to change. csPlane3 keep_plane = camera_plane;; // @@@ TODO: use keep_camera_z float keep_camera_z = 0; // Also keep z-coordinate of vertex 0. if (is_this_fog || po->flags.Check (CS_PORTAL_ZFILL)) { keep_camera_z = camera_vertices[po->GetVertexIndices ()[0]].z; } // First call OpenPortal(). csFlags g3d_flags = 0; if (po->flags.Check(CS_PORTAL_FLOAT)) g3d_flags.Set(CS_OPENPORTAL_FLOAT); if (po->flags.Check(CS_PORTAL_ZFILL)) g3d_flags.Set(CS_OPENPORTAL_ZFILL); if (po->flags.Check(CS_PORTAL_MIRROR)) g3d_flags.Set(CS_OPENPORTAL_MIRROR); g3d->OpenPortal (poly.GetVertexCount(), poly.GetVertices(), camera_plane, g3d_flags); // Draw through the portal. This can fail. // Drawing through a portal can fail because we have reached // the maximum number that a sector is drawn (for mirrors). po->Draw (poly, movtrans, rview, keep_plane); if (is_this_fog && fog_shader) { csSimpleRenderMesh mesh; mesh.meshtype = CS_MESHTYPE_TRIANGLEFAN; mesh.indexCount = (uint)po->GetVertexIndices ().GetSize (); // @@@ Weirdo overloads approaching, captain! mesh.indices = (const uint*)(int*)po->GetVertexIndices ().GetArray (); mesh.vertexCount = (uint)vertices.GetSize (); mesh.vertices = vertices.GetArray (); mesh.texcoords = 0; mesh.texture = 0; mesh.colors = 0; //mesh.object2camera = rview->GetCamera ()->GetTransform (); mesh.alphaType.alphaType = csAlphaMode::alphaSmooth; mesh.alphaType.autoAlphaMode = false; mesh.shader = fog_shader; // @@@ Hackish... csShaderVariableContext varContext; const csRefArray<csShaderVariable>& globVars = shader_man->GetShaderVariables (); for (size_t i = 0; i < globVars.GetSize (); i++) { varContext.AddVariable (globVars[i]); } const csRefArray<csShaderVariable>& sectorVars = rview->GetThisSector()->GetSVContext()->GetShaderVariables(); for (size_t i = 0; i < sectorVars.GetSize (); i++) { varContext.AddVariable (sectorVars[i]); } csVector4 fogPlane; iPortal *lastPortal = rview->GetLastPortal(); if(lastPortal) { csPlane3 plane; lastPortal->ComputeCameraPlane(rview->GetCamera()->GetTransform(), plane); fogPlane = plane.norm; fogPlane.w = plane.DD; } else { fogPlane = csVector4(0.0,0.0,1.0,0.0); } varContext.GetVariableAdd (fogplane_name)->SetValue (fogPlane); mesh.dynDomain = &varContext; // @@@ Could be used for z-fill and stuff, while we're at it? mesh.z_buf_mode = CS_ZBUF_TEST; g3d->DrawSimpleMesh (mesh); } // Make sure to close the portal again. g3d->ClosePortal (); }
void csShaderGLCGCommon::SetupState (const CS::Graphics::RenderMesh* /*mesh*/, CS::Graphics::RenderMeshModes& /*modes*/, const csShaderVariableStack& stack) { if ((clips.GetSize() > 0) && (programType == progVP)) { uint clipFlags = 0; shaderPlug->clipPlanes.SetShaderVars (stack); csVector4 packDist[2]; clipPackedDists[0]->GetValue (packDist[0]); clipPackedDists[1]->GetValue (packDist[1]); for (size_t c = 0; c < clips.GetSize(); c++) { const Clip& clip = clips[c]; bool hasClipDist = false; if (!clip.distance.IsConstant()) { csVector4 v; if (GetParamVectorVal (stack, clip.distance, &v)) { float distVal = v[clip.distComp]; if (clip.distNeg) distVal = -distVal; packDist[c/4][c%4] = distVal; hasClipDist = true; } else { // Force clipping to have no effect packDist[c/4][c%4] = -FLT_MAX; } } bool doClipping = false; /* Enable a clip plane if: - both plane and distance are constant - one is not constant and the SV value is present - both are not constant and the SV values are present */ csVector4 v; bool constPlane = clip.plane.IsConstant(); bool hasPlaneSV = !constPlane && GetParamVectorVal (stack, clip.plane, &v); bool constDist = clip.distance.IsConstant(); bool hasDistSV = !constDist && hasClipDist; doClipping = (constPlane && constDist) || (constPlane && hasDistSV) || (hasPlaneSV && constDist) || (hasPlaneSV && hasDistSV); if (doClipping) { clipFlags |= 1 << c; if (!constPlane) { csVector4 v = GetParamVectorVal (stack, clip.plane, csVector4 (0)); clipPlane[c]->SetValue (v); } } else { if (!constPlane) { // Force clip plane to not clip csVector4 v (0); clipPlane[c]->SetValue (v); } } } clipPackedDists[0]->SetValue (packDist[0]); clipPackedDists[1]->SetValue (packDist[1]); if ((programProfile == CG_PROFILE_VP40) || (programProfile == CG_PROFILE_GPU_VP)) { for (size_t c = 0; c < clips.GetSize(); c++) { if (clipFlags & (1 << c)) shaderPlug->clipPlanes.EnableClipPlane ((uint)c); } } else if ((programProfile == CG_PROFILE_ARBVP1) && (programPositionInvariant || (shaderPlug->vendor == CS::PluginCommon::ShaderProgramPluginGL::ATI))) { for (size_t c = 0; c < clips.GetSize(); c++) { const Clip& clip = clips[c]; if (clipFlags & (1 << c)) { csVector4 v ( GetParamVectorVal (stack, clip.plane, csVector4 (0, 0, 0, 0))); csPlane3 plane (v.x, v.y, v.z, v.w); float distVal = packDist[c/4][c%4]; plane.DD -= distVal / plane.Normal().Norm(); shaderPlug->clipPlanes.AddClipPlane (plane, clip.space); } } } } ApplyVariableMapArrays (stack); }
void csGenmeshSkelAnimationControl::Update (csTicks current, int, uint32) { if (last_update_time != current) { last_update_time = current; } else { return; } if (!mesh_obj->GetMeshWrapper() || !skeleton) { return; } Initialize(); csRef<csShaderVariable> _bones = mesh_obj->GetMeshWrapper()->GetSVContext ()->GetVariable (bones_name); if (_bones.IsValid()) { for (size_t i=0; i< used_bones.GetSize (); ++i) { int bone_idx = used_bones[i]; csReversibleTransform offset_tr = skeleton->GetBone(bone_idx)->GetFactory()->GetFullTransform().GetInverse()* skeleton->GetBone(bone_idx)->GetFullTransform(); csShaderVariable* boneQuat = _bones->GetArrayElement (i*2+0); csQuaternion quat; quat.SetMatrix(offset_tr.GetT2O()); boneQuat->SetValue(csVector4 (quat.v.x, quat.v.y, quat.v.z, quat.w)); csShaderVariable *boneOffs = _bones->GetArrayElement (i*2+1); csVector3 offset_pos = offset_tr.GetOrigin(); boneOffs->SetValue(csVector4(offset_pos.x, offset_pos.y, offset_pos.z, 0)); } } else { csRef<csShaderVariable> _bones; _bones.AttachNew(new csShaderVariable(bones_name)); _bones->SetType (csShaderVariable::ARRAY); _bones->SetArraySize (used_bones.GetSize ()*2); for (size_t i=0; i< used_bones.GetSize (); ++i) { int bone_idx = used_bones[i]; csReversibleTransform offset_tr = skeleton->GetBone(bone_idx)->GetFactory()->GetFullTransform().GetInverse()* skeleton->GetBone(bone_idx)->GetFullTransform(); csRef<csShaderVariable> boneQuat; boneQuat.AttachNew(new csShaderVariable(CS::InvalidShaderVarStringID)); _bones->SetArrayElement (i*2+0, boneQuat); boneQuat->SetValue(csVector4 (0, 0, 0, 1)); csRef<csShaderVariable> boneOffs; boneOffs.AttachNew(new csShaderVariable(CS::InvalidShaderVarStringID)); _bones->SetArrayElement (i*2+1, boneOffs); csVector3 offset_pos = offset_tr.GetOrigin(); boneOffs->SetValue(csVector4(offset_pos.x, offset_pos.y, offset_pos.z, 0)); } mesh_obj->GetMeshWrapper()->GetSVContext ()->AddVariable (_bones); vertices_mapped = true; } }
bool csShaderProgram::ProgramParamParser::ParseProgramParam ( iDocumentNode* node, ProgramParam& param, uint types) { const char* type = node->GetAttributeValue ("type"); if (type == 0) { synsrv->Report ("crystalspace.graphics3d.shader.common", CS_REPORTER_SEVERITY_WARNING, node, "No %s attribute", CS::Quote::Single ("type")); return false; } // Var for static data csRef<csShaderVariable> var; var.AttachNew (new csShaderVariable (CS::InvalidShaderVarStringID)); ProgramParamType paramType = ParamInvalid; if (strcmp (type, "shadervar") == 0) { const char* value = node->GetContentsValue(); if (!value) { synsrv->Report ("crystalspace.graphics3d.shader.common", CS_REPORTER_SEVERITY_WARNING, node, "Node has no contents"); return false; } CS::Graphics::ShaderVarNameParser nameParse (value); param.name = stringsSvName->Request (nameParse.GetShaderVarName()); for (size_t n = 0; n < nameParse.GetIndexNum(); n++) { param.indices.Push (nameParse.GetIndexValue (n)); } param.valid = true; return true; } else if (strcmp (type, "int") == 0) { paramType = ParamInt; } else if (strcmp (type, "float") == 0) { paramType = ParamFloat; } else if (strcmp (type, "vector2") == 0) { paramType = ParamVector2; } else if (strcmp (type, "vector3") == 0) { paramType = ParamVector3; } else if (strcmp (type, "vector4") == 0) { paramType = ParamVector4; } else if (strcmp (type, "matrix") == 0) { paramType = ParamMatrix; } else if (strcmp (type, "transform") == 0) { paramType = ParamTransform; } else if ((strcmp (type, "expression") == 0) || (strcmp (type, "expr") == 0)) { // Parse exp and save it csRef<iShaderVariableAccessor> acc = synsrv->ParseShaderVarExpr (node); var->SetAccessor (acc); param.var = var; param.valid = true; return true; } else if (strcmp (type, "array") == 0) { csArray<ProgramParam> allParams; ProgramParam tmpParam; csRef<iDocumentNodeIterator> it = node->GetNodes (); while (it->HasNext ()) { csRef<iDocumentNode> child = it->Next (); ParseProgramParam (child, tmpParam, types & 0x3F); allParams.Push (tmpParam); } //Save the params var->SetType (csShaderVariable::ARRAY); var->SetArraySize (allParams.GetSize ()); for (uint i = 0; i < allParams.GetSize (); i++) { var->SetArrayElement (i, allParams[i].var); } paramType = ParamArray; } else { synsrv->Report ("crystalspace.graphics3d.shader.common", CS_REPORTER_SEVERITY_WARNING, node, "Unknown type %s", CS::Quote::Single (type)); return false; } if (!(types & paramType)) { synsrv->Report ("crystalspace.graphics3d.shader.common", CS_REPORTER_SEVERITY_WARNING, node, "Type %s not supported by this parameter", CS::Quote::Single (type)); return false; } const uint directValueTypes = ParamInt | ParamFloat | ParamVector2 | ParamVector3 | ParamVector4 | ParamMatrix | ParamTransform; switch (paramType & directValueTypes) { case ParamInvalid: return false; break; case ParamInt: { int x = node->GetContentsValueAsInt (); var->SetValue (x); } break; case ParamFloat: { float x = node->GetContentsValueAsFloat (); var->SetValue (x); } break; case ParamVector2: { float x, y; const char* value = node->GetContentsValue(); if (!value) { synsrv->Report ("crystalspace.graphics3d.shader.common", CS_REPORTER_SEVERITY_WARNING, node, "Node has no contents"); return false; } if (csScanStr (value, "%f,%f", &x, &y) != 2) { synsrv->Report ("crystalspace.graphics3d.shader.common", CS_REPORTER_SEVERITY_WARNING, node, "Couldn't parse vector2 %s", CS::Quote::Single (value)); return false; } var->SetValue (csVector2 (x,y)); } break; case ParamVector3: { float x, y, z; const char* value = node->GetContentsValue(); if (!value) { synsrv->Report ("crystalspace.graphics3d.shader.common", CS_REPORTER_SEVERITY_WARNING, node, "Node has no contents"); return false; } if (csScanStr (value, "%f,%f,%f", &x, &y, &z) != 3) { synsrv->Report ("crystalspace.graphics3d.shader.common", CS_REPORTER_SEVERITY_WARNING, node, "Couldn't parse vector3 %s", CS::Quote::Single (value)); return false; } var->SetValue (csVector3 (x,y,z)); } break; case ParamVector4: { float x, y, z, w; const char* value = node->GetContentsValue(); if (!value) { synsrv->Report ("crystalspace.graphics3d.shader.common", CS_REPORTER_SEVERITY_WARNING, node, "Node has no contents"); return false; } if (csScanStr (value, "%f,%f,%f,%f", &x, &y, &z, &w) != 4) { synsrv->Report ("crystalspace.graphics3d.shader.common", CS_REPORTER_SEVERITY_WARNING, node, "Couldn't parse vector4 %s", CS::Quote::Single (value)); return false; } var->SetValue (csVector4 (x,y,z,w)); } break; case ParamMatrix: { csMatrix3 matrix; if (!synsrv->ParseMatrix (node, matrix)) return false; var->SetValue (matrix); } break; case ParamTransform: { csReversibleTransform t; csRef<iDocumentNode> matrix_node = node->GetNode ("matrix"); if (matrix_node) { csMatrix3 m; if (!synsrv->ParseMatrix (matrix_node, m)) return false; t.SetT2O (m); } csRef<iDocumentNode> vector_node = node->GetNode ("v"); if (vector_node) { csVector3 v; if (!synsrv->ParseVector (vector_node, v)) return false; t.SetOrigin (v); } var->SetValue (t); } break; } param.var = var; param.valid = true; return true; }