initial
5
MANIFEST.in
Normal file
|
@ -0,0 +1,5 @@
|
|||
include raylib/*.so
|
||||
exclude raylib/*.a
|
||||
exclude raylib/*.h
|
||||
exclude raylib/*.c
|
||||
exclude raylib/*.o
|
8
README.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
Python Bindings for Raylib
|
||||
|
||||
These bindings use CFFI rather than ctypes. Hopefully this will be faster, the static type knowledge from the C
|
||||
headers will result in fewer bugs, and using the original headers will make it easier to maintain.
|
||||
|
||||
Currently the goal is make usage as similar to the original C as CFFI will allow. There are a few differences
|
||||
you can see in the examples. Making a 'Pythonic' library would be an additional layer on top which hasn't been
|
||||
done yet.
|
BIN
examples/models/models_billboard.png
Normal file
After Width: | Height: | Size: 54 KiB |
74
examples/models/models_billboard.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
# /*******************************************************************************************
|
||||
# *
|
||||
# * raylib [models] example - Drawing billboards
|
||||
# *
|
||||
# * This example has been created using raylib 1.3 (www.raylib.com)
|
||||
# * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
# *
|
||||
# * Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
# *
|
||||
# ********************************************************************************************/
|
||||
|
||||
from raylib import *
|
||||
|
||||
|
||||
# Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
screenWidth = 800
|
||||
screenHeight = 450
|
||||
|
||||
InitWindow(screenWidth, screenHeight, b"raylib [models] example - drawing billboards")
|
||||
|
||||
# Define the camera to look into our 3d world
|
||||
cameraPtr = ffi.new("struct Camera3D *")
|
||||
camera = cameraPtr[0]
|
||||
|
||||
camera.position = [ 5.0, 4.0, 5.0 ]
|
||||
camera.target = [ 0.0, 2.0, 0.0 ]
|
||||
camera.up = [ 0.0, 1.0, 0.0 ]
|
||||
camera.fovy = 45.0
|
||||
camera.type = CAMERA_PERSPECTIVE
|
||||
|
||||
|
||||
bill = LoadTexture(b"resources/billboard.png") # Our texture billboard
|
||||
billPosition = [ 0.0, 2.0, 0.0 ] # Position where draw billboard
|
||||
|
||||
SetCameraMode(camera, CAMERA_ORBITAL) # Set an orbital camera mode
|
||||
|
||||
SetTargetFPS(60) # Set our game to run at 60 frames-per-second
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
||||
# Main game loop
|
||||
while not WindowShouldClose() : # Detect window close button or ESC key
|
||||
# Update
|
||||
#----------------------------------------------------------------------------------
|
||||
UpdateCamera(cameraPtr) # Update camera
|
||||
#----------------------------------------------------------------------------------
|
||||
|
||||
# Draw
|
||||
#----------------------------------------------------------------------------------
|
||||
BeginDrawing()
|
||||
|
||||
ClearBackground(RAYWHITE)
|
||||
|
||||
BeginMode3D(camera)
|
||||
|
||||
DrawBillboard(camera, bill, billPosition, 2.0, WHITE)
|
||||
|
||||
DrawGrid(10, 1.0) # Draw a grid
|
||||
|
||||
EndMode3D()
|
||||
|
||||
DrawFPS(10, 10)
|
||||
|
||||
EndDrawing()
|
||||
#----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
# De-Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
UnloadTexture(bill) # Unload texture
|
||||
|
||||
CloseWindow() # Close window and OpenGL context
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
BIN
examples/models/models_box_collisions.png
Normal file
After Width: | Height: | Size: 22 KiB |
124
examples/models/models_box_collisions.py
Normal file
|
@ -0,0 +1,124 @@
|
|||
# /*******************************************************************************************
|
||||
# *
|
||||
# * raylib [models] example - Detect basic 3d collisions (box vs sphere vs box)
|
||||
# *
|
||||
# * This example has been created using raylib 1.3 (www.raylib.com)
|
||||
# * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
# *
|
||||
# * Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
# *
|
||||
# ********************************************************************************************/
|
||||
|
||||
from raylib import *
|
||||
|
||||
# Initialization
|
||||
# --------------------------------------------------------------------------------------
|
||||
screenWidth = 800
|
||||
screenHeight = 450
|
||||
|
||||
InitWindow(screenWidth, screenHeight, b"raylib [models] example - box collisions")
|
||||
|
||||
# Define the camera to look into our 3d world
|
||||
camera = [[0.0, 10.0, 10.0], [0.0, 0.0, 0.0], [0.0, 1.0, 0.0], 45.0, 0]
|
||||
|
||||
playerPositionPtr = ffi.new("struct Vector3 *", [0.0, 1.0, 2.0])
|
||||
playerPosition = playerPositionPtr[0]
|
||||
|
||||
playerSizePtr = ffi.new("struct Vector3 *", [1.0, 2.0, 1.0])
|
||||
playerSize = playerSizePtr[0]
|
||||
playerColor = GREEN
|
||||
|
||||
enemyBoxPosPtr = ffi.new("struct Vector3 *", [-4.0, 1.0, 0.0])
|
||||
enemyBoxPos = enemyBoxPosPtr[0]
|
||||
enemyBoxSize = ffi.new("struct Vector3 *",[2.0, 2.0, 2.0])
|
||||
|
||||
enemySpherePos = [4.0, 0.0, 0.0]
|
||||
enemySphereSize = 1.5
|
||||
|
||||
collision = False
|
||||
|
||||
SetTargetFPS(60) # Set our game to run at 60 frames-per-second
|
||||
# --------------------------------------------------------------------------------------
|
||||
|
||||
# Main game loop
|
||||
while not WindowShouldClose(): # Detect window close button or ESC key
|
||||
# Update
|
||||
# ----------------------------------------------------------------------------------
|
||||
|
||||
# Move player
|
||||
if IsKeyDown(KEY_RIGHT):
|
||||
playerPosition.x += 0.2
|
||||
elif IsKeyDown(KEY_LEFT):
|
||||
playerPosition.x -= 0.2
|
||||
elif IsKeyDown(KEY_DOWN):
|
||||
playerPosition.z += 0.2
|
||||
elif IsKeyDown(KEY_UP):
|
||||
playerPosition.z -= 0.2
|
||||
|
||||
collision = False
|
||||
|
||||
# Check collisions player vs enemy-box
|
||||
if CheckCollisionBoxes([[playerPosition.x - playerSize.x / 2, playerPosition.y - playerSize.y / 2,
|
||||
playerPosition.z - playerSize.z / 2],
|
||||
[playerPosition.x + playerSize.x / 2, playerPosition.y + playerSize.y / 2,
|
||||
playerPosition.z + playerSize.z / 2]],
|
||||
[[enemyBoxPos.x - enemyBoxSize.x / 2,
|
||||
enemyBoxPos.y - enemyBoxSize.y / 2,
|
||||
enemyBoxPos.z - enemyBoxSize.z / 2],
|
||||
[enemyBoxPos.x + enemyBoxSize.x / 2,
|
||||
enemyBoxPos.y + enemyBoxSize.y / 2,
|
||||
enemyBoxPos.z + enemyBoxSize.z / 2]]):
|
||||
collision = True
|
||||
|
||||
# Check collisions player vs enemy-sphere
|
||||
if CheckCollisionBoxSphere([[playerPosition.x - playerSize.x / 2,
|
||||
playerPosition.y - playerSize.y / 2,
|
||||
playerPosition.z - playerSize.z / 2],
|
||||
[playerPosition.x + playerSize.x / 2,
|
||||
playerPosition.y + playerSize.y / 2,
|
||||
playerPosition.z + playerSize.z / 2]],
|
||||
enemySpherePos, enemySphereSize):
|
||||
collision = True
|
||||
|
||||
if collision:
|
||||
playerColor = RED
|
||||
else:
|
||||
playerColor = GREEN
|
||||
|
||||
# ----------------------------------------------------------------------------------
|
||||
|
||||
# Draw
|
||||
# ----------------------------------------------------------------------------------
|
||||
BeginDrawing()
|
||||
|
||||
ClearBackground(RAYWHITE)
|
||||
|
||||
BeginMode3D(camera)
|
||||
|
||||
# Draw enemy-box
|
||||
DrawCube(enemyBoxPos, enemyBoxSize.x, enemyBoxSize.y, enemyBoxSize.z, GRAY)
|
||||
DrawCubeWires(enemyBoxPos, enemyBoxSize.x, enemyBoxSize.y, enemyBoxSize.z, DARKGRAY)
|
||||
|
||||
# Draw enemy-sphere
|
||||
DrawSphere(enemySpherePos, enemySphereSize, GRAY)
|
||||
DrawSphereWires(enemySpherePos, enemySphereSize, 16, 16, DARKGRAY)
|
||||
|
||||
# Draw player
|
||||
DrawCubeV(playerPosition, playerSize, playerColor)
|
||||
|
||||
DrawGrid(10, 1.0) # Draw a grid
|
||||
|
||||
EndMode3D()
|
||||
|
||||
DrawText(b"Move player with cursors to collide", 220, 40, 20, GRAY)
|
||||
|
||||
DrawFPS(10, 10)
|
||||
|
||||
EndDrawing()
|
||||
# ----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
# De-Initialization
|
||||
# --------------------------------------------------------------------------------------
|
||||
CloseWindow() # Close window and OpenGL context
|
||||
# --------------------------------------------------------------------------------------
|
BIN
examples/models/models_cubicmap.png
Normal file
After Width: | Height: | Size: 403 KiB |
84
examples/models/models_cubicmap.py
Normal file
|
@ -0,0 +1,84 @@
|
|||
# /*******************************************************************************************
|
||||
# *
|
||||
# * raylib [models] example - Cubicmap loading and drawing
|
||||
# *
|
||||
# * This example has been created using raylib 1.8 (www.raylib.com)
|
||||
# * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
# *
|
||||
# * Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
# *
|
||||
# ********************************************************************************************/
|
||||
|
||||
from raylib import *
|
||||
|
||||
|
||||
# Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
screenWidth = 800
|
||||
screenHeight = 450
|
||||
|
||||
InitWindow(screenWidth, screenHeight, b"raylib [models] example - cubesmap loading and drawing")
|
||||
|
||||
# Define the camera to look into our 3d world
|
||||
camera = ffi.new("struct Camera3D *", [[ 16.0, 14.0, 16.0 ], [ 0.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], 45.0, 0 ])
|
||||
|
||||
image = LoadImage(b"resources/cubicmap.png") # Load cubicmap image (RAM)
|
||||
cubicmap = LoadTextureFromImage(image) # Convert image to texture to display (VRAM)
|
||||
|
||||
mesh = GenMeshCubicmap(image, [ 1.0, 1.0, 1.0 ])
|
||||
model = LoadModelFromMesh(mesh)
|
||||
|
||||
# NOTE: By default each cube is mapped to one part of texture atlas
|
||||
texture = LoadTexture(b"resources/cubicmap_atlas.png") # Load map texture
|
||||
model.materials[0].maps[MAP_DIFFUSE].texture = texture # Set map diffuse texture
|
||||
|
||||
mapPosition = [ -16.0, 0.0, -8.0 ] # Set model position
|
||||
|
||||
UnloadImage(image) # Unload cubesmap image from RAM, already uploaded to VRAM
|
||||
|
||||
SetCameraMode(camera[0], CAMERA_ORBITAL) # Set an orbital camera mode
|
||||
|
||||
SetTargetFPS(60) # Set our game to run at 60 frames-per-second
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
||||
# Main game loop
|
||||
while not WindowShouldClose(): # Detect window close button or ESC key
|
||||
|
||||
# Update
|
||||
#----------------------------------------------------------------------------------
|
||||
UpdateCamera(camera) # Update camera
|
||||
#----------------------------------------------------------------------------------
|
||||
|
||||
# Draw
|
||||
#----------------------------------------------------------------------------------
|
||||
BeginDrawing()
|
||||
|
||||
ClearBackground(RAYWHITE)
|
||||
|
||||
BeginMode3D(camera[0])
|
||||
|
||||
DrawModel(model, mapPosition, 1.0, WHITE)
|
||||
|
||||
EndMode3D()
|
||||
|
||||
DrawTextureEx(cubicmap, [ screenWidth - cubicmap.width*4 - 20, 20 ], 0.0, 4.0, WHITE)
|
||||
DrawRectangleLines(screenWidth - cubicmap.width*4 - 20, 20, cubicmap.width*4, cubicmap.height*4, GREEN)
|
||||
|
||||
DrawText(b"cubicmap image used to", 658, 90, 10, GRAY)
|
||||
DrawText(b"generate map 3d model", 658, 104, 10, GRAY)
|
||||
|
||||
DrawFPS(10, 10)
|
||||
|
||||
EndDrawing()
|
||||
#----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
# De-Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
UnloadTexture(cubicmap) # Unload cubicmap texture
|
||||
UnloadTexture(texture) # Unload map texture
|
||||
UnloadModel(model) # Unload map model
|
||||
|
||||
CloseWindow() # Close window and OpenGL context
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
80
examples/models/models_geometric_shapes.c
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [models] example - Draw some basic geometric shapes (cube, sphere, cylinder...)
|
||||
*
|
||||
* 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"
|
||||
|
||||
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 ]
|
||||
camera.position = (Vector3)[ 0.0, 10.0, 10.0 ]
|
||||
camera.target = (Vector3)[ 0.0, 0.0, 0.0 ]
|
||||
camera.up = (Vector3)[ 0.0, 1.0, 0.0 ]
|
||||
camera.fovy = 45.0
|
||||
camera.type = 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
|
||||
#----------------------------------------------------------------------------------
|
||||
|
||||
# Draw
|
||||
#----------------------------------------------------------------------------------
|
||||
BeginDrawing()
|
||||
|
||||
ClearBackground(RAYWHITE)
|
||||
|
||||
BeginMode3D(camera)
|
||||
|
||||
DrawCube((Vector3)[-4.0, 0.0, 2.0], 2.0, 5.0, 2.0, RED)
|
||||
DrawCubeWires((Vector3)[-4.0, 0.0, 2.0], 2.0, 5.0, 2.0, GOLD)
|
||||
DrawCubeWires((Vector3)[-4.0, 0.0, -2.0], 3.0, 6.0, 2.0, MAROON)
|
||||
|
||||
DrawSphere((Vector3)[-1.0, 0.0, -2.0], 1.0, GREEN)
|
||||
DrawSphereWires((Vector3)[1.0, 0.0, 2.0], 2.0, 16, 16, LIME)
|
||||
|
||||
DrawCylinder((Vector3)[4.0, 0.0, -2.0], 1.0, 2.0, 3.0, 4, SKYBLUE)
|
||||
DrawCylinderWires((Vector3)[4.0, 0.0, -2.0], 1.0, 2.0, 3.0, 4, DARKBLUE)
|
||||
DrawCylinderWires((Vector3)[4.5f, -1.0, 2.0], 1.0, 1.0, 2.0, 6, BROWN)
|
||||
|
||||
DrawCylinder((Vector3)[1.0, 0.0, -4.0], 0.0, 1.5f, 3.0, 8, GOLD)
|
||||
DrawCylinderWires((Vector3)[1.0, 0.0, -4.0], 0.0, 1.5f, 3.0, 8, PINK)
|
||||
|
||||
DrawGrid(10, 1.0) # Draw a grid
|
||||
|
||||
EndMode3D()
|
||||
|
||||
DrawFPS(10, 10)
|
||||
|
||||
EndDrawing()
|
||||
#----------------------------------------------------------------------------------
|
||||
]
|
||||
|
||||
# De-Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
CloseWindow() # Close window and OpenGL context
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
||||
return 0
|
||||
]
|
BIN
examples/models/models_geometric_shapes.png
Normal file
After Width: | Height: | Size: 33 KiB |
82
examples/models/models_heightmap.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [models] example - Heightmap loading and drawing
|
||||
*
|
||||
* This example has been created using raylib 1.8 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
int main()
|
||||
[
|
||||
# Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800
|
||||
int screenHeight = 450
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - heightmap loading and drawing")
|
||||
|
||||
# Define our custom camera to look into our 3d world
|
||||
Camera camera = [[ 18.0, 16.0, 18.0 ], [ 0.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], 45.0, 0 ]
|
||||
|
||||
Image image = LoadImage("resources/heightmap.png") # Load heightmap image (RAM)
|
||||
Texture2D texture = LoadTextureFromImage(image) # Convert image to texture (VRAM)
|
||||
|
||||
Mesh mesh = GenMeshHeightmap(image, (Vector3)[ 16, 8, 16 ]) # Generate heightmap mesh (RAM and VRAM)
|
||||
Model model = LoadModelFromMesh(mesh) # Load model from generated mesh
|
||||
|
||||
model.material.maps[MAP_DIFFUSE].texture = texture # Set map diffuse texture
|
||||
Vector3 mapPosition = [ -8.0, 0.0, -8.0 ] # Define model position
|
||||
|
||||
UnloadImage(image) # Unload heightmap image from RAM, already uploaded to VRAM
|
||||
|
||||
SetCameraMode(camera, CAMERA_ORBITAL) # Set an orbital camera mode
|
||||
|
||||
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
|
||||
#----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera) # Update camera
|
||||
#----------------------------------------------------------------------------------
|
||||
|
||||
# Draw
|
||||
#----------------------------------------------------------------------------------
|
||||
BeginDrawing()
|
||||
|
||||
ClearBackground(RAYWHITE)
|
||||
|
||||
BeginMode3D(camera)
|
||||
|
||||
DrawModel(model, mapPosition, 1.0, RED)
|
||||
|
||||
DrawGrid(20, 1.0)
|
||||
|
||||
EndMode3D()
|
||||
|
||||
DrawTexture(texture, screenWidth - texture.width - 20, 20, WHITE)
|
||||
DrawRectangleLines(screenWidth - texture.width - 20, 20, texture.width, texture.height, GREEN)
|
||||
|
||||
DrawFPS(10, 10)
|
||||
|
||||
EndDrawing()
|
||||
#----------------------------------------------------------------------------------
|
||||
]
|
||||
|
||||
# De-Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture) # Unload texture
|
||||
UnloadModel(model) # Unload model
|
||||
|
||||
CloseWindow() # Close window and OpenGL context
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
||||
return 0
|
||||
]
|
BIN
examples/models/models_heightmap.png
Normal file
After Width: | Height: | Size: 95 KiB |
196
examples/models/models_material_pbr.c
Normal file
|
@ -0,0 +1,196 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [models] example - PBR material
|
||||
*
|
||||
* This example has been created using raylib 1.8 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2017 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
|
||||
#define RLIGHTS_IMPLEMENTATION
|
||||
#include "rlights.h"
|
||||
|
||||
#define CUBEMAP_SIZE 512 # Cubemap texture size
|
||||
#define IRRADIANCE_SIZE 32 # Irradiance texture size
|
||||
#define PREFILTERED_SIZE 256 # Prefiltered HDR environment texture size
|
||||
#define BRDF_SIZE 512 # BRDF LUT texture size
|
||||
|
||||
# PBR material loading
|
||||
static Material LoadMaterialPBR(Color albedo, float metalness, float roughness)
|
||||
|
||||
int main()
|
||||
[
|
||||
# Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800
|
||||
int screenHeight = 450
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT) # Enable Multi Sampling Anti Aliasing 4x (if available)
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - pbr material")
|
||||
|
||||
# Define the camera to look into our 3d world
|
||||
Camera camera = [[ 4.0, 4.0, 4.0 ], [ 0.0, 0.5f, 0.0 ], [ 0.0, 1.0, 0.0 ], 45.0, 0 ]
|
||||
|
||||
# Load model and PBR material
|
||||
Model model = LoadModel("resources/pbr/trooper.obj")
|
||||
MeshTangents(&model.mesh)
|
||||
model.material = LoadMaterialPBR((Color)[ 255, 255, 255, 255 ], 1.0, 1.0)
|
||||
|
||||
# Define lights attributes
|
||||
# NOTE: Shader is passed to every light on creation to define shader bindings internally
|
||||
Light lights[MAX_LIGHTS] = [
|
||||
CreateLight(LIGHT_POINT, (Vector3)[ LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0 ], (Vector3)[ 0.0, 0.0, 0.0 ], (Color)[ 255, 0, 0, 255 ], model.material.shader),
|
||||
CreateLight(LIGHT_POINT, (Vector3)[ 0.0, LIGHT_HEIGHT, LIGHT_DISTANCE ], (Vector3)[ 0.0, 0.0, 0.0 ], (Color)[ 0, 255, 0, 255 ], model.material.shader),
|
||||
CreateLight(LIGHT_POINT, (Vector3)[ -LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0 ], (Vector3)[ 0.0, 0.0, 0.0 ], (Color)[ 0, 0, 255, 255 ], model.material.shader),
|
||||
CreateLight(LIGHT_DIRECTIONAL, (Vector3)[ 0.0, LIGHT_HEIGHT*2.0, -LIGHT_DISTANCE ], (Vector3)[ 0.0, 0.0, 0.0 ], (Color)[ 255, 0, 255, 255 ], model.material.shader)
|
||||
]
|
||||
|
||||
SetCameraMode(camera, CAMERA_ORBITAL) # Set an orbital camera mode
|
||||
|
||||
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
|
||||
#----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera) # Update camera
|
||||
|
||||
# Send to material PBR shader camera view position
|
||||
float cameraPos[3] = [ camera.position.x, camera.position.y, camera.position.z ]
|
||||
SetShaderValue(model.material.shader, model.material.shader.locs[LOC_VECTOR_VIEW], cameraPos, 3)
|
||||
#----------------------------------------------------------------------------------
|
||||
|
||||
# Draw
|
||||
#----------------------------------------------------------------------------------
|
||||
BeginDrawing()
|
||||
|
||||
ClearBackground(RAYWHITE)
|
||||
|
||||
BeginMode3D(camera)
|
||||
|
||||
DrawModel(model, Vector3Zero(), 1.0, WHITE)
|
||||
|
||||
DrawGrid(10, 1.0)
|
||||
|
||||
EndMode3D()
|
||||
|
||||
DrawFPS(10, 10)
|
||||
|
||||
EndDrawing()
|
||||
#----------------------------------------------------------------------------------
|
||||
]
|
||||
|
||||
# De-Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
UnloadModel(model) # Unload skybox model
|
||||
|
||||
CloseWindow() # Close window and OpenGL context
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
||||
return 0
|
||||
]
|
||||
|
||||
# Load PBR material (Supports: ALBEDO, NORMAL, METALNESS, ROUGHNESS, AO, EMMISIVE, HEIGHT maps)
|
||||
# NOTE: PBR shader is loaded inside this function
|
||||
static Material LoadMaterialPBR(Color albedo, float metalness, float roughness)
|
||||
[
|
||||
Material mat = [ 0 ] # NOTE: All maps textures are set to [ 0 ]
|
||||
|
||||
#define PATH_PBR_VS "resources/shaders/pbr.vs" # Path to physically based rendering vertex shader
|
||||
#define PATH_PBR_FS "resources/shaders/pbr.fs" # Path to physically based rendering fragment shader
|
||||
|
||||
mat.shader = LoadShader(PATH_PBR_VS, PATH_PBR_FS)
|
||||
|
||||
# Get required locations points for PBR material
|
||||
# NOTE: Those location names must be available and used in the shader code
|
||||
mat.shader.locs[LOC_MAP_ALBEDO] = GetShaderLocation(mat.shader, "albedo.sampler")
|
||||
mat.shader.locs[LOC_MAP_METALNESS] = GetShaderLocation(mat.shader, "metalness.sampler")
|
||||
mat.shader.locs[LOC_MAP_NORMAL] = GetShaderLocation(mat.shader, "normals.sampler")
|
||||
mat.shader.locs[LOC_MAP_ROUGHNESS] = GetShaderLocation(mat.shader, "roughness.sampler")
|
||||
mat.shader.locs[LOC_MAP_OCCLUSION] = GetShaderLocation(mat.shader, "occlusion.sampler")
|
||||
#mat.shader.locs[LOC_MAP_EMISSION] = GetShaderLocation(mat.shader, "emission.sampler")
|
||||
#mat.shader.locs[LOC_MAP_HEIGHT] = GetShaderLocation(mat.shader, "height.sampler")
|
||||
mat.shader.locs[LOC_MAP_IRRADIANCE] = GetShaderLocation(mat.shader, "irradianceMap")
|
||||
mat.shader.locs[LOC_MAP_PREFILTER] = GetShaderLocation(mat.shader, "prefilterMap")
|
||||
mat.shader.locs[LOC_MAP_BRDF] = GetShaderLocation(mat.shader, "brdfLUT")
|
||||
|
||||
# Set view matrix location
|
||||
mat.shader.locs[LOC_MATRIX_MODEL] = GetShaderLocation(mat.shader, "matModel")
|
||||
mat.shader.locs[LOC_MATRIX_VIEW] = GetShaderLocation(mat.shader, "view")
|
||||
mat.shader.locs[LOC_VECTOR_VIEW] = GetShaderLocation(mat.shader, "viewPos")
|
||||
|
||||
# Set PBR standard maps
|
||||
mat.maps[MAP_ALBEDO].texture = LoadTexture("resources/pbr/trooper_albedo.png")
|
||||
mat.maps[MAP_NORMAL].texture = LoadTexture("resources/pbr/trooper_normals.png")
|
||||
mat.maps[MAP_METALNESS].texture = LoadTexture("resources/pbr/trooper_metalness.png")
|
||||
mat.maps[MAP_ROUGHNESS].texture = LoadTexture("resources/pbr/trooper_roughness.png")
|
||||
mat.maps[MAP_OCCLUSION].texture = LoadTexture("resources/pbr/trooper_ao.png")
|
||||
|
||||
# Set environment maps
|
||||
#define PATH_CUBEMAP_VS "resources/shaders/cubemap.vs" # Path to equirectangular to cubemap vertex shader
|
||||
#define PATH_CUBEMAP_FS "resources/shaders/cubemap.fs" # Path to equirectangular to cubemap fragment shader
|
||||
#define PATH_SKYBOX_VS "resources/shaders/skybox.vs" # Path to skybox vertex shader
|
||||
#define PATH_IRRADIANCE_FS "resources/shaders/irradiance.fs" # Path to irradiance (GI) calculation fragment shader
|
||||
#define PATH_PREFILTER_FS "resources/shaders/prefilter.fs" # Path to reflection prefilter calculation fragment shader
|
||||
#define PATH_BRDF_VS "resources/shaders/brdf.vs" # Path to bidirectional reflectance distribution function vertex shader
|
||||
#define PATH_BRDF_FS "resources/shaders/brdf.fs" # Path to bidirectional reflectance distribution function fragment shader
|
||||
|
||||
Shader shdrCubemap = LoadShader(PATH_CUBEMAP_VS, PATH_CUBEMAP_FS)
|
||||
Shader shdrIrradiance = LoadShader(PATH_SKYBOX_VS, PATH_IRRADIANCE_FS)
|
||||
Shader shdrPrefilter = LoadShader(PATH_SKYBOX_VS, PATH_PREFILTER_FS)
|
||||
Shader shdrBRDF = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS)
|
||||
|
||||
# Setup required shader locations
|
||||
SetShaderValuei(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1])[ 0 ], 1)
|
||||
SetShaderValuei(shdrIrradiance, GetShaderLocation(shdrIrradiance, "environmentMap"), (int[1])[ 0 ], 1)
|
||||
SetShaderValuei(shdrPrefilter, GetShaderLocation(shdrPrefilter, "environmentMap"), (int[1])[ 0 ], 1)
|
||||
|
||||
Texture2D texHDR = LoadTexture("resources/dresden_square.hdr")
|
||||
Texture2D cubemap = GenTextureCubemap(shdrCubemap, texHDR, CUBEMAP_SIZE)
|
||||
mat.maps[MAP_IRRADIANCE].texture = GenTextureIrradiance(shdrIrradiance, cubemap, IRRADIANCE_SIZE)
|
||||
mat.maps[MAP_PREFILTER].texture = GenTexturePrefilter(shdrPrefilter, cubemap, PREFILTERED_SIZE)
|
||||
mat.maps[MAP_BRDF].texture = GenTextureBRDF(shdrBRDF, cubemap, BRDF_SIZE)
|
||||
UnloadTexture(cubemap)
|
||||
UnloadTexture(texHDR)
|
||||
|
||||
# Unload already used shaders (to create specific textures)
|
||||
UnloadShader(shdrCubemap)
|
||||
UnloadShader(shdrIrradiance)
|
||||
UnloadShader(shdrPrefilter)
|
||||
UnloadShader(shdrBRDF)
|
||||
|
||||
# Set textures filtering for better quality
|
||||
SetTextureFilter(mat.maps[MAP_ALBEDO].texture, FILTER_BILINEAR)
|
||||
SetTextureFilter(mat.maps[MAP_NORMAL].texture, FILTER_BILINEAR)
|
||||
SetTextureFilter(mat.maps[MAP_METALNESS].texture, FILTER_BILINEAR)
|
||||
SetTextureFilter(mat.maps[MAP_ROUGHNESS].texture, FILTER_BILINEAR)
|
||||
SetTextureFilter(mat.maps[MAP_OCCLUSION].texture, FILTER_BILINEAR)
|
||||
|
||||
# Enable sample usage in shader for assigned textures
|
||||
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "albedo.useSampler"), (int[1])[ 1 ], 1)
|
||||
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "normals.useSampler"), (int[1])[ 1 ], 1)
|
||||
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "metalness.useSampler"), (int[1])[ 1 ], 1)
|
||||
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "roughness.useSampler"), (int[1])[ 1 ], 1)
|
||||
SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "occlusion.useSampler"), (int[1])[ 1 ], 1)
|
||||
|
||||
int renderModeLoc = GetShaderLocation(mat.shader, "renderMode")
|
||||
SetShaderValuei(mat.shader, renderModeLoc, (int[1])[ 0 ], 1)
|
||||
|
||||
# Set up material properties color
|
||||
mat.maps[MAP_ALBEDO].color = albedo
|
||||
mat.maps[MAP_NORMAL].color = (Color)[ 128, 128, 255, 255 ]
|
||||
mat.maps[MAP_METALNESS].value = metalness
|
||||
mat.maps[MAP_ROUGHNESS].value = roughness
|
||||
mat.maps[MAP_OCCLUSION].value = 1.0
|
||||
mat.maps[MAP_EMISSION].value = 0.5f
|
||||
mat.maps[MAP_HEIGHT].value = 0.5f
|
||||
|
||||
return mat
|
||||
]
|
BIN
examples/models/models_material_pbr.png
Normal file
After Width: | Height: | Size: 317 KiB |
113
examples/models/models_mesh_generation.c
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib example - procedural mesh generation
|
||||
*
|
||||
* This example has been created using raylib 1.8 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2017 Ramon Santamaria (Ray San)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define NUM_MODELS 7 # We generate 7 parametric 3d shapes
|
||||
|
||||
int main()
|
||||
[
|
||||
# Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800
|
||||
int screenHeight = 450
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - mesh generation")
|
||||
|
||||
# We generate a checked image for texturing
|
||||
Image checked = GenImageChecked(2, 2, 1, 1, RED, GREEN)
|
||||
Texture2D texture = LoadTextureFromImage(checked)
|
||||
UnloadImage(checked)
|
||||
|
||||
Model models[NUM_MODELS]
|
||||
|
||||
models[0] = LoadModelFromMesh(GenMeshPlane(2, 2, 5, 5))
|
||||
models[1] = LoadModelFromMesh(GenMeshCube(2.0, 1.0, 2.0))
|
||||
models[2] = LoadModelFromMesh(GenMeshSphere(2, 32, 32))
|
||||
models[3] = LoadModelFromMesh(GenMeshHemiSphere(2, 16, 16))
|
||||
models[4] = LoadModelFromMesh(GenMeshCylinder(1, 2, 16))
|
||||
models[5] = LoadModelFromMesh(GenMeshTorus(0.25f, 4.0, 16, 32))
|
||||
models[6] = LoadModelFromMesh(GenMeshKnot(1.0, 2.0, 16, 128))
|
||||
|
||||
# Set checked texture as default diffuse component for all models material
|
||||
for (int i = 0 i < NUM_MODELS i++) models[i].material.maps[MAP_DIFFUSE].texture = texture
|
||||
|
||||
# Define the camera to look into our 3d world
|
||||
Camera camera = [[ 5.0, 5.0, 5.0 ], [ 0.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], 45.0, 0 ]
|
||||
|
||||
# Model drawing position
|
||||
Vector3 position = [ 0.0, 0.0, 0.0 ]
|
||||
|
||||
int currentModel = 0
|
||||
|
||||
SetCameraMode(camera, CAMERA_ORBITAL) # Set a orbital camera mode
|
||||
|
||||
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
|
||||
#----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera) # Update internal camera and our camera
|
||||
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
[
|
||||
currentModel = (currentModel + 1)%NUM_MODELS # Cycle between the textures
|
||||
]
|
||||
#----------------------------------------------------------------------------------
|
||||
|
||||
# Draw
|
||||
#----------------------------------------------------------------------------------
|
||||
BeginDrawing()
|
||||
|
||||
ClearBackground(RAYWHITE)
|
||||
|
||||
BeginMode3D(camera)
|
||||
|
||||
DrawModel(models[currentModel], position, 1.0, WHITE)
|
||||
|
||||
DrawGrid(10, 1.0)
|
||||
|
||||
EndMode3D()
|
||||
|
||||
DrawRectangle(30, 400, 310, 30, Fade(SKYBLUE, 0.5f))
|
||||
DrawRectangleLines(30, 400, 310, 30, Fade(DARKBLUE, 0.5f))
|
||||
DrawText("MOUSE LEFT BUTTON to CYCLE PROCEDURAL MODELS", 40, 410, 10, BLUE)
|
||||
|
||||
switch(currentModel)
|
||||
[
|
||||
case 0: DrawText("PLANE", 680, 10, 20, DARKBLUE) break
|
||||
case 1: DrawText("CUBE", 680, 10, 20, DARKBLUE) break
|
||||
case 2: DrawText("SPHERE", 680, 10, 20, DARKBLUE) break
|
||||
case 3: DrawText("HEMISPHERE", 640, 10, 20, DARKBLUE) break
|
||||
case 4: DrawText("CYLINDER", 680, 10, 20, DARKBLUE) break
|
||||
case 5: DrawText("TORUS", 680, 10, 20, DARKBLUE) break
|
||||
case 6: DrawText("KNOT", 680, 10, 20, DARKBLUE) break
|
||||
default: break
|
||||
]
|
||||
|
||||
EndDrawing()
|
||||
#----------------------------------------------------------------------------------
|
||||
]
|
||||
|
||||
# De-Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
||||
# Unload models data (GPU VRAM)
|
||||
for (int i = 0 i < NUM_MODELS i++) UnloadModel(models[i])
|
||||
|
||||
CloseWindow() # Close window and OpenGL context
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
||||
return 0
|
||||
]
|
BIN
examples/models/models_mesh_generation.png
Normal file
After Width: | Height: | Size: 27 KiB |
201
examples/models/models_mesh_picking.c
Normal file
|
@ -0,0 +1,201 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [models] example - Mesh picking in 3d mode, ground plane, triangle, mesh
|
||||
*
|
||||
* This example has been created using raylib 1.7 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
* Example contributed by Joel Davis (@joeld42)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
|
||||
#define FLT_MAX 3.40282347E+38F # Maximum value of a float, defined in <float.h>
|
||||
|
||||
int main()
|
||||
[
|
||||
# Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800
|
||||
int screenHeight = 450
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - mesh picking")
|
||||
|
||||
# Define the camera to look into our 3d world
|
||||
Camera camera
|
||||
camera.position = (Vector3)[ 20.0, 20.0, 20.0 ] # Camera position
|
||||
camera.target = (Vector3)[ 0.0, 8.0, 0.0 ] # Camera looking at point
|
||||
camera.up = (Vector3)[ 0.0, 1.6f, 0.0 ] # Camera up vector (rotation towards target)
|
||||
camera.fovy = 45.0 # Camera field-of-view Y
|
||||
camera.type = CAMERA_PERSPECTIVE # Camera mode type
|
||||
|
||||
Ray ray # Picking ray
|
||||
|
||||
Model tower = LoadModel("resources/models/turret.obj") # Load OBJ model
|
||||
Texture2D texture = LoadTexture("resources/models/turret_diffuse.png") # Load model texture
|
||||
tower.material.maps[MAP_DIFFUSE].texture = texture # Set model diffuse texture
|
||||
|
||||
Vector3 towerPos = [ 0.0, 0.0, 0.0 ] # Set model position
|
||||
BoundingBox towerBBox = MeshBoundingBox(tower.mesh) # Get mesh bounding box
|
||||
bool hitMeshBBox = false
|
||||
bool hitTriangle = false
|
||||
|
||||
# Test triangle
|
||||
Vector3 ta = (Vector3)[ -25.0, 0.5, 0.0 ]
|
||||
Vector3 tb = (Vector3)[ -4.0, 2.5, 1.0 ]
|
||||
Vector3 tc = (Vector3)[ -8.0, 6.5, 0.0 ]
|
||||
|
||||
Vector3 bary = [ 0.0, 0.0, 0.0 ]
|
||||
|
||||
SetCameraMode(camera, CAMERA_FREE) # Set a free camera mode
|
||||
|
||||
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
|
||||
#----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera) # Update camera
|
||||
|
||||
# Display information about closest hit
|
||||
RayHitInfo nearestHit
|
||||
char *hitObjectName = "None"
|
||||
nearestHit.distance = FLT_MAX
|
||||
nearestHit.hit = false
|
||||
Color cursorColor = WHITE
|
||||
|
||||
# Get ray and test against ground, triangle, and mesh
|
||||
ray = GetMouseRay(GetMousePosition(), camera)
|
||||
|
||||
# Check ray collision aginst ground plane
|
||||
RayHitInfo groundHitInfo = GetCollisionRayGround(ray, 0.0)
|
||||
|
||||
if ((groundHitInfo.hit) && (groundHitInfo.distance < nearestHit.distance))
|
||||
[
|
||||
nearestHit = groundHitInfo
|
||||
cursorColor = GREEN
|
||||
hitObjectName = "Ground"
|
||||
]
|
||||
|
||||
# Check ray collision against test triangle
|
||||
RayHitInfo triHitInfo = GetCollisionRayTriangle(ray, ta, tb, tc)
|
||||
|
||||
if ((triHitInfo.hit) && (triHitInfo.distance < nearestHit.distance))
|
||||
[
|
||||
nearestHit = triHitInfo
|
||||
cursorColor = PURPLE
|
||||
hitObjectName = "Triangle"
|
||||
|
||||
bary = Vector3Barycenter(nearestHit.position, ta, tb, tc)
|
||||
hitTriangle = true
|
||||
]
|
||||
else hitTriangle = false
|
||||
|
||||
RayHitInfo meshHitInfo
|
||||
|
||||
# Check ray collision against bounding box first, before trying the full ray-mesh test
|
||||
if (CheckCollisionRayBox(ray, towerBBox))
|
||||
[
|
||||
hitMeshBBox = true
|
||||
|
||||
# Check ray collision against model
|
||||
# NOTE: It considers model.transform matrix!
|
||||
meshHitInfo = GetCollisionRayModel(ray, &tower)
|
||||
|
||||
if ((meshHitInfo.hit) && (meshHitInfo.distance < nearestHit.distance))
|
||||
[
|
||||
nearestHit = meshHitInfo
|
||||
cursorColor = ORANGE
|
||||
hitObjectName = "Mesh"
|
||||
]
|
||||
|
||||
] hitMeshBBox = false
|
||||
#----------------------------------------------------------------------------------
|
||||
|
||||
# Draw
|
||||
#----------------------------------------------------------------------------------
|
||||
BeginDrawing()
|
||||
|
||||
ClearBackground(RAYWHITE)
|
||||
|
||||
BeginMode3D(camera)
|
||||
|
||||
# Draw the tower
|
||||
# WARNING: If scale is different than 1.0,
|
||||
# not considered by GetCollisionRayModel()
|
||||
DrawModel(tower, towerPos, 1.0, WHITE)
|
||||
|
||||
# Draw the test triangle
|
||||
DrawLine3D(ta, tb, PURPLE)
|
||||
DrawLine3D(tb, tc, PURPLE)
|
||||
DrawLine3D(tc, ta, PURPLE)
|
||||
|
||||
# Draw the mesh bbox if we hit it
|
||||
if (hitMeshBBox) DrawBoundingBox(towerBBox, LIME)
|
||||
|
||||
# If we hit something, draw the cursor at the hit point
|
||||
if (nearestHit.hit)
|
||||
[
|
||||
DrawCube(nearestHit.position, 0.3, 0.3, 0.3, cursorColor)
|
||||
DrawCubeWires(nearestHit.position, 0.3, 0.3, 0.3, RED)
|
||||
|
||||
Vector3 normalEnd
|
||||
normalEnd.x = nearestHit.position.x + nearestHit.normal.x
|
||||
normalEnd.y = nearestHit.position.y + nearestHit.normal.y
|
||||
normalEnd.z = nearestHit.position.z + nearestHit.normal.z
|
||||
|
||||
DrawLine3D(nearestHit.position, normalEnd, RED)
|
||||
]
|
||||
|
||||
DrawRay(ray, MAROON)
|
||||
|
||||
DrawGrid(10, 10.0)
|
||||
|
||||
EndMode3D()
|
||||
|
||||
# Draw some debug GUI text
|
||||
DrawText(FormatText("Hit Object: %s", hitObjectName), 10, 50, 10, BLACK)
|
||||
|
||||
if (nearestHit.hit)
|
||||
[
|
||||
int ypos = 70
|
||||
|
||||
DrawText(FormatText("Distance: %3.2f", nearestHit.distance), 10, ypos, 10, BLACK)
|
||||
|
||||
DrawText(FormatText("Hit Pos: %3.2f %3.2f %3.2f",
|
||||
nearestHit.position.x,
|
||||
nearestHit.position.y,
|
||||
nearestHit.position.z), 10, ypos + 15, 10, BLACK)
|
||||
|
||||
DrawText(FormatText("Hit Norm: %3.2f %3.2f %3.2f",
|
||||
nearestHit.normal.x,
|
||||
nearestHit.normal.y,
|
||||
nearestHit.normal.z), 10, ypos + 30, 10, BLACK)
|
||||
|
||||
if (hitTriangle) DrawText(FormatText("Barycenter: %3.2f %3.2f %3.2f", bary.x, bary.y, bary.z), 10, ypos + 45, 10, BLACK)
|
||||
]
|
||||
|
||||
DrawText("Use Mouse to Move Camera", 10, 430, 10, GRAY)
|
||||
|
||||
DrawText("(c) Turret 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY)
|
||||
|
||||
DrawFPS(10, 10)
|
||||
|
||||
EndDrawing()
|
||||
#----------------------------------------------------------------------------------
|
||||
]
|
||||
|
||||
# De-Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
UnloadModel(tower) # Unload model
|
||||
UnloadTexture(texture) # Unload texture
|
||||
|
||||
CloseWindow() # Close window and OpenGL context
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
||||
return 0
|
||||
]
|
BIN
examples/models/models_mesh_picking.png
Normal file
After Width: | Height: | Size: 136 KiB |
80
examples/models/models_obj_loading.c
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [models] example - Load and draw a 3d model (OBJ)
|
||||
*
|
||||
* This example has been created using raylib 1.3 (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"
|
||||
|
||||
int main()
|
||||
[
|
||||
# Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800
|
||||
int screenHeight = 450
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - obj model loading")
|
||||
|
||||
# Define the camera to look into our 3d world
|
||||
Camera camera = [ 0 ]
|
||||
camera.position = (Vector3)[ 8.0, 8.0, 8.0 ] # Camera position
|
||||
camera.target = (Vector3)[ 0.0, 2.5f, 0.0 ] # Camera looking at point
|
||||
camera.up = (Vector3)[ 0.0, 1.0, 0.0 ] # Camera up vector (rotation towards target)
|
||||
camera.fovy = 45.0 # Camera field-of-view Y
|
||||
camera.type = CAMERA_PERSPECTIVE # Camera mode type
|
||||
|
||||
Model model = LoadModel("resources/models/castle.obj") # Load OBJ model
|
||||
Texture2D texture = LoadTexture("resources/models/castle_diffuse.png") # Load model texture
|
||||
model.material.maps[MAP_DIFFUSE].texture = texture # Set map diffuse texture
|
||||
Vector3 position = [ 0.0, 0.0, 0.0 ] # Set model position
|
||||
|
||||
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
|
||||
#----------------------------------------------------------------------------------
|
||||
#...
|
||||
#----------------------------------------------------------------------------------
|
||||
|
||||
# Draw
|
||||
#----------------------------------------------------------------------------------
|
||||
BeginDrawing()
|
||||
|
||||
ClearBackground(RAYWHITE)
|
||||
|
||||
BeginMode3D(camera)
|
||||
|
||||
DrawModel(model, position, 0.2f, WHITE) # Draw 3d model with texture
|
||||
|
||||
DrawGrid(10, 1.0) # Draw a grid
|
||||
|
||||
DrawGizmo(position) # Draw gizmo
|
||||
|
||||
EndMode3D()
|
||||
|
||||
DrawText("(c) Castle 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY)
|
||||
|
||||
DrawFPS(10, 10)
|
||||
|
||||
EndDrawing()
|
||||
#----------------------------------------------------------------------------------
|
||||
]
|
||||
|
||||
# De-Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture) # Unload texture
|
||||
UnloadModel(model) # Unload model
|
||||
|
||||
CloseWindow() # Close window and OpenGL context
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
||||
return 0
|
||||
]
|
BIN
examples/models/models_obj_loading.png
Normal file
After Width: | Height: | Size: 260 KiB |
97
examples/models/models_orthographic_projection.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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.9.7 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2018 Max Danielsson & Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define FOVY_PERSPECTIVE 45.0
|
||||
#define WIDTH_ORTHOGRAPHIC 10.0
|
||||
|
||||
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.0, 10.0, 10.0 ], [ 0.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], 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
|
||||
#----------------------------------------------------------------------------------
|
||||
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)
|
||||
|
||||
BeginMode3D(camera)
|
||||
|
||||
DrawCube((Vector3)[-4.0, 0.0, 2.0], 2.0, 5.0, 2.0, RED)
|
||||
DrawCubeWires((Vector3)[-4.0, 0.0, 2.0], 2.0, 5.0, 2.0, GOLD)
|
||||
DrawCubeWires((Vector3)[-4.0, 0.0, -2.0], 3.0, 6.0, 2.0, MAROON)
|
||||
|
||||
DrawSphere((Vector3)[-1.0, 0.0, -2.0], 1.0, GREEN)
|
||||
DrawSphereWires((Vector3)[1.0, 0.0, 2.0], 2.0, 16, 16, LIME)
|
||||
|
||||
DrawCylinder((Vector3)[4.0, 0.0, -2.0], 1.0, 2.0, 3.0, 4, SKYBLUE)
|
||||
DrawCylinderWires((Vector3)[4.0, 0.0, -2.0], 1.0, 2.0, 3.0, 4, DARKBLUE)
|
||||
DrawCylinderWires((Vector3)[4.5f, -1.0, 2.0], 1.0, 1.0, 2.0, 6, BROWN)
|
||||
|
||||
DrawCylinder((Vector3)[1.0, 0.0, -4.0], 0.0, 1.5f, 3.0, 8, GOLD)
|
||||
DrawCylinderWires((Vector3)[1.0, 0.0, -4.0], 0.0, 1.5f, 3.0, 8, PINK)
|
||||
|
||||
DrawGrid(10, 1.0) # Draw a grid
|
||||
|
||||
EndMode3D()
|
||||
|
||||
DrawText("Press Spacebar to switch camera type", 10, GetScreenHeight() - 30, 20, DARKGRAY)
|
||||
|
||||
if (camera.type == CAMERA_ORTHOGRAPHIC) DrawText("ORTHOGRAPHIC", 10, 40, 20, BLACK)
|
||||
else if (camera.type == CAMERA_PERSPECTIVE) DrawText("PERSPECTIVE", 10, 40, 20, BLACK)
|
||||
|
||||
DrawFPS(10, 10)
|
||||
|
||||
EndDrawing()
|
||||
#----------------------------------------------------------------------------------
|
||||
]
|
||||
|
||||
# De-Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
CloseWindow() # Close window and OpenGL context
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
||||
return 0
|
||||
]
|
BIN
examples/models/models_orthographic_projection.png
Normal file
After Width: | Height: | Size: 32 KiB |
90
examples/models/models_skybox.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [models] example - Skybox loading and drawing
|
||||
*
|
||||
* This example has been created using raylib 1.8 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2017 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
int main()
|
||||
[
|
||||
# Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800
|
||||
int screenHeight = 450
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - skybox loading and drawing")
|
||||
|
||||
# Define the camera to look into our 3d world
|
||||
Camera camera = [[ 1.0, 1.0, 1.0 ], [ 0.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], 45.0, 0 ]
|
||||
|
||||
# Load skybox model
|
||||
Mesh cube = GenMeshCube(1.0, 1.0, 1.0)
|
||||
Model skybox = LoadModelFromMesh(cube)
|
||||
|
||||
# Load skybox shader and set required locations
|
||||
# NOTE: Some locations are automatically set at shader loading
|
||||
skybox.material.shader = LoadShader("resources/shaders/skybox.vs", "resources/shaders/skybox.fs")
|
||||
SetShaderValuei(skybox.material.shader, GetShaderLocation(skybox.material.shader, "environmentMap"), (int[1])[ MAP_CUBEMAP ], 1)
|
||||
|
||||
# Load cubemap shader and setup required shader locations
|
||||
Shader shdrCubemap = LoadShader("resources/shaders/cubemap.vs", "resources/shaders/cubemap.fs")
|
||||
SetShaderValuei(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1])[ 0 ], 1)
|
||||
|
||||
# Load HDR panorama (sphere) texture
|
||||
Texture2D texHDR = LoadTexture("resources/dresden_square.hdr")
|
||||
|
||||
# Generate cubemap (texture with 6 quads-cube-mapping) from panorama HDR texture
|
||||
# NOTE: New texture is generated rendering to texture, shader computes the sphre->cube coordinates mapping
|
||||
skybox.material.maps[MAP_CUBEMAP].texture = GenTextureCubemap(shdrCubemap, texHDR, 512)
|
||||
|
||||
UnloadTexture(texHDR) # Texture not required anymore, cubemap already generated
|
||||
UnloadShader(shdrCubemap) # Unload cubemap generation shader, not required anymore
|
||||
|
||||
SetCameraMode(camera, CAMERA_FIRST_PERSON) # Set a first person camera mode
|
||||
|
||||
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
|
||||
#----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera) # Update camera
|
||||
#----------------------------------------------------------------------------------
|
||||
|
||||
# Draw
|
||||
#----------------------------------------------------------------------------------
|
||||
BeginDrawing()
|
||||
|
||||
ClearBackground(RAYWHITE)
|
||||
|
||||
BeginMode3D(camera)
|
||||
|
||||
DrawModel(skybox, (Vector3)[0, 0, 0], 1.0, WHITE)
|
||||
|
||||
DrawGrid(10, 1.0)
|
||||
|
||||
EndMode3D()
|
||||
|
||||
DrawFPS(10, 10)
|
||||
|
||||
EndDrawing()
|
||||
#----------------------------------------------------------------------------------
|
||||
]
|
||||
|
||||
# De-Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
UnloadModel(skybox) # Unload skybox model (and textures)
|
||||
|
||||
CloseWindow() # Close window and OpenGL context
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
||||
return 0
|
||||
]
|
BIN
examples/models/models_skybox.png
Normal file
After Width: | Height: | Size: 417 KiB |
199
examples/models/models_yaw_pitch_roll.c
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [models] example - Plane rotations (yaw, pitch, roll)
|
||||
*
|
||||
* This example has been created using raylib 1.8 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Example based on Berni work on Raspberry Pi:
|
||||
* http:#forum.raylib.com/index.php?p=/discussion/124/line-versus-triangle-drawing-order
|
||||
*
|
||||
* Copyright (c) 2017 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
|
||||
# Draw angle gauge controls
|
||||
void DrawAngleGauge(Texture2D angleGauge, int x, int y, float angle, char title[], Color color)
|
||||
|
||||
#----------------------------------------------------------------------------------
|
||||
# Main entry point
|
||||
#----------------------------------------------------------------------------------
|
||||
int main()
|
||||
[
|
||||
# Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800
|
||||
const int screenHeight = 450
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - plane rotations (yaw, pitch, roll)")
|
||||
|
||||
Texture2D texAngleGauge = LoadTexture("resources/angle_gauge.png")
|
||||
Texture2D texBackground = LoadTexture("resources/background.png")
|
||||
Texture2D texPitch = LoadTexture("resources/pitch.png")
|
||||
Texture2D texPlane = LoadTexture("resources/plane.png")
|
||||
|
||||
RenderTexture2D framebuffer = LoadRenderTexture(192, 192)
|
||||
|
||||
# Model loading
|
||||
Model model = LoadModel("resources/plane.obj") # Load OBJ model
|
||||
model.material.maps[MAP_DIFFUSE].texture = LoadTexture("resources/plane_diffuse.png") # Set map diffuse texture
|
||||
|
||||
GenTextureMipmaps(&model.material.maps[MAP_DIFFUSE].texture)
|
||||
|
||||
Camera camera = [ 0 ]
|
||||
camera.position = (Vector3)[ 0.0, 60.0, -120.0 ]# Camera position perspective
|
||||
camera.target = (Vector3)[ 0.0, 12.0, 0.0 ] # Camera looking at point
|
||||
camera.up = (Vector3)[ 0.0, 1.0, 0.0 ] # Camera up vector (rotation towards target)
|
||||
camera.fovy = 30.0 # Camera field-of-view Y
|
||||
camera.type = CAMERA_PERSPECTIVE # Camera type
|
||||
|
||||
float pitch = 0.0
|
||||
float roll = 0.0
|
||||
float yaw = 0.0
|
||||
|
||||
SetTargetFPS(60)
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
while (!WindowShouldClose()) # Detect window close button or ESC key
|
||||
[
|
||||
# Update
|
||||
#----------------------------------------------------------------------------------
|
||||
|
||||
# Plane roll (x-axis) controls
|
||||
if (IsKeyDown(KEY_LEFT)) roll += 1.0
|
||||
else if (IsKeyDown(KEY_RIGHT)) roll -= 1.0
|
||||
else
|
||||
[
|
||||
if (roll > 0.0) roll -= 0.5f
|
||||
else if (roll < 0.0) roll += 0.5f
|
||||
]
|
||||
|
||||
# Plane yaw (y-axis) controls
|
||||
if (IsKeyDown(KEY_S)) yaw += 1.0
|
||||
else if (IsKeyDown(KEY_A)) yaw -= 1.0
|
||||
else
|
||||
[
|
||||
if (yaw > 0.0) yaw -= 0.5f
|
||||
else if (yaw < 0.0) yaw += 0.5f
|
||||
]
|
||||
|
||||
# Plane pitch (z-axis) controls
|
||||
if (IsKeyDown(KEY_DOWN)) pitch += 0.6f
|
||||
else if (IsKeyDown(KEY_UP)) pitch -= 0.6f
|
||||
else
|
||||
[
|
||||
if (pitch > 0.3f) pitch -= 0.3f
|
||||
else if (pitch < -0.3f) pitch += 0.3f
|
||||
]
|
||||
|
||||
# Wraps the phase of an angle to fit between -180 and +180 degrees
|
||||
int pitchOffset = pitch
|
||||
while (pitchOffset > 180) pitchOffset -= 360
|
||||
while (pitchOffset < -180) pitchOffset += 360
|
||||
pitchOffset *= 10
|
||||
|
||||
Matrix transform = MatrixIdentity()
|
||||
|
||||
transform = MatrixMultiply(transform, MatrixRotateZ(DEG2RAD*roll))
|
||||
transform = MatrixMultiply(transform, MatrixRotateX(DEG2RAD*pitch))
|
||||
transform = MatrixMultiply(transform, MatrixRotateY(DEG2RAD*yaw))
|
||||
|
||||
model.transform = transform
|
||||
#----------------------------------------------------------------------------------
|
||||
|
||||
# Draw
|
||||
#----------------------------------------------------------------------------------
|
||||
BeginDrawing()
|
||||
|
||||
ClearBackground(RAYWHITE)
|
||||
|
||||
# Draw framebuffer texture (Ahrs Display)
|
||||
int centerX = framebuffer.texture.width/2
|
||||
int centerY = framebuffer.texture.height/2
|
||||
float scaleFactor = 0.5f
|
||||
|
||||
BeginTextureMode(framebuffer)
|
||||
|
||||
BeginBlendMode(BLEND_ALPHA)
|
||||
|
||||
DrawTexturePro(texBackground, (Rectangle)[ 0, 0, texBackground.width, texBackground.height ],
|
||||
(Rectangle)[ centerX, centerY, texBackground.width*scaleFactor, texBackground.height*scaleFactor],
|
||||
(Vector2)[ texBackground.width/2*scaleFactor, texBackground.height/2*scaleFactor + pitchOffset*scaleFactor ], roll, WHITE)
|
||||
|
||||
DrawTexturePro(texPitch, (Rectangle)[ 0, 0, texPitch.width, texPitch.height ],
|
||||
(Rectangle)[ centerX, centerY, texPitch.width*scaleFactor, texPitch.height*scaleFactor ],
|
||||
(Vector2)[ texPitch.width/2*scaleFactor, texPitch.height/2*scaleFactor + pitchOffset*scaleFactor ], roll, WHITE)
|
||||
|
||||
DrawTexturePro(texPlane, (Rectangle)[ 0, 0, texPlane.width, texPlane.height ],
|
||||
(Rectangle)[ centerX, centerY, texPlane.width*scaleFactor, texPlane.height*scaleFactor ],
|
||||
(Vector2)[ texPlane.width/2*scaleFactor, texPlane.height/2*scaleFactor ], 0, WHITE)
|
||||
|
||||
EndBlendMode()
|
||||
|
||||
EndTextureMode()
|
||||
|
||||
# Draw 3D model (recomended to draw 3D always before 2D)
|
||||
BeginMode3D(camera)
|
||||
|
||||
DrawModel(model, (Vector3)[ 0, 6.0, 0 ], 1.0, WHITE) # Draw 3d model with texture
|
||||
DrawGrid(10, 10.0)
|
||||
|
||||
EndMode3D()
|
||||
|
||||
# Draw 2D GUI stuff
|
||||
DrawAngleGauge(texAngleGauge, 80, 70, roll, "roll", RED)
|
||||
DrawAngleGauge(texAngleGauge, 190, 70, pitch, "pitch", GREEN)
|
||||
DrawAngleGauge(texAngleGauge, 300, 70, yaw, "yaw", SKYBLUE)
|
||||
|
||||
DrawRectangle(30, 360, 260, 70, Fade(SKYBLUE, 0.5f))
|
||||
DrawRectangleLines(30, 360, 260, 70, Fade(DARKBLUE, 0.5f))
|
||||
DrawText("Pitch controlled with: KEY_UP / KEY_DOWN", 40, 370, 10, DARKGRAY)
|
||||
DrawText("Roll controlled with: KEY_LEFT / KEY_RIGHT", 40, 390, 10, DARKGRAY)
|
||||
DrawText("Yaw controlled with: KEY_A / KEY_S", 40, 410, 10, DARKGRAY)
|
||||
|
||||
# Draw framebuffer texture
|
||||
DrawTextureRec(framebuffer.texture, (Rectangle)[ 0, 0, framebuffer.texture.width, -framebuffer.texture.height ],
|
||||
(Vector2)[ screenWidth - framebuffer.texture.width - 20, 20 ], Fade(WHITE, 0.8f))
|
||||
|
||||
DrawRectangleLines(screenWidth - framebuffer.texture.width - 20, 20, framebuffer.texture.width, framebuffer.texture.height, DARKGRAY)
|
||||
|
||||
EndDrawing()
|
||||
#----------------------------------------------------------------------------------
|
||||
]
|
||||
|
||||
# De-Initialization
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
||||
# Unload all loaded data
|
||||
UnloadModel(model)
|
||||
|
||||
UnloadRenderTexture(framebuffer)
|
||||
|
||||
UnloadTexture(texAngleGauge)
|
||||
UnloadTexture(texBackground)
|
||||
UnloadTexture(texPitch)
|
||||
UnloadTexture(texPlane)
|
||||
|
||||
CloseWindow() # Close window and OpenGL context
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
||||
return 0
|
||||
]
|
||||
|
||||
# Draw angle gauge controls
|
||||
void DrawAngleGauge(Texture2D angleGauge, int x, int y, float angle, char title[], Color color)
|
||||
[
|
||||
Rectangle srcRec = [ 0, 0, angleGauge.width, angleGauge.height ]
|
||||
Rectangle dstRec = [ x, y, angleGauge.width, angleGauge.height ]
|
||||
Vector2 origin = [ angleGauge.width/2, angleGauge.height/2]
|
||||
int textSize = 20
|
||||
|
||||
DrawTexturePro(angleGauge, srcRec, dstRec, origin, angle, color)
|
||||
|
||||
DrawText(FormatText("%5.1f", angle), x - MeasureText(FormatText("%5.1f", angle), textSize) / 2, y + 10, textSize, DARKGRAY)
|
||||
DrawText(title, x - MeasureText(title, textSize) / 2, y + 60, textSize, DARKGRAY)
|
||||
]
|
BIN
examples/models/models_yaw_pitch_roll.png
Normal file
After Width: | Height: | Size: 180 KiB |
BIN
examples/models/resources/angle_gauge.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
examples/models/resources/background.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
examples/models/resources/billboard.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
examples/models/resources/cubicmap.png
Normal file
After Width: | Height: | Size: 201 B |
BIN
examples/models/resources/cubicmap_atlas.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
examples/models/resources/dresden_square.hdr
Normal file
BIN
examples/models/resources/heightmap.png
Normal file
After Width: | Height: | Size: 11 KiB |
1725
examples/models/resources/models/bridge.obj
Normal file
BIN
examples/models/resources/models/bridge_diffuse.png
Normal file
After Width: | Height: | Size: 311 KiB |
12919
examples/models/resources/models/castle.obj
Normal file
BIN
examples/models/resources/models/castle_diffuse.png
Normal file
After Width: | Height: | Size: 1.5 MiB |
4564
examples/models/resources/models/house.obj
Normal file
BIN
examples/models/resources/models/house_diffuse.png
Normal file
After Width: | Height: | Size: 384 KiB |
7301
examples/models/resources/models/market.obj
Normal file
BIN
examples/models/resources/models/market_diffuse.png
Normal file
After Width: | Height: | Size: 381 KiB |
1888
examples/models/resources/models/turret.obj
Normal file
BIN
examples/models/resources/models/turret_diffuse.png
Normal file
After Width: | Height: | Size: 372 KiB |
1030
examples/models/resources/models/well.obj
Normal file
BIN
examples/models/resources/models/well_diffuse.png
Normal file
After Width: | Height: | Size: 335 KiB |
18312
examples/models/resources/pbr/trooper.obj
Normal file
BIN
examples/models/resources/pbr/trooper_albedo.png
Normal file
After Width: | Height: | Size: 7.3 MiB |
BIN
examples/models/resources/pbr/trooper_ao.png
Normal file
After Width: | Height: | Size: 1.7 MiB |
BIN
examples/models/resources/pbr/trooper_metalness.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
examples/models/resources/pbr/trooper_normals.png
Normal file
After Width: | Height: | Size: 4.7 MiB |
BIN
examples/models/resources/pbr/trooper_roughness.png
Normal file
After Width: | Height: | Size: 2.7 MiB |
BIN
examples/models/resources/pitch.png
Normal file
After Width: | Height: | Size: 45 KiB |
10700
examples/models/resources/plane.obj
Normal file
BIN
examples/models/resources/plane.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
examples/models/resources/plane_diffuse.png
Normal file
After Width: | Height: | Size: 364 KiB |
140
examples/models/resources/shaders/brdf.fs
Normal file
|
@ -0,0 +1,140 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* rPBR [shader] - Bidirectional reflectance distribution function fragment shader
|
||||
*
|
||||
* Copyright (c) 2017 Victor Fisac
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#version 330
|
||||
#define MAX_SAMPLES 1024u
|
||||
|
||||
# Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord
|
||||
|
||||
# Constant values
|
||||
const float PI = 3.14159265359
|
||||
|
||||
# Output fragment color
|
||||
out vec4 finalColor
|
||||
|
||||
float DistributionGGX(vec3 N, vec3 H, float roughness)
|
||||
float RadicalInverse_VdC(uint bits)
|
||||
vec2 Hammersley(uint i, uint N)
|
||||
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
|
||||
float GeometrySchlickGGX(float NdotV, float roughness)
|
||||
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
|
||||
vec2 IntegrateBRDF(float NdotV, float roughness)
|
||||
|
||||
float DistributionGGX(vec3 N, vec3 H, float roughness)
|
||||
[
|
||||
float a = roughness*roughness
|
||||
float a2 = a*a
|
||||
float NdotH = max(dot(N, H), 0.0)
|
||||
float NdotH2 = NdotH*NdotH
|
||||
|
||||
float nom = a2
|
||||
float denom = (NdotH2*(a2 - 1.0) + 1.0)
|
||||
denom = PI*denom*denom
|
||||
|
||||
return nom/denom
|
||||
]
|
||||
|
||||
float RadicalInverse_VdC(uint bits)
|
||||
[
|
||||
bits = (bits << 16u) | (bits >> 16u)
|
||||
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u)
|
||||
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u)
|
||||
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u)
|
||||
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u)
|
||||
return float(bits) * 2.3283064365386963e-10 # / 0x100000000
|
||||
]
|
||||
|
||||
vec2 Hammersley(uint i, uint N)
|
||||
[
|
||||
return vec2(float(i)/float(N), RadicalInverse_VdC(i))
|
||||
]
|
||||
|
||||
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
|
||||
[
|
||||
float a = roughness*roughness
|
||||
float phi = 2.0 * PI * Xi.x
|
||||
float cosTheta = sqrt((1.0 - Xi.y)/(1.0 + (a*a - 1.0)*Xi.y))
|
||||
float sinTheta = sqrt(1.0 - cosTheta*cosTheta)
|
||||
|
||||
# Transform from spherical coordinates to cartesian coordinates (halfway vector)
|
||||
vec3 H = vec3(cos(phi)*sinTheta, sin(phi)*sinTheta, cosTheta)
|
||||
|
||||
# Transform from tangent space H vector to world space sample vector
|
||||
vec3 up = ((abs(N.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0))
|
||||
vec3 tangent = normalize(cross(up, N))
|
||||
vec3 bitangent = cross(N, tangent)
|
||||
vec3 sampleVec = tangent*H.x + bitangent*H.y + N*H.z
|
||||
|
||||
return normalize(sampleVec)
|
||||
]
|
||||
|
||||
float GeometrySchlickGGX(float NdotV, float roughness)
|
||||
[
|
||||
# For IBL k is calculated different
|
||||
float k = (roughness*roughness)/2.0
|
||||
|
||||
float nom = NdotV
|
||||
float denom = NdotV*(1.0 - k) + k
|
||||
|
||||
return nom/denom
|
||||
]
|
||||
|
||||
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
|
||||
[
|
||||
float NdotV = max(dot(N, V), 0.0)
|
||||
float NdotL = max(dot(N, L), 0.0)
|
||||
float ggx2 = GeometrySchlickGGX(NdotV, roughness)
|
||||
float ggx1 = GeometrySchlickGGX(NdotL, roughness)
|
||||
|
||||
return ggx1*ggx2
|
||||
]
|
||||
|
||||
vec2 IntegrateBRDF(float NdotV, float roughness)
|
||||
[
|
||||
vec3 V = vec3(sqrt(1.0 - NdotV*NdotV), 0.0, NdotV)
|
||||
float A = 0.0
|
||||
float B = 0.0
|
||||
vec3 N = vec3(0.0, 0.0, 1.0)
|
||||
|
||||
for(uint i = 0u i < MAX_SAMPLES i++)
|
||||
[
|
||||
# Generate a sample vector that's biased towards the preferred alignment direction (importance sampling)
|
||||
vec2 Xi = Hammersley(i, MAX_SAMPLES)
|
||||
vec3 H = ImportanceSampleGGX(Xi, N, roughness)
|
||||
vec3 L = normalize(2.0*dot(V, H)*H - V)
|
||||
float NdotL = max(L.z, 0.0)
|
||||
float NdotH = max(H.z, 0.0)
|
||||
float VdotH = max(dot(V, H), 0.0)
|
||||
|
||||
if (NdotL > 0.0)
|
||||
[
|
||||
float G = GeometrySmith(N, V, L, roughness)
|
||||
float G_Vis = (G*VdotH)/(NdotH*NdotV)
|
||||
float Fc = pow(1.0 - VdotH, 5.0)
|
||||
|
||||
A += (1.0 - Fc)*G_Vis
|
||||
B += Fc*G_Vis
|
||||
]
|
||||
]
|
||||
|
||||
# Calculate brdf average sample
|
||||
A /= float(MAX_SAMPLES)
|
||||
B /= float(MAX_SAMPLES)
|
||||
|
||||
return vec2(A, B)
|
||||
]
|
||||
|
||||
void main()
|
||||
[
|
||||
# Calculate brdf based on texture coordinates
|
||||
vec2 brdf = IntegrateBRDF(fragTexCoord.x, fragTexCoord.y)
|
||||
|
||||
# Calculate final fragment color
|
||||
finalColor = vec4(brdf.r, brdf.g, 0.0, 1.0)
|
||||
]
|
25
examples/models/resources/shaders/brdf.vs
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* rPBR [shader] - Bidirectional reflectance distribution function vertex shader
|
||||
*
|
||||
* Copyright (c) 2017 Victor Fisac
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#version 330
|
||||
|
||||
# Input vertex attributes
|
||||
in vec3 vertexPosition
|
||||
in vec2 vertexTexCoord
|
||||
|
||||
# Output vertex attributes (to fragment shader)
|
||||
out vec2 fragTexCoord
|
||||
|
||||
void main()
|
||||
[
|
||||
# Calculate fragment position based on model transformations
|
||||
fragTexCoord = vertexTexCoord
|
||||
|
||||
# Calculate final vertex position
|
||||
gl_Position = vec4(vertexPosition, 1.0)
|
||||
]
|
38
examples/models/resources/shaders/cubemap.fs
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* rPBR [shader] - Equirectangular to cubemap fragment shader
|
||||
*
|
||||
* Copyright (c) 2017 Victor Fisac
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#version 330
|
||||
|
||||
# Input vertex attributes (from vertex shader)
|
||||
in vec3 fragPos
|
||||
|
||||
# Input uniform values
|
||||
uniform sampler2D equirectangularMap
|
||||
|
||||
# Output fragment color
|
||||
out vec4 finalColor
|
||||
|
||||
vec2 SampleSphericalMap(vec3 v)
|
||||
[
|
||||
vec2 uv = vec2(atan(v.z, v.x), asin(v.y))
|
||||
uv *= vec2(0.1591, 0.3183)
|
||||
uv += 0.5
|
||||
return uv
|
||||
]
|
||||
|
||||
void main()
|
||||
[
|
||||
# Normalize local position
|
||||
vec2 uv = SampleSphericalMap(normalize(fragPos))
|
||||
|
||||
# Fetch color from texture map
|
||||
vec3 color = texture(equirectangularMap, uv).rgb
|
||||
|
||||
# Calculate final fragment color
|
||||
finalColor = vec4(color, 1.0)
|
||||
]
|
28
examples/models/resources/shaders/cubemap.vs
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* rPBR [shader] - Equirectangular to cubemap vertex shader
|
||||
*
|
||||
* Copyright (c) 2017 Victor Fisac
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#version 330
|
||||
|
||||
# Input vertex attributes
|
||||
in vec3 vertexPosition
|
||||
|
||||
# Input uniform values
|
||||
uniform mat4 projection
|
||||
uniform mat4 view
|
||||
|
||||
# Output vertex attributes (to fragment shader)
|
||||
out vec3 fragPos
|
||||
|
||||
void main()
|
||||
[
|
||||
# Calculate fragment position based on model transformations
|
||||
fragPos = vertexPosition
|
||||
|
||||
# Calculate final vertex position
|
||||
gl_Position = projection*view*vec4(vertexPosition, 1.0)
|
||||
]
|
58
examples/models/resources/shaders/irradiance.fs
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* rPBR [shader] - Irradiance cubemap fragment shader
|
||||
*
|
||||
* Copyright (c) 2017 Victor Fisac
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#version 330
|
||||
|
||||
# Input vertex attributes (from vertex shader)
|
||||
in vec3 fragPos
|
||||
|
||||
# Input uniform values
|
||||
uniform samplerCube environmentMap
|
||||
|
||||
# Constant values
|
||||
const float PI = 3.14159265359f
|
||||
|
||||
# Output fragment color
|
||||
out vec4 finalColor
|
||||
|
||||
void main()
|
||||
[
|
||||
# The sample direction equals the hemisphere's orientation
|
||||
vec3 normal = normalize(fragPos)
|
||||
|
||||
vec3 irradiance = vec3(0.0)
|
||||
|
||||
vec3 up = vec3(0.0, 1.0, 0.0)
|
||||
vec3 right = cross(up, normal)
|
||||
up = cross(normal, right)
|
||||
|
||||
float sampleDelta = 0.025f
|
||||
float nrSamples = 0.0
|
||||
|
||||
for (float phi = 0.0 phi < 2.0*PI phi += sampleDelta)
|
||||
[
|
||||
for (float theta = 0.0 theta < 0.5*PI theta += sampleDelta)
|
||||
[
|
||||
# Spherical to cartesian (in tangent space)
|
||||
vec3 tangentSample = vec3(sin(theta)*cos(phi), sin(theta)*sin(phi), cos(theta))
|
||||
|
||||
# tangent space to world
|
||||
vec3 sampleVec = tangentSample.x*right + tangentSample.y*up + tangentSample.z*normal
|
||||
|
||||
# Fetch color from environment cubemap
|
||||
irradiance += texture(environmentMap, sampleVec).rgb*cos(theta)*sin(theta)
|
||||
nrSamples++
|
||||
]
|
||||
]
|
||||
|
||||
# Calculate irradiance average value from samples
|
||||
irradiance = PI*irradiance*(1.0/float(nrSamples))
|
||||
|
||||
# Calculate final fragment color
|
||||
finalColor = vec4(irradiance, 1.0)
|
||||
]
|
298
examples/models/resources/shaders/pbr.fs
Normal file
|
@ -0,0 +1,298 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* rPBR [shader] - Physically based rendering fragment shader
|
||||
*
|
||||
* Copyright (c) 2017 Victor Fisac
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#version 330
|
||||
|
||||
#define MAX_REFLECTION_LOD 4.0
|
||||
#define MAX_DEPTH_LAYER 20
|
||||
#define MIN_DEPTH_LAYER 10
|
||||
|
||||
#define MAX_LIGHTS 4
|
||||
#define LIGHT_DIRECTIONAL 0
|
||||
#define LIGHT_POINT 1
|
||||
|
||||
struct MaterialProperty [
|
||||
vec3 color
|
||||
int useSampler
|
||||
sampler2D sampler
|
||||
]
|
||||
|
||||
struct Light [
|
||||
int enabled
|
||||
int type
|
||||
vec3 position
|
||||
vec3 target
|
||||
vec4 color
|
||||
]
|
||||
|
||||
# Input vertex attributes (from vertex shader)
|
||||
in vec3 fragPosition
|
||||
in vec2 fragTexCoord
|
||||
in vec3 fragNormal
|
||||
in vec3 fragTangent
|
||||
in vec3 fragBinormal
|
||||
|
||||
# Input material values
|
||||
uniform MaterialProperty albedo
|
||||
uniform MaterialProperty normals
|
||||
uniform MaterialProperty metalness
|
||||
uniform MaterialProperty roughness
|
||||
uniform MaterialProperty occlusion
|
||||
uniform MaterialProperty emission
|
||||
uniform MaterialProperty height
|
||||
|
||||
# Input uniform values
|
||||
uniform samplerCube irradianceMap
|
||||
uniform samplerCube prefilterMap
|
||||
uniform sampler2D brdfLUT
|
||||
|
||||
# Input lighting values
|
||||
uniform Light lights[MAX_LIGHTS]
|
||||
|
||||
# Other uniform values
|
||||
uniform int renderMode
|
||||
uniform vec3 viewPos
|
||||
vec2 texCoord
|
||||
|
||||
# Constant values
|
||||
const float PI = 3.14159265359
|
||||
|
||||
# Output fragment color
|
||||
out vec4 finalColor
|
||||
|
||||
vec3 ComputeMaterialProperty(MaterialProperty property)
|
||||
float DistributionGGX(vec3 N, vec3 H, float roughness)
|
||||
float GeometrySchlickGGX(float NdotV, float roughness)
|
||||
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
|
||||
vec3 fresnelSchlick(float cosTheta, vec3 F0)
|
||||
vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
|
||||
vec2 ParallaxMapping(vec2 texCoords, vec3 viewDir)
|
||||
|
||||
vec3 ComputeMaterialProperty(MaterialProperty property)
|
||||
[
|
||||
vec3 result = vec3(0.0, 0.0, 0.0)
|
||||
|
||||
if (property.useSampler == 1) result = texture(property.sampler, texCoord).rgb
|
||||
else result = property.color
|
||||
|
||||
return result
|
||||
]
|
||||
|
||||
float DistributionGGX(vec3 N, vec3 H, float roughness)
|
||||
[
|
||||
float a = roughness*roughness
|
||||
float a2 = a*a
|
||||
float NdotH = max(dot(N, H), 0.0)
|
||||
float NdotH2 = NdotH*NdotH
|
||||
|
||||
float nom = a2
|
||||
float denom = (NdotH2*(a2 - 1.0) + 1.0)
|
||||
denom = PI*denom*denom
|
||||
|
||||
return nom/denom
|
||||
]
|
||||
|
||||
float GeometrySchlickGGX(float NdotV, float roughness)
|
||||
[
|
||||
float r = (roughness + 1.0)
|
||||
float k = r*r/8.0
|
||||
|
||||
float nom = NdotV
|
||||
float denom = NdotV*(1.0 - k) + k
|
||||
|
||||
return nom/denom
|
||||
]
|
||||
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
|
||||
[
|
||||
float NdotV = max(dot(N, V), 0.0)
|
||||
float NdotL = max(dot(N, L), 0.0)
|
||||
float ggx2 = GeometrySchlickGGX(NdotV, roughness)
|
||||
float ggx1 = GeometrySchlickGGX(NdotL, roughness)
|
||||
|
||||
return ggx1*ggx2
|
||||
]
|
||||
|
||||
vec3 fresnelSchlick(float cosTheta, vec3 F0)
|
||||
[
|
||||
return F0 + (1.0 - F0)*pow(1.0 - cosTheta, 5.0)
|
||||
]
|
||||
|
||||
vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
|
||||
[
|
||||
return F0 + (max(vec3(1.0 - roughness), F0) - F0)*pow(1.0 - cosTheta, 5.0)
|
||||
]
|
||||
|
||||
vec2 ParallaxMapping(vec2 texCoords, vec3 viewDir)
|
||||
[
|
||||
# Calculate the number of depth layers and calculate the size of each layer
|
||||
float numLayers = mix(MAX_DEPTH_LAYER, MIN_DEPTH_LAYER, abs(dot(vec3(0.0, 0.0, 1.0), viewDir)))
|
||||
float layerDepth = 1.0/numLayers
|
||||
|
||||
# Calculate depth of current layer
|
||||
float currentLayerDepth = 0.0
|
||||
|
||||
# Calculate the amount to shift the texture coordinates per layer (from vector P)
|
||||
# Note: height amount is stored in height material attribute color R channel (sampler use is independent)
|
||||
vec2 P = viewDir.xy*height.color.r
|
||||
vec2 deltaTexCoords = P/numLayers
|
||||
|
||||
# Store initial texture coordinates and depth values
|
||||
vec2 currentTexCoords = texCoords
|
||||
float currentDepthMapValue = texture(height.sampler, currentTexCoords).r
|
||||
|
||||
while (currentLayerDepth < currentDepthMapValue)
|
||||
[
|
||||
# Shift texture coordinates along direction of P
|
||||
currentTexCoords -= deltaTexCoords
|
||||
|
||||
# Get depth map value at current texture coordinates
|
||||
currentDepthMapValue = texture(height.sampler, currentTexCoords).r
|
||||
|
||||
# Get depth of next layer
|
||||
currentLayerDepth += layerDepth
|
||||
]
|
||||
|
||||
# Get texture coordinates before collision (reverse operations)
|
||||
vec2 prevTexCoords = currentTexCoords + deltaTexCoords
|
||||
|
||||
# Get depth after and before collision for linear interpolation
|
||||
float afterDepth = currentDepthMapValue - currentLayerDepth
|
||||
float beforeDepth = texture(height.sampler, prevTexCoords).r - currentLayerDepth + layerDepth
|
||||
|
||||
# Interpolation of texture coordinates
|
||||
float weight = afterDepth/(afterDepth - beforeDepth)
|
||||
vec2 finalTexCoords = prevTexCoords*weight + currentTexCoords*(1.0 - weight)
|
||||
|
||||
return finalTexCoords
|
||||
]
|
||||
|
||||
void main()
|
||||
[
|
||||
# Calculate TBN and RM matrices
|
||||
mat3 TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal))
|
||||
|
||||
# Calculate lighting required attributes
|
||||
vec3 normal = normalize(fragNormal)
|
||||
vec3 view = normalize(viewPos - fragPosition)
|
||||
vec3 refl = reflect(-view, normal)
|
||||
|
||||
# Check if parallax mapping is enabled and calculate texture coordinates to use based on height map
|
||||
# NOTE: remember that 'texCoord' variable must be assigned before calling any ComputeMaterialProperty() function
|
||||
if (height.useSampler == 1) texCoord = ParallaxMapping(fragTexCoord, view)
|
||||
else texCoord = fragTexCoord # Use default texture coordinates
|
||||
|
||||
# Fetch material values from texture sampler or color attributes
|
||||
vec3 color = ComputeMaterialProperty(albedo)
|
||||
vec3 metal = ComputeMaterialProperty(metalness)
|
||||
vec3 rough = ComputeMaterialProperty(roughness)
|
||||
vec3 emiss = ComputeMaterialProperty(emission)
|
||||
vec3 ao = ComputeMaterialProperty(occlusion)
|
||||
|
||||
# Check if normal mapping is enabled
|
||||
if (normals.useSampler == 1)
|
||||
[
|
||||
# Fetch normal map color and transform lighting values to tangent space
|
||||
normal = ComputeMaterialProperty(normals)
|
||||
normal = normalize(normal*2.0 - 1.0)
|
||||
normal = normalize(normal*TBN)
|
||||
|
||||
# Convert tangent space normal to world space due to cubemap reflection calculations
|
||||
refl = normalize(reflect(-view, normal))
|
||||
]
|
||||
|
||||
# Calculate reflectance at normal incidence
|
||||
vec3 F0 = vec3(0.04)
|
||||
F0 = mix(F0, color, metal.r)
|
||||
|
||||
# Calculate lighting for all lights
|
||||
vec3 Lo = vec3(0.0)
|
||||
vec3 lightDot = vec3(0.0)
|
||||
|
||||
for (int i = 0 i < MAX_LIGHTS i++)
|
||||
[
|
||||
if (lights[i].enabled == 1)
|
||||
[
|
||||
# Calculate per-light radiance
|
||||
vec3 light = vec3(0.0)
|
||||
vec3 radiance = lights[i].color.rgb
|
||||
if (lights[i].type == LIGHT_DIRECTIONAL) light = -normalize(lights[i].target - lights[i].position)
|
||||
else if (lights[i].type == LIGHT_POINT)
|
||||
[
|
||||
light = normalize(lights[i].position - fragPosition)
|
||||
float distance = length(lights[i].position - fragPosition)
|
||||
float attenuation = 1.0/(distance*distance)
|
||||
radiance *= attenuation
|
||||
]
|
||||
|
||||
# Cook-torrance BRDF
|
||||
vec3 high = normalize(view + light)
|
||||
float NDF = DistributionGGX(normal, high, rough.r)
|
||||
float G = GeometrySmith(normal, view, light, rough.r)
|
||||
vec3 F = fresnelSchlick(max(dot(high, view), 0.0), F0)
|
||||
vec3 nominator = NDF*G*F
|
||||
float denominator = 4*max(dot(normal, view), 0.0)*max(dot(normal, light), 0.0) + 0.001
|
||||
vec3 brdf = nominator/denominator
|
||||
|
||||
# Store to kS the fresnel value and calculate energy conservation
|
||||
vec3 kS = F
|
||||
vec3 kD = vec3(1.0) - kS
|
||||
|
||||
# Multiply kD by the inverse metalness such that only non-metals have diffuse lighting
|
||||
kD *= 1.0 - metal.r
|
||||
|
||||
# Scale light by dot product between normal and light direction
|
||||
float NdotL = max(dot(normal, light), 0.0)
|
||||
|
||||
# Add to outgoing radiance Lo
|
||||
# Note: BRDF is already multiplied by the Fresnel so it doesn't need to be multiplied again
|
||||
Lo += (kD*color/PI + brdf)*radiance*NdotL*lights[i].color.a
|
||||
lightDot += radiance*NdotL + brdf*lights[i].color.a
|
||||
]
|
||||
]
|
||||
|
||||
# Calculate ambient lighting using IBL
|
||||
vec3 F = fresnelSchlickRoughness(max(dot(normal, view), 0.0), F0, rough.r)
|
||||
vec3 kS = F
|
||||
vec3 kD = 1.0 - kS
|
||||
kD *= 1.0 - metal.r
|
||||
|
||||
# Calculate indirect diffuse
|
||||
vec3 irradiance = texture(irradianceMap, fragNormal).rgb
|
||||
vec3 diffuse = color*irradiance
|
||||
|
||||
# Sample both the prefilter map and the BRDF lut and combine them together as per the Split-Sum approximation
|
||||
vec3 prefilterColor = textureLod(prefilterMap, refl, rough.r*MAX_REFLECTION_LOD).rgb
|
||||
vec2 brdf = texture(brdfLUT, vec2(max(dot(normal, view), 0.0), rough.r)).rg
|
||||
vec3 reflection = prefilterColor*(F*brdf.x + brdf.y)
|
||||
|
||||
# Calculate final lighting
|
||||
vec3 ambient = (kD*diffuse + reflection)*ao
|
||||
|
||||
# Calculate fragment color based on render mode
|
||||
vec3 fragmentColor = ambient + Lo + emiss # Physically Based Rendering
|
||||
|
||||
if (renderMode == 1) fragmentColor = color # Albedo
|
||||
else if (renderMode == 2) fragmentColor = normal # Normals
|
||||
else if (renderMode == 3) fragmentColor = metal # Metalness
|
||||
else if (renderMode == 4) fragmentColor = rough # Roughness
|
||||
else if (renderMode == 5) fragmentColor = ao # Ambient Occlusion
|
||||
else if (renderMode == 6) fragmentColor = emiss # Emission
|
||||
else if (renderMode == 7) fragmentColor = lightDot # Lighting
|
||||
else if (renderMode == 8) fragmentColor = kS # Fresnel
|
||||
else if (renderMode == 9) fragmentColor = irradiance # Irradiance
|
||||
else if (renderMode == 10) fragmentColor = reflection # Reflection
|
||||
|
||||
# Apply HDR tonemapping
|
||||
fragmentColor = fragmentColor/(fragmentColor + vec3(1.0))
|
||||
|
||||
# Apply gamma correction
|
||||
fragmentColor = pow(fragmentColor, vec3(1.0/2.2))
|
||||
|
||||
# Calculate final fragment color
|
||||
finalColor = vec4(fragmentColor, 1.0)
|
||||
]
|
49
examples/models/resources/shaders/pbr.vs
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* rPBR [shader] - Physically based rendering vertex shader
|
||||
*
|
||||
* Copyright (c) 2017 Victor Fisac
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#version 330
|
||||
|
||||
# Input vertex attributes
|
||||
in vec3 vertexPosition
|
||||
in vec2 vertexTexCoord
|
||||
in vec3 vertexNormal
|
||||
in vec4 vertexTangent
|
||||
|
||||
# Input uniform values
|
||||
uniform mat4 mvp
|
||||
uniform mat4 matModel
|
||||
|
||||
# Output vertex attributes (to fragment shader)
|
||||
out vec3 fragPosition
|
||||
out vec2 fragTexCoord
|
||||
out vec3 fragNormal
|
||||
out vec3 fragTangent
|
||||
out vec3 fragBinormal
|
||||
|
||||
void main()
|
||||
[
|
||||
# Calculate binormal from vertex normal and tangent
|
||||
vec3 vertexBinormal = cross(vertexNormal, vec3(vertexTangent))
|
||||
|
||||
# Calculate fragment normal based on normal transformations
|
||||
mat3 normalMatrix = transpose(inverse(mat3(matModel)))
|
||||
|
||||
# Calculate fragment position based on model transformations
|
||||
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0))
|
||||
|
||||
# Send vertex attributes to fragment shader
|
||||
fragTexCoord = vertexTexCoord
|
||||
fragNormal = normalize(normalMatrix*vertexNormal)
|
||||
fragTangent = normalize(normalMatrix*vec3(vertexTangent))
|
||||
fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal)
|
||||
fragBinormal = normalize(normalMatrix*vertexBinormal)
|
||||
fragBinormal = cross(fragNormal, fragTangent)
|
||||
|
||||
# Calculate final vertex position
|
||||
gl_Position = mvp*vec4(vertexPosition, 1.0)
|
||||
]
|
120
examples/models/resources/shaders/prefilter.fs
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* rPBR [shader] - Prefiltered environment for reflections fragment shader
|
||||
*
|
||||
* Copyright (c) 2017 Victor Fisac
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#version 330
|
||||
#define MAX_SAMPLES 1024u
|
||||
#define CUBEMAP_RESOLUTION 1024.0
|
||||
|
||||
# Input vertex attributes (from vertex shader)
|
||||
in vec3 fragPos
|
||||
|
||||
# Input uniform values
|
||||
uniform samplerCube environmentMap
|
||||
uniform float roughness
|
||||
|
||||
# Constant values
|
||||
const float PI = 3.14159265359f
|
||||
|
||||
# Output fragment color
|
||||
out vec4 finalColor
|
||||
|
||||
float DistributionGGX(vec3 N, vec3 H, float roughness)
|
||||
float RadicalInverse_VdC(uint bits)
|
||||
vec2 Hammersley(uint i, uint N)
|
||||
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
|
||||
|
||||
float DistributionGGX(vec3 N, vec3 H, float roughness)
|
||||
[
|
||||
float a = roughness*roughness
|
||||
float a2 = a*a
|
||||
float NdotH = max(dot(N, H), 0.0)
|
||||
float NdotH2 = NdotH*NdotH
|
||||
|
||||
float nom = a2
|
||||
float denom = (NdotH2*(a2 - 1.0) + 1.0)
|
||||
denom = PI*denom*denom
|
||||
|
||||
return nom/denom
|
||||
]
|
||||
|
||||
float RadicalInverse_VdC(uint bits)
|
||||
[
|
||||
bits = (bits << 16u) | (bits >> 16u)
|
||||
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u)
|
||||
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u)
|
||||
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u)
|
||||
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u)
|
||||
return float(bits) * 2.3283064365386963e-10 # / 0x100000000
|
||||
]
|
||||
|
||||
vec2 Hammersley(uint i, uint N)
|
||||
[
|
||||
return vec2(float(i)/float(N), RadicalInverse_VdC(i))
|
||||
]
|
||||
|
||||
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
|
||||
[
|
||||
float a = roughness*roughness
|
||||
float phi = 2.0 * PI * Xi.x
|
||||
float cosTheta = sqrt((1.0 - Xi.y)/(1.0 + (a*a - 1.0)*Xi.y))
|
||||
float sinTheta = sqrt(1.0 - cosTheta*cosTheta)
|
||||
|
||||
# Transform from spherical coordinates to cartesian coordinates (halfway vector)
|
||||
vec3 H = vec3(cos(phi)*sinTheta, sin(phi)*sinTheta, cosTheta)
|
||||
|
||||
# Transform from tangent space H vector to world space sample vector
|
||||
vec3 up = ((abs(N.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0))
|
||||
vec3 tangent = normalize(cross(up, N))
|
||||
vec3 bitangent = cross(N, tangent)
|
||||
vec3 sampleVec = tangent*H.x + bitangent*H.y + N*H.z
|
||||
|
||||
return normalize(sampleVec)
|
||||
]
|
||||
|
||||
void main()
|
||||
[
|
||||
# Make the simplyfying assumption that V equals R equals the normal
|
||||
vec3 N = normalize(fragPos)
|
||||
vec3 R = N
|
||||
vec3 V = R
|
||||
|
||||
vec3 prefilteredColor = vec3(0.0)
|
||||
float totalWeight = 0.0
|
||||
|
||||
for (uint i = 0u i < MAX_SAMPLES i++)
|
||||
[
|
||||
# Generate a sample vector that's biased towards the preferred alignment direction (importance sampling)
|
||||
vec2 Xi = Hammersley(i, MAX_SAMPLES)
|
||||
vec3 H = ImportanceSampleGGX(Xi, N, roughness)
|
||||
vec3 L = normalize(2.0*dot(V, H)*H - V)
|
||||
|
||||
float NdotL = max(dot(N, L), 0.0)
|
||||
if(NdotL > 0.0)
|
||||
[
|
||||
# Sample from the environment's mip level based on roughness/pdf
|
||||
float D = DistributionGGX(N, H, roughness)
|
||||
float NdotH = max(dot(N, H), 0.0)
|
||||
float HdotV = max(dot(H, V), 0.0)
|
||||
float pdf = D*NdotH/(4.0*HdotV) + 0.0001
|
||||
|
||||
float resolution = CUBEMAP_RESOLUTION
|
||||
float saTexel = 4.0*PI/(6.0*resolution*resolution)
|
||||
float saSample = 1.0/(float(MAX_SAMPLES)*pdf + 0.0001)
|
||||
float mipLevel = ((roughness == 0.0) ? 0.0 : 0.5*log2(saSample/saTexel))
|
||||
|
||||
prefilteredColor += textureLod(environmentMap, L, mipLevel).rgb*NdotL
|
||||
totalWeight += NdotL
|
||||
]
|
||||
]
|
||||
|
||||
# Calculate prefilter average color
|
||||
prefilteredColor = prefilteredColor/totalWeight
|
||||
|
||||
# Calculate final fragment color
|
||||
finalColor = vec4(prefilteredColor, 1.0)
|
||||
]
|
31
examples/models/resources/shaders/skybox.fs
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* rPBR [shader] - Background skybox fragment shader
|
||||
*
|
||||
* Copyright (c) 2017 Victor Fisac
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#version 330
|
||||
|
||||
# Input vertex attributes (from vertex shader)
|
||||
in vec3 fragPos
|
||||
|
||||
# Input uniform values
|
||||
uniform samplerCube environmentMap
|
||||
|
||||
# Output fragment color
|
||||
out vec4 finalColor
|
||||
|
||||
void main()
|
||||
[
|
||||
# Fetch color from texture map
|
||||
vec3 color = texture(environmentMap, fragPos).rgb
|
||||
|
||||
# Apply gamma correction
|
||||
color = color/(color + vec3(1.0))
|
||||
color = pow(color, vec3(1.0/2.2))
|
||||
|
||||
# Calculate final fragment color
|
||||
finalColor = vec4(color, 1.0)
|
||||
]
|
32
examples/models/resources/shaders/skybox.vs
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* rPBR [shader] - Background skybox vertex shader
|
||||
*
|
||||
* Copyright (c) 2017 Victor Fisac
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#version 330
|
||||
|
||||
# Input vertex attributes
|
||||
in vec3 vertexPosition
|
||||
|
||||
# Input uniform values
|
||||
uniform mat4 projection
|
||||
uniform mat4 view
|
||||
|
||||
# Output vertex attributes (to fragment shader)
|
||||
out vec3 fragPos
|
||||
|
||||
void main()
|
||||
[
|
||||
# Calculate fragment position based on model transformations
|
||||
fragPos = vertexPosition
|
||||
|
||||
# Remove translation from the view matrix
|
||||
mat4 rotView = mat4(mat3(view))
|
||||
vec4 clipPos = projection*rotView*vec4(vertexPosition, 1.0)
|
||||
|
||||
# Calculate final vertex position
|
||||
gl_Position = clipPos.xyww
|
||||
]
|
34
raylib/__init__.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
__version__ = "2.5.dev1"
|
||||
|
||||
from ._raylib_cffi import ffi, lib as rl
|
||||
from _raylib_cffi.lib import *
|
||||
|
||||
def Vector3(x, y, z):
|
||||
return ffi.new("struct Vector3 *", [x, y, z])[0]
|
||||
|
||||
LIGHTGRAY =( 200, 200, 200, 255 )
|
||||
GRAY =( 130, 130, 130, 255 )
|
||||
DARKGRAY =( 80, 80, 80, 255 )
|
||||
YELLOW =( 253, 249, 0, 255 )
|
||||
GOLD =( 255, 203, 0, 255 )
|
||||
ORANGE =( 255, 161, 0, 255 )
|
||||
PINK =( 255, 109, 194, 255 )
|
||||
RED =( 230, 41, 55, 255 )
|
||||
MAROON =( 190, 33, 55, 255 )
|
||||
GREEN =( 0, 228, 48, 255 )
|
||||
LIME =( 0, 158, 47, 255 )
|
||||
DARKGREEN =( 0, 117, 44, 255 )
|
||||
SKYBLUE =( 102, 191, 255, 255 )
|
||||
BLUE =( 0, 121, 241, 255 )
|
||||
DARKBLUE =( 0, 82, 172, 255 )
|
||||
PURPLE =( 200, 122, 255, 255 )
|
||||
VIOLET =( 135, 60, 190, 255 )
|
||||
DARKPURPLE =( 112, 31, 126, 255 )
|
||||
BEIGE =( 211, 176, 131, 255 )
|
||||
BROWN =( 127, 106, 79, 255 )
|
||||
DARKBROWN =( 76, 63, 47, 255 )
|
||||
WHITE =( 255, 255, 255, 255 )
|
||||
BLACK =( 0, 0, 0, 255 )
|
||||
BLANK =( 0, 0, 0, 0 )
|
||||
MAGENTA =( 255, 0, 255, 255 )
|
||||
RAYWHITE =( 245, 245, 245, 255 )
|
21455
raylib/_raylib_cffi.c
Normal file
BIN
raylib/_raylib_cffi.o
Normal file
26
raylib/build.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
from cffi import FFI
|
||||
import os
|
||||
ffibuilder = FFI()
|
||||
|
||||
# cdef() expects a single string declaring the C types, functions and
|
||||
# globals needed to use the shared object. It must be in valid C syntax.
|
||||
ffibuilder.cdef(open("raylib_modified.h").read().replace('RLAPI ', ''))
|
||||
|
||||
# set_source() gives the name of the python extension module to
|
||||
# produce, and some C source code as a string. This C code needs
|
||||
# to make the declarated functions, types and globals available,
|
||||
# so it is often just the "#include".
|
||||
ffibuilder.set_source("_raylib_cffi",
|
||||
"""
|
||||
#include "raylib.h" // the C header of the library
|
||||
""",
|
||||
#library_dirs=['/Volumes/Home/rich/raylib-latest/src'],
|
||||
# extra_link_args=['-Wl,-rpath,.'],
|
||||
#extra_link_args=["/usr/local/lib/libraylib.a","-framework OpenGL"]# -F/System/Library/Frameworks -framework OpenGL -framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo"]
|
||||
# library_dirs=[os.path.dirname(__file__)+"/../lib"],
|
||||
#libraries=['raylib']
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
ffibuilder.compile(verbose=True)
|
||||
os.system("clang -bundle -undefined dynamic_lookup ./_raylib_cffi.o -L/usr/local/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/sqlite/lib libraylib.a -F/System/Library/Frameworks -framework OpenGL -framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo -o ./_raylib_cffi.cpython-37m-darwin.so")
|
BIN
raylib/libraylib.a
Normal file
1406
raylib/raylib.h
Normal file
1065
raylib/raylib_cheatsheet_copy_paste.h
Normal file
1318
raylib/raylib_modified.h
Normal file
1181
raylib/raylib_modified_2.0.h
Normal file
30
setup.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
import pathlib
|
||||
from setuptools import setup
|
||||
|
||||
# The directory containing this file
|
||||
HERE = pathlib.Path(__file__).parent
|
||||
|
||||
# The text of the README file
|
||||
README = (HERE / "README.md").read_text()
|
||||
|
||||
# This call to setup() does all the work
|
||||
setup(
|
||||
name="raylib",
|
||||
version="2.5.dev1",
|
||||
description="Python CFFI bindings for Raylib",
|
||||
long_description=README,
|
||||
long_description_content_type="text/markdown",
|
||||
url="https://github.com/electronstudio/raylib-python-cffi",
|
||||
author="Electron Studio",
|
||||
author_email="richard@electronstudio.co.uk",
|
||||
license="LGPLv3+",
|
||||
classifiers=[
|
||||
"License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
],
|
||||
packages=["raylib"],
|
||||
include_package_data=False,
|
||||
install_requires=["cffi"],
|
||||
# cffi_modules=["raylib/build.py:ffibuilder"], # this would build libs whenever the module is installed, but we are distributing static libs instead
|
||||
)
|
39
test.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
from raylib import *
|
||||
|
||||
|
||||
InitWindow(800,450,b"foo")
|
||||
SetTargetFPS(60)
|
||||
|
||||
|
||||
|
||||
camera = ffi.new("struct Camera3D *", [[ 18.0, 16.0, 18.0 ], [ 0.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], 45.0, 0 ])
|
||||
|
||||
# (( 18.0, 16.0, 18.0 ), ( 0.0, 0.0, 0.0 ), ( 0.0, 1.0, 0.0 ), 45.0, 0 )
|
||||
|
||||
|
||||
|
||||
image = LoadImage(b"resources/heightmap.png") # Load heightmap image (RAM)
|
||||
texture = LoadTextureFromImage(image) # Convert image to texture (VRAM)
|
||||
|
||||
mesh = GenMeshHeightmap(image, ( 16, 8, 16 )) # Generate heightmap mesh (RAM and VRAM)
|
||||
model = LoadModelFromMesh(mesh) # Load model from generated mesh
|
||||
|
||||
model.materials[0].maps[MAP_DIFFUSE].texture = texture # Set map diffuse texture
|
||||
mapPosition = ( -8.0, 0.0, -8.0 ) # Define model position
|
||||
|
||||
UnloadImage(image) # Unload heightmap image from RAM, already uploaded to VRAM
|
||||
|
||||
SetCameraMode(camera[0], CAMERA_ORBITAL) # Set an orbital camera mode
|
||||
|
||||
|
||||
while not WindowShouldClose():
|
||||
UpdateCamera(camera)
|
||||
BeginDrawing()
|
||||
ClearBackground(RAYWHITE)
|
||||
BeginMode3D(camera[0])
|
||||
DrawModel(model, mapPosition, 1.0, RED)
|
||||
DrawGrid(20, 1.0)
|
||||
EndMode3D()
|
||||
DrawText(b"sdfsdf", 190, 200, 20, BLACK)
|
||||
EndDrawing()
|
||||
CloseWindow()
|