RenderViewer::RenderViewer() { mLayout = new MGUI::Layout(NULL, NULL); mTextBox = new MGUI::TextBox(NULL, mLayout); mTextBox->SetAlign(MGUI::eAlign::LEFT | MGUI::eAlign::BOTTOM); // create grid mesh mGridMesh = new Mesh(); SubMesh * pMeshBuffer = mGridMesh->NewSubMesh(); pMeshBuffer->GetRenderOp()->vertexDeclarations[0].AddElement(eVertexSemantic::POSITION, eVertexType::FLOAT2); pMeshBuffer->GetRenderOp()->vertexBuffers[0] = HWBufferManager::Instance()->NewVertexBuffer(2 * sizeof(float), (GRID_SIZE + 1) * 2 * 2); int index = 0; float * data = (float *)pMeshBuffer->GetRenderOp()->vertexBuffers[0]->Lock(eLockFlag::WRITE); { float _s = -GRID_SIZE / 2 * METER_LEN; float _e = GRID_SIZE / 2 * METER_LEN; float y = _s; float dy = METER_LEN; for (int i = 0; i < GRID_SIZE + 1; ++i) { data[index++] = _s; data[index++] = y; data[index++] = _e; data[index++] = y; y += dy; } float x = _s; float dx = METER_LEN; for (int i = 0; i < GRID_SIZE + 1; ++i) { data[index++] = x; data[index++] = _s; data[index++] = x; data[index++] = _e; x += dx; } } pMeshBuffer->GetRenderOp()->vertexBuffers[0]->Unlock(); pMeshBuffer->GetRenderOp()->primCount = (GRID_SIZE + 1) * 2; pMeshBuffer->GetRenderOp()->primType = ePrimType::LINE_LIST; ShaderFX * pShaderFX = ShaderFXManager::Instance()->Load("Grid", "Grid.mfx"); d_assert(pShaderFX != NULL); pMeshBuffer->SetShaderFX(pShaderFX); mGridMesh->SetLocalAabb(Aabb::Infinite); Layout(); World::Instance()->E_RenderEnd += new cListener0<RenderViewer>(this, &RenderViewer::OnUpdate); }
void MeshGroup::_genMesh(const Array<Mesh *> & arr, int first, int last, bool hasLightingColor) { MeshSourcePtr source = arr[0]->GetSource(); Mesh * mesh = new Mesh; for (int i = 0; i < source->GetMeshBufferCount(); ++i) { SubMesh * submesh = mesh->NewSubMesh(); VertexBufferPtr srcVB = source->GetMeshBuffer(i)->GetRenderOp()->vertexBuffers[0]; IndexBufferPtr srcIB = source->GetMeshBuffer(i)->GetRenderOp()->indexBuffer; int p_offset = source->GetMeshBuffer(i)->GetRenderOp()->vertexDeclarations[0].GetElementOffset(eVertexSemantic::POSITION); int n_offset = source->GetMeshBuffer(i)->GetRenderOp()->vertexDeclarations[0].GetElementOffset(eVertexSemantic::NORMAL); int stride = srcVB->GetStride(); VertexBufferPtr vb = HWBufferManager::Instance()->NewVertexBuffer(stride, srcVB->GetCount() * (last - first)); const char * v_src = (const char *)srcVB->Lock(eLockFlag::READ); char * v_dest = (char *)vb->Lock(eLockFlag::WRITE); for (int j = first; j < last; ++j) { const Mat4 & worldTM = arr[j]->GetWorldTM(); bool hasScale = arr[j]->GetWorldScale() != Float3(1, 1, 1); for (int k = 0; k < srcVB->GetCount(); ++k) { memcpy(v_dest, v_src, stride); Float3 * position = (Float3 *)(v_dest + p_offset); position->TransformA(worldTM); if (n_offset != -1) { Float3 * normal = (Float3 *)(v_dest + n_offset); normal->TransformN(worldTM); if (hasScale) { normal->Normalize(); } } v_dest += stride; v_src += stride; } } vb->Unlock(); srcVB->Unlock(); IndexBufferPtr ib = HWBufferManager::Instance()->NewIndexBuffer(srcIB->GetCount() * (last - first)); int startVertex = 0; const short * i_src = (const short *)srcIB->Lock(eLockFlag::READ); char * i_dest = (char *)ib->Lock(eLockFlag::WRITE); for (int j = first; j < last; ++j) { for (int k = 0; k < srcIB->GetCount(); ++k) { *i_dest++ = (*i_src++) + startVertex; } startVertex += srcVB->GetCount(); } ib->Unlock(); srcIB->Unlock(); submesh->GetRenderOp()->vertexDeclarations[0] = source->GetMeshBuffer(i)->GetRenderOp()->vertexDeclarations[0]; submesh->GetRenderOp()->vertexBuffers[0] = vb; submesh->GetRenderOp()->indexBuffer = ib; submesh->GetRenderOp()->primCount = ib->GetCount() / 3; submesh->GetRenderOp()->primType = ePrimType::TRIANGLE_LIST; if (hasLightingColor) { int count = submesh->GetRenderOp()->vertexBuffers[0]->GetCount(); submesh->GetRenderOp()->vertexDeclarations[LIGHTING_COLOR_STREAM].AddElement(eVertexSemantic::LIGHTING_COLOR, eVertexType::UBYTE4); submesh->GetRenderOp()->vertexBuffers[LIGHTING_COLOR_STREAM] = HWBufferManager::Instance()->NewVertexBuffer(4, count); Array<Rgba32> lightColors; Rgba32 * data = (Rgba32 *)submesh->GetRenderOp()->vertexBuffers[LIGHTING_COLOR_STREAM]->Lock(eLockFlag::WRITE); for (int j = first; j < last; ++j) { arr[j]->GetLightingColor(lightColors); d_assert (lightColors.Size() > 0); memcpy(data, &lightColors[0], 4 * count); startVertex += count; lightColors.Clear(); } submesh->GetRenderOp()->vertexBuffers[LIGHTING_COLOR_STREAM]->Unlock(); } *submesh->GetMaterial() = *source->GetMeshBuffer(i)->GetMaterial(); submesh->SetMeshShader(source->GetMeshBuffer(i)->GetShader()); } mesh->SetSLMode(hasLightingColor ? eStaticLightingMode::LIGHTING_COLOR : eStaticLightingMode::NONE); mMeshes.PushBack(mesh); }
Mesh * PS_MeshSet::_createClinder() { Float3 offset = mCenter; int rings = mRings; float radius = mRadius; float height = mHeight; if (rings < 1) return NULL; Mesh * pMesh = new Mesh; SubMesh * sm = pMesh->NewSubMesh(); int iVertexCount = (rings + 1) * 2; int iIndexCount = rings * 6; int iPrimCount = iIndexCount / 3; d_assert(iIndexCount < 65536); sm->GetRenderOp()->vertexDeclarations[0].AddElement(eVertexSemantic::POSITION, eVertexType::FLOAT3); sm->GetRenderOp()->vertexDeclarations[0].AddElement(eVertexSemantic::TEXCOORD0, eVertexType::FLOAT2); VertexBufferPtr buffer = HWBufferManager::Instance()->NewVertexBuffer(20, iVertexCount); float * vert = (float *)buffer->Lock(eLockFlag::WRITE); { float r_step = (2 * PI / rings); float u_step = 1 / (float)rings; float x, z, rads; for (int i = 0; i <= rings; ++i) { rads = i * r_step; Math::SinCos(rads, z, x); x *= radius; z *= radius; *vert++ = x + offset.x; *vert++ = 0 + offset.y; *vert++ = z + offset.z; *vert++ = i * u_step; *vert++ = 1; *vert++ = x + offset.x; *vert++ = height + offset.y; *vert++ = z + offset.z; *vert++ = i * u_step; *vert++ = 0; } } buffer->Unlock(); IndexBufferPtr ibuffer = HWBufferManager::Instance()->NewIndexBuffer(iIndexCount); short * indices = (short *)ibuffer->Lock(eLockFlag::WRITE); { for (short i = 0; i < rings; ++i) { int j = i * 2; *indices++ = j; *indices++ = j + 1; *indices++ = j + 2; *indices++ = j + 2; *indices++ = j + 1; *indices++ = j + 3; } } ibuffer->Unlock(); sm->GetRenderOp()->vertexBuffers[0] = buffer; sm->GetRenderOp()->indexBuffer = ibuffer; sm->GetRenderOp()->primType = ePrimType::TRIANGLE_LIST; sm->GetRenderOp()->primCount = iPrimCount; sm->GetMaterial()->cullMode = eCullMode::NONE; sm->GetMaterial()->maps[eMapType::DIFFUSE] = RenderHelper::Instance()->GetWhiteTexture(); pMesh->SetLocalAabb(Aabb(Float3(-radius, 0, -radius) + offset, Float3(radius, height, radius) + offset)); return pMesh; }
Mesh * PS_MeshSet::_createCone(bool up) { Float3 offset = mCenter; int rings = (mRings + 3) / 4; int segments = mSegments; float radius = mRadius; float height = mHeight; if (rings < 1) return NULL; Mesh * pMesh = new Mesh; SubMesh * sm = pMesh->NewSubMesh(); float h1 = up ? 0 : height; float h2 = up ? height : 0; int iVertexCount = 1 + (rings * 4 + 1); int iIndexCount = rings * 4 * 3; int iPrimCount = iIndexCount / 3; d_assert(iIndexCount < 65536); sm->GetRenderOp()->vertexDeclarations[0].AddElement(eVertexSemantic::POSITION, eVertexType::FLOAT3); sm->GetRenderOp()->vertexDeclarations[0].AddElement(eVertexSemantic::TEXCOORD0, eVertexType::FLOAT2); VertexBufferPtr buffer = HWBufferManager::Instance()->NewVertexBuffer(20, iVertexCount); float * vert = (float *)buffer->Lock(eLockFlag::WRITE); { float r_step = (PI2 / (rings * 4)); float d_step = (radius * 2 / rings); float u_step = 1 / (float)rings; float v_step = u_step; float x, z; float rads = -PI * 0.25f; *vert++ = 0 + offset.x; *vert++ = h1 + offset.x; *vert++ = 0 + offset.z; *vert++ = 0.5f; *vert++ = 0.5f; // top for (int i = 0; i <= rings; ++i) { Math::SinCos(rads, z, x); x *= radius; z *= radius; *vert++ = x + offset.x; *vert++ = h2 + offset.y; *vert++ = z + offset.z; *vert++ = i * u_step; *vert++ = 0; rads += r_step; } // right for (int i = 1; i <= rings; ++i) { Math::SinCos(rads, z, x); x *= radius; z *= radius; *vert++ = x + offset.x; *vert++ = h2 + offset.y; *vert++ = z + offset.z; *vert++ = 1; *vert++ = i * v_step; rads += r_step; } // bottom for (int i = 1; i <= rings; ++i) { Math::SinCos(rads, z, x); x *= radius; z *= radius; *vert++ = x + offset.x; *vert++ = h2 + offset.y; *vert++ = z + offset.z; *vert++ = 1 - i * u_step; *vert++ = 1; rads += r_step; } // left for (int i = 1; i <= rings; ++i) { Math::SinCos(rads, z, x); x *= radius; z *= radius; *vert++ = x + offset.x; *vert++ = h2 + offset.y; *vert++ = z + offset.z; *vert++ = 0; *vert++ = 1 - i * u_step; rads += r_step; } } buffer->Unlock(); IndexBufferPtr ibuffer = HWBufferManager::Instance()->NewIndexBuffer(iIndexCount); short * indices = (short *)ibuffer->Lock(eLockFlag::WRITE); { for (short i = 0; i < rings * 4; ++i) { *indices++ = i + 1; *indices++ = 0; *indices++ = i + 2; } } ibuffer->Unlock(); sm->GetRenderOp()->vertexBuffers[0] = buffer; sm->GetRenderOp()->indexBuffer = ibuffer; sm->GetRenderOp()->primType = ePrimType::TRIANGLE_LIST; sm->GetRenderOp()->primCount = iPrimCount; sm->GetMaterial()->cullMode = eCullMode::NONE; sm->GetMaterial()->maps[eMapType::DIFFUSE] = RenderHelper::Instance()->GetWhiteTexture(); pMesh->SetLocalAabb(Aabb(Float3(-radius, 0, -radius) + offset, Float3(radius, height, radius) + offset)); return pMesh; }
Mesh * PS_MeshSet::_createSphere() { Float3 offset = mCenter; int rings = mRings; int segments = mSegments; float radius = mRadius; if (rings < 1 || segments < 1) return NULL; Mesh * pMesh = new Mesh; SubMesh * sm = pMesh->NewSubMesh(); int iVertexCount = (rings + 1) * (segments + 1); int iIndexCount = rings * segments * 6; int iPrimCount = iIndexCount / 3; d_assert(iIndexCount < 65536); sm->GetRenderOp()->vertexDeclarations[0].AddElement(eVertexSemantic::POSITION, eVertexType::FLOAT3); sm->GetRenderOp()->vertexDeclarations[0].AddElement(eVertexSemantic::TEXCOORD0, eVertexType::FLOAT2); VertexBufferPtr buffer = HWBufferManager::Instance()->NewVertexBuffer(20, iVertexCount); float * vert = (float *)buffer->Lock(eLockFlag::WRITE); { float fTileRingAngle = (PI / rings); float fTileSegAngle = (PI * 2 / segments); float u_step = 1 / (float)rings; float v_step = 1 / (float)segments; float r; short i, j; Float3 pos; for (i = 0; i <= rings; ++i) { r = radius * Math::Sin(i * fTileRingAngle); pos.y = radius * Math::Cos(i * fTileRingAngle); for (j = 0; j <= segments; ++j) { pos.x = r * Math::Cos(j * fTileSegAngle); pos.z = r * Math::Sin(j * fTileSegAngle); *vert++ = pos.x + offset.x; *vert++ = pos.y + offset.y; *vert++ = pos.z + offset.z; *vert++ = i * u_step; *vert++ = j * v_step; } } } buffer->Unlock(); IndexBufferPtr ibuffer = HWBufferManager::Instance()->NewIndexBuffer(iIndexCount); short * indices = (short *)ibuffer->Lock(eLockFlag::WRITE); { short row = 0, row_n = 0; short i, j; for (i = 0; i < rings; ++i) { row_n = row + segments + 1; for (j = 0; j < segments; ++j) { *indices++ = row + j; *indices++ = row + j + 1; *indices++ = row_n + j; *indices++ = row_n + j; *indices++ = row + j + 1; *indices++ = row_n + j + 1; } row += segments + 1; } } ibuffer->Unlock(); sm->GetRenderOp()->vertexBuffers[0] = buffer; sm->GetRenderOp()->indexBuffer = ibuffer; sm->GetRenderOp()->primCount = iPrimCount; sm->GetRenderOp()->primType= ePrimType::TRIANGLE_LIST; sm->GetMaterial()->maps[eMapType::DIFFUSE] = RenderHelper::Instance()->GetWhiteTexture(); pMesh->SetLocalAabb(Aabb(Float3(-radius, -radius, -radius) + offset, Float3(radius, radius, radius) + offset)); return pMesh; }