summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRay <[email protected]>2018-04-01 00:27:20 +0200
committerGitHub <[email protected]>2018-04-01 00:27:20 +0200
commit564baa22d65d6cace2b98d370f1716081830af09 (patch)
treeb3069f737afdb5965038b9d6c8d7363da8a00338
parentb4e2f5b45c22e560bf785cf412154fc32d995e1e (diff)
parent42e64e931b27a27795f471817dc93551f4f752e8 (diff)
downloadraylib-564baa22d65d6cace2b98d370f1716081830af09.tar.gz
raylib-564baa22d65d6cace2b98d370f1716081830af09.zip
Merge pull request #513 from autious/master
Add orthographic 3d rendering mode
-rw-r--r--examples/models/models_orthographic_projection.c112
-rw-r--r--src/core.c71
-rw-r--r--src/raylib.h11
3 files changed, 183 insertions, 11 deletions
diff --git a/examples/models/models_orthographic_projection.c b/examples/models/models_orthographic_projection.c
new file mode 100644
index 00000000..2c2a89d1
--- /dev/null
+++ b/examples/models/models_orthographic_projection.c
@@ -0,0 +1,112 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Show the difference between perspective and orthographic projection
+*
+* This program is heavily based on the geometric objects example
+*
+* This example has been created using raylib 1.0 (www.raylib.com)
+* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+* Copyright (c) 2014 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#define FOVY_PERSPECTIVE 45.0f
+#define WIDTH_ORTHOGRAPHIC 10.0f
+
+int main()
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ int screenWidth = 800;
+ int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - geometric shapes");
+
+ // Define the camera to look into our 3d world
+ Camera camera = {{ 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, FOVY_PERSPECTIVE, CAMERA_PERSPECTIVE };
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ // TODO: Update your variables here
+ //----------------------------------------------------------------------------------
+ //
+
+ // Input
+ //----------------------------------------------------------------------------------
+ if(IsKeyPressed(KEY_SPACE))
+ {
+ if(camera.type == CAMERA_PERSPECTIVE)
+ {
+ camera.fovy = WIDTH_ORTHOGRAPHIC;
+ camera.type = CAMERA_ORTHOGRAPHIC;
+ }
+ else
+ {
+ camera.fovy = FOVY_PERSPECTIVE;
+ camera.type = CAMERA_PERSPECTIVE;
+ }
+ }
+
+
+ // Draw
+ //----------------------------------------------------------------------------------
+
+
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ Begin3dMode(camera);
+
+ DrawCube((Vector3){-4.0f, 0.0f, 2.0f}, 2.0f, 5.0f, 2.0f, RED);
+ DrawCubeWires((Vector3){-4.0f, 0.0f, 2.0f}, 2.0f, 5.0f, 2.0f, GOLD);
+ DrawCubeWires((Vector3){-4.0f, 0.0f, -2.0f}, 3.0f, 6.0f, 2.0f, MAROON);
+
+ DrawSphere((Vector3){-1.0f, 0.0f, -2.0f}, 1.0f, GREEN);
+ DrawSphereWires((Vector3){1.0f, 0.0f, 2.0f}, 2.0f, 16, 16, LIME);
+
+ DrawCylinder((Vector3){4.0f, 0.0f, -2.0f}, 1.0f, 2.0f, 3.0f, 4, SKYBLUE);
+ DrawCylinderWires((Vector3){4.0f, 0.0f, -2.0f}, 1.0f, 2.0f, 3.0f, 4, DARKBLUE);
+ DrawCylinderWires((Vector3){4.5f, -1.0f, 2.0f}, 1.0f, 1.0f, 2.0f, 6, BROWN);
+
+ DrawCylinder((Vector3){1.0f, 0.0f, -4.0f}, 0.0f, 1.5f, 3.0f, 8, GOLD);
+ DrawCylinderWires((Vector3){1.0f, 0.0f, -4.0f}, 0.0f, 1.5f, 3.0f, 8, PINK);
+
+ DrawGrid(10, 1.0f); // Draw a grid
+
+ End3dMode();
+
+ DrawFPS(10, 10);
+
+ DrawText("Press Spacebar to switch camera type", 10, 40, 24, BLACK);
+
+ if(camera.type == CAMERA_ORTHOGRAPHIC)
+ {
+ DrawText("Orthographic", 10, 65, 24, BLACK);
+ }
+ else if(camera.type == CAMERA_PERSPECTIVE)
+ {
+ DrawText("Perspective", 10, 65, 24, BLACK);
+ }
+
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/src/core.c b/src/core.c
index 89a6f924..99cc3c5a 100644
--- a/src/core.c
+++ b/src/core.c
@@ -919,13 +919,26 @@ void Begin3dMode(Camera camera)
rlPushMatrix(); // Save previous matrix, which contains the settings for the 2d ortho projection
rlLoadIdentity(); // Reset current matrix (PROJECTION)
- // Setup perspective projection
float aspect = (float)screenWidth/(float)screenHeight;
- double top = 0.01*tan(camera.fovy*0.5*DEG2RAD);
- double right = top*aspect;
+
+ if(camera.type == CAMERA_PERSPECTIVE)
+ {
+ // Setup perspective projection
+ double top = 0.01*tan(camera.fovy*0.5*DEG2RAD);
+ double right = top*aspect;
+
+ rlFrustum(-right, right, -top, top, 0.01, 1000.0);
+ }
+ else if(camera.type == CAMERA_ORTHOGRAPHIC)
+ {
+ // Setup orthographic projection
+ double top = camera.fovy/2.0;
+ double right = top*aspect;
+
+ rlOrtho(-right,right,-top,top, 0.01, 1000.0);
+ }
// NOTE: zNear and zFar values are important when computing depth buffer values
- rlFrustum(-right, right, -top, top, 0.01, 1000.0);
rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
@@ -1013,22 +1026,48 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera)
TraceLog(LOG_DEBUG, "Device coordinates: (%f, %f, %f)", deviceCoords.x, deviceCoords.y, deviceCoords.z);
- // Calculate projection matrix from perspective
- Matrix matProj = MatrixPerspective(camera.fovy*DEG2RAD, ((double)GetScreenWidth()/(double)GetScreenHeight()), 0.01, 1000.0);
-
// Calculate view matrix from camera look at
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
+ Matrix matProj;
+
+ if(camera.type == CAMERA_PERSPECTIVE)
+ {
+ // Calculate projection matrix from perspective
+ matProj = MatrixPerspective(camera.fovy*DEG2RAD, ((double)GetScreenWidth()/(double)GetScreenHeight()), 0.01, 1000.0);
+ }
+ else if(camera.type == CAMERA_ORTHOGRAPHIC)
+ {
+ float aspect = (float)screenWidth/(float)screenHeight;
+ double top = camera.fovy/2.0;
+ double right = top*aspect;
+ // Calculate projection matrix from orthographic
+ matProj = MatrixOrtho(-right, right, -top, top, 0.01, 1000.0);
+ }
+
// Unproject far/near points
Vector3 nearPoint = rlUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 0.0f }, matProj, matView);
Vector3 farPoint = rlUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 1.0f }, matProj, matView);
+ // Unproject the mouse cursor in the near plane.
+ // We need this as the source position because orthographic projects, compared to perspect doesn't have a
+ // convergence point, meaning that the "eye" of the camera is more like a plane than a point.
+ Vector3 cameraPlanePointerPos = rlUnproject((Vector3){ deviceCoords.x, deviceCoords.y, -1.0f }, matProj, matView);
+
// Calculate normalized direction vector
Vector3 direction = Vector3Subtract(farPoint, nearPoint);
direction = Vector3Normalize(direction);
+ if(camera.type == CAMERA_PERSPECTIVE)
+ {
+ ray.position = camera.position;
+ }
+ else if(camera.type == CAMERA_ORTHOGRAPHIC)
+ {
+ ray.position = cameraPlanePointerPos;
+ }
+
// Apply calculated vectors to ray
- ray.position = camera.position;
ray.direction = direction;
return ray;
@@ -1038,7 +1077,21 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera)
Vector2 GetWorldToScreen(Vector3 position, Camera camera)
{
// Calculate projection matrix (from perspective instead of frustum
- Matrix matProj = MatrixPerspective(camera.fovy*DEG2RAD, (double)GetScreenWidth()/(double)GetScreenHeight(), 0.01, 1000.0);
+ Matrix matProj;
+
+ if(camera.type == CAMERA_PERSPECTIVE)
+ {
+ // Calculate projection matrix from perspective
+ matProj = MatrixPerspective(camera.fovy*DEG2RAD, ((double)GetScreenWidth()/(double)GetScreenHeight()), 0.01, 1000.0);
+ }
+ else if(camera.type == CAMERA_ORTHOGRAPHIC)
+ {
+ float aspect = (float)screenWidth/(float)screenHeight;
+ double top = camera.fovy/2.0;
+ double right = top*aspect;
+ // Calculate projection matrix from orthographic
+ matProj = MatrixOrtho(-right, right, -top, top, 0.01, 1000.0);
+ }
// Calculate view matrix from camera look at (and transpose it)
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
diff --git a/src/raylib.h b/src/raylib.h
index c94f4477..f40124e9 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -398,12 +398,19 @@ typedef struct SpriteFont {
CharInfo *chars; // Characters info data
} SpriteFont;
+// Camera projection modes
+typedef enum {
+ CAMERA_PERSPECTIVE = 0,
+ CAMERA_ORTHOGRAPHIC
+} CameraType;
+
// Camera type, defines a camera position/orientation in 3d space
typedef struct Camera {
Vector3 position; // Camera position
Vector3 target; // Camera target it looks-at
Vector3 up; // Camera up vector (rotation over its axis)
- float fovy; // Camera field-of-view apperture in Y (degrees)
+ float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic
+ CameraType type; // Camera type, controlling projection type, either CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC.
} Camera;
// Camera2D type, defines a 2d camera
@@ -726,7 +733,7 @@ RLAPI void BeginTextureMode(RenderTexture2D target); // Initializes
RLAPI void EndTextureMode(void); // Ends drawing to render texture
// Screen-space-related functions
-RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position
+RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position
RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position for a 3d world space position
RLAPI Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix)