1 /*
2 Copyright (C) 2005-2007 Feeling Software Inc.
3 Portions of the code are:
4 Copyright (C) 2005-2007 Sony Computer Entertainment America
5
6 MIT License: http://www.opensource.org/licenses/mit-license.php
7 */
8
9 #include "StdAfx.h"
10 #include "FCDocument/FCDEffectTechnique.h"
11 #include "FCDocument/FCDocument.h"
12 #include "FCDocument/FCDEffectPass.h"
13 #include "FCDocument/FCDEffectPassShader.h"
14 #include "FCDocument/FCDEffectPassState.h"
15 #include "FCDocument/FCDEffectParameter.h"
16
17 //
18 // FCDEffectPass
19 //
20
21 ImplementObjectType(FCDEffectPass);
22 ImplementParameterObject(FCDEffectPass, FCDEffectPassShader, shaders, new FCDEffectPassShader(parent->GetDocument(), parent));
23 ImplementParameterObjectNoCtr(FCDEffectPass, FCDEffectPassState, states);
24
FCDEffectPass(FCDocument * document,FCDEffectTechnique * _parent)25 FCDEffectPass::FCDEffectPass(FCDocument* document, FCDEffectTechnique *_parent)
26 : FCDObject(document), parent(_parent)
27 , InitializeParameterNoArg(name)
28 , InitializeParameterNoArg(shaders)
29 , InitializeParameterNoArg(states)
30 {
31 }
32
~FCDEffectPass()33 FCDEffectPass::~FCDEffectPass()
34 {
35 parent = NULL;
36 }
37
38 // Adds a new shader to the pass.
AddShader()39 FCDEffectPassShader* FCDEffectPass::AddShader()
40 {
41 FCDEffectPassShader* shader = new FCDEffectPassShader(GetDocument(), this);
42 shaders.push_back(shader);
43 SetNewChildFlag();
44 return shader;
45 }
46
47 // Adds a new vertex shader to the pass.
48 // If a vertex shader already exists within the pass, it will be released.
AddVertexShader()49 FCDEffectPassShader* FCDEffectPass::AddVertexShader()
50 {
51 FCDEffectPassShader* vertexShader;
52 for (vertexShader = GetVertexShader(); vertexShader != NULL; vertexShader = GetVertexShader())
53 {
54 SAFE_RELEASE(vertexShader);
55 }
56
57 vertexShader = AddShader();
58 vertexShader->AffectsVertices();
59 SetNewChildFlag();
60 return vertexShader;
61 }
62
63 // Adds a new fragment shader to the pass.
64 // If a fragment shader already exists within the pass, it will be released.
AddFragmentShader()65 FCDEffectPassShader* FCDEffectPass::AddFragmentShader()
66 {
67 FCDEffectPassShader* fragmentShader;
68 for (fragmentShader = GetFragmentShader(); fragmentShader != NULL; fragmentShader = GetFragmentShader())
69 {
70 SAFE_RELEASE(fragmentShader);
71 }
72
73 fragmentShader = AddShader();
74 fragmentShader->AffectsFragments();
75 SetNewChildFlag();
76 return fragmentShader;
77 }
78
Clone(FCDEffectPass * clone) const79 FCDEffectPass* FCDEffectPass::Clone(FCDEffectPass* clone) const
80 {
81 if (clone == NULL) clone = new FCDEffectPass(const_cast<FCDocument*>(GetDocument()), parent);
82
83 clone->name = name;
84
85 // Clone the shaders
86 clone->shaders.reserve(shaders.size());
87 for (const FCDEffectPassShader** itS = shaders.begin(); itS != shaders.end(); ++itS)
88 {
89 FCDEffectPassShader* clonedShader = clone->AddShader();
90 (*itS)->Clone(clonedShader);
91 }
92
93 // Clone the states
94 clone->states.reserve(states.size());
95 for (const FCDEffectPassState** itS = states.begin(); itS != states.end(); ++itS)
96 {
97 FCDEffectPassState* clonedState = clone->AddRenderState((*itS)->GetType());
98 (*itS)->Clone(clonedState);
99 }
100
101 return clone;
102 }
103
104 // Retrieve the type-specific shaders
GetVertexShader() const105 const FCDEffectPassShader* FCDEffectPass::GetVertexShader() const
106 {
107 for (const FCDEffectPassShader** itS = shaders.begin(); itS != shaders.end(); ++itS)
108 {
109 if ((*itS)->IsVertexShader()) return (*itS);
110 }
111 return NULL;
112 }
113
GetFragmentShader() const114 const FCDEffectPassShader* FCDEffectPass::GetFragmentShader() const
115 {
116 for (const FCDEffectPassShader** itS = shaders.begin(); itS != shaders.end(); ++itS)
117 {
118 if ((*itS)->IsFragmentShader()) return (*itS);
119 }
120 return NULL;
121 }
122
AddRenderState(FUDaePassState::State type)123 FCDEffectPassState* FCDEffectPass::AddRenderState(FUDaePassState::State type)
124 {
125 FCDEffectPassState* state = new FCDEffectPassState(GetDocument(), type);
126
127 // Ordered-insertion into the states container.
128 size_t stateCount = states.size();
129 size_t insertIndex;
130 for (insertIndex = 0; insertIndex < stateCount; ++insertIndex)
131 {
132 if (type < states[insertIndex]->GetType()) break;
133 }
134 states.insert(insertIndex, state);
135
136 SetNewChildFlag();
137 return state;
138 }
139
FindRenderState(FUDaePassState::State type) const140 const FCDEffectPassState* FCDEffectPass::FindRenderState(FUDaePassState::State type) const
141 {
142 for (const FCDEffectPassState** itS = states.begin(); itS != states.end(); ++itS)
143 {
144 if ((*itS)->GetType() == type) return (*itS);
145 }
146 return NULL;
147 }
148