void Render(IntPtr pParam) { // Attention! // The main thing you should keep in the mind is that matrix multiplication order should be // reversed when passing matrix to pRender3D->SetMatrix or pRender3D->MultMatrix methods. // camera setup // here and below matrix multiplication order is reversed TMatrix4x4 set = TMatrix4x4.MatrixRotate((float)(Math.Sin(uiCounter / 150f) * 65f), new TPoint3(0f, 1f, 0f)) * TMatrix4x4.MatrixRotate(30f, new TPoint3(1f, 0f, 0f)) * TMatrix4x4.MatrixTranslate(new TPoint3(0f, 0f, -2.5f)) * TMatrix4x4.MatrixIdentity; pRender3D.SetMatrix(ref set); // Draw entire scene. // draw tiled grass floor // Some low-level things will be shown below, mainly for education purpose. // Of course, there is a way to do the same thing without using low-level API. pRender3D.PushMatrix(); // save current matrix // multiplicates current matrix with given one TMatrix4x4 mult = TMatrix4x4.MatrixScale(new TPoint3(8f, 8f, 8f)) * TMatrix4x4.MatrixRotate(-90f, new TPoint3(1f, 0f, 0f)); pRender3D.MultMatrix(ref mult); set = TMatrix4x4.MatrixScale(new TPoint3(8f, 8f, 8f)); pCoreRenderer.SetMatrix(ref set, E_MATRIX_TYPE.MT_TEXTURE); // a simple way to tile texture // Here is the way for instant rendering of any custom geometry. pTexGrass.Bind(0); // current texture setup pRender3D.Draw(ref desc, E_CORE_RENDERER_DRAW_MODE.CRDM_TRIANGLE_STRIP, 4); set = TMatrix4x4.MatrixIdentity; pCoreRenderer.SetMatrix(ref set, E_MATRIX_TYPE.MT_TEXTURE); // return texture matrix to its normal state pRender3D.PopMatrix(); // return previous matrix // Ok, that's all with low-level things in this example. // turn off backface culling because of trees leaves (they will look better) and sprites rendering (we want txt and owl to be visible from both sides) pRender3D.ToggleBackfaceCulling(false); // draw some trees // turn on alpha test for correct rendering of trees leaves pRender3D.ToggleAlphaTest(true); // precalculate similar for all trees transformation part to make it faster TMatrix4x4 tree_rotate_and_scale = TMatrix4x4.MatrixScale(new TPoint3(2f, 2f, 2f)) * TMatrix4x4.MatrixRotate(-90f, new TPoint3(1f, 0f, 0f)); // some copy-pasted code for each tree to draw all of them pRender3D.PushMatrix(); mult = tree_rotate_and_scale * TMatrix4x4.MatrixTranslate(new TPoint3(2.3f, 0f, 1.2f)); pRender3D.MultMatrix(ref mult); pTexTree1.Bind(0); // way to set current texture pMeshTree1.Draw(); pRender3D.PopMatrix(); pRender3D.PushMatrix(); mult = tree_rotate_and_scale * TMatrix4x4.MatrixTranslate(new TPoint3(-2.15f, 0f, -1.75f)); pRender3D.MultMatrix(ref mult); pTexTree1.Bind(0); pMeshTree1.Draw(); pRender3D.PopMatrix(); pRender3D.PushMatrix(); mult = tree_rotate_and_scale * TMatrix4x4.MatrixTranslate(new TPoint3(-0.5f, 0f, -1f)); pRender3D.MultMatrix(ref mult); pTexTree2.Bind(0); pMeshTree2.Draw(); pRender3D.PopMatrix(); pRender3D.PushMatrix(); mult = tree_rotate_and_scale * TMatrix4x4.MatrixTranslate(new TPoint3(0.75f, 0f, 0.1f)); pRender3D.MultMatrix(ref mult); pTexTree2.Bind(0); pMeshTree2.Draw(); pRender3D.PopMatrix(); pRender3D.PushMatrix(); mult = tree_rotate_and_scale * TMatrix4x4.MatrixTranslate(new TPoint3(0.5f, 0f, -1.5f)); pRender3D.MultMatrix(ref mult); pTexTree3.Bind(0); pMeshTree3.Draw(); pRender3D.PopMatrix(); pRender3D.PushMatrix(); mult = tree_rotate_and_scale * TMatrix4x4.MatrixTranslate(new TPoint3(-0.75f, 0f, 0.25f)); pRender3D.MultMatrix(ref mult); pTexTree3.Bind(0); pMeshTree3.Draw(); pRender3D.PopMatrix(); pRender3D.ToggleAlphaTest(false); // we don't need alphatest anymore // we use blending for further font and sprite rendering pRender3D.ToggleBlending(true); // draw text pRender3D.PushMatrix(); const string txt = "The very basics of the 3D graphics."; const float txt_scale = 0.005f; uint w, h; pFont.GetTextDimensions(txt, out w, out h); mult = TMatrix4x4.MatrixScale(new TPoint3(txt_scale, txt_scale, txt_scale)) * // tex is drawing in rather huge coordinates, so we will downscale it TMatrix4x4.MatrixTranslate(new TPoint3(0f, h / 2f * txt_scale, 1.25f)); // move text up on half of it's height and little forward pRender3D.MultMatrix(ref mult); TColor4 c = TColor4.ColorOfficialOrange(); pRender3D.SetColor(ref c); // set current color pFont.Draw3D(txt); c = TColor4.ColorWhite(); pRender3D.SetColor(ref c); // return color back to white pRender3D.PopMatrix(); // draw owl animated sprite as billboard pRender3D.PushMatrix(); // here is a way to make a billboard sprite in 3D TMatrix4x4 cur_matrix = new TMatrix4x4(); pRender3D.GetMatrix(out cur_matrix); // first we must get current matrix // now we set new current matrix TMatrix4x4 matr = TMatrix4x4.MatrixScale(new TPoint3((owlGoLeft ? -1f : 1f), 1f, 1f)) * // the way to mirror sprite picture TMatrix4x4.MatrixBillboard( // this function will remove any rotation from given matrix TMatrix4x4.MatrixScale(new TPoint3(0.35f, 0.35f, 0.35f)) * TMatrix4x4.MatrixTranslate(new TPoint3(owlX, 1f, -0.35f)) * cur_matrix); pRender3D.SetMatrix(ref matr); pTexOwl.Draw3D((uiCounter / 2) % 15); // fast way to render texture as square plane with size 1.0 pRender3D.PopMatrix(); pRender3D.ToggleBlending(false); pRender3D.ToggleBackfaceCulling(true); // turn backface culling back on here // draw monster pRender3D.PushMatrix(); TPoint3 extents = new TPoint3(); pModelZard.GetExtents(out extents); // retrieves dimensions of the model (ex. extents.x is a half of the models width) // here we will let monster go circles const float speed = 1.2f; float angle = uiCounter / 75f; TPoint3 circle_center = new TPoint3(1f, 0f, 0.25f); mult = TMatrix4x4.MatrixRotate(-90f, new TPoint3(1f, 0f, 0f)) * TMatrix4x4.MatrixRotate(angle * 180f / (float)Math.PI, new TPoint3(0f, -1f, 0f)) * TMatrix4x4.MatrixTranslate(new TPoint3((float)(Math.Cos(angle) * speed), extents.z, (float)(Math.Sin(angle) * speed)) + circle_center); pRender3D.MultMatrix(ref mult); pTexZard.Bind(0); // this model uses frame based animation, we just need to switch between meshes uint meshes_count; pModelZard.MeshsCount(out meshes_count); pModelZard.DrawMesh(uiCounter % meshes_count); pRender3D.PopMatrix(); }
void Render(IntPtr pParam) { // camera setup TMatrix4x4 mat = TMatrix4x4.MatrixIdentity; transform.Clear(ref mat); mat = TMatrix4x4.MatrixTranslate(new TPoint3(0f, -4.5f, -4f - (float)Math.Abs(Math.Sin(uiCounter / 250f)) * 5f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixRotate(15f + (float)Math.Cos(uiCounter / 200f) * 10f, new TPoint3(1f, 0f, 0f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixRotate(uiCounter / 5f, new TPoint3(0f, 1f, 0f)); transform.MultLocal(ref mat); mat = transform.Top; pRender3D.SetMatrix(ref mat); // set light in the world coordinate system pLightDirect.Update(); // draw floor p_render.Unbind(E_ENGINE_OBJECT_TYPE.EOT_MATERIAL); // unbind last material from previous frame for (int i = -5; i < 5; ++i) { for (int j = -5; j < 5; ++j) { transform.Push(); mat = TMatrix4x4.MatrixTranslate(new TPoint3(i * 5f, 0f, j * 5f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixScale(new TPoint3(5f, 5f, 5f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixRotate(-90f, new TPoint3(1f, 0f, 0f)); transform.MultLocal(ref mat); mat = transform.Top; pRender3D.SetMatrix(ref mat); pTexFloor.Draw3D(); transform.Pop(); } } // draw desk TPoint3 desk_extents, extents; pMdlDesk.GetExtents(out desk_extents); TPoint3 desk_pos = new TPoint3(0f, desk_extents.z * 10f, 0f); transform.Push(); mat = TMatrix4x4.MatrixTranslate(desk_pos); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixScale(new TPoint3(10f, 10f, 10f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixRotate(-90f, new TPoint3(1f, 0f, 0f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixRotate(180f, new TPoint3(0f, 0f, 1f)); transform.MultLocal(ref mat); mat = transform.Top; pRender3D.SetMatrix(ref mat); pMdlDesk.Draw(); transform.Pop(); // draw chair pMdlChair.GetExtents(out extents); transform.Push(); mat = TMatrix4x4.MatrixTranslate(new TPoint3(-1.5f, extents.z * 5f, 4.5f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixScale(new TPoint3(5f, 5f, 5f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixRotate(-90f, new TPoint3(1f, 0f, 0f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixRotate(65f, new TPoint3(0f, 0f, 1f)); transform.MultLocal(ref mat); mat = transform.Top; pRender3D.SetMatrix(ref mat); pMdlChair.Draw(); transform.Pop(); // draw music box pMdlMusicBox.GetExtents(out extents); transform.Push(); mat = TMatrix4x4.MatrixTranslate(desk_pos + new TPoint3(-2.75f, extents.y * 6f, -1f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixScale(new TPoint3(3f, 3f, 3f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixRotate(-90f, new TPoint3(1f, 0f, 0f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixRotate(25f, new TPoint3(0f, 0f, 1f)); transform.MultLocal(ref mat); mat = transform.Top; pRender3D.SetMatrix(ref mat); pMdlMusicBox.Draw(); transform.Pop(); // draw table-lamp pMdlLamp.GetExtents(out extents); transform.Push(); mat = TMatrix4x4.MatrixTranslate(desk_pos + new TPoint3(3.75f, extents.z * 8f - 0.2f, -1f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixScale(new TPoint3(4f, 4f, 4f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixRotate(-90f, new TPoint3(1f, 0f, 0f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixRotate(-150f, new TPoint3(0f, 0f, 1f)); transform.MultLocal(ref mat); mat = transform.Top; pRender3D.SetMatrix(ref mat); pMdlLamp.Draw(); // here we set light position in the coordinate space of the lamp (object space) TPoint3 light_pos = new TPoint3(0.35f, 0f, extents.z - 0.15f); pLightSpot.SetPosition(ref light_pos); pLightSpot.Update(); // draw light halo bool is_light_active; pLightSpot.GetEnabled(out is_light_active); if (is_light_active) { pRender3D.ToggleLighting(false); pRender3D.SetBlendMode(E_BLENDING_EFFECT.BE_ADD); pRender3D.ToggleBlending(true); TColor4 col = TColor4.ColorYellow(200); pRender3D.SetColor(ref col); mat = TMatrix4x4.MatrixTranslate(light_pos + new TPoint3(0f, 0f, -0.1f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixScale(new TPoint3(0.25f, 0.25f, 0.25f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixBillboard(transform.Top); pRender3D.SetMatrix(ref mat); pTexLight.Draw3D(); pRender3D.ToggleLighting(true); } transform.Pop(); // draw snow globe and church pSnowGlobe.GetExtents(out extents); transform.Push(); mat = TMatrix4x4.MatrixTranslate(desk_pos + new TPoint3(1f, extents.z * 4f + 0.75f, 0.5f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixScale(new TPoint3(2f, 2f, 2f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixRotate(-90f, new TPoint3(1f, 0f, 0f)); transform.MultLocal(ref mat); transform.Push(); mat = TMatrix4x4.MatrixTranslate(new TPoint3(0f, 0f, 0.125f)); transform.MultLocal(ref mat); mat = TMatrix4x4.MatrixScale(new TPoint3(0.7f, 0.7f, 0.7f)); transform.MultLocal(ref mat); mat = transform.Top; pRender3D.SetMatrix(ref mat); pModelChurch.Draw(); transform.Pop(); mat = transform.Top; pRender3D.SetMatrix(ref mat); pSnowGlobe.Draw(); transform.Pop(); }