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