libnoise と OpenGL を使用して地形生成に取り組んでいます。見た目のように、やや複雑な通常の生成アルゴリズムを作成しました。
list = glGenLists(1);
glNewList(list, GL_COMPILE);
glPushAttrib(GL_ENABLE_BIT);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glDisable(GL_TEXTURE_2D);
glPushMatrix();
int h = 256;
int w = 256;
float h1 = 0.0f;
float h2 = 0.0f;
float h3 = 0.0f;
float div = 7.0f;
float lPos[] = { 128, image.GetHeight() + 15.0f, 128, 1.0f };
for (int x = 1; x < h; x++)
{
glColor3ub(139, 69, 19);
glLightfv(GL_LIGHT0, GL_POSITION, lPos);
glBegin(GL_TRIANGLE_STRIP);
for (int z = 1; z < w; z++)
{
h1 = image.GetValue(x, z).red / 7.0f;
h2 = image.GetValue(x + 1, z).red / 7.0f;
Vector3 t1, t2, t3;
Vector3 v1, v2, v3, v4, v5, v6;
t1 = Vector3(x, h1, z);
t2 = Vector3(x - 1, image.GetValue(x - 1, z).red / div, z);
t3 = Vector3(x, image.GetValue(x, z - 1).red / div, z - 1);
v1 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));
t2 = Vector3(x + 1, image.GetValue(x + 1, z).red / div, z);
t3 = Vector3(x, image.GetValue(x, z + 1).red / div, z + 1);
v2 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));
t2 = Vector3(x + 1, image.GetValue(x + 1, z).red / div, z);
t3 = Vector3(x + 1, image.GetValue(x + 1, z - 1).red / div, z - 1);
v3 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));
t2 = Vector3(x + 1, image.GetValue(x + 1, z - 1).red / div, - 1);
t3 = Vector3(x , image.GetValue(x, z - 1).red / div, z - 1);
v4 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));
t2 = Vector3(x - 1, image.GetValue(x - 1, z + 1).red / div, z + 1);
t3 = Vector3(x - 1, image.GetValue(x - 1, z).red / div, z);
v5 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));
t2 = Vector3(x - 1, image.GetValue(x - 1, z + 1).red / div, z + 1);
t3 = Vector3(x, image.GetValue(x, z + 1).red / div, z + 1);
v6 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));
Vector3 normal1 = Vector3::Normalize((v1 + v2 + v3 + v4 + v5 + v6) / 6);
glNormal3f(normal1.X, normal1.Y, normal1.Z);
glVertex3f(x, h1, z);
t1 = Vector3(x + 1, h2, z);
t2 = Vector3(x + 1 - 1, image.GetValue(x + 1 - 1, z).red / div, z);
t3 = Vector3(x + 1, image.GetValue(x + 1, z - 1).red / div, z - 1);
v1 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));
t2 = Vector3(x + 1 + 1, image.GetValue(x + 1 + 1, z).red / div, z);
t3 = Vector3(x + 1, image.GetValue(x + 1, z + 1).red / div, z + 1);
v2 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));
t2 = Vector3(x + 1 + 1, image.GetValue(x + 1 + 1, z).red / div, z);
t3 = Vector3(x + 1 + 1, image.GetValue(x + 1 + 1, z - 1).red / div, z - 1);
v3 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));
t2 = Vector3(x + 1 + 1, image.GetValue(x + 1 + 1, z - 1).red / div, -1);
t3 = Vector3(x + 1, image.GetValue(x + 1, z - 1).red / div, z - 1);
v4 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));
t2 = Vector3(x + 1 - 1, image.GetValue(x + 1 - 1, z + 1).red / div, z + 1);
t3 = Vector3(x + 1 - 1, image.GetValue(x + 1 - 1, z).red / div, z);
v5 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));
t2 = Vector3(x + 1 - 1, image.GetValue(x + 1 - 1, z + 1).red / div, z + 1);
t3 = Vector3(x + 1, image.GetValue(x + 1, z + 1).red / div, z + 1);
v6 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));
normal1 = Vector3::Normalize((v1 + v2 + v3 + v4 + v5 + v6) / 6);
glNormal3f(normal1.X, normal1.Y, normal1.Z);
glVertex3f(x + 1, h2, z);
}
glEnd();
}
glPopMatrix();
glPopAttrib();
glEndList();
ご覧のとおり、周囲の 6 つの面の法線を平均化して法線を生成し、滑らかなシェーディングを実現しています。問題は、一部の部分 (特に地形の低い部分) で、ビットが黒っぽいままで、奇妙に陰影が付けられていることです。ここに写真があります:
私の通常の世代の仕組み:
ノート!!!!Yを描いたのはZのことでした、ごめんなさい!
画像は次のとおりです。
緑は最初の頂点です。
赤は 2 番目の頂点 (x 軸上の最初の + 1)
です。黄色は隣接する三角形の点です。
X は外側のループです。
Z は内側のループです。
を使用しているのでGL_TRIANGLE_STRIP
、次の反復で三角形を作成するために必要なのは 2 つの頂点だけです。
したがって...各三角形が構築されます:
p1 = (x, 画像の高さ, z)
p2 = (x + 1, 画像の高さ, z)
そして次の反復 (z++)
p3 = (x、像高、z + 1)
p4 = (x + 1、像高、z + 1)
...等。