samples/3D: (#992) Added acquired input / 3D demo 'walkAround'
authorJerome St-Louis <jerome@ecere.com>
Wed, 19 Feb 2014 08:28:41 +0000 (03:28 -0500)
committerJerome St-Louis <jerome@ecere.com>
Wed, 19 Feb 2014 08:28:41 +0000 (03:28 -0500)
- ecere/gfx/Object: Added missing null pointer checks

ecere/src/gfx/3D/Object.ec
samples/3D/walkAround/walkAround.ec [new file with mode: 0644]
samples/3D/walkAround/walkAround.epj [new file with mode: 0644]

index 268bf2d..73855dd 100644 (file)
@@ -634,7 +634,7 @@ public:
             children.Remove(child);
             child.Free(displaySystem);
          }
-         if(flags.ownMesh)
+         if(flags.ownMesh && mesh)
          {
             DisplaySystem meshDisplaySystem = mesh.displaySystem;
             mesh.Free(0);
@@ -1071,7 +1071,7 @@ public:
 
             mesh.Unlock(flags);
          }
-         if(freeMesh)
+         if(freeMesh && objectMesh)
          {
             if(objectMesh.displaySystem)
                objectMesh.displaySystem.RemoveMesh(objectMesh);
diff --git a/samples/3D/walkAround/walkAround.ec b/samples/3D/walkAround/walkAround.ec
new file mode 100644 (file)
index 0000000..5af0fcf
--- /dev/null
@@ -0,0 +1,304 @@
+import "ecere"
+
+class WalkAroundApp : GuiApplication
+{
+   driver = "OpenGL";
+   // driver = "Direct3D";
+   timerResolution = 60;
+   appName = "3D Walkaround Sample";
+   Time lastTime;
+   bool wasProcessingMoves;
+
+   bool Cycle(bool idle)
+   {
+      bool processMoves = form && form.acquiredInput;
+      if(processMoves)
+      {
+         Time time = GetTime(), diffTime;
+         int xd = 0, yd = 0;
+         MouseButtons buttons;
+         if(wasProcessingMoves != processMoves)
+         {
+            lastTime = time;
+            GetMouseState(&buttons, &xd, &yd);
+         }
+         diffTime = time - lastTime;
+         lastTime = time;
+         GetMouseState(&buttons, &xd, &yd);
+         if(form)
+         {
+            bool updateCamera = false;
+            float speed = 50;
+            float cameraSpeed = 0.5;
+            Vector3D movement { };
+            Euler orientation = camera.orientation;
+            Euler euler = orientation;
+            euler.roll = 0;
+            orientation.roll = 0;
+
+            euler.yaw -= xd * cameraSpeed;
+            euler.pitch -= yd * cameraSpeed;
+            if(GetKeyState(right)) euler.yaw   -= diffTime * cameraSpeed;
+            if(GetKeyState(left))  euler.yaw   += diffTime * cameraSpeed;
+            if(GetKeyState(up))    euler.pitch -= diffTime * cameraSpeed;
+            if(GetKeyState(down))  euler.pitch += diffTime * cameraSpeed;
+            euler.pitch = Min(Max(euler.pitch, Degrees { -89.9 }), Degrees { 89.9 });
+            if(orientation.yaw != euler.yaw || orientation.pitch != euler.pitch || orientation.roll != euler.roll)
+            {
+               camera.orientation = euler;
+               updateCamera = true;
+            }
+
+            if(GetKeyState(e))                  movement.y -= diffTime * speed;
+            if(GetKeyState(c))                  movement.y += diffTime * speed;
+            if(GetKeyState(s) || buttons.right) movement.z -= diffTime * speed;
+            if(GetKeyState(w) || buttons.left)  movement.z += diffTime * speed;
+            if(GetKeyState(a))                  movement.x -= diffTime * speed;
+            if(GetKeyState(d))                  movement.x += diffTime * speed;
+            if(movement.x || movement.y || movement.z)
+            {
+               camera.Move(movement);
+               updateCamera = true;
+            }
+
+            if(updateCamera)
+            {
+               camera.Update();
+               form.Update(null);
+            }
+         }
+      }
+      wasProcessingMoves = processMoves;
+      return true;
+   }
+};
+
+define app = (WalkAroundApp)__thisModule.application;
+
+Camera camera
+{
+   fixed,
+   position = Vector3D { 0, -100, -200 },
+   orientation = Euler { 0, 0, 0 },
+   fov = 70;
+};
+
+Light light
+{
+   diffuse = white;
+   specular = white;
+   orientation = Euler { 0, 70 };
+};
+
+define width = 10;
+define height = 10;
+define tileSize = 30;
+define gap = 5;
+
+class WalkAroundForm : Window
+{
+   caption = "3D Walkaround Sample";
+   background = black;
+
+   borderStyle = sizable;
+   hasMaximize = true;
+   hasMinimize = true;
+   hasClose = true;
+   clientSize = { 632, 438 };
+
+   Array<Material> materials { size = 8 };
+   Array<int> map { size = width * height };
+   Array<int> elv { size = width * height };
+   Array<Color> colors { [ black, red, green, blue, cyan, magenta, white, gray, orange, yellow, brown, aquamarine, goldenrod ] };
+   Array<Cube> cubes { };
+
+   Material sideMat { opacity = 0.5f, diffuse = teal, ambient = teal, flags = { doubleSided = true, translucent = true } };
+   Material dolphin1Mat { opacity = 1.0f, diffuse = skyBlue, ambient = skyBlue };
+   Material dolphin2Mat { opacity = 1.0f, diffuse = lightGray, ambient = lightGray };
+   Object dolphinModel { };
+   Object dolphin1 { };
+   Object dolphin2 { };
+   Cube cube { };
+   Array<Bitmap> textures { };
+   bool acquiredInput;
+
+   WalkAroundForm()
+   {
+      RandomSeed(1234);
+      GenerateMap();
+   }
+
+   void GenerateMap()
+   {
+      int i;
+      for(i = 0; i < map.count; i++)
+      {
+         int num = map[i] = GetRandom(0, 7);
+         elv[i] = GetRandom(1, 100);
+      }
+   }
+
+   bool OnLoadGraphics()
+   {
+      Bitmap textureFile { };
+      int i, x, y;
+      PrimitiveGroup group;
+
+      dolphinModel.Load(":dolphin.3ds", null, displaySystem);
+      dolphinModel.Merge(displaySystem);
+      dolphinModel.mesh.ApplyMaterial(null);
+
+      dolphin1.Duplicate(dolphinModel);
+      dolphin1.transform.position = { -20, -50, 10 };
+      dolphin1.transform.scaling = { 0.2, 0.2, 0.2 };
+      dolphin1.UpdateTransform();
+      dolphin1.material = dolphin1Mat;
+
+      dolphin2.Duplicate(dolphinModel);
+      dolphin2.transform.position = { 60, -30, -5 };
+      dolphin2.transform.scaling = { 0.2, 0.2, 0.2 };
+      dolphin2.UpdateTransform();
+      dolphin2.material = dolphin2Mat;
+
+      if(textureFile.Load(":texture1.pcx", null, null))
+      {
+         int count = 8;
+         int height = textureFile.height / count;
+         for(i = 0; i < count; i++)
+         {
+            Bitmap tex { };
+            tex.Allocate(null, textureFile.width, height, 0, pixelFormat888, false);
+            tex.Grab(textureFile, 0, i * height);
+            tex.MakeMipMaps(displaySystem);
+            textures.Add(tex);
+
+            materials[i] =
+            {
+               ambient = white;
+               diffuse = white;
+               baseMap = tex;
+               opacity = 1.0f;
+            };
+         }
+      }
+      delete textureFile;
+
+      for(y = 0; y < height; y++)
+      {
+         for(x = 0; x < width; x++)
+         {
+            int ix = y * width + x;
+            int num = map[ix];
+            int xs = -((tileSize+gap) * width) / 2;
+            int ys = -((tileSize+gap) * height) / 2;
+            float h = elv[ix];
+            Cube cube { };
+
+            PrimitiveGroup face;
+            cubes.Add(cube);
+            cube.Create(displaySystem);
+            cube.flags.translucent = true;
+
+            for(face = cube.mesh.groups.first; face; face = face.next)
+               face.material = face.prev ? sideMat : materials[num];
+            cube.mesh.ApplyTranslucency(cube);
+            cube.transform.position = { x * (tileSize + gap), -h/2, y * (tileSize + gap) };
+            cube.transform.scaling = { tileSize, h, tileSize };
+            cube.transform.orientation = Euler { 0, 0, 0 };
+            cube.UpdateTransform();
+         }
+      }
+      return true;
+   }
+
+   void OnUnloadGraphics()
+   {
+      for(c : cubes)
+         c.Free(displaySystem);
+      dolphinModel.Free(displaySystem);
+      dolphin1.Free(displaySystem);
+      dolphin2.Free(displaySystem);
+      cubes.Free();
+   }
+
+   void OnResize(int w, int h)
+   {
+      camera.Setup(w, h, null);
+      camera.Update();
+   }
+
+   void OnRedraw(Surface surface)
+   {
+      surface.Clear(depthBuffer);
+      display.SetCamera(surface, camera);
+      display.SetLight(0, light);
+      display.ambient = Color { 100, 100, 100 };
+
+      for(c : cubes)
+         display.DrawObject(c);
+
+      display.DrawObject(dolphin1);
+      display.DrawObject(dolphin2);
+
+      display.SetCamera(surface, null);
+
+      if(!acquiredInput)
+      {
+         surface.foreground = white;
+         surface.WriteTextf(50, 50, "Press I to acquire mouse Input, F for Full screen.");
+      }
+   }
+
+   bool OnKeyHit(Key key, unichar ch)
+   {
+      switch(key)
+      {
+         case escape: Destroy(0); break;
+         case wheelDown:
+            camera.Move({ 0, -4, 0 });
+            camera.Update();
+            Update(null);
+            break;
+         case wheelUp:
+            camera.Move({ 0, 4, 0 });
+            camera.Update();
+            Update(null);
+            break;
+         case i:
+         {
+            acquiredInput ^= true;
+            AcquireInput(acquiredInput);
+            Update(null);
+            break;
+         }
+         case f:
+         {
+            bool fullScreen = !app.fullScreen;
+            AcquireInput(false);
+            if(fullScreen)
+            {
+               anchor = { 0, 0, 0, 0 };
+               borderStyle = none;
+            }
+            else
+            {
+               borderStyle = sizable;
+               nativeDecorations = true;
+               hasMaximize = true;
+               hasMinimize = true;
+               hasClose = true;
+               state = normal;
+               anchor = { };
+               clientSize = { 632, 438 };
+               position = position;
+            }
+            app.fullScreen = fullScreen;
+            AcquireInput(acquiredInput);
+            break;
+         }
+      }
+      return true;
+   }
+}
+
+WalkAroundForm form {};
diff --git a/samples/3D/walkAround/walkAround.epj b/samples/3D/walkAround/walkAround.epj
new file mode 100644 (file)
index 0000000..a2c813d
--- /dev/null
@@ -0,0 +1,41 @@
+{
+   "Version" : 0.2,
+   "ModuleName" : "walkAround",
+   "Options" : {
+      "Warnings" : "All",
+      "TargetType" : "Executable",
+      "TargetFileName" : "walkAround",
+      "Libraries" : [
+         "ecere"
+      ]
+   },
+   "Configurations" : [
+      {
+         "Name" : "Debug",
+         "Options" : {
+            "Debug" : true,
+            "Optimization" : "None",
+            "PreprocessorDefinitions" : [
+               "_DEBUG"
+            ],
+            "FastMath" : false
+         }
+      },
+      {
+         "Name" : "Release",
+         "Options" : {
+            "Debug" : false,
+            "Optimization" : "Speed",
+            "FastMath" : true
+         }
+      }
+   ],
+   "Files" : [
+      "walkAround.ec"
+   ],
+   "ResourcesPath" : "",
+   "Resources" : [
+      "../terrainCameraDemo/res/texture1.pcx",
+      "../ModelViewer/models/dolphin.3ds"
+   ]
+}