Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/GraphicCover.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (show annotations) (download) (as text)
Tue Nov 23 14:34:03 2010 UTC (13 years, 5 months ago) by okadu
File MIME type: text/x-c++src
File size: 9447 byte(s)
[okadu] Version 2.13
1 #include "stdafx.h"
2 #include "CCamera.h"
3 #include "CShadowVolume.h"
4 #include "CScene.h"
5 #include "CEnvPlugin.h"
6 #include "CSurfacePlugin.h"
7 #include "CSceneryMode.h"
8 #include "CConfigMode.h"
9
10 // 外部定数
11 extern const float CLIP_PLANE_NEAR;
12
13 // 内部定数
14 const int GRID_SIZE = 32; // グリッドサイズ
15 const float GRID_ZOOM = 2.0f; // グリッド拡大率
16 const float TANGENT_LEN = 4.0f; // 接線表示長さ
17
18 // 外部グローバル
19 extern bool g_StencilEnabled;
20
21 // 内部グローバル
22 bool g_ShadowNeeded; // 影が必要かどうか
23 CVertex g_DetailGridVertex; // グリッド頂点バッファ
24 CShadowVolume g_ShadowVolume; // シャドウボリューム
25
26 /*
27 * 直線と 1 点の距離を求める
28 *
29 * 戻り値: 距離
30 */
31 float LinePointDistance(
32 VEC3 *p1, // 直線が通る 1 点
33 VEC3 *n1, // 直線の方向ベクトル
34 VEC3 *p2 // 点
35 ){
36 return V3Len(&(*p2-(*p1+*n1*V3Dot(n1, &(*p2-*p1)))));
37 }
38
39 /*
40 * 行列正規化
41 */
42 void NormalizeMatrix(MTX4 *mtx){
43 V3Norm((VEC3 *)&mtx->_11, (VEC3 *)&mtx->_11);
44 V3Norm((VEC3 *)&mtx->_21, (VEC3 *)&mtx->_21);
45 V3Norm((VEC3 *)&mtx->_31, (VEC3 *)&mtx->_31);
46 }
47
48 /*
49 * 2 直線の最近点を求める
50 *
51 * 戻り値: 平行なら true を返す
52 */
53 bool LineLineNearest(
54 VEC3 *m1, // 直線 1 上の最近点
55 VEC3 *m2, // 直線 2 上の最近点
56 VEC3 *p1, // 直線 1 を通る 1 点
57 VEC3 *n1, // 直線 1 の方向ベクトル
58 VEC3 *p2, // 直線 2 を通る 1 点
59 VEC3 *n2 // 直線 2 の方向ベクトル
60 ){
61 VEC3 r = *p2-*p1;
62 float d = V3Len(&r);
63 float n12 = V3Dot(n1, n2);
64 float t = 1.0f-n12*n12;
65 if(t<0.000001f) return true;
66 *m1 = *p1+*n1*(V3Dot(n1, &(r-*n2*V3Dot(n2, &r)))/t);
67 *m2 = *p2+*n2*(V3Dot(n2, &(*n1*V3Dot(n1, &r)-r))/t);
68 return false;
69 }
70
71 /*
72 * 2 直線の距離を求める
73 *
74 * 戻り値: 距離
75 */
76 float LineLineDistance(
77 VEC3 *p1, // 直線 1 を通る 1 点
78 VEC3 *n1, // 直線 1 の方向ベクトル
79 VEC3 *p2, // 直線 2 を通る 1 点
80 VEC3 *n2 // 直線 2 の方向ベクトル
81 ){
82 VEC3 m1, m2;
83 return LineLineNearest(&m1, &m2, p1, n1, p2, n2)
84 ? V3Len(&(m1-m2)) : LinePointDistance(p1, n1, p2);
85 }
86
87 /*
88 * ある点から一定距離にある直線上の点 (2 個) を求める
89 */
90 void LinePointPosition(
91 VEC3 *d1, // 結果 1
92 VEC3 *d2, // 結果 2
93 VEC3 *p1, // 直線が通る 1 点
94 VEC3 *n1, // 直線の方向ベクトル
95 VEC3 *p2, // 点
96 float x // 距離
97 ){
98 float r, beta, gamma, tx = p1->x-p2->x, ty = p1->y-p2->y, tz = p1->z-p2->z;
99 beta = n1->x*tx+n1->y*ty+n1->z*tz;
100 gamma = tx*tx+ty*ty+tz*tz-x*x;
101 r = sqrt(beta*beta-4*gamma);
102 *d1 = *p1+*n1*(-beta+r);
103 *d2 = *p1+*n1*(-beta-r);
104 }
105
106 /*
107 * グリッド作成
108 */
109 void InitGrid(){
110 int i, cnt = 0;
111 VTX_L grid[(GRID_SIZE-1)*16]; // 両端・両側・±・XZ・
112 for(i = -GRID_SIZE/2+1; i<GRID_SIZE/2; i++){
113 D3DCOLOR color = i%5 ? 0x00c0c0ff : 0x000000ff;
114 D3DCOLOR alpha = (255*(GRID_SIZE/2-1-abs(i))/(GRID_SIZE/2-1))<<24;
115 grid[cnt].x = i; grid[cnt].y = 0.0f; grid[cnt].z = -GRID_SIZE/2;
116 grid[cnt].d = color; cnt++;
117 grid[cnt].x = i; grid[cnt].y = 0.0f; grid[cnt].z = 0.0f;
118 grid[cnt].d = color|alpha; cnt++;
119 grid[cnt].x = i; grid[cnt].y = 0.0f; grid[cnt].z = GRID_SIZE/2;
120 grid[cnt].d = color; cnt++;
121 grid[cnt].x = i; grid[cnt].y = 0.0f; grid[cnt].z = 0.0f;
122 grid[cnt].d = color|alpha; cnt++;
123 grid[cnt].x = -GRID_SIZE/2; grid[cnt].y = 0.0f; grid[cnt].z = i;
124 grid[cnt].d = color; cnt++;
125 grid[cnt].x = 0.0f; grid[cnt].y = 0.0f; grid[cnt].z = i;
126 grid[cnt].d = color|alpha; cnt++;
127 grid[cnt].x = GRID_SIZE/2; grid[cnt].y = 0.0f; grid[cnt].z = i;
128 grid[cnt].d = color; cnt++;
129 grid[cnt].x = 0.0f; grid[cnt].y = 0.0f; grid[cnt].z = i;
130 grid[cnt].d = color|alpha; cnt++;
131 }
132 g_DetailGridVertex.Create(grid, FVF_L, sizeof(VTX_L)*(GRID_SIZE-1)*8);
133 }
134
135 /*
136 * グリッド描画
137 */
138 void DrawGrid(
139 VEC3 pos // 中心座標
140 ){
141 int i;
142 float cdist = CCamera::GetCurrentCamera()->GetDist(), gscale;
143 cdist *= g_FovRatio;
144 if(cdist>GRID_ZOOM*2000.0f) gscale = 100.0f;
145 else if(cdist>GRID_ZOOM*1000.0f) gscale = 50.0f;
146 else if(cdist>GRID_ZOOM*400.0f) gscale = 20.0f;
147 else if(cdist>GRID_ZOOM*200.0f) gscale = 10.0f;
148 else if(cdist>GRID_ZOOM*100.0f) gscale = 5.0f;
149 else if(cdist>GRID_ZOOM*40.0f) gscale = 2.0f;
150 else if(cdist>GRID_ZOOM*20.0f) gscale = 1.0f;
151 else if(cdist>GRID_ZOOM*10.0f) gscale = 0.5f;
152 else if(cdist>GRID_ZOOM*4.0f) gscale = 0.2f;
153 else gscale = 0.1f;
154 float fscale = 0.003f*cdist/gscale, gstep = 5.0f*gscale;
155 MTX4 move;
156 VEC3 tpos(Round(pos.x/gstep)*gstep, pos.y, Round(pos.z/gstep)*gstep);
157 D3DXMatrixTranslation(&move, tpos.x, tpos.y, tpos.z);
158 move._11 *= gscale; move._22 *= gscale; move._33 *= gscale;
159 pos = (pos-tpos)/gscale;
160 devSetTexture(0, NULL);
161 devSetZRead(FALSE);
162 devSetZWrite(FALSE);
163 devSetLighting(FALSE);
164 devTransform(&move);
165 devResetMaterial();
166 devTEX_POINT(0);
167 devTEX_POINT(1);
168 g_DetailGridVertex.RenderLL();
169 Draw3DLine(pos, VEC3(pos.x, 0.0f, GRID_SIZE), 0xffff8000, 0x00ff8000);
170 Draw3DLine(pos, VEC3(pos.x, 0.0f, -GRID_SIZE), 0xffff8000, 0x00ff8000);
171 Draw3DLine(pos, VEC3(GRID_SIZE, 0.0f, pos.z), 0xffff8000, 0x00ff8000);
172 Draw3DLine(pos, VEC3(-GRID_SIZE, 0.0f, pos.z), 0xffff8000, 0x00ff8000);
173 int step = 100.0f<=cdist/gscale && cdist/gscale<200.0f ? 2 : 1;
174 int lim = 20000.0f<=cdist ? 0 : 2;
175 VEC3 vdir = GetVDir();
176 VEC3 xofs = 0.5f*GRID_SIZE*V3RIGHT, zofs = 0.5f*GRID_SIZE*V3DIR;
177 float xs = vdir.x<0.0f ? -1.0f : 1.0f, zs = vdir.z<0.0f ? -1.0f : 1.0f;
178 float uinv = vdir.y<0.0f ? 1.0f : -1.0f;
179 for(i = -lim; i<=lim; i += step){
180 char *fmt = (char *)(gscale<1.0f ? "%.1f" : "%.0f");
181 D3DCOLOR col = ((255*(3-abs(i))/3)<<24)|0x00ffffff;
182 if(vdir.x<0.0f) g_StrTex->RenderRight3D(-zofs+5.0f*i*V3RIGHT, -V3DIR*xs, uinv*xs*V3RIGHT,
183 col, 0xff000000, FlashIn(fmt, tpos.x+i*gstep), fscale);
184 else g_StrTex->RenderLeft3D(-zofs+5.0f*i*V3RIGHT, -V3DIR*xs, uinv*xs*V3RIGHT,
185 col, 0xff000000, FlashIn(fmt, tpos.x+i*gstep), fscale);
186 if(vdir.z<0.0f) g_StrTex->RenderLeft3D(-xofs+5.0f*i*V3DIR, V3RIGHT*zs, uinv*zs*V3DIR,
187 col, 0xff000000, FlashIn(fmt, tpos.z+i*gstep), fscale);
188 else g_StrTex->RenderRight3D(-xofs+5.0f*i*V3DIR, V3RIGHT*zs, uinv*zs*V3DIR,
189 col, 0xff000000, FlashIn(fmt, tpos.z+i*gstep), fscale);
190 }
191 float midfix = 0.5f*FONT_HEIGHT*fscale;
192 g_StrTex->RenderCenter3D(zofs+midfix*V3DIR, V3RIGHT*zs, uinv*zs*V3DIR,
193 0xffffffff, 0xff000000, "Z", fscale);
194 g_StrTex->RenderCenter3D(xofs+midfix*V3RIGHT, -V3DIR*xs, uinv*xs*V3RIGHT,
195 0xffffffff, 0xff000000, "X", fscale);
196 }
197
198 /*
199 * XZ 接線描画
200 */
201 void DrawTangent(
202 VEC3 pos, // 中心座標
203 VEC3 norm, // 法線
204 D3DCOLOR col, // 色
205 CLineDumpL *dump // ダンパ
206 ){
207 VEC3 xn(norm.y, -norm.x, 0.0f), zn(0.0f, -norm.z, norm.y);
208 D3DCOLOR col2 = col&0x00ffffff;
209 V3Norm(&xn, &xn);
210 V3Norm(&zn, &zn);
211 xn *= TANGENT_LEN; zn *= TANGENT_LEN;
212 if(dump){
213 dump->Add(pos, col, pos+xn, col2);
214 dump->Add(pos, col, pos-xn, col2);
215 dump->Add(pos, col, pos+zn, col2);
216 dump->Add(pos, col, pos-zn, col2);
217 }else{
218 Draw3DLine(pos, pos+xn, col, col2);
219 Draw3DLine(pos, pos-xn, col, col2);
220 Draw3DLine(pos, pos+zn, col, col2);
221 Draw3DLine(pos, pos-zn, col, col2);
222 }
223 }
224
225 /*
226 * フォーカス描画
227 */
228 void DrawFocus(
229 VEC3 pos // 中心座標
230 ){
231 devResetMatrix();
232 devSetTexture(0, NULL);
233 devSetZRead(FALSE);
234 devSetZWrite(FALSE);
235 devSetLighting(FALSE);
236 devResetMaterial();
237 Draw3DLine(pos, pos+VEC3(0.0f, 0.0f, TANGENT_LEN), 0xffff8000, 0x00ff8000);
238 Draw3DLine(pos, pos+VEC3(0.0f, 0.0f, -TANGENT_LEN), 0xffff8000, 0x00ff8000);
239 Draw3DLine(pos, pos+VEC3(TANGENT_LEN, 0.0f, 0.0f), 0xffff8000, 0x00ff8000);
240 Draw3DLine(pos, pos+VEC3(-TANGENT_LEN, 0.0f, 0.0f), 0xffff8000, 0x00ff8000);
241 }
242
243 /*
244 * 影付き 3D 直線を描画
245 */
246 void Draw3DLineWithShadow(
247 VEC3 pos1, VEC3 pos2, // 座標
248 D3DCOLOR c1, D3DCOLOR c2 // 色
249 ){
250 VEC3 p1 = WorldToScreen(pos1), p2 = WorldToScreen(pos2);
251 if(p1.z<0.0f && p2.z<0.0f) return;
252 if(p1.z<0.0f || p2.z<0.0f){
253 VEC3 vp = GetVPos(), vd = GetVDir();
254 float q1 = V3Dot(&(vp-pos1), &vd)+CLIP_PLANE_NEAR/g_FovRatio;
255 float q2 = V3Dot(&(pos2-vp), &vd);
256 if(p1.z<0.0f) p1 = WorldToScreen((q2*pos1+q1*pos2)/(q1+q2));
257 else p2 = WorldToScreen((q2*pos1+q1*pos2)/(q1+q2));
258 }
259 int p1x = Round(p1.x), p1y = Round(p1.y);
260 int p2x = Round(p2.x), p2y = Round(p2.y);
261 D3DCOLOR s2 = (c2 ? c2 : c1)&0xff000000;
262 Draw2DLine(p1x+1, p1y+1, p2x+1, p2y+1, c1&0xff000000, s2 ? s2 : 0x01000000);
263 Draw2DLine(p1x, p1y, p2x, p2y, c1, c2);
264 }
265
266 /*
267 * 3D 点を 2D 矩形で描画
268 */
269 void Draw3DPointAs2DRect(
270 VEC3 pos, // 座標
271 D3DCOLOR color, // 色
272 int r // 半径
273 ){
274 VEC3 p = WorldToScreen(pos);
275 if(p.z<0.0f) return;
276 int px = Round(p.x), py = Round(p.y);
277 Draw2DRect(px-r+1, py-r+1, px+r+1, py+r+1, 0xff000000);
278 Draw2DRect(px-r, py-r, px+r, py+r, color);
279 }
280
281 /*
282 * 影を初期化
283 */
284 void InitShadow(){
285 CEnvPlugin *env = g_RSPV ? g_Env : g_Scene->GetEnv();
286 if(g_ConfigMode->GetShadow() && env->GetShadowColor()
287 && !g_SystemSwitch[SYS_SW_NIGHT].GetValue() && g_StencilEnabled){
288 g_ShadowNeeded = true;
289 g_ShadowVolume.Reset();
290 }else{
291 g_ShadowNeeded = false;
292 }
293 }
294
295 /*
296 * 影を落とす
297 */
298 void CastShadow(
299 CObject *obj // オブジェクト
300 ){
301 if(!g_ShadowNeeded || g_RenderBlink) return;
302 g_ShadowVolume.BuildFromMesh(obj, VEC3(svl.dir.Direction));
303 }
304
305 /*
306 * 影のレンダリング
307 */
308 void RenderShadow(){
309 if(!g_ShadowNeeded) return;
310 CEnvPlugin *env = g_RSPV ? g_Env : g_Scene->GetEnv();
311 devSetTexture(0, NULL);
312 g_ShadowVolume.Render();
313 g_ShadowVolume.Draw(ScaleColor(env->GetShadowColor(), g_DayAlpha));
314 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26