DrawLine3DとMV1DrawModelで描画した物を交差させたい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
KRNKRS
記事: 40
登録日時: 12年前
連絡を取る:

DrawLine3DとMV1DrawModelで描画した物を交差させたい

#1

投稿記事 by KRNKRS » 8年前

DrawLine3Dでグリッドを、MV1DrawModelでmv1形式の3Dモデルを表示させているのですが、
グリッドとモデルを交差、つまり、線をモデルに埋まらせたくても描画順の関係か、
モデルが常に手前に表示され、グリッド線は常に奥側に表示されてしまいます。
(グリッド->モデルの順に描画しています)

おそらくZバッファ関連だと思いモデルに対して「MV1SetUseZBuffer」「MV1SetWriteZBuffer」を適用しているのですが、
解決に至ってはいません。
どうせならと「SetUseZBuffer3D」「SetWriteZBuffer3D」も試しに使用してみても同様でした。
(そもそも DrawSphere3D, DrawCapsule3D, DrawCone3D, DrawPolygon3D, DrawPolygonIndexed3D 用なので当たり前ですが...)

交差させる解決方法はないでしょうか。
よろしくお願いいたします。
最後に編集したユーザー KRNKRS on 2017年2月11日(土) 13:13 [ 編集 1 回目 ]

と成りのトトロ

Re: DrawLine3DとMV1DrawModelで描画した物を交差させたい

#2

投稿記事 by と成りのトトロ » 8年前

抽象論でなく具体的にコードを提示をお願い致します。例えばこのようにVS2008,DirectXで動くものです。

コード:

///// 3Dオブジェクト /////

#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

#include <windows.h>
#include <tchar.h>
#include <d3d9.h>
#include <d3dx9.h>

_TCHAR gName[100] = _T("---3Dオブジェクト描画サンプル---");


// ウィンドウプロシージャ//---05---
LRESULT CALLBACK WndProc(HWND hWnd, UINT mes, WPARAM wParam, LPARAM lParam){
   if(mes == WM_DESTROY) {PostQuitMessage(0); return 0;}
   return DefWindowProc(hWnd, mes, wParam, lParam);
}

/////エントリーポイント:_tWinMain------------------------------------------------------------------
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
   // アプリケーションの初期化
   MSG msg; HWND hWnd;
   WNDCLASSEX wcex ={sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInstance, NULL, NULL,
                                    (HBRUSH)(COLOR_WINDOW+1), NULL, (_TCHAR*)gName, NULL};
   if(!RegisterClassEx(&wcex))
      return 0;

   if(!(hWnd = CreateWindow(gName, gName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
                                    NULL, NULL, hInstance, NULL)))
      return 0;

   // Direct3Dの初期化
   LPDIRECT3D9 g_pD3D;
   LPDIRECT3DDEVICE9 g_pD3DDev;
   if( !(g_pD3D = Direct3DCreate9( D3D_SDK_VERSION )) ) return 0;

   D3DPRESENT_PARAMETERS d3dpp = {0,0,D3DFMT_UNKNOWN,0,D3DMULTISAMPLE_NONE,0,
                                                      D3DSWAPEFFECT_DISCARD,NULL,TRUE,TRUE,D3DFMT_D24S8,0,D3DPRESENT_RATE_DEFAULT,D3DPRESENT_INTERVAL_DEFAULT}; 

   if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDev ) ) )
   if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDev ) ) )
   {
      g_pD3D->Release();
      return 0;
   }

   // 立方体オブジェクト生成
   ID3DXBuffer *pMaterials;
   DWORD NumMaterials;
   ID3DXMesh *pMesh; // XファイルはDirect3DX(エクステンション)のヘルパー関数であるD3DXLoadMeshFromX関数によってダイレクトに読み込む
   if(FAILED(D3DXLoadMeshFromX( _T("d:/dat/Cube2.x"), D3DXMESH_MANAGED, g_pD3DDev, NULL, &pMaterials, NULL, &NumMaterials, &pMesh))){
      g_pD3DDev->Release(); g_pD3D->Release(); return 0;
   }

   // 軸オブジェクト生成
   ID3DXBuffer *pAX_Materials;
   DWORD AX_NumMaterials;
   ID3DXMesh *pAX_Mesh;// XファイルはDirect3DX(エクステンション)のヘルパー関数であるD3DXLoadMeshFromX関数によってダイレクトに読み込む
   if(FAILED(D3DXLoadMeshFromX( _T("d:/dat/Axis.x"), D3DXMESH_MANAGED, g_pD3DDev, NULL, &pAX_Materials, NULL, &AX_NumMaterials, &pAX_Mesh))){
      pMesh->Release(); g_pD3DDev->Release(); g_pD3D->Release(); return 0;
   }

   // ライト
   D3DLIGHT9 light;
   ZeroMemory(&light, sizeof(D3DLIGHT9) );
   light.Direction = D3DXVECTOR3(-1, -20, 0);
   light.Type = D3DLIGHT_DIRECTIONAL; 
   light.Diffuse.r = 1.0f;
   light.Diffuse.g = 1.0f;
   light.Diffuse.b = 1.0f;
   light.Ambient.r = 0.5f;
   light.Ambient.g = 0.5f;
   light.Ambient.b = 0.5f;
   light.Range = 1000;

   g_pD3DDev->SetLight( 0, &light );
   g_pD3DDev->LightEnable( 0, true );
   g_pD3DDev->SetRenderState( D3DRS_LIGHTING, TRUE );
   g_pD3DDev->SetRenderState( D3DRS_AMBIENT, 0x00808080 );   // アンビエントライト

   // ウィンドウ表示---------------------------------------------------------------------------------------------------
   ShowWindow( hWnd, SW_SHOW );/////-----------------------------------------------------------------------------------


   ////////////////////////////
   // メッセージループ--------------------------------------------------------------------------------------------------
   /////
   D3DXMATRIX World;          // 立方体ワールド変換行列
   D3DXMATRIX Rot_X, Rot_Y;   // 立方体回転行列
   D3DXMATRIX Offset;         // 立方体オフセット行列
   D3DXMATRIX AXWorld;   // 軸ワールド変換行列
   D3DXMatrixIdentity( &AXWorld );   // 軸は原点に位置するので単位行列
   D3DXMATRIX View;   // ビュー変換行列
   D3DXMATRIX Persp;   // 射影変換行列
   D3DCOLORVALUE MAmbient = {0.2f, 0.2f, 0.2f, 1.0f};   // マテリアルのアンビエント反射率

   FLOAT Ang = 0.0f;   // 回転角度
   unsigned int i;
   do{
      Sleep(1);
      if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ){ DispatchMessage(&msg);}
      g_pD3DDev->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(40,40,80), 1.0f, 0 );
      g_pD3DDev->BeginScene();

      Ang += 1;

      ///////////////////////////
      // ライト
      ////////
          // ライトの方向回転
          light.Direction.x = 20 * sin( D3DXToRadian(Ang) );
          light.Direction.z = 20 * cos( D3DXToRadian(Ang) );
          g_pD3DDev->SetLight( 0, &light );

      ///////////////////////////
      // 立方体
      ////////
          D3DXMatrixRotationX( &Rot_X, D3DXToRadian(Ang*0.15f) );
          D3DXMatrixRotationY( &Rot_Y, D3DXToRadian(Ang*0.2f)+70.0f );
          D3DXMatrixTranslation( &Offset, 10, 10, 10 );

          D3DXMatrixIdentity( &World );          // 単位行列化
          D3DXMatrixMultiply( &World, &World, &Offset );   // まずオフセットして、
          D3DXMatrixMultiply( &World, &World, &Rot_X );    // X軸回転後
          D3DXMatrixMultiply( &World, &World, &Rot_Y );    // Y軸回転させます。

      // ビュー変換
          // 視点は原点固定ですが、カメラの位置は適当です
      D3DXMatrixLookAtLH(
                  &View,
                  &D3DXVECTOR3(47.5f*cos(D3DXToRadian(Ang*0.7f)), 70.2f*cos(D3DXToRadian(Ang*0.2f)), 56.7f*sin( D3DXToRadian(Ang*1.2f))),
                  &D3DXVECTOR3(0, 0, 0),
                  &D3DXVECTOR3( sin(D3DXToRadian(Ang*0.4f)), 1, 0)
                  );

      // 射影変換
      D3DXMatrixPerspectiveFovLH( &Persp, D3DXToRadian(45), 640.0f/480.0f, 1.0f, 10000.0f);

      // 行列登録
      g_pD3DDev->SetTransform(D3DTS_WORLD, &World);
      g_pD3DDev->SetTransform(D3DTS_VIEW, &View);
      g_pD3DDev->SetTransform(D3DTS_PROJECTION, &Persp);

      // 立方体描画
      for(i=0; i<NumMaterials; i++){
         D3DXMATERIAL *mtrl = (D3DXMATERIAL*)(pMaterials->GetBufferPointer());
                 mtrl->MatD3D.Ambient = MAmbient;
         g_pD3DDev->SetMaterial( &mtrl->MatD3D );
         pMesh->DrawSubset(i); 
      };

      ///////////////////////////
      // 軸
      ////////
      // ワールド変換(単位行列のみ)
      g_pD3DDev->SetTransform(D3DTS_WORLD, &AXWorld);

      for(i=0; i<AX_NumMaterials; i++){      // 軸描画
         D3DXMATERIAL *mtrl = ( (D3DXMATERIAL*)(pAX_Materials->GetBufferPointer()) + i);
                 mtrl->MatD3D.Ambient = MAmbient;
         g_pD3DDev->SetMaterial( &mtrl->MatD3D );
         pAX_Mesh->DrawSubset(i); 
      };

      g_pD3DDev->EndScene();
      g_pD3DDev->Present( NULL, NULL, NULL, NULL );
   }while(msg.message != WM_QUIT);
/////--------------------------------------------------------------------------
   pMesh->Release();
   pAX_Mesh->Release();
   g_pD3DDev->Release();
   g_pD3D->Release();
   return 0;
}
/////

KRNKRS
記事: 40
登録日時: 12年前
連絡を取る:

Re: DrawLine3DとMV1DrawModelで描画した物を交差させたい

#3

投稿記事 by KRNKRS » 8年前

申し訳ありません。
コードを貼っているつもりになっていました。

[ModelView.cpp]

コード:

#include "ModelView.h"
#include "globalValues.h"

//コンストラクタ,デストラクタ略
int ModelView::Initialize() 
{ 
    m_modelHandle = MV1LoadModel("test.mv1");
    if (m_modelHandle == -1)
    {
        return DXLIB_FAILURE;
    }
    MV1SetUseZBuffer(m_modelHandle, true);
    MV1SetWriteZBuffer(m_modelHandle, true);
    MV1SetVisible(m_modelHandle, true);
    position = VECTOR_ZERO;
    rotate = VECTOR_ZERO;
    return DXLIB_SUCCESS;
}

const void ModelView::Draw()
{
    MV1SetPosition(m_modelHandle, position);
    MV1SetRotationXYZ(m_modelHandle, rotate);
    MV1DrawModel(m_modelHandle);
}
[grid.cpp]

コード:

//Initialize,コンストラクタ,デストラクタ略
const void Grid::Draw()
{
    //GRID_HALFSIZE : 100
    //GRID_SPACE : 10
    //グリッド描画
    for (float x = -GRID_HALFSIZE; x <= GRID_HALFSIZE; x += GRID_SPACE)
    {
        axisX.start = { x, -GRID_HALFSIZE, 0 };
        axisX.end = { x, GRID_HALFSIZE , 0 };
        axisX.color = static_cast<int>(x) != 0 ? COLOR_WHITE : COLOR_BLUE;
        DrawLine3D(axisX.start, axisX.end, axisX.color);
    }
    for (float y = -GRID_HALFSIZE; y <= GRID_HALFSIZE; y += GRID_SPACE)
    {
        axisY.start = { -GRID_HALFSIZE, y, 0 };
        axisY.end = { GRID_HALFSIZE , y, 0 };
        axisY.color = static_cast<int>(y) != 0 ? COLOR_WHITE : COLOR_RED;
        DrawLine3D(axisY.start, axisY.end, axisY.color);
    }
    axisZ.color = COLOR_GREEN;
    axisZ.start = {0, 0, -GRID_HALFSIZE };
    axisZ.end = { 0, 0, GRID_HALFSIZE };
    DrawLine3D(axisZ.start, axisZ.end, axisZ.color);
}
[main.cpp]

コード:

#include "main.h"
#include "globalValues.h"

int Initialize()
{
    //ウィンドウ設定
    ChangeWindowMode(true);
    SetWindowSizeChangeEnableFlag(false);
    SetGraphMode(DEFAULT_CLIENT_SIZE_X, DEFAULT_CLIENT_SIZE_Y, COLOR_BIT)
    if (DxLib_Init() != DXLIB_SUCCESS)
    {
        return DXLIB_FAILURE;
    }
    SetDrawScreen(DX_SCREEN_BACK);

    //ライト設定
    SetUseLighting(true);
    ChangeLightTypeDir(VGet(-1, -1, -1));
    SetLightEnable(true);

    //カメラ設定
    SetCameraNearFar(CAMERA_NEAR, CAMERA_FAR);  //0.1f, 300.0f
    SetupCamera_Perspective(FOV);  //60度(PI / 3.0f)
    SetCameraPositionAndTargetAndUpVec(VGet(50, 100, 100), VECTOR_ZERO, VECTOR_Z_AXIS);

    //クラス初期化
    m_modelView.Initialize();

    return DXLIB_SUCCESS;
}

const void Draw()
{
    ClearDrawScreen();
    {
        m_grid.Draw();
        m_modelView.Draw();
    }
    ScreenFlip();
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    Initialize();

    //メインループ
    while (ProcessMessage() == DXLIB_SUCCESS)
    {
        Draw();
    }
    DxLib_End();
    return DXLIB_SUCCESS;
}

と成りのトトロ

Re: DrawLine3DとMV1DrawModelで描画した物を交差させたい

#4

投稿記事 by と成りのトトロ » 8年前

ルールの一読をお願い致します。。
ルールのテンプレートです。(皆さんこういう感じに書かれています)
[1] 質問文
 [1.1] 自分が今行いたい事は何か
 [1.2] どのように取り組んだか(プログラムコードがある場合記載)
 [1.3] どのようなエラーやトラブルで困っているか(エラーメッセージが解る場合は記載)
 [1.4] 今何がわからないのか、知りたいのか

[2] 環境  
 [2.1] OS : Windows, Linux等々
 [2.2] コンパイラ名 : VC++ 2008EE, Borand C++, gcc等々

[3] その他
 ・どの程度C言語を理解しているか
 ・ライブラリを使っている場合は何を使っているか
------------------------------------------------------------------------------------
プロジェクトファイルとヘッダーもお送りください。お願い致します。出来ればモデルも。

KRNKRS
記事: 40
登録日時: 12年前
連絡を取る:

Re: DrawLine3DとMV1DrawModelで描画した物を交差させたい

#5

投稿記事 by KRNKRS » 8年前

[1]についてはNo.1,3にて記述されているので割愛します。
[2.1]Windos7 Home Premium
[2.2]VisualStudio2015 C++
[3]C++使用は2,3ヶ月程度でクラスやポインタが分かってきたかな位のレベルです(あくまで自己評価の上ですが)。
ライブラリはDXライブラリのみです。

こちらの諸事情によりプロジェクトファイルやヘッダー、モデルをお送りすることができません。
申し訳ありません。

と成りのトトロ

Re: DrawLine3DとMV1DrawModelで描画した物を交差させたい

#6

投稿記事 by と成りのトトロ » 8年前

DirectX,DxLibに詳しい方がいらしゃいますのでがアドバイスがあるでしょう。

>(グリッド->モデルの順に描画しています)
逆順でも変わらないのですか。

KRNKRS
記事: 40
登録日時: 12年前
連絡を取る:

Re: DrawLine3DとMV1DrawModelで描画した物を交差させたい

#7

投稿記事 by KRNKRS » 8年前

逆だとグリッドが必ず手前に表示されます

Math

Re: DrawLine3DとMV1DrawModelで描画した物を交差させたい

#8

投稿記事 by Math » 8年前

本家”DXライブラリ置き場掲示板”で聞かれたら良いと思いますよ!

KRNKRS
記事: 40
登録日時: 12年前
連絡を取る:

Re: DrawLine3DとMV1DrawModelで描画した物を交差させたい

#9

投稿記事 by KRNKRS » 8年前

解決しました
・SetUseZBuffer3D
・SetWriteZBuffer3D
を有効化すれば大丈夫でした。
質問内で「使用してもだめだった」というのは私の勘違いだったようです。
混乱させてしまい申し訳ありませんでした。

閉鎖

“C言語何でも質問掲示板” へ戻る