球の描画
皆さんはDxLibを用いて球を描画する際どのような関数を使いますか?
多くの方は DrawSphere3D という関数を使われると思います。
DrawSphere3D
上記の関数はDxLib内の関数になっておりDxLibを用いて使うことが可能です。
この関数は 中心座標・半径・色・頂点数 を引数に持たせるだけで簡単に球を描画してくれる関数です。
私はこの関数を用いて球を描画していました。
弱点
ですがこの関数では下半分がステージ等に埋もれた時にも下のほうが描画されているということに気づきました。
そうなると見えない場所を描画するといった負荷がかかってきます。
そういう場合に半球(上半分)のみを描画したいと思いませんか。
半球だけ描画する関数なんかあるの?
結論 ありません。
ないなら作る。それがプログラマーです。
今回使う関数がこちら DrawPolygonIndexed3D
この関数は _頂点情報・ポリゴン配列情報・テクスチャハンドル_のみで使うことができます。
#include<DxLib>
#include<vector>
//関数の引数部分にあたる
struct PolygonInfo
{
std::vector<VERTEX3D> vertex;
std::vector<unsigned short> Indices;
}
{
//使用する定数
static const int VERTEX_NUM = 16;//頂点数 2のべき乗を推奨
static const float RADIUS = 100.0f;//半径
static const VECTOR POSITION = {0.0f,0.0f,0.0f};//中心座標
static const float PI = 3.141592;
PolygonInfo polInfo_;
auto& vertexes = polInfo_.vertex;
vertexes.clear();
float radper = (360.0f / VERTEX_NUM)/180.0f *PI;
{
//一番上の頂点を設定する
VERTEX3D vertex = {};
VECTOR pos = POSITION;
pos.y += RADIUS;
vertex.pos = pos;
vertex.norm = VNorm(VSub(vertex.pos, POSITION));
vertex.dif = COLOR_U8(255, 255, 255, 255);
vertex.spc = COLOR_U8(255, 255, 255, 255);
vertex.u = 0.5f;
vertex.v = 0.5f;
vertex.su = vertex.u;
vertex.sv = vertex.v;
vertexes.push_back(vertex);
}
for (int i = 0; i < VERTEX_NUM / 4; i++)
{
float posY = POSITION.y + cosf((i + 1) * radper) * RADIUS;
for (int j = 0; j < VERTEX_NUM; j++)
{
VERTEX3D vertex = {};
VECTOR pos = POSITION;
pos.x = POSITION.x + RADIUS * cosf(radper * j) * sinf((i + 1) * radper);
pos.y =posY;
pos.z = POSITION.z + RADIUS * sinf(radper * j) * sinf((i + 1) * radper);
vertex.pos = pos;
vertex.norm = VNorm(VSub(vertex.pos, POSITION));
vertex.dif = COLOR_U8(255, 255, 255, 255);
vertex.spc = COLOR_U8(255, 255, 255, 255);
vertex.u = (pos.x - POSITION.x) / (RADIUS * 2) + 0.5f;
vertex.v = (pos.z - POSITION.z) / (RADIUS * 2) + 0.5f;
vertex.su = vertex.u;
vertex.sv = vertex.v;
vertexes.push_back(vertex);
}
}
auto& indices = polInfo_.Indices;
indices.clear();
for (int i = 0; i < VERTEX_NUM; i++)
{
indices.push_back(0);
indices.push_back((i + 1) % VERTEX_NUM + 1);
indices.push_back(i + 1);
for (int j = 0; j < VERTEX_NUM / 4 - 1; j++)
{
indices.push_back(j * VERTEX_NUM + i + 1);
indices.push_back(j * VERTEX_NUM + (i + 1) % VERTEX_NUM + 1);
indices.push_back((j + 1) * VERTEX_NUM + (i + 1) % VERTEX_NUM + 1);
indices.push_back(j * VERTEX_NUM + i + 1);
indices.push_back((j + 1) * VERTEX_NUM + (i + 1) % VERTEX_NUM + 1);
indices.push_back((j + 1) * VERTEX_NUM + i + 1);
}
}
DrawPolygonIndexed3D(
vertexes.data(),
static_cast<int>(vertexes.size()),
indices.data(),
static_cast<int>(indices.size())/3,
DX_NONE_GRAPH, //画像のハンドル
TRUE);
}
この結果を見てわかるように裏側が描画されません。これは バックカリング が行われているからです。
裏側を描画したい場合は
SetUseBackCulling(false);
をDrawする前に追加お願いします。
