00001
00002
00003
00004
00005 #include "MFCBase.h"
00006 #include "DxSRenderView.h"
00007
00008
00009 #ifdef _DEBUG
00010 #define new DEBUG_NEW
00011 #undef THIS_FILE
00012 static char THIS_FILE[] = __FILE__;
00013 #endif
00014
00015
00016 using namespace jbxl;
00017 using namespace jbxwl;
00018
00019
00040
00041
00042
00043 IMPLEMENT_DYNCREATE(CDxSRenderView, CExView)
00044
00045
00046 CDxSRenderView::CDxSRenderView()
00047 {
00048 cnstXYRate = true;
00049
00050 pCounter = NULL;
00051 volumeColor = TRUE;
00052 }
00053
00054
00055
00056 CDxSRenderView::~CDxSRenderView()
00057 {
00058 }
00059
00060
00061
00062 BEGIN_MESSAGE_MAP(CDxSRenderView, CDxVTXBaseView)
00063
00064 ON_WM_TIMER()
00065
00066 END_MESSAGE_MAP()
00067
00068
00069
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00085
00086
00087 #ifdef _DEBUG
00088 void CDxSRenderView::AssertValid() const
00089 {
00090 CDxVTXBaseView::AssertValid();
00091 }
00092
00093
00094 void CDxSRenderView::Dump(CDumpContext& dc) const
00095 {
00096 CDxVTXBaseView::Dump(dc);
00097 }
00098 #endif //_DEBUG
00099
00100
00101
00103
00104
00105
00106 void CDxSRenderView::OnInitialUpdate()
00107 {
00108
00109
00110 msGraph = pDoc->msGraph;
00111 if (msGraph.isNull()) return;
00112
00113 double rzxy = msGraph.RZxy;
00114 if (rzxy==0.0) rzxy = 1.0;
00115
00116 Rbound.xmax = msGraph.xs;
00117 Rbound.ymax = msGraph.ys;
00118 Rbound.zmax = (int)(msGraph.zs/rzxy+0.5);
00119 Rbound.xmin = Rbound.ymin = Rbound.zmin = 0;
00120
00121 center = D3DXVECTOR3((Rbound.xmax + Rbound.xmin)/2.f,
00122 (Rbound.ymax + Rbound.ymin)/2.f,
00123 (Rbound.zmax + Rbound.zmin)/2.f);
00124 xsize = Rbound.xmax - Rbound.xmin + 1;
00125 ysize = Rbound.ymax - Rbound.ymin + 1;
00126 zsize = Rbound.zmax - Rbound.zmin + 1;
00127 msize = Max(xsize, ysize);
00128 msize = Max(msize, zsize);
00129
00130 sizeFac = Min(sizeFac, 1.0/msize);
00131
00132 int dxsize = msize;
00133 if (dxsize<MSG_DEFAULT_WINDOW_SIZE) dxsize = MSG_DEFAULT_WINDOW_SIZE;
00134 if (Dx9ReverseZMode) reverseZ = true;
00135 else reverseZ = false;
00136
00137 BOOL rslt = InitDevice(dxsize, dxsize);
00138 if (!rslt) {
00139 CString mesg;
00140 mesg.LoadString(IDS_STR_FAIL_GET_DX9DEV);
00141 MessageBox(_T("CDxSRenderView::OnInitialUpdate():\n\n") + mesg);
00142 pFrame->doneErrorMessage = TRUE;
00143 return;
00144 }
00145
00146 if (!PrepareVB()) return;
00147 SetState();
00148
00149 origXSize = MSG_DEFAULT_WINDOW_SIZE;
00150 origYSize = MSG_DEFAULT_WINDOW_SIZE;
00151 sizeXYRate = origYSize/(double)origXSize;
00152
00153
00154 SetWindowSize(MSG_DEFAULT_WINDOW_SIZE, MSG_DEFAULT_WINDOW_SIZE);
00155 hasViewData = TRUE;
00156
00157 Title = pDoc->preTitle + pDoc->Title + pDoc->pstTitle;
00158 this->SetTitle(Title);
00159
00160 return;
00161 }
00162
00163
00164
00165 void CDxSRenderView::SetState()
00166 {
00167 D3DLIGHT9 m_light;
00168 D3DXVECTOR3 mVecDir;
00169
00170 D3DCAPS9 caps;
00171
00172 lpD3DDevice->GetDeviceCaps(&caps);
00173
00174
00175
00176
00177
00178
00179
00180
00181 lpD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
00182
00183
00184 lpD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
00185
00186
00187 lpD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
00188
00189
00190 lpD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
00191
00192
00193 lpD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
00194
00195
00196 lpD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
00197 ZeroMemory(&m_light, sizeof(D3DLIGHT9));
00198 m_light.Type = D3DLIGHT_DIRECTIONAL;
00199 m_light.Diffuse.r = 1.0f;
00200 m_light.Diffuse.g = 1.0f;
00201 m_light.Diffuse.b = 1.0f;
00202
00203
00204
00205 mVecDir = D3DXVECTOR3(1.0f, -2.0f, -1.0f);
00206
00207 D3DXVec3Normalize((D3DXVECTOR3*)&m_light.Direction, &mVecDir);
00208 lpD3DDevice->SetLight(0, &m_light);
00209 lpD3DDevice->LightEnable(0, TRUE);
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 D3DXMatrixPerspectiveFovLH(&matProj, (float)(PI/3.0), 1.0f, 0.1f, (float)(10.0*msize*sizeFac));
00226 lpD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
00227
00228
00229
00230
00231
00232 if (mWheelAc==0.0) mWheelAc = 1.5*msize*sizeFac;
00233 ExMouseWheel();
00234
00235
00236 lpD3DDevice->SetFVF(FVF_SVERTEXV);
00237
00238 D3DXMatrixTranslation(&matTrans, -(float)(center.x*sizeFac), -(float)(center.y*sizeFac), (float)(center.z*sizeFac));
00239 lpD3DDevice->SetTransform(D3DTS_WORLD, &matTrans);
00240 }
00241
00242
00243
00244 void CDxSRenderView::ExMouseWheel()
00245 {
00246 if (Xabs(mWheelAc)<1.0) mWheelAc = Sign(mWheelAc);
00247
00248
00249 D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0.0f, (float)mWheelAc, 0.0f), &D3DXVECTOR3(0,0,0), &D3DXVECTOR3(0,0,1));
00250 lpD3DDevice->SetTransform(D3DTS_VIEW, &matView);
00251
00252 double pointsize = sizeFac/Xabs(mWheelAc)*1000.0;
00253 lpD3DDevice->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&pointsize));
00254 }
00255
00256
00257
00258 void CDxSRenderView::ExecRender()
00259 {
00260 HRESULT hr;
00261
00262
00263 hr = lpD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,96), 1.0f, 0);
00264 if (FAILED(hr)) { DEBUG_ERROR("CDxSRenderView::ExecRender(): ERROR: 画面クリアに失敗しました\n"); return;}
00265
00266
00267 hr = lpD3DDevice->BeginScene();
00268 if (FAILED(hr)) { DEBUG_ERROR("CDxSRenderView::ExecRender(): ERROR: シーンの開始に失敗しました\n"); return;}
00269
00270 hr = lpD3DDevice->SetStreamSource(0, vb, 0, sizeof(SVERTEXV));
00271 if (FAILED(hr)) { DEBUG_ERROR("CDxSRenderView::ExecRender(): ERROR: ストリームの設定に失敗しました\n"); lpD3DDevice->EndScene(); return;}
00272
00273 hr = Dx9DrawPrimitive(lpD3DDevice, D3DPT_POINTLIST, 1, datano);
00274 if (FAILED(hr)) { DEBUG_ERROR("CDxSRenderView::ExecRender(): ERROR: プリミティブ描画に失敗しました\n"); lpD3DDevice->EndScene(); return;}
00275
00276 hr = lpD3DDevice->EndScene();
00277 if (FAILED(hr)) { DEBUG_ERROR("CDxSRenderView::ExecRender(): ERROR: シーンの終了に失敗しました\n"); return;}
00278
00279
00280
00281 hr = lpD3DDevice->Present(NULL, NULL, NULL, NULL);
00282 if (FAILED(hr)) {
00283
00284 hr = ResetDx9Device(lpD3DDevice, &d3dParam, this);
00285 if (FAILED(hr)) {
00286 CString mesg;
00287 mesg.LoadString(IDS_STR_FAIL_RESTR_DX9DEV);
00288 MessageBox(_T("CDxSRenderView::ExecRender():\n\n") + mesg);
00289 pFrame->SendMessage(WM_CLOSE);
00290
00291 }
00292 }
00293 }
00294
00295
00296
00297
00298 BOOL CDxSRenderView::PrepareVB()
00299 {
00300 int i, j, k;
00301 int x, y, z;
00302 int ii, jj, kk;
00303 int is, js, ks;
00304 int ie, je, ke;
00305 double rzxy;
00306
00307
00308 pCounter = new CProgressBarDLG(IDD_PROGBAR, NULL, TRUE);
00309 if (pCounter!=NULL) {
00310 CString mesg;
00311 mesg.LoadString(IDS_STR_PROC_VERTEX_BUF);
00312 char* mbstr = ts2mbs(mesg);
00313 pCounter->Start(msGraph.xs*msGraph.ys*msGraph.zs*2, mbstr);
00314 ::free(mbstr);
00315 }
00316
00317 datano = GetValidVoxelNum();
00318 if (datano<=0) {
00319 if (pCounter!=NULL) {
00320 pCounter->Stop();
00321 deleteNull(pCounter);
00322 pFrame->cancelOperation = TRUE;
00323 pFrame->doneErrorMessage = TRUE;
00324 }
00325 CString mesg, noti;
00326 if (datano==-1) {
00327 mesg.LoadString(IDS_STR_CANCEL_VERTEX_BUF_SET1);
00328 noti.LoadString(IDS_STR_CANCEL);
00329 MessageBox(_T("CDxSRenderView::PrepareVB():\n\n") + mesg, noti);
00330 }
00331 else if (datano==0) {
00332 mesg.LoadString(IDS_STR_INFO_VERTEX_ZERO);
00333 noti.LoadString(IDS_STR_INFO);
00334 MessageBox(_T("CDxSRenderView::PrepareVB():\n\n") + mesg, noti);
00335 }
00336 else {
00337 mesg.LoadString(IDS_STR_ERR_VERTEX_NUM);
00338 noti.LoadString(IDS_STR_ERROR);
00339 MessageBox(_T("CDxSRenderView::PrepareVB():\n\n") + mesg, noti);
00340 }
00341 return FALSE;
00342 }
00343
00344 lpD3DDevice->CreateVertexBuffer(sizeof(SVERTEXV)*datano, 0, FVF_SVERTEXV, D3DPOOL_MANAGED, &vb, NULL);
00345 if (vb==NULL) {
00346 if (pCounter!=NULL) {
00347 pCounter->Stop();
00348 deleteNull(pCounter);
00349 }
00350 CString mesg, noti;
00351 mesg.LoadString(IDS_STR_FAIL_GET_VERTEX_BUF);
00352 noti.LoadString(IDS_STR_ERROR);
00353 MessageBox(_T("CDxSRenderView::PrepareVB():\n\n") + mesg, noti);
00354 return FALSE;
00355 }
00356
00357 SVERTEXV *v;
00358 vb->Lock(0, 0, (void **)&v, 0);
00359
00360 rzxy = msGraph.RZxy;
00361 if (rzxy==0.0) rzxy = 1.0;
00362
00363 int cnt= 0;
00364 for (k=0; k<msGraph.zs; k++) {
00365 for (j=0; j<msGraph.ys; j++) {
00366 for (i=0; i<msGraph.xs; i++) {
00367 x = y = z = 0;
00368 bool chk = false;
00369 if (msGraph.point(i, j, k)!=0) {
00370 is = js = ks = -1;
00371 ie = je = ke = 1;
00372
00373
00374 if (i==0) { is = 0; x = -10; chk = true;}
00375 if (i==msGraph.xs-1) { ie = 0; x = 10; chk = true;}
00376 if (j==0) { js = 0; y = -10; chk = true;}
00377 if (j==msGraph.ys-1) { je = 0; y = 10; chk = true;}
00378 if (k==0) { ks = 0; z = -10; chk = true;}
00379 if (k==msGraph.zs-1) { ke = 0; z = 10; chk = true; if (msGraph.zs==1) z = -10;}
00380
00381
00382 for (kk=ks; kk<=ke; kk++)
00383 for (jj=js; jj<=je; jj++)
00384 for (ii=is; ii<=ie; ii++) {
00385 if (msGraph.point(i+ii, j+jj, k+kk)==0) {
00386 x = x + ii;
00387 y = y + jj;
00388 z = z + kk;
00389 chk = true;
00390 }
00391 }
00392
00393
00394 if (chk) {
00395
00396 v[cnt].ps = 3.5f;
00397 v[cnt].x = i*(float)sizeFac;
00398 v[cnt].y = j*(float)sizeFac;
00399
00400 if (reverseZ) v[cnt].z = -(msGraph.zs-1-k)*(float)(sizeFac/rzxy);
00401 else v[cnt].z = -k*(float)(sizeFac/rzxy);
00402
00403 int n2 = x*x + y*y + z*z;
00404 if (n2!=0) {
00405 float nn = (float)sqrt((double)n2);
00406
00407 v[cnt].nx = x/nn;
00408 v[cnt].ny = y/nn;
00409
00410 if (reverseZ) v[cnt].nz = z/nn;
00411 else v[cnt].nz = -z/nn;
00412 }
00413
00414 else {
00415 v[cnt].nx = -1.0f;
00416 v[cnt].ny = 1.0f;
00417 v[cnt].nz = 1.0f;
00418 }
00419
00420 if (volumeColor) {
00421 if (msGraph.color == GRAPH_COLOR_R4G4B4A4 || msGraph.color == GRAPH_COLOR_RGBA16) {
00422 v[cnt].color = Dx9Word2RGBA((uWord)msGraph.point(i, j, k));
00423 }
00424 else if (msGraph.color == GRAPH_COLOR_A4R4G4B4 || msGraph.color == GRAPH_COLOR_ARGB16) {
00425 v[cnt].color = Dx9Word2ARGB((uWord)msGraph.point(i, j, k));
00426 }
00427 else {
00428 v[cnt].color = Dx9Word2RGB((uWord)msGraph.point(i, j, k));
00429 }
00430 }
00431 else {
00432 v[cnt].color = D3DCOLOR_RGBA(192, 192, 192, 192);
00433 }
00434 cnt++;
00435 }
00436 }
00437 }
00438 }
00439
00440
00441 if (pCounter!=NULL) {
00442 pCounter->SetPos(msGraph.xs*msGraph.ys*msGraph.zs + (k+1)*msGraph.xs*msGraph.ys);
00443 if (pCounter->isCanceled()) {
00444 pCounter->Stop();
00445 deleteNull(pCounter);
00446 vb->Unlock();
00447 DXRELEASE(vb);
00448
00449 CString mesg, noti;
00450 mesg.LoadString(IDS_STR_CANCEL_VERTEX_BUF_SET2);
00451 mesg.LoadString(IDS_STR_CANCEL);
00452 MessageBox(_T("CDxSRenderView::PrepareVB():\n\n") + mesg, noti);
00453
00454 pFrame->cancelOperation = TRUE;
00455 pFrame->doneErrorMessage = TRUE;
00456 return FALSE;
00457 }
00458 }
00459 }
00460
00461 datano = cnt;
00462 vb->Unlock();
00463
00464 if (pCounter!=NULL) {
00465 pCounter->Stop();
00466 deleteNull(pCounter);
00467 }
00468 return TRUE;
00469 }
00470
00471
00472
00473
00474
00475 void CDxSRenderView::ExRotationAngle()
00476 {
00477 angleZ = -angleX;
00478 angleX = -angleY;
00479 angleY = 0.0;
00480 }
00481
00482
00483
00484 void CDxSRenderView::ClearObject()
00485 {
00486 hasViewData = FALSE;
00487
00488 }
00489
00490
00491
00492 void CDxSRenderView::InitObject()
00493 {
00494 SetState();
00495
00496 hasViewData = TRUE;
00497 }
00498
00499
00500
00501 int CDxSRenderView::GetValidVoxelNum()
00502 {
00503 int i, j, k;
00504 int ii, jj, kk;
00505 int is, js, ks;
00506 int ie, je, ke;
00507 int cnt = 0;
00508
00509 for (k=0; k<msGraph.zs; k++) {
00510 for (j=0; j<msGraph.ys; j++) {
00511 for (i=0; i<msGraph.xs; i++) {
00512 bool chk = false;
00513 if (msGraph.point(i, j, k)!=0) {
00514 is = js = ks = -1;
00515 ie = je = ke = 1;
00516
00517 if (i==0 || i==msGraph.xs-1 ||
00518 j==0 || j==msGraph.ys-1 ||
00519 k==0 || k==msGraph.zs-1 ) chk = true;
00520 else {
00521 for (kk=ks; kk<=ke; kk++)
00522 for (jj=js; jj<=je; jj++)
00523 for (ii=is; ii<=ie; ii++) {
00524 if (msGraph.point(i+ii, j+jj, k+kk)==0) chk = true;
00525 }
00526 }
00527 }
00528 if (chk) cnt++;
00529 }
00530 }
00531 if (pCounter!=NULL) {
00532 pCounter->SetPos((k+1)*msGraph.xs*msGraph.ys);
00533 if (pCounter->isCanceled()) return -1;
00534 }
00535 }
00536 return cnt;
00537 }
00538
00539