Dx_libのDrawPolygon3Dの仕様について

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

Dx_libのDrawPolygon3Dの仕様について

#1

投稿記事 by ようすけ » 13年前

ただいまDx_libを使用してプログラミングを行っています。
言語はC++でVisualC++2010を用いています。
過去の掲示板などを参考に3Dの背景についてプログラミングを勉強しているのですが、
過去の掲示板の質問の中で以下のようなコードが紹介されていました。

コード:

#include "DxLib.h" 
#include <cstdlib> 

// 行列計算 
void CalcRotateMatrix(MATRIX *pMatResult, const VECTOR& pos, const VECTOR &rot) 
{ 
    // 移動 
    MATRIX m; 
    CreateTranslationMatrix(pMatResult, pos.x, pos.y, pos.z); 

    // 回転Z 
    CreateRotationZMatrix(&m, rot.z); 
    CreateMultiplyMatrix(pMatResult, &m, pMatResult); 

    // 回転Y 
    CreateRotationYMatrix(&m, rot.y); 
    CreateMultiplyMatrix(pMatResult, &m, pMatResult); 

    // 回転X 
    CreateRotationXMatrix(&m, rot.x); 
    CreateMultiplyMatrix(pMatResult, &m, pMatResult); 
} 

// ワールド行列を変更して表示 
void DrawTransRotatePolygon1(int img, VERTEX_3D *vertex, int vertexNum, const VECTOR& pos, const VECTOR &rot) 
{ 
    // 行列計算 
    MATRIX  matResult, matOrgWorld; 
    CalcRotateMatrix(&matResult, pos, rot); 
    GetTransformToWorldMatrix(&matOrgWorld); 

    // 描画 
    SetTransformToWorld(&matResult); 
    DrawPolygon3DBase(vertex, vertexNum, DX_PRIMTYPE_TRIANGLESTRIP, img, FALSE); 
    SetTransformToWorld(&matOrgWorld); 
} 

// 頂点を変更して表示 
void DrawTransRotatePolygon2(int img, VERTEX_3D *vertex, int vertexNum, const VECTOR& pos, const VECTOR &rot) 
{ 
    // 行列計算 
    MATRIX  matResult; 
    CalcRotateMatrix(&matResult, pos, rot); 

    // 座標計算 
    VERTEX_3D *v = (VERTEX_3D*)std::malloc(sizeof(VERTEX_3D) * vertexNum); 
    if(v == NULL)   return; 

    for(int n=0; n<vertexNum; ++n) 
    { 
        v[n] = vertex[n]; 
        VectorTransform(&v[n].pos, &v[n].pos, &matResult); 
    } 

    // 描画 
    DrawPolygon3DBase(v, vertexNum, DX_PRIMTYPE_TRIANGLESTRIP, img, FALSE); 

    std::free(v); 
} 

// カメラ設定 
void SetDefaultCamera() 
{ 
    MATRIX cam; 
    VECTOR vCamPos = { 0, 0, 100 }, vCamAt = { 0, 0, 0 }, vCamUp = { 0, 1, 0 }; 
    CreateLookAtMatrix(&cam, &vCamPos, &vCamAt, &vCamUp); 
    SetTransformToView(&cam); 
} 

// 頂点情報 
const float basePosX = 0.f, basePosY = 0.f, basePosZ = 0.f, baseLengh = 20.f; 
VERTEX_3D   vertex[] = 
{ 
    { basePosX - baseLengh, basePosY + baseLengh, basePosZ, 255, 255, 255, 255, 0.f, 0.f }, 
    { basePosX - baseLengh, basePosY - baseLengh, basePosZ, 255, 255, 255, 255, 0.f, 1.f }, 
    { basePosX + baseLengh, basePosY + baseLengh, basePosZ, 255, 255, 255, 255, 1.f, 0.f }, 
    { basePosX + baseLengh, basePosY - baseLengh, basePosZ, 255, 255, 255, 255, 1.f, 1.f }, 
}; 


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hP, LPSTR lpC, int nC) 
{ 
    //  初期化 
    ChangeWindowMode(TRUE); 
    if(DxLib_Init() == -1) return(-1); 
    SetDrawScreen(DX_SCREEN_BACK); 

    int img = LoadGraph("test.png"); 
    const float pi = 3.1415926535f, offsetRotate = 1.f * pi / 180.f; 
    VECTOR p1 = { 20, 0, 0 }, p2 = { -20, 0, 0 }, rot = { 0 }; 
     
    // カメラ設定 
    SetDefaultCamera(); 

    //メインループ 
    while(ProcessMessage() == 0) 
    { 
        char key[256]; 
        GetHitKeyStateAll(key); 
        if(key[KEY_INPUT_ESCAPE])   break; 

        if(key[KEY_INPUT_DOWN])     rot.x += offsetRotate; 
        if(key[KEY_INPUT_UP])       rot.x -= offsetRotate; 
        if(key[KEY_INPUT_LEFT])     rot.y += offsetRotate; 
        if(key[KEY_INPUT_RIGHT])    rot.y -= offsetRotate; 

        ClearDrawScreen(); 
        DrawTransRotatePolygon1(img, vertex, 4, p1, rot); 
        DrawTransRotatePolygon2(img, vertex, 4, p2, rot); 
        ScreenFlip(); 
    } 

    DxLib_End(); 
    return 0; 
} 
この中で気になったのが、DrawTransRotatePolygon1(img, vertex, 4, p1, rot); という1文です。
本来のDx_libのDrawPolygon3Dのリファレンスでは、「PolygonNum × 3 個の頂点データが必要になります。」とあります。
しかし実際に実行すると、きれいに四角形の画像が表示されています。
これは内部で何が起こっているのでしょうか。
最初、「4端の点と中心から4つの3角形のテクスチャを作っているのでは」とも思いましたが中心の座標がないため
どのような形でテクスチャが作られているのかがわかりません。
お教えいただければ幸いです。

史上最悪のデスペナ
記事: 521
登録日時: 14年前

Re: Dx_libのDrawPolygon3Dの仕様について

#2

投稿記事 by 史上最悪のデスペナ » 13年前

ベクトルはご存知ですか?高校生で習う内容なのですが。

こんな感じで二本の矢印があれば平行四辺形が作れるのです
こんな感じ.png
ちらっと見た感じだと、
キー入力で片方のベクトルを回転させていくと四角形が変化しますよ
というプログラムに見えたのですが、あってます?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: Dx_libのDrawPolygon3Dの仕様について

#3

投稿記事 by softya(ソフト屋) » 13年前

DX_PRIMTYPE_TRIANGLESTRIPと指定されていますので、こういう頂点情報の構成になるはずです。
http://msdn.microsoft.com/ja-jp/library ... 85%29.aspx

DrawPolygon3DとDrawPolygon3DBaseは、そういう意味で動作が違います。
DX_PRIMTYPE_TRIANGLELISTと指定するとDrawPolygon3Dと同じ動作になるはずです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ようすけ
記事: 12
登録日時: 13年前

Re: Dx_libのDrawPolygon3Dの仕様について

#4

投稿記事 by ようすけ » 13年前

史上最悪のデスペナ様
お返事ありがとうございます。プログラムの内容はその通りです。
お貼りいただいた画像ですが、リンクが切れていて見ることが出来ません。

softya(ソフト屋)様
お返事ありがとうございます、DX_PRIMTYPE_TRIANGLESTRIPについては良く分かりました。
ですが、張られているURLの説明だと、この場合4つのテクスチャを使用するには6つのベクトルが必要だと書いてあります。
生成されるテクスチャが2枚ならば納得できるのですが、コードではDrawPolygon3DbaseのPolygonNumを4と指定しています。
この場合4枚テクスチャが生成されると理解しているのですが、その場合TRIANGLESTRIPでも頂点情報が足りないのではと思います。
それともそもそもDrawPolygon3Dbaseの理解が間違っているのでしょうか?

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: Dx_libのDrawPolygon3Dの仕様について

#5

投稿記事 by ISLe » 13年前

A,B,C,Dの順で頂点があるとき、TRIANGLESTRIPだと、
A,B,Cでひとつの三角形(ポリゴン)
B,C,Dでひとつの三角形(ポリゴン)
が描画されるということです。

A,B,C,B,C,Dで6つ使ってます。

ようすけ
記事: 12
登録日時: 13年前

Re: Dx_libのDrawPolygon3Dの仕様について

#6

投稿記事 by ようすけ » 13年前

ISLe様
お返事ありがとうございます。
生成するテクスチャが2枚ならそれで納得できるのですが、このコードのように4枚の場合どうなるのでしょう?
ABC,BCD,CDA、DABの4つが生成されて互いに重なっている状態になるのでしょうか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: Dx_libのDrawPolygon3Dの仕様について

#7

投稿記事 by softya(ソフト屋) » 13年前

>ABC,BCD,CDA、DABの4つが生成されて互いに重なっている状態になるのでしょうか?

ストリップのルールで、BCDまでで停止します。
試しに頂点座標を1つ変更してみると4つの頂点で表現されていて2つの三角形から構成される四角形であることがよくわかると思います。

4頂点の位置関係がよくわかる参考素材。
strip.png
strip.png (1.07 KiB) 閲覧数: 3731 回
>生成するテクスチャが2枚ならそれで納得できるのですが、このコードのように4枚の場合どうなるのでしょう?

DrawPolygon3DBaseは2回呼び出されてますので、四角形を2つ書いている事になりますので問題ないです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ようすけ
記事: 12
登録日時: 13年前

Re: Dx_libのDrawPolygon3Dの仕様について

#8

投稿記事 by ようすけ » 13年前

softya(ソフト屋) 様、お返事ありがとうございます。返信が送れて申し訳ありません。

>DrawPolygon3DBaseは2回呼び出されてますので、四角形を2つ書いている事になりますので問題ないです。
それは2枚×2回で4枚ということでしょうか?

私が疑問に思っているところは

コード:

 DrawPolygon3DBase(vertex, vertexNum, DX_PRIMTYPE_TRIANGLESTRIP, img, FALSE); 
のvertexnumに4が入っているところです。
Dx_libの説明ではここにはテクスチャの枚数が入る、ということなのですが
ここを4にしているということは4頂点から4枚のテクスチャが作られているのではないかと理解しています。
DrawPolygon3DBaseは2回呼び出されているので画面上には計8枚のテクスチャがある状態だと捉えているのですが、
それは
>ストリップのルールで、BCDまでで停止します。
とおっしゃるように、4枚描画しようとした結果ルール側で強制的に2枚となり、
4×2回=8枚になるところが2×2回=4枚になる、という解釈でよろしいのでしょうか?

私の疑問に思っている点の説明不足、また分かりづらい説明のせいで混乱させてしまい申し訳ないです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: Dx_libのDrawPolygon3Dの仕様について

#9

投稿記事 by softya(ソフト屋) » 13年前

>のvertexnumに4が入っているところです。
DrawPolygon3Dのパラメータは、PolygonNumで三角形の数ですがDrawPolygon3DBaseはvertexNumなので頂点数です。
4頂点で2つの三角形ですから、ようすけさん的な表現をすれば2つのテクスチャでしょうか。

DrawPolygon3DBaseは2回呼び出されていますので、4頂点で表わされる2つの三角形を2回描画している事になります。
{ basePosX - baseLengh, basePosY + baseLengh, basePosZ, 255, 255, 255, 255, 0.f, 0.f },
{ basePosX - baseLengh, basePosY - baseLengh, basePosZ, 255, 255, 255, 255, 0.f, 1.f },
{ basePosX + baseLengh, basePosY + baseLengh, basePosZ, 255, 255, 255, 255, 1.f, 0.f },
{ basePosX + baseLengh, basePosY - baseLengh, basePosZ+5, 255, 255, 255, 255, 1.f, 1.f },
とかしてもらうと三角形がどう構成されるか把握できると思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ようすけ
記事: 12
登録日時: 13年前

Re: Dx_libのDrawPolygon3Dの仕様について

#10

投稿記事 by ようすけ » 13年前

softya(ソフト屋) 様
お早い返信ありがとうございます、ようやく疑問が解けました。
DrawPolygon3DからDrawPolygon3Dbaseに変わる過程で変数の意味が変わっていたのですね。
おかげさまで謎が解けてようやくすっきりしました、本当にありがとうございます。

閉鎖

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