//******************************************************************************* void CWaterEnvMap::initTestVB() { _TestVB.setPreferredMemory(CVertexBuffer::AGPPreferred, true); _TestVB.setName("TestVB"); _TestVB.clearValueEx(); _TestVB.addValueEx (CVertexBuffer::Position, CVertexBuffer::Float3); _TestVB.addValueEx (CVertexBuffer::TexCoord0, CVertexBuffer::Float3); _TestVB.initEx(); _TestVB.setNumVertices(TEST_VB_NUM_SEGMENT * 2 * (TEST_VB_NUM_SLICE + 1)); _TestIB.setFormat(NL_DEFAULT_INDEX_BUFFER_FORMAT); _TestIB.setNumIndexes(3 * TEST_VB_NUM_TRIS); { CVertexBufferReadWrite vbrw; CIndexBufferReadWrite ibrw; _TestVB.lock(vbrw); _TestIB.lock(ibrw); uint triIndex = 0; for(uint k = 0; k < TEST_VB_NUM_SEGMENT; ++k) { float theta = 2 * (float) (NLMISC::Pi * (double) k / (double) TEST_VB_NUM_SEGMENT); for(uint l = 0; l <= TEST_VB_NUM_SLICE; ++l) { float phi = (float) (NLMISC::Pi / 2 * (1 - 2 * (double) l / (double) TEST_VB_NUM_SLICE)); CVector pos; pos.sphericToCartesian(1.f, theta, phi); #define VERT_INDEX(k, l) ((l) + ((k) % TEST_VB_NUM_SEGMENT) * (TEST_VB_NUM_SLICE + 1)) vbrw.setVertexCoord(VERT_INDEX(k, l), pos); vbrw.setValueFloat3Ex(CVertexBuffer::TexCoord0, VERT_INDEX(k, l), pos); if (l != TEST_VB_NUM_SLICE) { ibrw.setTri(3 * triIndex++, VERT_INDEX(k, l), VERT_INDEX(k + 1, l), VERT_INDEX(k + 1, l + 1)); ibrw.setTri(3 * triIndex++, VERT_INDEX(k, l), VERT_INDEX(k + 1, l + 1), VERT_INDEX(k, l + 1)); } } } nlassert(triIndex == TEST_VB_NUM_TRIS); } }
//******************************************************************************* void CWaterEnvMap::initFlattenVB() { _FlattenVB.setPreferredMemory(CVertexBuffer::AGPPreferred, true); _FlattenVB.setName("Flatten VB"); _FlattenVB.clearValueEx(); _FlattenVB.addValueEx (CVertexBuffer::Position, CVertexBuffer::Float3); _FlattenVB.addValueEx (CVertexBuffer::TexCoord0, CVertexBuffer::Float3); _FlattenVB.initEx(); nlctassert(FVB_NUM_SIDES % 4 == 0); // number of sides must be a multiple of 4 so that sections sides will align with corners _FlattenVB.setNumVertices(FVB_NUM_VERTS); _FlattenIB.setFormat(NL_DEFAULT_INDEX_BUFFER_FORMAT); _FlattenIB.setNumIndexes(3 * FVB_NUM_TRIS); { CVertexBufferReadWrite vbrw; CIndexBufferReadWrite ibrw; _FlattenVB.lock(vbrw); _FlattenIB.lock(ibrw); for(uint l = 0; l < FVB_NUM_SIDES; ++l) { double angle = NLMISC::Pi * 0.25 + 2 * NLMISC::Pi * (double) l / (double) FVB_NUM_SIDES; for(uint k = 0; k < FVB_NUM_SECTIONS + 1; ++k) { double radius = (double) k / (double) (FVB_NUM_SECTIONS - 1); float x = (float) (radius * cos(angle)); float y = (float) (radius * sin(angle)); if (k < FVB_NUM_SECTIONS) { ibrw.setTri(3 * 2 * (k + (l * FVB_NUM_SECTIONS)), getFVBVertex(k, l), getFVBVertex(k + 1, l + 1), getFVBVertex(k + 1, l)); ibrw.setTri(3 * (2 * (k + (l * FVB_NUM_SECTIONS)) + 1), getFVBVertex(k, l), getFVBVertex(k, l + 1), getFVBVertex(k + 1, l + 1)); } else { uint side = l / (FVB_NUM_SIDES / 4); switch(side) { case 0: // top x /= y; y = 1.f; break; case 1: // left y /= -x; x = -1.f; break; case 2: // bottom x /= -y; y = -1.f; break; case 3: // right y /= x; x = 1.f; break; default: nlassert(0); break; } } CVector dir; //dir.sphericToCartesian(1.f, (float) angle, (float) (NLMISC::Pi * 0.5 * acos(std::max(0.f, (1.f - (float) k / (FVB_NUM_SECTIONS - 1)))))); dir.sphericToCartesian(1.f, (float) angle, (float) acos(std::min(1.f, (float) k / (FVB_NUM_SECTIONS - 1)))); vbrw.setValueFloat3Ex(CVertexBuffer::Position, getFVBVertex(k, l), x, 0.5f, y); vbrw.setValueFloat3Ex(CVertexBuffer::TexCoord0, getFVBVertex(k, l), -dir.x, dir.z, -dir.y); } } } }