| 1 |
#include "stdafx.h" |
| 2 |
#include "CLensFlare.h" |
| 3 |
#include "CModelPlugin.h" |
| 4 |
#include "CConfigMode.h" |
| 5 |
|
| 6 |
/* |
| 7 |
* Ç |
| 8 |
*/ |
| 9 |
char *CFlareElement::Read( |
| 10 |
char *str // ÎŰśń |
| 11 |
){ |
| 12 |
char *tmp, *eee; |
| 13 |
m_Texture = NULL; |
| 14 |
if(tmp = BeginBlock(str, "Circle")){ |
| 15 |
str = tmp; |
| 16 |
m_Type = 0; |
| 17 |
}else if(tmp = BeginBlock(str, "Hexagon")){ |
| 18 |
str = tmp; |
| 19 |
m_Type = 1; |
| 20 |
}else if(tmp = BeginBlock(str, "Texture")){ |
| 21 |
str = tmp; |
| 22 |
m_Type = 2; |
| 23 |
}else{ |
| 24 |
return NULL; |
| 25 |
} |
| 26 |
if(!(str = AsgnFloat(eee = str, "Distance", &m_Distance))) throw CSynErr(eee); |
| 27 |
if(!(str = AsgnFloat(eee = str, "Radius", &m_Radius))) throw CSynErr(eee); |
| 28 |
if(m_Type<2){ |
| 29 |
if(!(str = AsgnColor(eee = str, "InnerColor", &m_InnerColor))) throw CSynErr(eee); |
| 30 |
if(!(str = AsgnColor(eee = str, "OuterColor", &m_OuterColor))) throw CSynErr(eee); |
| 31 |
}else{ |
| 32 |
if(!(str = AsgnString(eee = str, "TexFileName", &m_TexFileName))) throw CSynErr(eee); |
| 33 |
if(tmp = AsgnColor(eee = str, "Color", &m_InnerColor)) str = tmp; |
| 34 |
else m_InnerColor = 0xffffffff; |
| 35 |
m_OuterColor = m_InnerColor; |
| 36 |
} |
| 37 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 38 |
return str; |
| 39 |
} |
| 40 |
|
| 41 |
/* |
| 42 |
* f[^Ç |
| 43 |
*/ |
| 44 |
void CFlareElement::LoadData(){ |
| 45 |
if(m_Type==2) m_Texture = g_TexList.Get( |
| 46 |
FALSE, m_TexFileName.c_str(), 0, !g_NamedObjectMipMap); |
| 47 |
} |
| 48 |
|
| 49 |
//////////////////////////////////////////////////////////////////////////////// |
| 50 |
//////////////////////////////////////////////////////////////////////////////// |
| 51 |
|
| 52 |
/* |
| 53 |
* Ç |
| 54 |
*/ |
| 55 |
char *CLensFlare::Read( |
| 56 |
char *str // ÎŰśń |
| 57 |
){ |
| 58 |
char *tmp, *eee; |
| 59 |
if(!(str = BeginBlock(str, "LensFlare"))) return NULL; |
| 60 |
if(!(str = AsgnFloat(eee = str, "StartAngle", &m_StartAngle))) throw CSynErr(eee); |
| 61 |
if(tmp = AsgnFloat(eee = str, "Twinkle", &m_Twinkle)) str = tmp; |
| 62 |
else m_Twinkle = 0.0f; |
| 63 |
if(tmp = AsgnFloat(eee = str, "Inclination", &m_Inclination)) str = tmp; |
| 64 |
else m_Inclination = 0.0f; |
| 65 |
m_StartAngle = cosf(D3DXToRadian(m_StartAngle)); |
| 66 |
m_Flare.clear(); |
| 67 |
CFlareElement flare; |
| 68 |
while(tmp = flare.Read(str)){ |
| 69 |
str = tmp; |
| 70 |
m_Flare.push_back(flare); |
| 71 |
} |
| 72 |
m_Flare.sort(); |
| 73 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 74 |
return str; |
| 75 |
} |
| 76 |
|
| 77 |
/* |
| 78 |
* f[^Ç |
| 79 |
*/ |
| 80 |
void CLensFlare::LoadData(){ |
| 81 |
IFlareElement ifl = m_Flare.begin(); |
| 82 |
for(; ifl!=m_Flare.end(); ifl++) ifl->LoadData(); |
| 83 |
} |
| 84 |
|
| 85 |
/* |
| 86 |
* _O |
| 87 |
*/ |
| 88 |
void CLensFlare::Render( |
| 89 |
VEC3 pos, // őšŔW |
| 90 |
VEC3 dir, // őšűü |
| 91 |
VEC3 toward, // îűü |
| 92 |
float vol, // }X^At@l |
| 93 |
float maxdist // ĹĺŁ |
| 94 |
){ |
| 95 |
if(!m_Flare.size()) return; |
| 96 |
float range = V3Len(&(GetVPos()-pos)); |
| 97 |
VEC3 vCamera = GetVDir(); |
| 98 |
V3Norm(&dir, &dir); |
| 99 |
V3Norm(&toward, &toward); |
| 100 |
V3Norm(&vCamera, &vCamera); |
| 101 |
float angle = V3Dot(&dir, &-toward); |
| 102 |
if(angle<=m_StartAngle) return; |
| 103 |
devBLEND_ADD2(); // ÁZ[hÉÝč |
| 104 |
float alpha = vol*(angle-m_StartAngle)/(1.0f-m_StartAngle); |
| 105 |
float shift = 0.0f, bl = alpha*FRand2(1.0f-m_Twinkle, 1.0f); |
| 106 |
IFlareElement ifl = m_Flare.begin(); |
| 107 |
VEC3 tpos = pos, approach = dir+m_Inclination*vCamera; |
| 108 |
//V3Norm(&approach, &approach); |
| 109 |
for(; ifl!=m_Flare.end(); ifl++){ |
| 110 |
float dist = ifl->m_Distance; |
| 111 |
float atn = bl*(maxdist<0.0f ? 1.0f : (maxdist-V3Len(&(tpos-pos)))/maxdist); |
| 112 |
tpos += range*(dist-shift)*approach; |
| 113 |
if(atn<=0.0f) break; |
| 114 |
devTransBillboard(tpos); |
| 115 |
switch(ifl->m_Type){ |
| 116 |
case 0: |
| 117 |
devSetTexture(0, NULL); |
| 118 |
Fill3DCircle(V3ZERO, ifl->m_Radius, |
| 119 |
ScaleColor(ifl->m_InnerColor, atn), ScaleColor(ifl->m_OuterColor, atn)); |
| 120 |
break; |
| 121 |
case 1: |
| 122 |
devSetTexture(0, NULL); |
| 123 |
Fill3DHex(V3ZERO, ifl->m_Radius, |
| 124 |
ScaleColor(ifl->m_InnerColor, atn), ScaleColor(ifl->m_OuterColor, atn)); |
| 125 |
break; |
| 126 |
case 2: |
| 127 |
SetUVMap(0.0f, 0.0f, 1.0f, 1.0f); |
| 128 |
devSetTexture(0, ifl->m_Texture); |
| 129 |
TexMap3DRect( |
| 130 |
VEC3(-ifl->m_Radius, ifl->m_Radius, 0.0f), |
| 131 |
VEC3(ifl->m_Radius, ifl->m_Radius, 0.0f), |
| 132 |
VEC3(ifl->m_Radius, -ifl->m_Radius, 0.0f), |
| 133 |
VEC3(-ifl->m_Radius, -ifl->m_Radius, 0.0f), |
| 134 |
ScaleColor(ifl->m_InnerColor, atn)); |
| 135 |
break; |
| 136 |
} |
| 137 |
shift = dist; |
| 138 |
} |
| 139 |
devBLEND_ALPHA(); // ź§ž[hÉߡ |
| 140 |
} |
| 141 |
|
| 142 |
//////////////////////////////////////////////////////////////////////////////// |
| 143 |
//////////////////////////////////////////////////////////////////////////////// |
| 144 |
|
| 145 |
/* |
| 146 |
* Ç |
| 147 |
*/ |
| 148 |
char *CWhiteout::Read( |
| 149 |
char *str // ÎŰśń |
| 150 |
){ |
| 151 |
char *eee; |
| 152 |
if(!(str = BeginBlock(str, "Whiteout"))) return NULL; |
| 153 |
if(!(str = AsgnFloat(eee = str, "StartAngle", &m_StartAngle))) throw CSynErr(eee); |
| 154 |
if(!(str = AsgnColor(eee = str, "Color", &m_Color))) throw CSynErr(eee); |
| 155 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 156 |
m_StartAngle = cosf(D3DXToRadian(m_StartAngle)); |
| 157 |
return str; |
| 158 |
} |
| 159 |
|
| 160 |
/* |
| 161 |
* _O |
| 162 |
*/ |
| 163 |
void CWhiteout::Render( |
| 164 |
VEC3 dir, // őšűü |
| 165 |
float vol // }X^At@l |
| 166 |
){ |
| 167 |
if(!m_Color) return; |
| 168 |
VEC3 vLight = -dir; // JŠçőšÖĚxNg |
| 169 |
VEC3 vCamera = GetVDir(); // JĚüŤ |
| 170 |
V3Norm(&vCamera, &vCamera); |
| 171 |
V3Norm(&vLight, &vLight); |
| 172 |
float angle = V3Dot(&vLight, &vCamera); |
| 173 |
if(angle<=m_StartAngle) return; |
| 174 |
float alpha = vol*(angle-m_StartAngle)/(1.0f-m_StartAngle); |
| 175 |
Fill2DRect(0, 0, g_DispWidth, g_DispHeight, ScaleColor(m_Color, alpha)); |
| 176 |
} |
| 177 |
|
| 178 |
//////////////////////////////////////////////////////////////////////////////// |
| 179 |
//////////////////////////////////////////////////////////////////////////////// |
| 180 |
|
| 181 |
/* |
| 182 |
* RXgN^ |
| 183 |
*/ |
| 184 |
CHeadlightInst::CHeadlightInst( |
| 185 |
VEC3 pos, // őšŔW |
| 186 |
VEC3 dir, // őšűü |
| 187 |
CHeadlight *hl // wbhCg |
| 188 |
){ |
| 189 |
m_RenderPos = pos; |
| 190 |
m_RenderDir = dir; |
| 191 |
m_Headlight = hl; |
| 192 |
} |
| 193 |
|
| 194 |
//////////////////////////////////////////////////////////////////////////////// |
| 195 |
//////////////////////////////////////////////////////////////////////////////// |
| 196 |
|
| 197 |
// static o |
| 198 |
list<CHeadlightInst> CHeadlight::ms_RenderList; |
| 199 |
|
| 200 |
/* |
| 201 |
* [static] |
| 202 |
* Xgúť |
| 203 |
*/ |
| 204 |
void CHeadlight::InitRenderList(){ |
| 205 |
ms_RenderList.clear(); |
| 206 |
} |
| 207 |
|
| 208 |
/* |
| 209 |
* [static] |
| 210 |
* SÄ_O |
| 211 |
*/ |
| 212 |
void CHeadlight::RenderAll(){ |
| 213 |
devSetTexture(0, NULL); |
| 214 |
//devSetZRead(FALSE); |
| 215 |
devSetZWrite(FALSE); |
| 216 |
devSetLighting(FALSE); |
| 217 |
IHeadlightInst ihi = ms_RenderList.begin(); |
| 218 |
for(; ihi!=ms_RenderList.end(); ihi++) ihi->m_Headlight->Render(&*ihi); |
| 219 |
ms_RenderList.clear(); |
| 220 |
//devSetZRead(TRUE); |
| 221 |
devSetZWrite(TRUE); |
| 222 |
devSetLighting(TRUE); |
| 223 |
} |
| 224 |
|
| 225 |
/* |
| 226 |
* Ç |
| 227 |
*/ |
| 228 |
char *CHeadlight::Read( |
| 229 |
char *str, // ÎŰśń |
| 230 |
CModelPlugin *mpi // ÔçqvOC |
| 231 |
){ |
| 232 |
char *tmp, *eee; |
| 233 |
string obj; |
| 234 |
if(!(str = BeginBlock(str, "Headlight"))) return NULL; |
| 235 |
if(!(str = AsgnString(eee = str, "AttachObject", &obj))) throw CSynErr(eee); |
| 236 |
if(!(m_Link = mpi->FindObject(obj))) |
| 237 |
throw CSynErr(eee, "%s: \"%s\"", lang(UndefinedObject), obj.c_str()); |
| 238 |
if(!(str = AsgnVector3D(eee = str, "SourceCoord", &m_SourceCoord))) throw CSynErr(eee); |
| 239 |
if(!(str = AsgnVector3D(eee = str, "Direction", &m_Direction))) throw CSynErr(eee); |
| 240 |
if(!(str = AsgnFloat(eee = str, "MaxDistance", &m_MaxDistance))) throw CSynErr(eee); |
| 241 |
if(tmp = m_LensFlare.Read(eee = str)) str = tmp; |
| 242 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 243 |
return str; |
| 244 |
} |
| 245 |
|
| 246 |
/* |
| 247 |
* f[^Ç |
| 248 |
*/ |
| 249 |
void CHeadlight::LoadData(){ |
| 250 |
m_LensFlare.LoadData(); |
| 251 |
} |
| 252 |
|
| 253 |
/* |
| 254 |
* _OXgÉo^ |
| 255 |
*/ |
| 256 |
bool CHeadlight::Register(){ |
| 257 |
CObject *obj = m_Link->GetObject(); |
| 258 |
VEC3 renderpos = obj->GetPos(), renderdir; |
| 259 |
VEC3 right, up, dir, ldir, tdir; |
| 260 |
V3Norm(&right, &obj->GetRight()); |
| 261 |
V3Norm(&up, &obj->GetUp()); |
| 262 |
V3Norm(&dir, &obj->GetDir()); |
| 263 |
renderpos += m_SourceCoord.x*right+m_SourceCoord.y*up+m_SourceCoord.z*dir; |
| 264 |
V3Norm(&renderdir, &(m_Direction.x*right+m_Direction.y*up+m_Direction.z*dir)); |
| 265 |
ms_RenderList.push_back(CHeadlightInst(renderpos, renderdir, this)); |
| 266 |
return true; |
| 267 |
} |
| 268 |
|
| 269 |
/* |
| 270 |
* _O |
| 271 |
*/ |
| 272 |
void CHeadlight::Render( |
| 273 |
CHeadlightInst *inst // CX^X |
| 274 |
){ |
| 275 |
m_LensFlare.Render(inst->m_RenderPos, inst->m_RenderDir, |
| 276 |
inst->m_RenderPos-GetVPos(), 1.0f, m_MaxDistance); |
| 277 |
} |