Merge branch 'master' of https://github.com/raysan5/raylib into raysan5-master

# Conflicts:
#	projects/VS2017/examples/core_basic_window.vcxproj
#	projects/VS2017/examples/core_basic_window_cpp.vcxproj
#	projects/VS2017/raylib/raylib.vcxproj
#	src/raylib.h
This commit is contained in:
Jak Barnes 2019-04-20 12:58:57 +01:00
commit 31e9cfe2a5
112 changed files with 5118 additions and 3866 deletions

View File

@ -7,6 +7,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
- [raylib-lua-ffi](https://github.com/raysan5/raylib/issues/693) : raylib **Lua** ffi binding
- [raylib-go](https://github.com/gen2brain/raylib-go) : raylib **Go** binding
- [raylib-Nim](https://gitlab.com/define-private-public/raylib-Nim) : raylib **Nim** binding
- [raylib-cr](https://github.com/AregevDev/raylib-cr) : raylib **Crystal** binding
- [cray](https://gitlab.com/Zatherz/cray) - raylib **Crystal** binding
- [Graphics::Raylib](https://metacpan.org/pod/Graphics::Raylib) : raylib **Perl** wrapper
- [raylib-pascal](https://github.com/drezgames/raylib-pascal) - raylib **Pascal** binding
@ -19,8 +20,12 @@ Some people ported raylib to other languages in form of bindings or wrappers to
- [raylib-java](https://github.com/XoanaIO/raylib-java) : raylib **Java** binding
- [raylib-chaiscript](https://github.com/RobLoach/raylib-chaiscript) : raylib **ChaiScript** binding
- [node-raylib](https://github.com/RobLoach/node-raylib) : **Node.js** raylib binding
- *[raylib flat-assembler Usage example]()*
- [raylib-odin](https://github.com/kevinw/raylib-odin): **Odin** raylib binding
- [raylib-factor](https://github.com/Silverbeard00/raylib-factor): **Factor** raylib binding
- *[raylib COBOL Usage example](https://github.com/Martinfx/Cobol/tree/master/OpenCobol/Games/raylib)*
- *raylib flat-assembler Usage example*: not uploaded yet...
Missing some language? Check the [bindings not yet in this list](https://gist.github.com/raysan5/5764cc5b885183f523fce47f098f3d9b#bindings-not-yet-in-the-official-list) or create a new binding! :)
Usually, raylib bindings follow the convention: `raylib-{language}`

126
CHANGELOG
View File

@ -3,6 +3,132 @@ changelog
Current Release: raylib 2.0.0 (July 2018)
-----------------------------------------------
Release: raylib 2.5 (May 2019)
-----------------------------------------------
KEY CHANGES:
- New text management API
- Cubemap textures support
- Skeletal model animation support
- New textures drawing: Quad and N-Patch based rectangles
- New drawing shapes available: CircleSector, Ring and RectangleRounded
- VR system redesign to allow custom device parameters and distortion shader
Detailed changes:
[build] ...
[build] REVIEWED: Notepad++ NppExec scripts
[build] REVIEWED: VS2015 and VS2017 projects
[build] REVIEWED: Android APK build pipeline
[core] Converted most #defined values as enum values
[core] Complete redesign of RPI input system
[core] ADDED: IsWindowResized() - Check if window has been resized
[core] ADDED: IsWindowHidden() - Check if window is currently hidden
[core] ADDED: UnhideWindow() - Show the window
[core] ADDED: HideWindow() - Hide the window
[core] ADDED: GetWindowHandle() - Get native window handle
[core] ADDED: GetMonitorCount() - Get number of connected monitors
[core] ADDED: GetMonitorWidth() - Get primary monitor width
[core] ADDED: GetMonitorHeight() - Get primary monitor height
[core] ADDED: GetMonitorPhysicalWidth() - Get primary monitor physical width in millimetres
[core] ADDED: GetMonitorPhysicalHeight() - Get primary monitor physical height in millimetres
[core] ADDED: GetMonitorName() - Get the human-readable, UTF-8 encoded name of the primary monitor
[core] ADDED: GetClipboardText() - Get clipboard text content
[core] ADDED: SetClipboardText() - Set clipboard text content
[core] ADDED: ColorFromHSV() - Returns a Color from HSV values
[core] ADDED: FileExists() - Check if file exists
[core] ADDED: GetFileNameWithoutExt() - Get filename string without extension (memory should be freed)
[core] ADDED: GetDirectoryFiles() - Get filenames in a directory path (memory should be freed)
[core] ADDED: ClearDirectoryFiles() - Clear directory files paths buffers (free memory)
[core] ADDED: OpenURL() - Open URL with default system browser (if available)
[core] ADDED: SetMouseOffset() - Set mouse offset
[core] ADDED: SetMouseScale() - Set mouse scaling
[core] REMOVED: ShowLogo() - Activate raylib logo at startup (can be done with flags)
[shapes] ADDED: DrawCircleSector() - Draw a piece of a circle
[shapes] ADDED: DrawCircleSectorLines() - Draw circle sector outline
[shapes] ADDED: DrawRing() - Draw ring
[shapes] ADDED: DrawRingLines() - Draw ring outline
[shapes] ADDED: DrawRectangleRounded() - Draw rectangle with rounded edges
[shapes] ADDED: DrawRectangleRoundedLines() - Draw rectangle with rounded edges outline
[shapes] ADDED: SetShapesTexture() - Define default texture used to draw shapes
[textures] REVIEWED: ExportImage() - Reorder function parameters
[textures] REVIEWED: ImageDrawRectangle() - Remove unneeded parameter
[textures] ADDED: ExportImageAsCode() - Export image as code file defining an array of bytes
[textures] ADDED: LoadTextureCubemap() - Load cubemap from image, multiple image cubemap layouts supported
[textures] ADDED: ImageExtractPalette() - Extract color palette from image to maximum size (memory should be freed)
[textures] ADDED: ImageDrawRectangleLines() - Draw rectangle lines within an image
[textures] ADDED: DrawTextureQuad() - Draw texture quad with tiling and offset parameters
[textures] ADDED: DrawTextureNPatch() - Draws a texture (or part of it) that stretches or shrinks nicely
[models] REVIEWED: LoadMesh() -> LoadMeshes() - Support multiple meshes loading
[models] REVIEWED: LoadMaterial() -> LoadMaterials() - Support multiple materials loading
[models] REVIEWED: ExportMesh() - Reorder parameters
[models] ADDED: DrawCubeWiresV() - Draw cube wires (Vector version)
[models] ADDED: GenMeshPoly() - Generate polygonal mesh
[models] ADDED: SetMaterialTexture() - Set texture for a material map type (MAP_DIFFUSE, MAP_SPECULAR...)
[models] ADDED: SetModelMeshMaterial() - Set material for a mesh
[models] ADDED: LoadModelAnimations() - Load model animations from file
[models] ADDED: UpdateModelAnimation() - Update model animation pose
[models] ADDED: UnloadModelAnimation() - Unload animation data
[models] ADDED: IsModelAnimationValid() - Check model animation skeleton match
[rlgl] Improved internal batching mechanism (multibuffering support, triangle texcoords...)
[rlgl] REVIEWED: rlPushMatrix()/rlPopMatrix() - Now works like OpenGL 1.1
[rlgl] REVIEWED: SetShaderValue() - More generic, now requires uniform type
[rlgl] REMOVED: SetShaderValuei() - Can be acoomplished with new SetShaderValue()
[rlgl] ADDED: SetShaderValueV() - Set shader uniform value vector
[rlgl] ADDED: SetShaderValueTexture() - Set shader uniform value for texture
[rlgl] ADDED: BeginScissorMode() - Begin scissor mode (define screen area for following drawing)
[rlgl] ADDED: EndScissorMode() - End scissor mode
[rlgl] ADDED: SetVrConfiguration() - Set stereo rendering configuration parameters
[rlgl] REVIEWED: InitVrSimulator() - No input parameter required, use SetVrConfiguration()
[text] REVIEWED: LoadFontEx() - Reorder function parameters
[text] REVIEWED: LoadFontData() - Reorder function parameters
[text] REVIEWED: GenImageFontAtlas() - Reorder function parameters
[text] RENAMED: FormatText() -> TextFormat()
[text] RENAMED: SubText() -> TextSubtext()
[text] ADDED: LoadFontFromImage() - Load font from Image (XNA style)
[text] ADDED: DrawTextRec() - Draw text using font inside rectangle limits
[text] ADDED: DrawTextRecEx() - Draw text using font inside rectangle limits with support for text selection
[text] ADDED: TextIsEqual() - Check if two text string are equal
[text] ADDED: TextLength() - Get text length, checks for '\0' ending
[text] ADDED: TextReplace() - Replace text string (memory should be freed!)
[text] ADDED: TextInsert() - Insert text in a position (memory should be freed!)
[text] ADDED: TextJoin() - Join text strings with delimiter
[text] ADDED: TextSplit() - Split text into multiple strings
[text] ADDED: TextAppend() - Append text at specific position and move cursor!
[text] ADDED: TextFindIndex() - Find first text occurrence within a string
[text] ADDED: TextToUpper() - Get upper case version of provided string
[text] ADDED: TextToLower() - Get lower case version of provided string
[text] ADDED: TextToPascal() - Get Pascal case notation version of provided string
[text] ADDED: TextToInteger() - Get integer value from text (negative values not supported)
[raudio] ADDED: ExportWave() - Export wave data to file
[raudio] ADDED: ExportWaveAsCode() - Export wave sample data to code (.h)
[raudio] ADDED: IsAudioStreamPlaying() - Check if audio stream is playing
[raudio] ADDED: SetAudioStreamVolume() - Set volume for audio stream (1.0 is max level)
[raudio] ADDED: SetAudioStreamPitch() - Set pitch for audio stream (1.0 is base level)
[examples] ADDED: core_custom_logging - Custom trace log system
[examples] ADDED: core_input_multitouch - Multitouch input example
[examples] REVIEWED: core_vr_simulator - HMD device parameters and distortion shader should be provided
[examples] ADDED: core_window_scale_letterbox - Windows resizing and letterbox content
[examples] ADDED: shapes_rectangle_scaling_mouse - Scale a rectangle with mouse
TODO: [examples] ADDED: shapes_draw_circle_sector - Circle sector drawing
TODO: [examples] ADDED: shapes_draw_ring - Ring drawing
TODO: [examples] ADDED: shapes_draw_rectangle_rounded - Rounded rectangle drawing
[examples] ADDED: textures_background_scrolling - Scrolling and parallaz background effect
[examples] ADDED: textures_image_npatch - Drawing N-Patch based boxes
TODO: [examples] ADDED: textures_sprite_button
TODO: [examples] ADDED: textures_sprite_explosion
[examples] ADDED: text_draw_inside_rectangle - Drawing text inside a delimited rectangle box
[examples] ADDED: models_animation - Animated models loading and animation playing
[examples] ADDED: models_obj_viewer - Draw and drop models viewer
[examples] ADDED: models_rlgl_solar_system - Solar system simulation using rlgl functionality
[examples] ADDED: shaders_palette_switch - Switching color palette on shader
[examples] ADDED: shaders_raymarching - Raymarching shader
[examples] ADDED: shaders_texture_drawing - Texture drawing on GPU
[examples] REVIEWED: audio_raw_stream - Mostly rewritten
[games] ADDED: GGJ19 game - Cat vs Roomba
[*] Updated external libraries to latest version
[*] Multiple bugs corrected (check github issues)
-----------------------------------------------
Release: raylib 2.0 (July 2018)
-----------------------------------------------

View File

@ -225,3 +225,8 @@ Refactored all raylib configuration #defines into a **centralized `config.h` hea
A part of that, lots of new features, like a brand **new font rendering and packaging system** for TTF fonts with **SDF support** (thanks to the amazing STB headers), new functions for **CPU image data manipulation**, new orthographic 3d camera mode, a complete review of `raymath.h` single-file header-only library for better consistency and performance, new examples and way, [way more](https://github.com/raysan5/raylib/blob/master/CHANGELOG).
Probably by now, **raylib 2.0 is the simplest and easiest-to-use library to learn (and understand) videogames programming**... but, undoubtly its development has exceeded any initial objective; raylib has become a simple and easy-to-use trully multiplatform portable standalone media library with thousands of possibilities... and that's just the beginning!
notes on raylib 2.5
-------------------
SOON.

View File

@ -4,11 +4,13 @@
raylib is highly inspired by Borland BGI graphics lib and by XNA framework.
raylib could be useful for prototyping, tools development, graphic applications, embedded systems and education.
raylib is especially well suited for prototyping, tooling, graphical applications, embedded systems and education.
NOTE for ADVENTURERS: raylib is a programming library to enjoy videogames programming;
no fancy interface, no visual helpers, no auto-debugging... just coding in the most
pure spartan-programmers way. Are you ready to learn? Jump to [code examples!](http://www.raylib.com/examples.html)
pure spartan-programmers way.
Ready to learn? Jump to [code examples!](http://www.raylib.com/examples.html)
[![Build Status](https://travis-ci.org/raysan5/raylib.svg?branch=master)](https://travis-ci.org/raysan5/raylib)
[![https://ci.appveyor.com/api/projects/status/github/raysan5/raylib?svg=true](https://ci.appveyor.com/api/projects/status/github/raysan5/raylib?svg=true)](https://ci.appveyor.com/project/raysan5/raylib)
@ -18,20 +20,20 @@ pure spartan-programmers way. Are you ready to learn? Jump to [code examples!](h
features
--------
- **NO external dependencies**, all required libraries included with raylib
- **NO external dependencies**, all required libraries are bundled into raylib
- Multiple platforms supported: **Windows, Linux, MacOS, Android... and many more!**
- Written in plain C code (C99) in PascalCase/camelCase notation
- Hardware accelerated with OpenGL (**1.1, 2.1, 3.3 or ES 2.0**)
- **Unique OpenGL abstraction layer** (usable as standalone module): [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h)
- Multiple Fonts formats supported (XNA fonts, AngelCode fonts, TTF)
- Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC)
- **Full 3d support** for 3d Shapes, Models, Billboards, Heightmaps and more!
- **Full 3D support**, including 3D Shapes, Models, Billboards, Heightmaps and more!
- Flexible Materials system, supporting classic maps and **PBR maps**
- Shaders support, including Model shaders and Postprocessing shaders
- Custom shaders, including model and postprocessing shaders.
- **Powerful math module** for Vector, Matrix and Quaternion operations: [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h)
- Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, XM, MOD)
- **VR stereo rendering** support with configurable HMD device parameters
- Bindings to **Lua** ([raylib-lua](https://github.com/raysan5/raylib-lua)), **Go** ([raylib-go](https://github.com/gen2brain/raylib-go)) and [more](https://github.com/raysan5/raylib/blob/master/CONTRIBUTING.md#raylib-bindings)!
- Bindings to [multiple code languages](https://github.com/raysan5/raylib/blob/master/BINDINGS.md)!
raylib uses on its [core](https://github.com/raysan5/raylib/blob/master/src/core.c) module the outstanding [GLFW3](http://www.glfw.org/) library, embedded inside raylib in the form of [rglfw](https://github.com/raysan5/raylib/blob/master/src/rglfw.c) module, avoiding that way external dependencies.
@ -46,16 +48,16 @@ raylib uses internally multiple single-file header-only libraries to support mul
build and installation
----------------------
Binary releases for Windows, Linux and macOS are available at the [Github Releases](https://github.com/raysan5/raylib/releases) page. raylib is also available via multiple package managers on multiple OS distributions. For more info check [raylib Wiki](https://github.com/raysan5/raylib/wiki).
Binary releases for Windows, Linux and macOS are available at the [Github Releases page](https://github.com/raysan5/raylib/releases). raylib is also available via multiple package managers on multiple OS distributions. For more info check [raylib Wiki](https://github.com/raysan5/raylib/wiki).
To build raylib yourself, check out also the [raylib Wiki](https://github.com/raysan5/raylib/wiki) for detailed instructions.
If you wish to build raylib yourself, [the raylib Wiki](https://github.com/raysan5/raylib/wiki) also contains detailed instructions on how to approach that.
raylib has been developed using exclusively two tools:
raylib has been developed exclusively using two tools:
* Notepad++ (text editor) - [http://notepad-plus-plus.org/](http://notepad-plus-plus.org/)
* MinGW (GCC compiler) - [http://www.mingw.org/](http://www.mingw.org/)
* Notepad++ (text editor) - [http://notepad-plus-plus.org](http://notepad-plus-plus.org/)
* MinGW (GCC compiler) - [http://www.mingw.org](http://www.mingw.org/)
Those are the tools recommended to develop with raylib, in fact, those are the tools my students use.
Those tools are recommended for raylib development.
contact
-------
@ -71,7 +73,7 @@ contact
If you are using raylib and you enjoy it, please, [let me know][raysan5].
If you feel you can help, then, [helpme!](http://www.raylib.com/helpme.html)
If you are able to contribute, then please [helpme](http://www.raylib.com/helpme.html)!
license
-------

View File

@ -7,10 +7,10 @@ Here it is a wish-list with features and ideas to improve the library.
Note that [raylib source code](https://github.com/raysan5/raylib/tree/master/src) has some *TODO* marks around code with pending things to review and improve. Check [GitHub Issues](https://github.com/raysan5/raylib/issues) for further details!
**raylib 2.x**
- [ ] raynet: Network module
- [ ] rnet: Network module
- [ ] Support Vulkan API (GRAPHICS_API_VULKAN)
- [ ] Basic CPU/GPU stats sytem (memory, draws, time...)
- [ ] Support Animated models
- [x] Support Animated models (2.5)
**raylib 1.8**
- [x] Improved Materials system with PBR support

View File

@ -47,6 +47,7 @@ if(${PLATFORM} MATCHES "Android")
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_billboard.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_rlgl_solar_system.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_obj_viewer.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_animation.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_custom_uniform.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_model_shader.c)

View File

@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
# Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.
@ -377,7 +377,7 @@ EXAMPLES = \
core/core_2d_camera \
core/core_world_screen \
core/core_vr_simulator \
core/core_multitouch \
core/core_input_multitouch \
shapes/shapes_logo_raylib \
shapes/shapes_basic_shapes \
shapes/shapes_colors_palette \

View File

@ -7,7 +7,7 @@
* This example has been created using raylib 1.6 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2015-2018 Ramon Santamaria (@raysan5) and James Hofmann (@triplefox)
* Copyright (c) 2015-2019 Ramon Santamaria (@raysan5) and James Hofmann (@triplefox)
*
********************************************************************************************/

View File

@ -1,17 +1,15 @@
/*******************************************************************************************
*
* raylib [core] example - Multitouch input
* raylib [core] example - Input multitouch
*
* This example has been created using raylib 2.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
* Example by Berni
* Copyright (c) 2014-2019 Berni and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include <stdio.h>
int main()
{
@ -20,13 +18,13 @@ int main()
int screenWidth = 800;
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - multitouch input");
InitWindow(screenWidth, screenHeight, "raylib [core] example - input multitouch");
Vector2 ballPosition = { -100.0f, -100.0f };
Color ballColor;
int PressedCounter = 0;
Vector2 TouchPos;
char Str[16];
Color ballColor = BEIGE;
int touchCounter = 0;
Vector2 touchPosition;
SetTargetFPS(60);
//---------------------------------------------------------------------------------------
@ -44,11 +42,11 @@ int main()
if (IsMouseButtonDown(MOUSE_MIDDLE_BUTTON)) ballColor = LIME;
if (IsMouseButtonDown(MOUSE_RIGHT_BUTTON)) ballColor = DARKBLUE;
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) PressedCounter = 10;
if (IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) PressedCounter = 10;
if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) PressedCounter = 10;
if(PressedCounter > 0)
PressedCounter--;
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) touchCounter = 10;
if (IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) touchCounter = 10;
if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) touchCounter = 10;
if (touchCounter > 0) touchCounter--;
//----------------------------------------------------------------------------------
// Draw
@ -60,19 +58,18 @@ int main()
// Multitouch
for (int i = 0; i < MAX_TOUCH_POINTS; ++i)
{
TouchPos = GetTouchPosition(i); // Get the touch point
touchPosition = GetTouchPosition(i); // Get the touch point
if( (TouchPos.x >= 0) && (TouchPos.y >= 0) ) // Make sure point is not (-1,-1) as this means there is no touch for it
if ((touchPosition.x >= 0) && (touchPosition.y >= 0)) // Make sure point is not (-1,-1) as this means there is no touch for it
{
DrawCircleV(TouchPos, 34, ORANGE); // Draw a circle there
sprintf(Str,"%d",i);
DrawText(Str, TouchPos.x - 10, TouchPos.y - 70, 40, BLACK); // Also show its index number
// Draw circle and touch index number
DrawCircleV(touchPosition, 34, ORANGE);
DrawText(FormatText("%d", i), touchPosition.x - 10, touchPosition.y - 70, 40, BLACK);
}
}
// Draw the normal mouse location
DrawCircleV(ballPosition, 30 + (PressedCounter * 3), ballColor);
DrawCircleV(ballPosition, 30 + (touchCounter*3), ballColor);
DrawText("move ball with mouse and click mouse button to change color", 10, 10, 20, DARKGRAY);
DrawText("touch the screen at multiple locations to get multiple balls", 10, 30, 20, DARKGRAY);

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -23,7 +23,35 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [core] example - vr simulator");
// Init VR simulator (Oculus Rift CV1 parameters)
InitVrSimulator(GetVrDeviceInfo(HMD_OCULUS_RIFT_CV1));
InitVrSimulator();
VrDeviceInfo hmd = { 0 }; // VR device parameters (head-mounted-device)
// Oculus Rift CV1 parameters for simulator
hmd.hResolution = 2160; // HMD horizontal resolution in pixels
hmd.vResolution = 1200; // HMD vertical resolution in pixels
hmd.hScreenSize = 0.133793f; // HMD horizontal size in meters
hmd.vScreenSize = 0.0669f; // HMD vertical size in meters
hmd.vScreenCenter = 0.04678f; // HMD screen center in meters
hmd.eyeToScreenDistance = 0.041f; // HMD distance between eye and display in meters
hmd.lensSeparationDistance = 0.07f; // HMD lens separation distance in meters
hmd.interpupillaryDistance = 0.07f; // HMD IPD (distance between pupils) in meters
// NOTE: CV1 uses a Fresnel-hybrid-asymmetric lenses with specific distortion compute shaders.
// Following parameters are an approximation to distortion stereo rendering but results differ from actual device.
hmd.lensDistortionValues[0] = 1.0f; // HMD lens distortion constant parameter 0
hmd.lensDistortionValues[1] = 0.22f; // HMD lens distortion constant parameter 1
hmd.lensDistortionValues[2] = 0.24f; // HMD lens distortion constant parameter 2
hmd.lensDistortionValues[3] = 0.0f; // HMD lens distortion constant parameter 3
hmd.chromaAbCorrection[0] = 0.996f; // HMD chromatic aberration correction parameter 0
hmd.chromaAbCorrection[1] = -0.004f; // HMD chromatic aberration correction parameter 1
hmd.chromaAbCorrection[2] = 1.014f; // HMD chromatic aberration correction parameter 2
hmd.chromaAbCorrection[3] = 0.0f; // HMD chromatic aberration correction parameter 3
// Distortion shader (uses device lens distortion and chroma)
Shader distortion = LoadShader(0, "resources/distortion.fs");
SetVrConfiguration(hmd, distortion); // Set Vr device parameters for stereo rendering
// Define the camera to look into our 3d world
Camera camera;
@ -77,6 +105,8 @@ int main()
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadShader(distortion); // Unload distortion shader
CloseVrSimulator(); // Close VR simulator
CloseWindow(); // Close window and OpenGL context

View File

@ -0,0 +1,88 @@
/*******************************************************************************************
*
* raylib [core] example - window scale letterbox
*
* This example has been created using raylib 2.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2019 Anata and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#define max(a, b) ((a)>(b)? (a) : (b))
#define min(a, b) ((a)<(b)? (a) : (b))
int main()
{
const int windowWidth = 800;
const int windowHeight = 450;
// Enable config flags for resizable window and vertical synchro
SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_VSYNC_HINT);
InitWindow(windowWidth, windowHeight, "raylib [core] example - window scale letterbox");
SetWindowMinSize(320, 240);
int gameScreenWidth = 640;
int gameScreenHeight = 480;
// Render texture initialization
RenderTexture2D target = LoadRenderTexture(gameScreenWidth, gameScreenHeight);
SetTextureFilter(target.texture, FILTER_BILINEAR); // Texture scale filter to use
Color colors[10] = { 0 };
for (int i = 0; i < 10; i++) colors[i] = (Color){ GetRandomValue(100, 250), GetRandomValue(50, 150), GetRandomValue(10, 100), 255 };
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while( !WindowShouldClose() ) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// Compute required framebuffer scaling
float scale = min((float)GetScreenWidth()/gameScreenWidth, (float)GetScreenHeight()/gameScreenHeight);
if (IsKeyPressed(KEY_SPACE))
{
// Recalculate random colors for the bars
for (int i = 0; i < 10; i++) colors[i] = (Color){ GetRandomValue(100, 250), GetRandomValue(50, 150), GetRandomValue(10, 100), 255 };
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(BLACK);
// Draw everything in the render texture
BeginTextureMode(target);
ClearBackground(RAYWHITE); // Clear render texture background color
for (int i = 0; i < 10; i++) DrawRectangle(0, (gameScreenHeight/10)*i, gameScreenWidth, gameScreenHeight/10, colors[i]);
DrawText("You can resize the window,\nand see the screen scaling!", 10, 25, 20, WHITE);
EndTextureMode();
// Draw RenderTexture2D to window, properly scaled
DrawTexturePro(target.texture, (Rectangle){ 0.0f, 0.0f, (float)target.texture.width, (float)-target.texture.height },
(Rectangle){ (GetScreenWidth() - ((float)gameScreenWidth*scale))*0.5, (GetScreenHeight() - ((float)gameScreenHeight*scale))*0.5,
(float)gameScreenWidth*scale, (float)gameScreenHeight*scale }, (Vector2){ 0, 0 }, 0.0f, WHITE);
EndDrawing();
//--------------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadRenderTexture(target); // Unload render texture
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,43 @@
#version 330
in vec2 fragTexCoord;
in vec4 fragColor;
out vec4 finalColor;
uniform sampler2D texture0;
uniform vec2 leftLensCenter = vec2(0.288, 0.5);
uniform vec2 rightLensCenter = vec2(0.712, 0.5);
uniform vec2 leftScreenCenter = vec2(0.25, 0.5);
uniform vec2 rightScreenCenter = vec2(0.75, 0.5);
uniform vec2 scale = vec2(0.25, 0.45);
uniform vec2 scaleIn = vec2(4, 2.2222);
uniform vec4 hmdWarpParam = vec4(1, 0.22, 0.24, 0);
uniform vec4 chromaAbParam = vec4(0.996, -0.004, 1.014, 0.0);
void main()
{
vec2 lensCenter = fragTexCoord.x < 0.5? leftLensCenter : rightLensCenter;
vec2 screenCenter = fragTexCoord.x < 0.5? leftScreenCenter : rightScreenCenter;
vec2 theta = (fragTexCoord - lensCenter)*scaleIn;
float rSq = theta.x*theta.x + theta.y*theta.y;
vec2 theta1 = theta*(hmdWarpParam.x + hmdWarpParam.y*rSq + hmdWarpParam.z*rSq*rSq + hmdWarpParam.w*rSq*rSq*rSq);
vec2 thetaBlue = theta1*(chromaAbParam.z + chromaAbParam.w*rSq);
vec2 tcBlue = lensCenter + scale*thetaBlue;
if (any(bvec2(clamp(tcBlue, screenCenter - vec2(0.25, 0.5), screenCenter + vec2(0.25, 0.5)) - tcBlue)))
{
finalColor = vec4(0.0, 0.0, 0.0, 1.0);
}
else
{
float blue = texture(texture0, tcBlue).b;
vec2 tcGreen = lensCenter + scale*theta1;
float green = texture(texture0, tcGreen).g;
vec2 thetaRed = theta1*(chromaAbParam.x + chromaAbParam.y*rSq);
vec2 tcRed = lensCenter + scale*thetaRed;
float red = texture(texture0, tcRed).r;
finalColor = vec4(red, green, blue, 1.0);
}
};

View File

@ -1,19 +1,16 @@
/*******************************************************************************************
*
* raylib [models] example - Load IQM 3d model with animations and play them
* raylib [models] example - Load 3d model with animations and play them
*
* This example has been created using raylib 2.0 (www.raylib.com)
* This example has been created using raylib 2.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2018 @culacant and @raysan5
* Copyright (c) 2019 Ramon Santamaria (@raysan5) and @culacant
*
********************************************************************************************/
#include "raylib.h"
#define RIQM_IMPLEMENTATION
#include "riqm.h"
int main()
{
// Initialization
@ -21,7 +18,7 @@ int main()
int screenWidth = 800;
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [models] example - iqm animation");
InitWindow(screenWidth, screenHeight, "raylib [models] example - model animation");
// Define the camera to look into our 3d world
Camera camera = { 0 };
@ -31,17 +28,16 @@ int main()
camera.fovy = 45.0f; // Camera field-of-view Y
camera.type = CAMERA_PERSPECTIVE; // Camera mode type
// Load the animated model mesh and basic data
AnimatedModel model = LoadAnimatedModel("resources/guy.iqm");
// Load model texture and set material
// NOTE: There is only 1 mesh and 1 material (both at index 0), thats what the 2 0's are
model = AnimatedModelAddTexture(model, "resources/guytex.png"); // REPLACE!
model = SetMeshMaterial(model, 0, 0); // REPLACE!
Model model = LoadModel("resources/guy/guy.iqm"); // Load the animated model mesh and basic data
Texture2D texture = LoadTexture("resources/guy/guytex.png"); // Load model texture and set material
SetMaterialTexture(&model.materials[0], MAP_DIFFUSE, texture); // Set model material map texture
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
// Load animation data
Animation anim = LoadAnimationFromIQM("resources/guyanim.iqm");
int animsCount = 0;
ModelAnimation *anims = LoadModelAnimations("resources/guy/guyanim.iqm", &animsCount);
int animFrameCounter = 0;
SetCameraMode(camera, CAMERA_FREE); // Set free camera mode
@ -60,7 +56,8 @@ int main()
if (IsKeyDown(KEY_SPACE))
{
animFrameCounter++;
AnimateModel(model, anim, animFrameCounter); // Animate the model with animation data and frame
UpdateModelAnimation(model, anims[0], animFrameCounter);
if (animFrameCounter >= anims[0].frameCount) animFrameCounter = 0;
}
//----------------------------------------------------------------------------------
@ -72,14 +69,18 @@ int main()
BeginMode3D(camera);
DrawAnimatedModel(model, Vector3Zero(), 1.0f, WHITE); // Draw animated model
DrawModelEx(model, position, (Vector3){ 1.0f, 0.0f, 0.0f }, -90.0f, (Vector3){ 1.0f, 1.0f, 1.0f }, WHITE);
for (int i = 0; i < model.boneCount; i++)
{
DrawCube(anims[0].framePoses[animFrameCounter][i].translation, 0.2f, 0.2f, 0.2f, RED);
}
DrawGrid(10, 1.0f); // Draw a grid
EndMode3D();
DrawText("PRESS SPACE to PLAY IQM MODEL ANIMATION", 10, 10, 20, MAROON);
DrawText("PRESS SPACE to PLAY MODEL ANIMATION", 10, 10, 20, MAROON);
DrawText("(c) Guy IQM 3D model by @culacant", screenWidth - 200, screenHeight - 20, 10, GRAY);
EndDrawing();
@ -88,8 +89,10 @@ int main()
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadAnimation(anim); // Unload animation data
UnloadAnimatedModel(model); // Unload animated model
// Unload model animations data
for (int i = 0; i < animsCount; i++) UnloadModelAnimation(anims[i]);
UnloadModel(model); // Unload model
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

View File

@ -31,7 +31,7 @@ int main()
// NOTE: By default each cube is mapped to one part of texture atlas
Texture2D texture = LoadTexture("resources/cubicmap_atlas.png"); // Load map texture
model.material.maps[MAP_DIFFUSE].texture = texture; // Set map diffuse texture
model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set map diffuse texture
Vector3 mapPosition = { -16.0f, 0.0f, -8.0f }; // Set model position

View File

@ -29,7 +29,7 @@ int main()
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
model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set map diffuse texture
Vector3 mapPosition = { -8.0f, 0.0f, -8.0f }; // Define model position
UnloadImage(image); // Unload heightmap image from RAM, already uploaded to VRAM

View File

@ -12,6 +12,8 @@
#include "raylib.h"
#include "raymath.h"
#include <stdio.h>
#define RLIGHTS_IMPLEMENTATION
#include "rlights.h"
@ -34,20 +36,29 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [models] example - pbr material");
// Define the camera to look into our 3d world
Camera camera = {{ 4.0f, 4.0f, 4.0f }, { 0.0f, 0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
Camera camera = { 0 };
camera.position = (Vector3){ 4.0f, 4.0f, 4.0f }; // Camera position
camera.target = (Vector3){ 0.0f, 0.5f, 0.0f }; // Camera looking at point
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
camera.fovy = 45.0f; // Camera field-of-view Y
camera.type = CAMERA_PERSPECTIVE; // Camera mode type
// Load model and PBR material
Model model = LoadModel("resources/pbr/trooper.obj");
MeshTangents(&model.mesh);
model.material = LoadMaterialPBR((Color){ 255, 255, 255, 255 }, 1.0f, 1.0f);
// Mesh tangents are generated... and uploaded to GPU
// NOTE: New VBO for tangents is generated at default location and also binded to mesh VAO
MeshTangents(&model.meshes[0]);
model.materials[0] = LoadMaterialPBR((Color){ 255, 255, 255, 255 }, 1.0f, 1.0f);
// 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.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 0, 255 }, model.material.shader),
CreateLight(LIGHT_POINT, (Vector3){ 0.0f, LIGHT_HEIGHT, LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 255, 0, 255 }, model.material.shader),
CreateLight(LIGHT_POINT, (Vector3){ -LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 0, 255, 255 }, model.material.shader),
CreateLight(LIGHT_DIRECTIONAL, (Vector3){ 0.0f, LIGHT_HEIGHT*2.0f, -LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 255, 255 }, model.material.shader)
CreateLight(LIGHT_POINT, (Vector3){ LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 0, 255 }, model.materials[0].shader),
CreateLight(LIGHT_POINT, (Vector3){ 0.0f, LIGHT_HEIGHT, LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 255, 0, 255 }, model.materials[0].shader),
CreateLight(LIGHT_POINT, (Vector3){ -LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 0, 255, 255 }, model.materials[0].shader),
CreateLight(LIGHT_DIRECTIONAL, (Vector3){ 0.0f, LIGHT_HEIGHT*2.0f, -LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 255, 255 }, model.materials[0].shader)
};
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
@ -64,7 +75,7 @@ int main()
// 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, UNIFORM_VEC3);
SetShaderValue(model.materials[0].shader, model.materials[0].shader.locs[LOC_VECTOR_VIEW], cameraPos, UNIFORM_VEC3);
//----------------------------------------------------------------------------------
// Draw
@ -143,9 +154,13 @@ static Material LoadMaterialPBR(Color albedo, float metalness, float roughness)
#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);
printf("Loaded shader: cubemap\n");
Shader shdrIrradiance = LoadShader(PATH_SKYBOX_VS, PATH_IRRADIANCE_FS);
printf("Loaded shader: irradiance\n");
Shader shdrPrefilter = LoadShader(PATH_SKYBOX_VS, PATH_PREFILTER_FS);
printf("Loaded shader: prefilter\n");
Shader shdrBRDF = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS);
printf("Loaded shader: brdf\n");
// Setup required shader locations
SetShaderValue(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, UNIFORM_INT);

View File

@ -39,7 +39,7 @@ int main()
models[7] = LoadModelFromMesh(GenMeshPoly(5, 2.0f));
// 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;
for (int i = 0; i < NUM_MODELS; i++) models[i].materials[0].maps[MAP_DIFFUSE].texture = texture;
// Define the camera to look into our 3d world
Camera camera = {{ 5.0f, 5.0f, 5.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
@ -65,6 +65,17 @@ int main()
{
currentModel = (currentModel + 1)%NUM_MODELS; // Cycle between the textures
}
if (IsKeyPressed(KEY_RIGHT))
{
currentModel++;
if (currentModel >= NUM_MODELS) currentModel = 0;
}
else if (IsKeyPressed(KEY_LEFT))
{
currentModel--;
if (currentModel < 0) currentModel = NUM_MODELS - 1;
}
//----------------------------------------------------------------------------------
// Draw

View File

@ -36,10 +36,10 @@ int main()
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
tower.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set model diffuse texture
Vector3 towerPos = { 0.0f, 0.0f, 0.0f }; // Set model position
BoundingBox towerBBox = MeshBoundingBox(tower.mesh); // Get mesh bounding box
BoundingBox towerBBox = MeshBoundingBox(tower.meshes[0]); // Get mesh bounding box
bool hitMeshBBox = false;
bool hitTriangle = false;

View File

@ -30,7 +30,7 @@ int main()
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
model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set map diffuse texture
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
SetTargetFPS(60); // Set our game to run at 60 frames-per-second

View File

@ -5,7 +5,7 @@
* This example has been created using raylib 2.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
@ -27,10 +27,10 @@ int main()
Model model = LoadModel("resources/models/turret.obj"); // Load default model obj
Texture2D texture = LoadTexture("resources/models/turret_diffuse.png"); // Load default model texture
model.material.maps[MAP_DIFFUSE].texture = texture; // Bind texture to model
model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Bind texture to model
Vector3 position = { 0.0, 0.0, 0.0 }; // Set model position
BoundingBox bounds = MeshBoundingBox(model.mesh); // Set model bounds
BoundingBox bounds = MeshBoundingBox(model.meshes[0]); // Set model bounds
bool selected = false; // Selected object flag
SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode
@ -54,15 +54,15 @@ int main()
{
if (IsFileExtension(droppedFiles[0], ".obj"))
{
UnloadMesh(&model.mesh);
model.mesh = LoadMesh(droppedFiles[0]);
bounds = MeshBoundingBox(model.mesh);
for (int i = 0; i < model.meshCount; i++) UnloadMesh(&model.meshes[i]);
model.meshes = LoadMeshes(droppedFiles[0], &model.meshCount);
bounds = MeshBoundingBox(model.meshes[0]);
}
else if (IsFileExtension(droppedFiles[0], ".png"))
{
UnloadTexture(texture);
texture = LoadTexture(droppedFiles[0]);
model.material.maps[MAP_DIFFUSE].texture = texture;
model.materials[0].maps[MAP_DIFFUSE].texture = texture;
}
strcpy(objFilename, GetFileName(droppedFiles[0]));

View File

@ -29,8 +29,8 @@ int main()
// 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");
SetShaderValue(skybox.material.shader, GetShaderLocation(skybox.material.shader, "environmentMap"), (int[1]){ MAP_CUBEMAP }, UNIFORM_INT);
skybox.materials[0].shader = LoadShader("resources/shaders/skybox.vs", "resources/shaders/skybox.fs");
SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "environmentMap"), (int[1]){ MAP_CUBEMAP }, UNIFORM_INT);
// Load cubemap shader and setup required shader locations
Shader shdrCubemap = LoadShader("resources/shaders/cubemap.vs", "resources/shaders/cubemap.fs");
@ -41,7 +41,7 @@ int main()
// 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);
skybox.materials[0].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

View File

@ -38,9 +38,9 @@ int main()
// 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
model.materials[0].maps[MAP_DIFFUSE].texture = LoadTexture("resources/plane_diffuse.png"); // Set map diffuse texture
GenTextureMipmaps(&model.material.maps[MAP_DIFFUSE].texture);
GenTextureMipmaps(&model.materials[0].maps[MAP_DIFFUSE].texture);
Camera camera = { 0 };
camera.position = (Vector3){ 0.0f, 60.0f, -120.0f };// Camera position perspective

View File

Before

Width:  |  Height:  |  Size: 295 KiB

After

Width:  |  Height:  |  Size: 295 KiB

View File

@ -1,7 +1,7 @@
# reference material
mtllib myCube.mtl
#mtllib cube.mtl
# object Pau_Box
# object box
# vertex (XZY)
v 5.5 0 1.5
@ -14,85 +14,55 @@ v 5.5 3 -1.5
v 8.5 3 -1.5
# normals (XYZ)
# red
vn 0 -1 0
#blue
vn 0 1 0
#top
vn 0 0 1
#yellow
vn 1 0 0
#bottom
vn 0 0 -1
#green
vn -1 0 0
# UVs (XY)
# yellow (1234)
vt 0.5 0 0
vt 1 0 0
vt 1 0.5 0
vt 0.5 0.5 0
# red (5678)
vt 0.5 0.5 0
vt 1 0.5 0
vt 0.5 1 0
vt 1 1 0
#bottom (9101112)
vt 0 0.5 0
vt 1 0.5 0
vt 1 0 0
vt 0 0 0
#top (13141516)
vt 0 0.5 0
vt 1 0.5 0
vt 1 1 0
vt 0 1 0
#green (17181920)
vt 0.5 0 0
vt 0 0 0
vt 0 0.5 0
vt 0.5 0.5 0
#blue (21222324)
vt 0 0.5 0
vt 0.5 0.5 0
vt 0.5 1 0
vt 0 1 0
# merger
g Pau_Box
g box
# reference material
usemtl Material_1
#usemtl mat01
# bottom
# faces
f 1/9/1 3/10/1 4/11/1
f 4/11/1 2/12/1 1/9/1
# top
f 5/13/2 6/14/2 8/15/2
f 8/15/2 7/16/2 5/13/2
# front-yellow
f 1/17/6 2/18/6 6/19/6
f 6/19/6 5/20/6 1/17/6
# right-blue
f 2/6/1 4/5/1 8/7/1
f 8/7/1 6/8/1 2/6/1
# back-green
f 4/2/3 3/1/3 7/4/3
f 7/4/3 8/3/3 4/2/3
# left-red
f 3/22/5 1/21/5 5/24/5
f 5/24/5 7/23/5 3/22/5

View File

@ -10,13 +10,13 @@
#version 330
#define MAX_SAMPLES 1024u
// Input vertex attributes (from vertex shader)
in vec2 fragTexCoord;
// Constant values
const float PI = 3.14159265359;
const uint MAX_SAMPLES = 1024u;
// Output fragment color
out vec4 finalColor;
@ -93,7 +93,7 @@ vec2 IntegrateBRDF(float NdotV, float roughness)
vec3 V = vec3(sqrt(1.0 - NdotV*NdotV), 0.0, NdotV);
vec3 N = vec3(0.0, 0.0, 1.0);
for (int i = 0; i < MAX_SAMPLES; i++)
for (uint i = 0u; i < MAX_SAMPLES; i++)
{
// Generate a sample vector that's biased towards the preferred alignment direction (importance sampling)

View File

@ -9,7 +9,7 @@
#version 330
// Input vertex attributes (from vertex shader)
in vec3 fragPos;
in vec3 fragPosition;
// Input uniform values
uniform samplerCube environmentMap;
@ -23,7 +23,7 @@ out vec4 finalColor;
void main()
{
// The sample direction equals the hemisphere's orientation
vec3 normal = normalize(fragPos);
vec3 normal = normalize(fragPosition);
vec3 irradiance = vec3(0.0);

View File

@ -11,7 +11,7 @@
#define CUBEMAP_RESOLUTION 1024.0
// Input vertex attributes (from vertex shader)
in vec3 fragPos;
in vec3 fragPosition;
// Input uniform values
uniform samplerCube environmentMap;
@ -79,7 +79,7 @@ vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
void main()
{
// Make the simplyfying assumption that V equals R equals the normal
vec3 N = normalize(fragPos);
vec3 N = normalize(fragPosition);
vec3 R = N;
vec3 V = R;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 580 KiB

File diff suppressed because it is too large Load Diff

View File

@ -1,833 +0,0 @@
/**********************************************************************************************
*
* riqm - InterQuake Model format (IQM) loader for animated meshes
*
* CONFIGURATION:
*
* #define RIQM_IMPLEMENTATION
* Generates the implementation of the library into the included file.
* If not defined, the library is in header only mode and can be included in other headers
* or source files without problems. But only ONE file should hold the implementation.
*
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2018 Jonas Daeyaert (@culacant) and Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#ifndef RIQM_H
#define RIQM_H
//#define RIQM_STATIC
#ifdef RIQM_STATIC
#define RIQMDEF static // Functions just visible to module including this file
#else
#ifdef __cplusplus
#define RIQMDEF extern "C" // Functions visible from other files (no name mangling of functions in C++)
#else
#define RIQMDEF extern // Functions visible from other files
#endif
#endif
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
#define JOINT_NAME_LENGTH 32 // Joint name string length
#define MESH_NAME_LENGTH 32 // Mesh name string length
typedef struct Joint {
char name[JOINT_NAME_LENGTH];
int parent;
} Joint;
typedef struct Pose {
Vector3 translation;
Quaternion rotation;
Vector3 scale;
} Pose;
typedef struct Animation {
int jointCount; // Number of joints (bones)
Joint *joints; // Joints array
// NOTE: Joints in anims do not have names
int frameCount; // Number of animation frames
float framerate; // Frame change speed
Pose **framepose; // Poses array by frame (and one pose by joint)
} Animation;
// Animated Model type
typedef struct AnimatedModel {
Matrix transform; // Local transform matrix
int meshCount; // Number of meshes
Mesh *meshes; // Meshes array
int materialCount; // Number of materials
Material *materials; // Materials array
int *meshMaterialId; // Mesh materials ids
// Animation required data
int jointCount; // Number of joints (and keyposes)
Joint *joints; // Mesh joints (bones)
Pose *basepose; // Mesh base-poses by joint
} AnimatedModel;
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
// Loading/Unloading functions
RIQMDEF AnimatedModel LoadAnimatedModel(const char *filename);
RIQMDEF void UnloadAnimatedModel(AnimatedModel model);
RIQMDEF Animation LoadAnimation(const char *filename);
RIQMDEF void UnloadAnimation(Animation anim);
RIQMDEF AnimatedModel AnimatedModelAddTexture(AnimatedModel model, const char *filename); // GENERIC!
RIQMDEF AnimatedModel SetMeshMaterial(AnimatedModel model, int meshid, int textureid); // GENERIC!
// Usage functionality
RIQMDEF bool CheckSkeletonsMatch(AnimatedModel model, Animation anim);
RIQMDEF void AnimateModel(AnimatedModel model, Animation anim, int frame);
RIQMDEF void DrawAnimatedModel(AnimatedModel model, Vector3 position, float scale, Color tint);
RIQMDEF void DrawAnimatedModelEx(AnimatedModel model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint);
#endif // RIQM_H
/***********************************************************************************
*
* RIQM IMPLEMENTATION
*
************************************************************************************/
#if defined(RIQM_IMPLEMENTATION)
//#include "utils.h" // Required for: fopen() Android mapping
#include <stdio.h> // Required for: FILE, fopen(), fclose(), feof(), fseek(), fread()
#include <stdlib.h> // Required for: malloc(), free()
#include <string.h> // Required for: strncmp(),strcpy()
#include "raymath.h" // Required for: Vector3, Quaternion functions
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
#define IQM_MAGIC "INTERQUAKEMODEL" // IQM file magic number
#define IQM_VERSION 2 // only IQM version 2 supported
#define ANIMJOINTNAME "ANIMJOINT" // default joint name (used in Animation)
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
// iqm file structs
typedef struct IQMHeader {
char magic[16];
unsigned int version;
unsigned int filesize;
unsigned int flags;
unsigned int num_text, ofs_text;
unsigned int num_meshes, ofs_meshes;
unsigned int num_vertexarrays, num_vertexes, ofs_vertexarrays;
unsigned int num_triangles, ofs_triangles, ofs_adjacency;
unsigned int num_joints, ofs_joints;
unsigned int num_poses, ofs_poses;
unsigned int num_anims, ofs_anims;
unsigned int num_frames, num_framechannels, ofs_frames, ofs_bounds;
unsigned int num_comment, ofs_comment;
unsigned int num_extensions, ofs_extensions;
} IQMHeader;
typedef struct IQMMesh {
unsigned int name;
unsigned int material;
unsigned int first_vertex, num_vertexes;
unsigned int first_triangle, num_triangles;
} IQMMesh;
typedef struct IQMTriangle {
unsigned int vertex[3];
} IQMTriangle;
typedef struct IQMAdjacency { // adjacency unused by default
unsigned int triangle[3];
} IQMAdjacency;
typedef struct IQMJoint {
unsigned int name;
int parent;
float translate[3], rotate[4], scale[3];
} IQMJoint;
typedef struct IQMPose {
int parent;
unsigned int mask;
float channeloffset[10];
float channelscale[10];
} IQMPose;
typedef struct IQMAnim {
unsigned int name;
unsigned int first_frame, num_frames;
float framerate;
unsigned int flags;
} IQMAnim;
typedef struct IQMVertexArray {
unsigned int type;
unsigned int flags;
unsigned int format;
unsigned int size;
unsigned int offset;
} IQMVertexArray;
typedef struct IQMBounds { // bounds unused by default
float bbmin[3], bbmax[3];
float xyradius, radius;
} IQMBounds;
typedef enum {
IQM_POSITION = 0,
IQM_TEXCOORD = 1,
IQM_NORMAL = 2,
IQM_TANGENT = 3, // tangents unused by default
IQM_BLENDINDEXES = 4,
IQM_BLENDWEIGHTS = 5,
IQM_COLOR = 6, // vertex colors unused by default
IQM_CUSTOM = 0x10 // custom vertex values unused by default
} IQMVertexType;
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
static AnimatedModel LoadIQM(const char *filename);
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
// Load .iqm file and initialize animated model
AnimatedModel LoadAnimatedModel(const char *filename)
{
AnimatedModel out = LoadIQM(filename);
for (int i = 0; i < out.meshCount; i++) rlLoadMesh(&out.meshes[i], false);
out.transform = MatrixIdentity();
out.meshMaterialId = malloc(sizeof(int)*out.meshCount);
out.materials = NULL;
out.materialCount = 0;
for (int i = 0; i < out.meshCount; i++) out.meshMaterialId[i] = -1;
return out;
}
// Add a texture to an animated model
AnimatedModel AnimatedModelAddTexture(AnimatedModel model, const char *filename)
{
Texture2D texture = LoadTexture(filename);
model.materials = realloc(model.materials, sizeof(Material)*(model.materialCount + 1));
model.materials[model.materialCount] = LoadMaterialDefault();
model.materials[model.materialCount].maps[MAP_DIFFUSE].texture = texture;
model.materialCount++;
return model;
}
// Set the material for a meshes
AnimatedModel SetMeshMaterial(AnimatedModel model, int meshid, int textureid)
{
if (meshid > model.meshCount)
{
TraceLog(LOG_WARNING, "MeshId greater than meshCount\n");
return model;
}
if (textureid > model.materialCount)
{
TraceLog(LOG_WARNING,"textureid greater than materialCount\n");
return model;
}
model.meshMaterialId[meshid] = textureid;
return model;
}
// Load animations from a .iqm file
Animation LoadAnimationFromIQM(const char *filename)
{
Animation animation = { 0 };
FILE *iqmFile;
IQMHeader iqm;
iqmFile = fopen(filename,"rb");
if (!iqmFile)
{
TraceLog(LOG_ERROR, "[%s] Unable to open file", filename);
return animation;
}
// header
fread(&iqm, sizeof(IQMHeader), 1, iqmFile);
if (strncmp(iqm.magic, IQM_MAGIC, sizeof(IQM_MAGIC)))
{
TraceLog(LOG_ERROR, "Magic Number \"%s\"does not match.", iqm.magic);
fclose(iqmFile);
return animation;
}
if (iqm.version != IQM_VERSION)
{
TraceLog(LOG_ERROR, "IQM version %i is incorrect.", iqm.version);
fclose(iqmFile);
return animation;
}
// header
if (iqm.num_anims > 1) TraceLog(LOG_WARNING, "More than 1 animation in file, only the first one will get loaded");
// joints
IQMPose *poses;
poses = malloc(sizeof(IQMPose)*iqm.num_poses);
fseek(iqmFile, iqm.ofs_poses, SEEK_SET);
fread(poses, sizeof(IQMPose)*iqm.num_poses, 1, iqmFile);
animation.jointCount = iqm.num_poses;
animation.joints = malloc(sizeof(Joint)*iqm.num_poses);
for (int j = 0; j < iqm.num_poses; j++)
{
strcpy(animation.joints[j].name, ANIMJOINTNAME);
animation.joints[j].parent = poses[j].parent;
}
// animations
IQMAnim anim = {0};
fseek(iqmFile, iqm.ofs_anims, SEEK_SET);
fread(&anim, sizeof(IQMAnim), 1, iqmFile);
animation.frameCount = anim.num_frames;
animation.framerate = anim.framerate;
// frameposes
unsigned short *framedata = malloc(sizeof(unsigned short)*iqm.num_frames*iqm.num_framechannels);
fseek(iqmFile, iqm.ofs_frames, SEEK_SET);
fread(framedata, sizeof(unsigned short)*iqm.num_frames*iqm.num_framechannels, 1, iqmFile);
animation.framepose = malloc(sizeof(Pose*)*anim.num_frames);
for (int j = 0; j < anim.num_frames; j++) animation.framepose[j] = malloc(sizeof(Pose)*iqm.num_poses);
int dcounter = anim.first_frame*iqm.num_framechannels;
for (int frame = 0; frame < anim.num_frames; frame++)
{
for (int i = 0; i < iqm.num_poses; i++)
{
animation.framepose[frame][i].translation.x = poses[i].channeloffset[0];
if (poses[i].mask & 0x01)
{
animation.framepose[frame][i].translation.x += framedata[dcounter]*poses[i].channelscale[0];
dcounter++;
}
animation.framepose[frame][i].translation.y = poses[i].channeloffset[1];
if (poses[i].mask & 0x02)
{
animation.framepose[frame][i].translation.y += framedata[dcounter]*poses[i].channelscale[1];
dcounter++;
}
animation.framepose[frame][i].translation.z = poses[i].channeloffset[2];
if (poses[i].mask & 0x04)
{
animation.framepose[frame][i].translation.z += framedata[dcounter]*poses[i].channelscale[2];
dcounter++;
}
animation.framepose[frame][i].rotation.x = poses[i].channeloffset[3];
if (poses[i].mask & 0x08)
{
animation.framepose[frame][i].rotation.x += framedata[dcounter]*poses[i].channelscale[3];
dcounter++;
}
animation.framepose[frame][i].rotation.y = poses[i].channeloffset[4];
if (poses[i].mask & 0x10)
{
animation.framepose[frame][i].rotation.y += framedata[dcounter]*poses[i].channelscale[4];
dcounter++;
}
animation.framepose[frame][i].rotation.z = poses[i].channeloffset[5];
if (poses[i].mask & 0x20)
{
animation.framepose[frame][i].rotation.z += framedata[dcounter]*poses[i].channelscale[5];
dcounter++;
}
animation.framepose[frame][i].rotation.w = poses[i].channeloffset[6];
if (poses[i].mask & 0x40)
{
animation.framepose[frame][i].rotation.w += framedata[dcounter]*poses[i].channelscale[6];
dcounter++;
}
animation.framepose[frame][i].scale.x = poses[i].channeloffset[7];
if (poses[i].mask & 0x80)
{
animation.framepose[frame][i].scale.x += framedata[dcounter]*poses[i].channelscale[7];
dcounter++;
}
animation.framepose[frame][i].scale.y = poses[i].channeloffset[8];
if (poses[i].mask & 0x100)
{
animation.framepose[frame][i].scale.y += framedata[dcounter]*poses[i].channelscale[8];
dcounter++;
}
animation.framepose[frame][i].scale.z = poses[i].channeloffset[9];
if (poses[i].mask & 0x200)
{
animation.framepose[frame][i].scale.z += framedata[dcounter]*poses[i].channelscale[9];
dcounter++;
}
animation.framepose[frame][i].rotation = QuaternionNormalize(animation.framepose[frame][i].rotation);
}
}
// Build frameposes
for (int frame = 0; frame < anim.num_frames; frame++)
{
for (int i = 0; i < animation.jointCount; i++)
{
if (animation.joints[i].parent >= 0)
{
animation.framepose[frame][i].rotation = QuaternionMultiply(animation.framepose[frame][animation.joints[i].parent].rotation, animation.framepose[frame][i].rotation);
animation.framepose[frame][i].translation = Vector3RotateByQuaternion(animation.framepose[frame][i].translation, animation.framepose[frame][animation.joints[i].parent].rotation);
animation.framepose[frame][i].translation = Vector3Add(animation.framepose[frame][i].translation, animation.framepose[frame][animation.joints[i].parent].translation);
animation.framepose[frame][i].scale = Vector3MultiplyV(animation.framepose[frame][i].scale, animation.framepose[frame][animation.joints[i].parent].scale);
}
}
}
free(framedata);
free(poses);
fclose(iqmFile);
return animation;
}
// Unload animated model
void UnloadAnimatedModel(AnimatedModel model)
{
free(model.materials);
free(model.meshMaterialId);
free(model.joints);
free(model.basepose);
for (int i = 0; i < model.meshCount; i++) rlUnloadMesh(&model.meshes[i]);
free(model.meshes);
}
// Unload animation
void UnloadAnimation(Animation anim)
{
free(anim.joints);
free(anim.framepose);
for (int i = 0; i < anim.frameCount; i++) free(anim.framepose[i]);
}
// Check if skeletons match, only parents and jointCount are checked
bool CheckSkeletonsMatch(AnimatedModel model, Animation anim)
{
if (model.jointCount != anim.jointCount) return 0;
for (int i = 0; i < model.jointCount; i++)
{
if (model.joints[i].parent != anim.joints[i].parent) return 0;
}
return 1;
}
// Calculate the animated vertex positions and normals based on an animation at a given frame
void AnimateModel(AnimatedModel model, Animation anim, int frame)
{
if (frame >= anim.frameCount) frame = frame%anim.frameCount;
for (int m = 0; m < model.meshCount; m++)
{
Vector3 outv = {0};
Vector3 outn = {0};
Vector3 baset = {0};
Quaternion baser = {0};
Vector3 bases = {0};
Vector3 outt = {0};
Quaternion outr = {0};
Vector3 outs = {0};
int vcounter = 0;
int wcounter = 0;
int weightId = 0;
for (int i = 0; i < model.meshes[m].vertexCount; i++)
{
weightId = model.meshes[m].weightId[wcounter];
baset = model.basepose[weightId].translation;
baser = model.basepose[weightId].rotation;
bases = model.basepose[weightId].scale;
outt = anim.framepose[frame][weightId].translation;
outr = anim.framepose[frame][weightId].rotation;
outs = anim.framepose[frame][weightId].scale;
// vertices
// NOTE: We use meshes.baseVertices (default position) to calculate meshes.vertices (animated position)
outv = (Vector3){ model.meshes[m].baseVertices[vcounter], model.meshes[m].baseVertices[vcounter + 1], model.meshes[m].baseVertices[vcounter + 2] };
outv = Vector3MultiplyV(outv, outs);
outv = Vector3Subtract(outv, baset);
outv = Vector3RotateByQuaternion(outv, QuaternionMultiply(outr, QuaternionInvert(baser)));
outv = Vector3Add(outv, outt);
model.meshes[m].vertices[vcounter] = outv.x;
model.meshes[m].vertices[vcounter + 1] = outv.y;
model.meshes[m].vertices[vcounter + 2] = outv.z;
// normals
// NOTE: We use meshes.baseNormals (default normal) to calculate meshes.normals (animated normals)
outn = (Vector3){ model.meshes[m].baseNormals[vcounter], model.meshes[m].baseNormals[vcounter + 1], model.meshes[m].baseNormals[vcounter + 2] };
outn = Vector3RotateByQuaternion(outn, QuaternionMultiply(outr, QuaternionInvert(baser)));
model.meshes[m].normals[vcounter] = outn.x;
model.meshes[m].normals[vcounter + 1] = outn.y;
model.meshes[m].normals[vcounter + 2] = outn.z;
vcounter += 3;
wcounter += 4;
}
}
}
// Draw an animated model
void DrawAnimatedModel(AnimatedModel model, Vector3 position, float scale, Color tint)
{
Vector3 vScale = { scale, scale, scale };
Vector3 rotationAxis = { 1.0f, 0.0f,0.0f };
DrawAnimatedModelEx(model, position, rotationAxis, -90.0f, vScale, tint);
}
// Draw an animated model with extended parameters
void DrawAnimatedModelEx(AnimatedModel model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint)
{
if (model.materialCount == 0)
{
TraceLog(LOG_WARNING,"No materials set, can't draw animated meshes\n");
return;
}
Matrix matScale = MatrixScale(scale.x, scale.y, scale.z);
Matrix matRotation = MatrixRotate(rotationAxis, rotationAngle*DEG2RAD);
Matrix matTranslation = MatrixTranslate(position.x, position.y, position.z);
Matrix matTransform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation);
model.transform = MatrixMultiply(model.transform, matTransform);
for (int i = 0; i < model.meshCount; i++)
{
rlUpdateMesh(model.meshes[i], 0, model.meshes[i].vertexCount); // Update vertex position
rlUpdateMesh(model.meshes[i], 2, model.meshes[i].vertexCount); // Update vertex normals
rlDrawMesh(model.meshes[i], model.materials[model.meshMaterialId[i]], model.transform); // Draw meshes
}
}
// Load animated model meshes from IQM file
static AnimatedModel LoadIQM(const char *filename)
{
AnimatedModel model = { 0 };
FILE *iqmFile;
IQMHeader iqm;
IQMMesh *imesh;
IQMTriangle *tri;
IQMVertexArray *va;
IQMJoint *ijoint;
float *vertex;
float *normal;
float *text;
char *blendi;
unsigned char *blendw;
iqmFile = fopen(filename, "rb");
if (!iqmFile)
{
TraceLog(LOG_ERROR, "[%s] Unable to open file", filename);
return model;
}
// header
fread(&iqm,sizeof(IQMHeader), 1, iqmFile);
if (strncmp(iqm.magic, IQM_MAGIC, sizeof(IQM_MAGIC)))
{
TraceLog(LOG_ERROR, "Magic Number \"%s\"does not match.", iqm.magic);
fclose(iqmFile);
return model;
}
if(iqm.version != IQM_VERSION)
{
TraceLog(LOG_ERROR, "IQM version %i is incorrect.", iqm.version);
fclose(iqmFile);
return model;
}
// meshes
imesh = malloc(sizeof(IQMMesh)*iqm.num_meshes);
fseek(iqmFile, iqm.ofs_meshes, SEEK_SET);
fread(imesh, sizeof(IQMMesh)*iqm.num_meshes, 1, iqmFile);
model.meshCount = iqm.num_meshes;
model.meshes = malloc(sizeof(Mesh)*iqm.num_meshes);
char name[MESH_NAME_LENGTH];
for (int i = 0; i < iqm.num_meshes; i++)
{
fseek(iqmFile,iqm.ofs_text+imesh[i].name,SEEK_SET);
fread(name, sizeof(char)*MESH_NAME_LENGTH, 1, iqmFile); // Mesh name not used...
model.meshes[i].vertexCount = imesh[i].num_vertexes;
model.meshes[i].baseVertices = malloc(sizeof(float)*imesh[i].num_vertexes*3); // Default IQM base position
model.meshes[i].baseNormals = malloc(sizeof(float)*imesh[i].num_vertexes*3); // Default IQM base normal
model.meshes[i].texcoords = malloc(sizeof(float)*imesh[i].num_vertexes*2);
model.meshes[i].weightId = malloc(sizeof(int)*imesh[i].num_vertexes*4);
model.meshes[i].weightBias = malloc(sizeof(float)*imesh[i].num_vertexes*4);
model.meshes[i].triangleCount = imesh[i].num_triangles;
model.meshes[i].indices = malloc(sizeof(unsigned short)*imesh[i].num_triangles*3);
// What we actually process for rendering, should be updated transforming meshes.vertices and meshes.normals
model.meshes[i].vertices = malloc(sizeof(float)*imesh[i].num_vertexes*3);
model.meshes[i].normals = malloc(sizeof(float)*imesh[i].num_vertexes*3);
}
// tris
tri = malloc(sizeof(IQMTriangle)*iqm.num_triangles);
fseek(iqmFile, iqm.ofs_triangles, SEEK_SET);
fread(tri, sizeof(IQMTriangle)*iqm.num_triangles, 1, iqmFile);
for (int m = 0; m < iqm.num_meshes; m++)
{
int tcounter = 0;
for (int i = imesh[m].first_triangle; i < imesh[m].first_triangle+imesh[m].num_triangles; i++)
{
// IQM triangles are stored counter clockwise, but raylib sets opengl to clockwise drawing, so we swap them around
model.meshes[m].indices[tcounter+2] = tri[i].vertex[0] - imesh[m].first_vertex;
model.meshes[m].indices[tcounter+1] = tri[i].vertex[1] - imesh[m].first_vertex;
model.meshes[m].indices[tcounter] = tri[i].vertex[2] - imesh[m].first_vertex;
tcounter += 3;
}
}
// vertarrays
va = malloc(sizeof(IQMVertexArray)*iqm.num_vertexarrays);
fseek(iqmFile, iqm.ofs_vertexarrays, SEEK_SET);
fread(va, sizeof(IQMVertexArray)*iqm.num_vertexarrays, 1, iqmFile);
for (int i = 0; i < iqm.num_vertexarrays; i++)
{
switch (va[i].type)
{
case IQM_POSITION:
{
vertex = malloc(sizeof(float)*iqm.num_vertexes*3);
fseek(iqmFile, va[i].offset, SEEK_SET);
fread(vertex, sizeof(float)*iqm.num_vertexes*3, 1, iqmFile);
for (int m = 0; m < iqm.num_meshes; m++)
{
int vcounter = 0;
for (int i = imesh[m].first_vertex*3; i < (imesh[m].first_vertex + imesh[m].num_vertexes)*3; i++)
{
model.meshes[m].vertices[vcounter] = vertex[i];
model.meshes[m].baseVertices[vcounter] = vertex[i];
vcounter++;
}
}
} break;
case IQM_NORMAL:
{
normal = malloc(sizeof(float)*iqm.num_vertexes*3);
fseek(iqmFile, va[i].offset, SEEK_SET);
fread(normal, sizeof(float)*iqm.num_vertexes*3, 1, iqmFile);
for (int m = 0; m < iqm.num_meshes; m++)
{
int vcounter = 0;
for (int i = imesh[m].first_vertex*3; i < (imesh[m].first_vertex + imesh[m].num_vertexes)*3; i++)
{
model.meshes[m].normals[vcounter] = normal[i];
model.meshes[m].baseNormals[vcounter] = normal[i];
vcounter++;
}
}
} break;
case IQM_TEXCOORD:
{
text = malloc(sizeof(float)*iqm.num_vertexes*2);
fseek(iqmFile, va[i].offset, SEEK_SET);
fread(text, sizeof(float)*iqm.num_vertexes*2, 1, iqmFile);
for (int m = 0; m < iqm.num_meshes; m++)
{
int vcounter = 0;
for (int i = imesh[m].first_vertex*2; i < (imesh[m].first_vertex + imesh[m].num_vertexes)*2; i++)
{
model.meshes[m].texcoords[vcounter] = text[i];
vcounter++;
}
}
} break;
case IQM_BLENDINDEXES:
{
blendi = malloc(sizeof(char)*iqm.num_vertexes*4);
fseek(iqmFile, va[i].offset, SEEK_SET);
fread(blendi, sizeof(char)*iqm.num_vertexes*4, 1, iqmFile);
for (int m = 0; m < iqm.num_meshes; m++)
{
int vcounter = 0;
for (int i = imesh[m].first_vertex*4; i < (imesh[m].first_vertex + imesh[m].num_vertexes)*4; i++)
{
model.meshes[m].weightId[vcounter] = blendi[i];
vcounter++;
}
}
} break;
case IQM_BLENDWEIGHTS:
{
blendw = malloc(sizeof(unsigned char)*iqm.num_vertexes*4);
fseek(iqmFile,va[i].offset,SEEK_SET);
fread(blendw,sizeof(unsigned char)*iqm.num_vertexes*4,1,iqmFile);
for (int m = 0; m < iqm.num_meshes; m++)
{
int vcounter = 0;
for (int i = imesh[m].first_vertex*4; i < (imesh[m].first_vertex + imesh[m].num_vertexes)*4; i++)
{
model.meshes[m].weightBias[vcounter] = blendw[i]/255.0f;
vcounter++;
}
}
} break;
}
}
// joints, include base poses
ijoint = malloc(sizeof(IQMJoint)*iqm.num_joints);
fseek(iqmFile, iqm.ofs_joints, SEEK_SET);
fread(ijoint, sizeof(IQMJoint)*iqm.num_joints, 1, iqmFile);
model.jointCount = iqm.num_joints;
model.joints = malloc(sizeof(Joint)*iqm.num_joints);
model.basepose = malloc(sizeof(Pose)*iqm.num_joints);
for (int i = 0; i < iqm.num_joints; i++)
{
// joints
model.joints[i].parent = ijoint[i].parent;
fseek(iqmFile, iqm.ofs_text + ijoint[i].name, SEEK_SET);
fread(model.joints[i].name,sizeof(char)*JOINT_NAME_LENGTH, 1, iqmFile);
// basepose
model.basepose[i].translation.x = ijoint[i].translate[0];
model.basepose[i].translation.y = ijoint[i].translate[1];
model.basepose[i].translation.z = ijoint[i].translate[2];
model.basepose[i].rotation.x = ijoint[i].rotate[0];
model.basepose[i].rotation.y = ijoint[i].rotate[1];
model.basepose[i].rotation.z = ijoint[i].rotate[2];
model.basepose[i].rotation.w = ijoint[i].rotate[3];
model.basepose[i].scale.x = ijoint[i].scale[0];
model.basepose[i].scale.y = ijoint[i].scale[1];
model.basepose[i].scale.z = ijoint[i].scale[2];
}
// build base pose
for (int i = 0; i < model.jointCount; i++)
{
if (model.joints[i].parent >= 0)
{
model.basepose[i].rotation = QuaternionMultiply(model.basepose[model.joints[i].parent].rotation, model.basepose[i].rotation);
model.basepose[i].translation = Vector3RotateByQuaternion(model.basepose[i].translation, model.basepose[model.joints[i].parent].rotation);
model.basepose[i].translation = Vector3Add(model.basepose[i].translation, model.basepose[model.joints[i].parent].translation);
model.basepose[i].scale = Vector3MultiplyV(model.basepose[i].scale, model.basepose[model.joints[i].parent].scale);
}
}
fclose(iqmFile);
free(imesh);
free(tri);
free(va);
free(vertex);
free(normal);
free(text);
free(blendi);
free(blendw);
free(ijoint);
return model;
}
#endif

View File

@ -24,7 +24,7 @@
* This example is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software:
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -113,7 +113,7 @@ int main()
material.maps[MAP_DIFFUSE].color = WHITE;
material.maps[MAP_SPECULAR].color = WHITE;
model.material = material; // Apply material to model
model.materials[0] = material; // Apply material to model
Light spotLight = CreateLight(LIGHT_SPOT, (Vector3){3.0f, 5.0f, 2.0f}, (Color){255, 255, 255, 255});
spotLight->target = (Vector3){0.0f, 0.0f, 0.0f};

View File

@ -0,0 +1,61 @@
#version 330
// Input vertex attributes (from vertex shader)
in vec2 fragTexCoord;
in vec4 fragColor;
// Output fragment color
out vec4 finalColor;
// Custom variables
#define PI 3.14159265358979323846
uniform float uTime = 0.0;
float divisions = 5.0;
float angle = 0.0;
vec2 VectorRotateTime(vec2 v, float speed)
{
float time = uTime*speed;
float localTime = fract(time); // The time domain this works on is 1 sec.
if ((localTime >= 0.0) && (localTime < 0.25)) angle = 0.0;
else if ((localTime >= 0.25) && (localTime < 0.50)) angle = PI/4*sin(2*PI*localTime - PI/2);
else if ((localTime >= 0.50) && (localTime < 0.75)) angle = PI*0.25;
else if ((localTime >= 0.75) && (localTime < 1.00)) angle = PI/4*sin(2*PI*localTime);
// Rotate vector by angle
v -= 0.5;
v = mat2(cos(angle), -sin(angle), sin(angle), cos(angle))*v;
v += 0.5;
return v;
}
float Rectangle(in vec2 st, in float size, in float fill)
{
float roundSize = 0.5 - size/2.0;
float left = step(roundSize, st.x);
float top = step(roundSize, st.y);
float bottom = step(roundSize, 1.0 - st.y);
float right = step(roundSize, 1.0 - st.x);
return (left*bottom*right*top)*fill;
}
void main()
{
vec2 fragPos = fragTexCoord;
fragPos.xy += uTime/9.0;
fragPos *= divisions;
vec2 ipos = floor(fragPos); // Get the integer coords
vec2 fpos = fract(fragPos); // Get the fractional coords
fpos = VectorRotateTime(fpos, 0.2);
float alpha = Rectangle(fpos, 0.216, 1.0);
vec3 color = vec3(0.3, 0.3, 0.3);
finalColor = vec4(color, alpha);
}

View File

@ -45,7 +45,7 @@ int main()
Model model = LoadModel("resources/models/barracks.obj"); // Load OBJ model
Texture2D texture = LoadTexture("resources/models/barracks_diffuse.png"); // Load model texture (diffuse map)
model.material.maps[MAP_DIFFUSE].texture = texture; // Set model diffuse texture
model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set model diffuse texture
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position

View File

@ -50,8 +50,8 @@ int main()
// NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/grayscale.fs", GLSL_VERSION));
model.material.shader = shader; // Set shader effect to 3d model
model.material.maps[MAP_DIFFUSE].texture = texture; // Bind texture to model
model.materials[0].shader = shader; // Set shader effect to 3d model
model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Bind texture to model
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position

View File

@ -74,7 +74,7 @@ int main()
Model model = LoadModel("resources/models/church.obj"); // Load OBJ model
Texture2D texture = LoadTexture("resources/models/church_diffuse.png"); // Load model texture (diffuse map)
model.material.maps[MAP_DIFFUSE].texture = texture; // Set model diffuse texture
model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set model diffuse texture
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position

View File

@ -0,0 +1,71 @@
/*******************************************************************************************
*
* raylib [textures] example - Shader texture drawing
*
* This example illustrates how to draw on a blank texture using a shader
*
* This example has been created using raylib 2.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2019 Michał Ciesielski and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - shader texture drawing");
Image imBlank = GenImageColor(1024, 1024, BLANK);
Texture2D texture = LoadTextureFromImage(imBlank); // Load blank texture to fill on shader
UnloadImage(imBlank);
// NOTE: Using GLSL 330 shader version, on OpenGL ES 2.0 use GLSL 100 shader version
Shader shader = LoadShader(0, "resources/shaders/glsl330/cubes_panning.fs");
float time = 0.0f;
int timeLoc = GetShaderLocation(shader, "uTime");
SetShaderValue(shader, timeLoc, &time, UNIFORM_FLOAT);
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
while (!WindowShouldClose())
{
// Update
//----------------------------------------------------------------------------------
time = GetTime();
SetShaderValue(shader, timeLoc, &time, UNIFORM_FLOAT);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
BeginShaderMode(shader); // Enable our custom shader for next shapes/textures drawings
DrawTexture(texture, 0, 0, WHITE); // Drawing BLANK texture, all magic happens on shader
EndShaderMode(); // Disable our custom shader, return to default shader
DrawText("BACKGROUND is PAINTED and ANIMATED on SHADER!", 10, 10, 20, MAROON);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadShader(shader);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,92 @@
/*******************************************************************************************
*
* raylib [shapes] example - rectangle scaling by mouse
*
* This example has been created using raylib 2.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2019 Demioz and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#define MOUSE_SCALE_MARK_SIZE 12
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - rectangle scaling mouse");
Rectangle rec = { 100, 100, 200, 80 };
Vector2 mousePosition = { 0 };
bool mouseScaleReady = false;
bool mouseScaleMode = false;
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
mousePosition = GetMousePosition();
if (CheckCollisionPointRec(mousePosition, rec) &&
CheckCollisionPointRec(mousePosition, (Rectangle){ rec.x + rec.width - MOUSE_SCALE_MARK_SIZE, rec.y + rec.height - MOUSE_SCALE_MARK_SIZE, MOUSE_SCALE_MARK_SIZE, MOUSE_SCALE_MARK_SIZE }))
{
mouseScaleReady = true;
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) mouseScaleMode = true;
}
else mouseScaleReady = false;
if (mouseScaleMode)
{
mouseScaleReady = true;
rec.width = (mousePosition.x - rec.x);
rec.height = (mousePosition.y - rec.y);
if (rec.width < MOUSE_SCALE_MARK_SIZE) rec.width = MOUSE_SCALE_MARK_SIZE;
if (rec.height < MOUSE_SCALE_MARK_SIZE) rec.height = MOUSE_SCALE_MARK_SIZE;
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) mouseScaleMode = false;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText("Scale rectangle dragging from bottom-right corner!", 10, 10, 20, GRAY);
DrawRectangleRec(rec, Fade(GREEN, 0.5f));
if (mouseScaleReady)
{
DrawRectangleLinesEx(rec, 1, RED);
DrawTriangle((Vector2){ rec.x + rec.width - MOUSE_SCALE_MARK_SIZE, rec.y + rec.height },
(Vector2){ rec.x + rec.width, rec.y + rec.height },
(Vector2){ rec.x + rec.width, rec.y + rec.height - MOUSE_SCALE_MARK_SIZE }, RED);
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@ -0,0 +1,87 @@
/*******************************************************************************************
*
* raylib [textures] example - Background scrolling
*
* This example has been created using raylib 2.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2019 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - background scrolling");
// NOTE: Be careful, background width must be equal or bigger than screen width
// if not, texture should be draw more than two times for scrolling effect
Texture2D background = LoadTexture("resources/cyberpunk_street_background.png");
Texture2D midground = LoadTexture("resources/cyberpunk_street_midground.png");
Texture2D foreground = LoadTexture("resources/cyberpunk_street_foreground.png");
float scrollingBack = 0;
float scrollingMid = 0;
float scrollingFore = 0;
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
scrollingBack -= 0.1f;
scrollingMid -= 0.5f;
scrollingFore -= 1.0f;
// NOTE: Texture is scaled twice its size, so it sould be considered on scrolling
if (scrollingBack <= -background.width*2) scrollingBack = 0;
if (scrollingMid <= -midground.width*2) scrollingMid = 0;
if (scrollingFore <= -foreground.width*2) scrollingFore = 0;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(GetColor(0x052c46ff));
// Draw background image twice
// NOTE: Texture is scaled twice its size
DrawTextureEx(background, (Vector2){ scrollingBack, 20 }, 0.0f, 2.0f, WHITE);
DrawTextureEx(background, (Vector2){ background.width*2 + scrollingBack, 20 }, 0.0f, 2.0f, WHITE);
// Draw midground image twice
DrawTextureEx(midground, (Vector2){ scrollingMid, 20 }, 0.0f, 2.0f, WHITE);
DrawTextureEx(midground, (Vector2){ midground.width*2 + scrollingMid, 20 }, 0.0f, 2.0f, WHITE);
// Draw foreground image twice
DrawTextureEx(foreground, (Vector2){ scrollingFore, 70 }, 0.0f, 2.0f, WHITE);
DrawTextureEx(foreground, (Vector2){ foreground.width*2 + scrollingFore, 70 }, 0.0f, 2.0f, WHITE);
DrawText("BACKGROUND SCROLLING & PARALLAX", 10, 10, 20, RED);
DrawText("(c) Cyberpunk Street Environment by Luis Zuno (@ansimuz)", screenWidth - 330, screenHeight - 20, 10, RAYWHITE);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(background); // Unload background texture
UnloadTexture(midground); // Unload midground texture
UnloadTexture(foreground); // Unload foreground texture
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -27,13 +27,13 @@ int main()
int frameHeight = scarfy.height;
// NOTE: Source rectangle (part of the texture to use for drawing)
Rectangle sourceRec = { 0.0f, 0.0f, (float)frameWidth, (float)frameHeight };
Rectangle sourceRec = { 0.0f, 0.0f, frameWidth, frameHeight };
// NOTE: Destination rectangle (screen rectangle where drawing part of texture)
Rectangle destRec = { (float)screenWidth/2, (float)screenHeight/2, (float)frameWidth*2, (float)frameHeight*2 };
Rectangle destRec = { screenWidth/2, screenHeight/2, frameWidth*2, frameHeight*2 };
// NOTE: Origin of the texture (rotation/scale point), it's relative to destination rectangle size
Vector2 origin = { (float)frameWidth, (float)frameHeight };
Vector2 origin = { frameWidth, frameHeight };
int rotation = 0;

View File

@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
# Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.

View File

@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
# Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.

View File

@ -8,7 +8,7 @@
* This game has been created using raylib (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
********************************************************************************************/

View File

@ -4,7 +4,7 @@
*
* Ending Screen Functions Definitions (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -4,7 +4,7 @@
*
* Gameplay Screen Functions Definitions (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -4,7 +4,7 @@
*
* Logo Screen Functions Definitions (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -4,7 +4,7 @@
*
* Title Screen Functions Definitions (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -4,7 +4,7 @@
*
* Screens Functions Declarations (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
# Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.

View File

@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
# Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.

View File

@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
# Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.

View File

@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
# Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.

View File

@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
# Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.

View File

@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
# Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.

View File

@ -4,7 +4,7 @@
*
* Ending Screen Functions Definitions (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -4,7 +4,7 @@
*
* Gameplay Screen Functions Definitions (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -4,7 +4,7 @@
*
* Logo Screen Functions Definitions (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -3,7 +3,7 @@
* raylib - transmission mission
*
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -3,7 +3,7 @@
* raylib - transmission mission
*
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -4,7 +4,7 @@
*
* Screens Functions Declarations (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -7,7 +7,7 @@
* This game has been created using raylib (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
********************************************************************************************/

View File

@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
# Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.

View File

@ -22,33 +22,33 @@
<ProjectGuid>{0981CA98-E4A5-4DF1-987F-A41D09131EFC}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>core_basic_window</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
<ProjectName>core_basic_window</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@ -73,7 +73,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)$(ProjectName)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)$(ProjectName)\$(Configuration)\temp\</IntDir>
<IntDir>$(ProjectDir)$(ProjectName)\$(Configuration)\temp</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<LinkIncremental>true</LinkIncremental>

View File

@ -22,33 +22,33 @@
<ProjectGuid>{B655E850-3322-42F7-941D-6AC18FD66CA1}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>raylib_example_cpp</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
<ProjectName>core_basic_window_cpp</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

View File

@ -22,7 +22,7 @@
<ProjectGuid>{E89D61AC-55DE-4482-AFD4-DF7242EBC859}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>raylib</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -34,20 +34,20 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@ -163,7 +163,6 @@
<ClCompile Include="..\..\..\src\core.c" />
<ClCompile Include="..\..\..\src\models.c" />
<ClCompile Include="..\..\..\src\rglfw.c" />
<ClCompile Include="..\..\..\src\rnet.c" />
<ClCompile Include="..\..\..\src\shapes.c" />
<ClCompile Include="..\..\..\src\text.c" />
<ClCompile Include="..\..\..\src\textures.c" />
@ -185,12 +184,8 @@
<ClInclude Include="..\..\..\src\raylib.h" />
<ClInclude Include="..\..\..\src\raymath.h" />
<ClInclude Include="..\..\..\src\rlgl.h" />
<ClInclude Include="..\..\..\src\rnet.h" />
<ClInclude Include="..\..\..\src\utils.h" />
</ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
# Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.

View File

@ -14,7 +14,7 @@
# Many thanks to Milan Nikolic (@gen2brain) for implementing Android platform pipeline.
# Many thanks to Emanuele Petriglia for his contribution on GNU/Linux pipeline.
#
# Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
# Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty.
# In no event will the authors be held liable for any damages arising from
@ -155,7 +155,7 @@ endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Emscripten required variables
EMSDK_PATH = C:/emsdk
EMSCRIPTEN_VERSION ?= 1.38.21
EMSCRIPTEN_VERSION ?= 1.38.30
CLANG_VERSION = e$(EMSCRIPTEN_VERSION)_64bit
PYTHON_VERSION = 2.7.13.1_64bit\python-2.7.13.amd64
NODE_VERSION = 8.9.1_64bit

View File

@ -6,7 +6,7 @@
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2018 Ahmad Fatoum & Ramon Santamaria (@raysan5)
* Copyright (c) 2018-2019 Ahmad Fatoum & Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@ -25,7 +25,7 @@
*
**********************************************************************************************/
#define RAYLIB_VERSION "2.4-dev"
#define RAYLIB_VERSION "2.5-dev"
// Edit to control what features Makefile'd raylib is compiled with
#if defined(RAYLIB_CMAKE)
@ -57,8 +57,6 @@
//------------------------------------------------------------------------------------
// Support VR simulation functionality (stereo rendering)
#define SUPPORT_VR_SIMULATOR 1
// Include stereo rendering distortion shader (shader_distortion.h)
#define SUPPORT_DISTORTION_SHADER 1
//------------------------------------------------------------------------------------
@ -66,10 +64,10 @@
//------------------------------------------------------------------------------------
// Draw rectangle shapes using font texture white character instead of default white texture
// Allows drawing rectangles and text with a single draw call, very useful for GUI systems!
#define SUPPORT_FONT_TEXTURE
#define SUPPORT_FONT_TEXTURE 1
// Use QUADS instead of TRIANGLES for drawing when possible
// Some lines-based shapes could still use lines
#define SUPPORT_QUADS_DRAW_MODE
#define SUPPORT_QUADS_DRAW_MODE 1
//------------------------------------------------------------------------------------
// Module: textures - Configuration Flags
@ -114,6 +112,8 @@
// Selected desired model fileformats to be supported for loading
#define SUPPORT_FILEFORMAT_OBJ 1
#define SUPPORT_FILEFORMAT_MTL 1
#define SUPPORT_FILEFORMAT_IQM 1
#define SUPPORT_FILEFORMAT_GLTF 1
// Support procedural mesh generation functions, uses external par_shapes.h library
// NOTE: Some generated meshes DO NOT include generated texture coordinates
#define SUPPORT_MESH_GENERATION 1

View File

@ -68,7 +68,7 @@
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@ -361,6 +361,15 @@ typedef struct {
static InputEventWorker eventWorkers[10]; // List of worker threads for every monitored "/dev/input/event<N>"
typedef struct{
int Contents[8];
char Head;
char Tail;
} KeyEventFifo;
static KeyEventFifo lastKeyPressedEvdev; // Buffer for holding keydown events as they arrive (Needed due to multitreading of event workers)
static char currentKeyStateEvdev[512] = { 0 }; // Registers current frame key state from event based driver (Needs to be seperate because the legacy console based method clears keys on every frame)
#endif
#if defined(PLATFORM_WEB)
static bool toggleCursorLock = false; // Ask for cursor pointer lock on next click
@ -470,7 +479,7 @@ static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadE
static void InitKeyboard(void); // Init raw keyboard system (standard input reading)
static void ProcessKeyboard(void); // Process keyboard events
static void RestoreKeyboard(void); // Restore keyboard system
static void InitMouse(void); // Mouse initialization (including mouse thread)
static void InitEvdevInput(void); // Mouse initialization (including mouse thread)
static void EventThreadSpawn(char *device); // Identifies a input device and spawns a thread to handle it if needed
static void *EventThread(void *arg); // Input device events reading thread
static void InitGamepad(void); // Init raw gamepad input
@ -590,7 +599,7 @@ void InitWindow(int width, int height, const char *title)
#if defined(PLATFORM_RPI)
// Init raw input system
InitMouse(); // Mouse init
InitEvdevInput(); // Mouse init
InitKeyboard(); // Keyboard init
InitGamepad(); // Gamepad init
#endif
@ -1155,7 +1164,7 @@ void BeginMode2D(Camera2D camera)
Matrix matTransform = MatrixMultiply(MatrixMultiply(matOrigin, MatrixMultiply(matScale, matRotation)), matTranslation);
rlMultMatrixf(MatrixToFloat(matTransform));
rlMultMatrixf(MatrixToFloat(matTransform)); // Apply transformation to modelview
}
// Ends 2D mode with custom camera
@ -2347,6 +2356,9 @@ static bool InitGraphicsDevice(int width, int height)
//glfwWindowHint(GLFW_REFRESH_RATE, 0); // Refresh rate for fullscreen window
//glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); // OpenGL API to use. Alternative: GLFW_OPENGL_ES_API
//glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers
#if defined(PLATFORM_DESKTOP)
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE); // Scale content area based on the monitor content scale where window is placed on
#endif
// Check some Window creation flags
if (configFlags & FLAG_WINDOW_HIDDEN) glfwWindowHint(GLFW_VISIBLE, GL_FALSE); // Visible window
@ -3054,9 +3066,17 @@ static void PollInputEvents(void)
#endif
#if defined(PLATFORM_RPI)
// Register previous keys states
for (int i = 0; i < 512; i++)previousKeyState[i] = currentKeyState[i];
// Grab a keypress from the evdev fifo if avalable
if(lastKeyPressedEvdev.Head != lastKeyPressedEvdev.Tail)
{
lastKeyPressed = lastKeyPressedEvdev.Contents[lastKeyPressedEvdev.Tail]; // Read the key from the buffer
lastKeyPressedEvdev.Tail = (lastKeyPressedEvdev.Tail + 1) & 0x07; // Increment the tail pointer forwards and binary wraparound after 7 (fifo is 8 elements long)
}
// Register previous mouse states
previousMouseWheelY = currentMouseWheelY;
currentMouseWheelY = 0;
@ -3174,7 +3194,7 @@ static void PollInputEvents(void)
}
else currentGamepadState[i][j] = 0;
//printf("Gamepad %d, button %d: Digital: %d, Analog: %g\n", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]);
//TraceLog(LOG_DEBUG, "Gamepad %d, button %d: Digital: %d, Analog: %g", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]);
}
// Register axis data for every connected gamepad
@ -3211,10 +3231,10 @@ static void PollInputEvents(void)
#endif
#if defined(PLATFORM_RPI)
// NOTE: Mouse input events polling is done asynchonously in another pthread - MouseThread()
// NOTE: Mouse input events polling is done asynchonously in another pthread - EventThread()
// NOTE: Keyboard reading could be done using input_event(s) reading or just read from stdin,
// we use method 2 (stdin) but maybe in a future we should change to method 1...
// we now use both methods inside here. 2nd method is still used for legacy purposes (Allows for input trough SSH console)
ProcessKeyboard();
// NOTE: Gamepad (Joystick) input events polling is done asynchonously in another pthread - GamepadThread()
@ -3684,7 +3704,6 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
ProcessGestureEvent(gestureEvent);
}
#else
// Support only simple touch position
if (flags == AMOTION_EVENT_ACTION_DOWN)
{
@ -3776,18 +3795,19 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent
y = touchEvent->touches[i].canvasY;
}
printf("%s, numTouches: %d %s%s%s%s\n", emscripten_event_type_to_string(eventType), event->numTouches,
TraceLog(LOG_DEBUG, "%s, numTouches: %d %s%s%s%s", emscripten_event_type_to_string(eventType), event->numTouches,
event->ctrlKey? " CTRL" : "", event->shiftKey? " SHIFT" : "", event->altKey? " ALT" : "", event->metaKey? " META" : "");
for (int i = 0; i < event->numTouches; ++i)
{
const EmscriptenTouchPoint *t = &event->touches[i];
printf(" %ld: screen: (%ld,%ld), client: (%ld,%ld), page: (%ld,%ld), isChanged: %d, onTarget: %d, canvas: (%ld, %ld)\n",
TraceLog(LOG_DEBUG, " %ld: screen: (%ld,%ld), client: (%ld,%ld), page: (%ld,%ld), isChanged: %d, onTarget: %d, canvas: (%ld, %ld)",
t->identifier, t->screenX, t->screenY, t->clientX, t->clientY, t->pageX, t->pageY, t->isChanged, t->onTarget, t->canvasX, t->canvasY);
}
*/
#if defined(SUPPORT_GESTURES_SYSTEM)
GestureEvent gestureEvent;
// Register touch actions
@ -3822,6 +3842,17 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent
// Gesture data is sent to gestures system for processing
ProcessGestureEvent(gestureEvent);
#else
// Support only simple touch position
if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART)
{
// Get first touch position
touchPosition[0] = (Vector2){ touchEvent->touches[0].targetX, touchEvent->touches[0].targetY };
touchPosition[0].x /= (float)GetScreenWidth();
touchPosition[0].y /= (float)GetScreenHeight();
}
#endif
return 1;
}
@ -3830,12 +3861,12 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent
static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData)
{
/*
printf("%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"\n",
TraceLog(LOG_DEBUG, "%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"",
eventType != 0? emscripten_event_type_to_string(eventType) : "Gamepad state",
gamepadEvent->timestamp, gamepadEvent->connected, gamepadEvent->index, gamepadEvent->numAxes, gamepadEvent->numButtons, gamepadEvent->id, gamepadEvent->mapping);
for(int i = 0; i < gamepadEvent->numAxes; ++i) printf("Axis %d: %g\n", i, gamepadEvent->axis[i]);
for(int i = 0; i < gamepadEvent->numButtons; ++i) printf("Button %d: Digital: %d, Analog: %g\n", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]);
for(int i = 0; i < gamepadEvent->numAxes; ++i) TraceLog(LOG_DEBUG, "Axis %d: %g", i, gamepadEvent->axis[i]);
for(int i = 0; i < gamepadEvent->numButtons; ++i) TraceLog(LOG_DEBUG, "Button %d: Digital: %d, Analog: %g", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]);
*/
if ((gamepadEvent->connected) && (gamepadEvent->index < MAX_GAMEPADS)) gamepadReady[gamepadEvent->index] = true;
@ -3910,15 +3941,14 @@ static void ProcessKeyboard(void)
// Reset pressed keys array (it will be filled below)
for (int i = 0; i < 512; i++) currentKeyState[i] = 0;
// Check keys from event input workers (This is the new keyboard reading method)
for (int i = 0; i < 512; i++) currentKeyState[i] = currentKeyStateEvdev[i];
// Fill all read bytes (looking for keys)
for (int i = 0; i < bufferByteCount; i++)
{
TraceLog(LOG_DEBUG, "Bytes on keysBuffer: %i", bufferByteCount);
//printf("Key(s) bytes: ");
//for (int i = 0; i < bufferByteCount; i++) printf("0x%02x ", keysBuffer[i]);
//printf("\n");
// NOTE: If (key == 0x1b), depending on next key, it could be a special keymap code!
// Up -> 1b 5b 41 / Left -> 1b 5b 44 / Right -> 1b 5b 43 / Down -> 1b 5b 42
if (keysBuffer[i] == 0x1b)
@ -4010,8 +4040,8 @@ static void RestoreKeyboard(void)
ioctl(STDIN_FILENO, KDSKBMODE, defaultKeyboardMode);
}
// Mouse initialization (including mouse thread)
static void InitMouse(void)
// Initialise user input from evdev(/dev/input/event<N>) this means mouse, keyboard or gamepad devices
static void InitEvdevInput(void)
{
char path[MAX_FILEPATH_LENGTH];
DIR *directory;
@ -4023,6 +4053,11 @@ static void InitMouse(void)
touchPosition[i].x = -1;
touchPosition[i].y = -1;
}
// Reset keypress buffer
lastKeyPressedEvdev.Head = 0;
lastKeyPressedEvdev.Tail = 0;
// Reset keyboard key state
for (int i = 0; i < 512; i++) currentKeyStateEvdev[i] = 0;
// Open the linux directory of "/dev/input"
directory = opendir(DEFAULT_EVDEV_PATH);
@ -4191,7 +4226,7 @@ static void EventThreadSpawn(char *device)
// Decide what to do with the device
//-------------------------------------------------------------------------------------------------------
if (worker->isTouch || worker->isMouse)
if (worker->isTouch || worker->isMouse || worker->isKeyboard)
{
// Looks like a interesting device
TraceLog(LOG_INFO, "Opening input device [%s] (%s%s%s%s%s)", device,
@ -4241,13 +4276,35 @@ static void EventThreadSpawn(char *device)
// Input device events reading thread
static void *EventThread(void *arg)
{
// Scancode to keycode mapping for US keyboards
// TODO: Proabobly replace this with a keymap from the X11 to get the correct regional map for the keyboard (Currently non US keyboards will have the wrong mapping for some keys)
static const int keymap_US[] =
{0,256,49,50,51,52,53,54,55,56,57,48,45,61,259,258,81,87,69,82,84,
89,85,73,79,80,91,93,257,341,65,83,68,70,71,72,74,75,76,59,39,96,
340,92,90,88,67,86,66,78,77,44,46,47,344,332,342,32,280,290,291,
292,293,294,295,296,297,298,299,282,281,327,328,329,333,324,325,
326,334,321,322,323,320,330,0,85,86,300,301,89,90,91,92,93,94,95,
335,345,331,283,346,101,268,265,266,263,262,269,264,267,260,261,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,347,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,0,0,0,0,0,200,201,202,203,204,205,206,207,208,209,210,
211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,
227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,
243,244,245,246,247,248,0,0,0,0,0,0,0,};
struct input_event event;
GestureEvent gestureEvent;
InputEventWorker *worker = (InputEventWorker *)arg;
bool GestureNeedsUpdate = false;
int touchAction = -1;
bool gestureUpdate = false;
int keycode;
while (!windowShouldClose)
{
// Try to read data from the device and only continue if successful
if (read(worker->fd, &event, sizeof(event)) == (int)sizeof(event))
{
// Relative movement parsing
@ -4257,16 +4314,22 @@ static void *EventThread(void *arg)
{
mousePosition.x += event.value;
touchPosition[0].x = mousePosition.x;
gestureEvent.touchAction = TOUCH_MOVE;
GestureNeedsUpdate = true;
#if defined(SUPPORT_GESTURES_SYSTEM)
touchAction = TOUCH_MOVE;
gestureUpdate = true;
#endif
}
if (event.code == REL_Y)
{
mousePosition.y += event.value;
touchPosition[0].y = mousePosition.y;
gestureEvent.touchAction = TOUCH_MOVE;
GestureNeedsUpdate = true;
#if defined(SUPPORT_GESTURES_SYSTEM)
touchAction = TOUCH_MOVE;
gestureUpdate = true;
#endif
}
if (event.code == REL_WHEEL)
@ -4282,15 +4345,21 @@ static void *EventThread(void *arg)
if (event.code == ABS_X)
{
mousePosition.x = (event.value - worker->absRange.x)*screenWidth/worker->absRange.width; // Scale acording to absRange
gestureEvent.touchAction = TOUCH_MOVE;
GestureNeedsUpdate = true;
#if defined(SUPPORT_GESTURES_SYSTEM)
touchAction = TOUCH_MOVE;
gestureUpdate = true;
#endif
}
if (event.code == ABS_Y)
{
mousePosition.y = (event.value - worker->absRange.y)*screenHeight/worker->absRange.height; // Scale acording to absRange
gestureEvent.touchAction = TOUCH_MOVE;
GestureNeedsUpdate = true;
#if defined(SUPPORT_GESTURES_SYSTEM)
touchAction = TOUCH_MOVE;
gestureUpdate = true;
#endif
}
// Multitouch movement
@ -4325,17 +4394,43 @@ static void *EventThread(void *arg)
// Button parsing
if (event.type == EV_KEY)
{
// Mouse button parsing
if ((event.code == BTN_TOUCH) || (event.code == BTN_LEFT))
{
currentMouseStateEvdev[MOUSE_LEFT_BUTTON] = event.value;
if (event.value > 0) gestureEvent.touchAction = TOUCH_DOWN;
else gestureEvent.touchAction = TOUCH_UP;
GestureNeedsUpdate = true;
#if defined(SUPPORT_GESTURES_SYSTEM)
if (event.value > 0) touchAction = TOUCH_DOWN;
else touchAction = TOUCH_UP;
gestureUpdate = true;
#endif
}
if (event.code == BTN_RIGHT) currentMouseStateEvdev[MOUSE_RIGHT_BUTTON] = event.value;
if (event.code == BTN_MIDDLE) currentMouseStateEvdev[MOUSE_MIDDLE_BUTTON] = event.value;
// Keyboard button parsing
if((event.code >= 1) && (event.code <= 255)) //Keyboard keys appear for codes 1 to 255
{
keycode = keymap_US[event.code & 0xFF]; // The code we get is a scancode so we look up the apropriate keycode
// Make sure we got a valid keycode
if((keycode > 0) && (keycode < sizeof(currentKeyState)))
{
// Store the key information for raylib to later use
currentKeyStateEvdev[keycode] = event.value;
if(event.value > 0)
{
// Add the key int the fifo
lastKeyPressedEvdev.Contents[lastKeyPressedEvdev.Head] = keycode; // Put the data at the front of the fifo snake
lastKeyPressedEvdev.Head = (lastKeyPressedEvdev.Head + 1) & 0x07; // Increment the head pointer forwards and binary wraparound after 7 (fifo is 8 elements long)
// TODO: This fifo is not fully threadsafe with multiple writers, so multiple keyboards hitting a key at the exact same time could miss a key (double write to head before it was incremented)
}
TraceLog(LOG_DEBUG, "KEY%s ScanCode: %4i KeyCode: %4i",event.value == 0 ? "UP":"DOWN", event.code, keycode);
}
}
}
// Screen confinement
@ -4346,22 +4441,31 @@ static void *EventThread(void *arg)
if (mousePosition.y > screenHeight/mouseScale.y) mousePosition.y = screenHeight/mouseScale.y;
// Gesture update
if (GestureNeedsUpdate)
if (gestureUpdate)
{
#if defined(SUPPORT_GESTURES_SYSTEM)
GestureEvent gestureEvent = { 0 };
gestureEvent.pointCount = 0;
gestureEvent.touchAction = touchAction;
if (touchPosition[0].x >= 0) gestureEvent.pointCount++;
if (touchPosition[1].x >= 0) gestureEvent.pointCount++;
if (touchPosition[2].x >= 0) gestureEvent.pointCount++;
if (touchPosition[3].x >= 0) gestureEvent.pointCount++;
gestureEvent.pointerId[0] = 0;
gestureEvent.pointerId[1] = 1;
gestureEvent.pointerId[2] = 2;
gestureEvent.pointerId[3] = 3;
gestureEvent.position[0] = touchPosition[0];
gestureEvent.position[1] = touchPosition[1];
gestureEvent.position[2] = touchPosition[2];
gestureEvent.position[3] = touchPosition[3];
ProcessGestureEvent(gestureEvent);
#endif
}
}
else

1584
src/external/tinyobj_loader_c.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

File diff suppressed because it is too large Load Diff

View File

@ -46,7 +46,7 @@
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
* Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -4,19 +4,20 @@
*
* FEATURES:
* - NO external dependencies, all required libraries included with raylib
* - Multiple platforms support: Windows, Linux, FreeBSD, OpenBSD, NetBSD, DragonFly, MacOS, UWP, Android, Raspberry Pi, HTML5.
* - Multiplatform: Windows, Linux, FreeBSD, OpenBSD, NetBSD, DragonFly, MacOS, UWP, Android, Raspberry Pi, HTML5.
* - Written in plain C code (C99) in PascalCase/camelCase notation
* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3 or ES2 - choose at compile)
* - Unique OpenGL abstraction layer (usable as standalone module): [rlgl]
* - Powerful fonts module with Fonts support (XNA fonts, AngelCode fonts, TTF)
* - Powerful fonts module (XNA SpriteFonts, BMFonts, TTF)
* - Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC)
* - Full 3d support for 3d Shapes, Models, Billboards, Heightmaps and more!
* - Flexible Materials system, supporting classic maps and PBR maps
* - Skeletal Animation support (CPU bones-based animation)
* - Shaders support, including Model shaders and Postprocessing shaders
* - Powerful math module for Vector, Matrix and Quaternion operations: [raymath]
* - Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, XM, MOD)
* - VR stereo rendering with configurable HMD device parameters
* - Complete bindings to LUA (raylib-lua) and Go (raylib-go)
* - Bindings to multiple programming languages available!
*
* NOTES:
* One custom font is loaded by default when InitWindow() [core]
@ -24,24 +25,26 @@
* If using OpenGL 3.3 or ES2, several vertex buffers (VAO/VBO) are created to manage lines-triangles-quads
*
* DEPENDENCIES (included):
* rglfw (github.com/glfw/glfw) for window/context management and input (only PLATFORM_DESKTOP) [core]
* glad (github.com/Dav1dde/glad) for OpenGL extensions loading (3.3 Core profile, only PLATFORM_DESKTOP) [rlgl]
* mini_al (github.com/dr-soft/mini_al) for audio device/context management [audio]
* [core] rglfw (github.com/glfw/glfw) for window/context management and input (only PLATFORM_DESKTOP)
* [rlgl] glad (github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading (only PLATFORM_DESKTOP)
* [raudio] miniaudio (github.com/dr-soft/miniaudio) for audio device/context management
*
* OPTIONAL DEPENDENCIES (included):
* stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...) [textures]
* stb_image_resize (Sean Barret) for image resizing algorythms [textures]
* stb_image_write (Sean Barret) for image writting (PNG) [utils]
* stb_truetype (Sean Barret) for ttf fonts loading [text]
* stb_rect_pack (Sean Barret) for rectangles packing [text]
* stb_vorbis (Sean Barret) for OGG audio loading [audio]
* stb_perlin (Sean Barret) for Perlin noise image generation [textures]
* par_shapes (Philip Rideout) for parametric 3d shapes generation [models]
* jar_xm (Joshua Reisenauer) for XM audio module loading [audio]
* jar_mod (Joshua Reisenauer) for MOD audio module loading [audio]
* dr_flac (David Reid) for FLAC audio file loading [audio]
* dr_mp3 (David Reid) for MP3 audio file loading [audio]
* rgif (Charlie Tangora, Ramon Santamaria) for GIF recording [core]
* [core] rgif (Charlie Tangora, Ramon Santamaria) for GIF recording
* [textures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...)
* [textures] stb_image_write (Sean Barret) for image writting (BMP, TGA, PNG, JPG)
* [textures] stb_image_resize (Sean Barret) for image resizing algorythms
* [textures] stb_perlin (Sean Barret) for Perlin noise image generation
* [text] stb_truetype (Sean Barret) for ttf fonts loading
* [text] stb_rect_pack (Sean Barret) for rectangles packing
* [models] par_shapes (Philip Rideout) for parametric 3d shapes generation
* [models] tinyobj_loader_c (Syoyo Fujita) for models loading (OBJ, MTL)
* [models] cgltf (Johannes Kuhlmann) for models loading (glTF)
* [raudio] stb_vorbis (Sean Barret) for OGG audio loading
* [raudio] dr_flac (David Reid) for FLAC audio file loading
* [raudio] dr_mp3 (David Reid) for MP3 audio file loading
* [raudio] jar_xm (Joshua Reisenauer) for XM audio module loading
* [raudio] jar_mod (Joshua Reisenauer) for MOD audio module loading
*
*
* LICENSE: zlib/libpng
@ -49,7 +52,7 @@
* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software:
*
* Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@ -326,7 +329,7 @@ typedef struct Camera3D {
int type; // Camera type, defines projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
} Camera3D;
#define Camera Camera3D // Camera type fallback, defaults to Camera3D
typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D
// Camera2D type, defines a 2d camera
typedef struct Camera2D {
@ -336,12 +339,6 @@ typedef struct Camera2D {
float zoom; // Camera zoom (scaling), should be 1.0f by default
} Camera2D;
// Bounding box type
typedef struct BoundingBox {
Vector3 min; // Minimum vertex box-corner
Vector3 max; // Maximum vertex box-corner
} BoundingBox;
// Vertex data definning a mesh
// NOTE: Data stored in CPU memory (and GPU)
typedef struct Mesh {
@ -358,10 +355,10 @@ typedef struct Mesh {
unsigned short *indices;// Vertex indices (in case vertex data comes indexed)
// Animation vertex data
float *baseVertices; // Vertex base position (required to apply bones transformations)
float *baseNormals; // Vertex base normals (required to apply bones transformations)
float *weightBias; // Vertex weight bias
int *weightId; // Vertex weight id
float *animVertices; // Animated vertex positions (after bones transformations)
float *animNormals; // Animated normals (after bones transformations)
int *boneIds; // Vertex bone ids, up to 4 bones influence by vertex (skinning)
float *boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning)
// OpenGL identifiers
unsigned int vaoId; // OpenGL Vertex Array Object id
@ -388,22 +385,45 @@ typedef struct Material {
float *params; // Material generic parameters (if required)
} Material;
// Transformation properties
typedef struct Transform {
Vector3 translation; // Translation
Quaternion rotation; // Rotation
Vector3 scale; // Scale
} Transform;
// Bone information
typedef struct BoneInfo {
char name[32]; // Bone name
int parent; // Bone parent
} BoneInfo;
// Model type
typedef struct Model {
Mesh mesh; // Vertex data buffers (RAM and VRAM)
Matrix transform; // Local transform matrix
Material material; // Shader and textures data
/*
Mesh *meshes; // Vertex data buffers (RAM and VRAM)
int meshCount;
Material *materials; // Shader and textures data
int materialCount;
int meshCount; // Number of meshes
Mesh *meshes; // Meshes array
int *meshMaterial; // Material assigned to every mesh
*/
int materialCount; // Number of materials
Material *materials; // Materials array
int *meshMaterial; // Mesh material number
// Animation data
int boneCount; // Number of bones
BoneInfo *bones; // Bones information (skeleton)
Transform *bindPose; // Bones base transformation (pose)
} Model;
// Model animation
typedef struct ModelAnimation {
int boneCount; // Number of bones
BoneInfo *bones; // Bones information (skeleton)
int frameCount; // Number of animation frames
Transform **framePoses; // Poses array by frame
} ModelAnimation;
// Ray type (useful for raycast)
typedef struct Ray {
Vector3 position; // Ray position (origin)
@ -418,6 +438,12 @@ typedef struct RayHitInfo {
Vector3 normal; // Surface normal of hit
} RayHitInfo;
// Bounding box type
typedef struct BoundingBox {
Vector3 min; // Minimum vertex box-corner
Vector3 max; // Maximum vertex box-corner
} BoundingBox;
// Wave type, defines audio wave data
typedef struct Wave {
unsigned int sampleCount; // Number of samples
@ -468,16 +494,6 @@ typedef struct VrDeviceInfo {
float chromaAbCorrection[4]; // HMD chromatic aberration correction parameters
} VrDeviceInfo;
// VR Stereo rendering configuration for simulator
typedef struct VrStereoConfig {
RenderTexture2D stereoFbo; // VR stereo rendering framebuffer
Shader distortionShader; // VR stereo rendering distortion shader
Matrix eyesProjection[2]; // VR stereo rendering eyes projection matrices
Matrix eyesViewOffset[2]; // VR stereo rendering eyes view offset matrices
int eyeViewportRight[4]; // VR stereo rendering right eye viewport [x, y, w, h]
int eyeViewportLeft[4]; // VR stereo rendering left eye viewport [x, y, w, h]
} VrStereoConfig;
// Network typedefs
typedef uint32_t SocketChannel;
typedef struct _AddressInformation * AddressInformation;
@ -575,7 +591,6 @@ typedef struct Packet
//----------------------------------------------------------------------------------
// Enumerators Definition
//----------------------------------------------------------------------------------
// System config flags
// NOTE: Used for bit masks
typedef enum {
@ -591,7 +606,7 @@ typedef enum {
// Trace log type
typedef enum {
LOG_ALL, // Display all logs
LOG_ALL = 0, // Display all logs
LOG_TRACE,
LOG_DEBUG,
LOG_INFO,
@ -874,7 +889,7 @@ typedef enum {
MAP_IRRADIANCE, // NOTE: Uses GL_TEXTURE_CUBE_MAP
MAP_PREFILTER, // NOTE: Uses GL_TEXTURE_CUBE_MAP
MAP_BRDF
} TexmapIndex;
} MaterialMapType;
#define MAP_DIFFUSE MAP_ALBEDO
#define MAP_SPECULAR MAP_METALNESS
@ -980,16 +995,6 @@ typedef enum {
CAMERA_ORTHOGRAPHIC
} CameraType;
// Head Mounted Display devices
typedef enum {
HMD_DEFAULT_DEVICE = 0,
HMD_OCULUS_RIFT_DK2,
HMD_OCULUS_RIFT_CV1,
HMD_OCULUS_GO,
HMD_VALVE_HTC_VIVE,
HMD_SONY_PSVR
} VrDeviceType;
// Type of n-patch
typedef enum {
NPT_9PATCH = 0, // Npatch defined by 3x3 tiles
@ -1065,7 +1070,7 @@ RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a r
RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position for a 3d world space position
RLAPI Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix)
// timing-related functions
// Timing-related functions
RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum)
RLAPI int GetFPS(void); // Returns current FPS
RLAPI float GetFrameTime(void); // Returns time in seconds for last frame drawn
@ -1188,10 +1193,13 @@ RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color);
RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line defining thickness
RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line using cubic-bezier curves in-out
RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
RLAPI void DrawCircleSector(Vector2 center, float radius, int startAngle, int endAngle, Color color); // Draw a piece of a circle
RLAPI void DrawCircleSector(Vector2 center, float radius, int startAngle, int endAngle, int segments, Color color); // Draw a piece of a circle
RLAPI void DrawCircleSectorLines(Vector2 center, float radius, int startAngle, int endAngle, int segments, Color color); // Draw circle sector outline
RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle
RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
RLAPI void DrawRing(Vector2 center, float innerRadius, float outerRadius, int startAngle, int endAngle, int segments, Color color); // Draw ring
RLAPI void DrawRingLines(Vector2 center, float innerRadius, float outerRadius, int startAngle, int endAngle, int segments, Color color); // Draw ring outline
RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
@ -1201,6 +1209,8 @@ RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Col
RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors
RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
RLAPI void DrawRectangleLinesEx(Rectangle rec, int lineThick, Color color); // Draw rectangle outline with extended parameters
RLAPI void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle with rounded edges
RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, int lineThick, Color color); // Draw rectangle with rounded edges outline
RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle
RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline
RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
@ -1371,19 +1381,27 @@ RLAPI void DrawGizmo(Vector3 position);
//------------------------------------------------------------------------------------
// Model loading/unloading functions
RLAPI Model LoadModel(const char *fileName); // Load model from files (mesh and material)
RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh
RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials)
RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material)
RLAPI void UnloadModel(Model model); // Unload model from memory (RAM and/or VRAM)
// Mesh loading/unloading functions
RLAPI Mesh LoadMesh(const char *fileName); // Load mesh from file
RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM)
RLAPI Mesh *LoadMeshes(const char *fileName, int *meshCount); // Load meshes from model file
RLAPI void ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file
RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM)
// Mesh manipulation functions
RLAPI BoundingBox MeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
RLAPI void MeshTangents(Mesh *mesh); // Compute mesh tangents
RLAPI void MeshBinormals(Mesh *mesh); // Compute mesh binormals
// Material loading/unloading functions
RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file
RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture); // Set texture for a material map type (MAP_DIFFUSE, MAP_SPECULAR...)
RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Set material for a mesh
// Model animations loading/unloading functions
RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animsCount); // Load model animations from file
RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose
RLAPI void UnloadModelAnimation(ModelAnimation anim); // Unload animation data
RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match
// Mesh generation functions
RLAPI Mesh GenMeshPoly(int sides, float radius); // Generate polygonal mesh
@ -1397,10 +1415,10 @@ RLAPI Mesh GenMeshKnot(float radius, float size, int radSeg, int sides);
RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size); // Generate heightmap mesh from image data
RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data
// Material loading/unloading functions
RLAPI Material LoadMaterial(const char *fileName); // Load material from file
RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
// Mesh manipulation functions
RLAPI BoundingBox MeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
RLAPI void MeshTangents(Mesh *mesh); // Compute mesh tangents
RLAPI void MeshBinormals(Mesh *mesh); // Compute mesh binormals
// Model drawing functions
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
@ -1441,6 +1459,7 @@ RLAPI int GetShaderLocation(Shader shader, const char *uniformName);
RLAPI void SetShaderValue(Shader shader, int uniformLoc, const void *value, int uniformType); // Set shader uniform value
RLAPI void SetShaderValueV(Shader shader, int uniformLoc, const void *value, int uniformType, int count); // Set shader uniform value vector
RLAPI void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
RLAPI void SetShaderValueTexture(Shader shader, int uniformLoc, Texture2D texture); // Set shader uniform value for texture
RLAPI void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
RLAPI void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
RLAPI Matrix GetMatrixModelview(); // Get internal modelview matrix
@ -1450,7 +1469,7 @@ RLAPI Matrix GetMatrixModelview(); // Get
RLAPI Texture2D GenTextureCubemap(Shader shader, Texture2D skyHDR, int size); // Generate cubemap texture from HDR texture
RLAPI Texture2D GenTextureIrradiance(Shader shader, Texture2D cubemap, int size); // Generate irradiance texture using cubemap data
RLAPI Texture2D GenTexturePrefilter(Shader shader, Texture2D cubemap, int size); // Generate prefilter texture using cubemap data
RLAPI Texture2D GenTextureBRDF(Shader shader, int size); // Generate BRDF texture using cubemap data
RLAPI Texture2D GenTextureBRDF(Shader shader, int size); // Generate BRDF texture
// Shading begin/end functions
RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing
@ -1461,10 +1480,10 @@ RLAPI void BeginScissorMode(int x, int y, int width, int height); // Beg
RLAPI void EndScissorMode(void); // End scissor mode
// VR control functions
RLAPI VrDeviceInfo GetVrDeviceInfo(int vrDeviceType); // Get VR device information for some standard devices
RLAPI void InitVrSimulator(VrDeviceInfo info); // Init VR simulator for selected device parameters
RLAPI void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
RLAPI void InitVrSimulator(void); // Init VR simulator for selected device parameters
RLAPI void CloseVrSimulator(void); // Close VR simulator for current device
RLAPI void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
RLAPI void SetVrConfiguration(VrDeviceInfo info, Shader distortion); // Set stereo rendering configuration parameters
RLAPI bool IsVrSimulatorReady(void); // Detect if VR simulator is ready
RLAPI void ToggleVrMode(void); // Enable/Disable VR experience
RLAPI void BeginVrDrawing(void); // Begin VR simulator stereo rendering

View File

@ -1,8 +1,8 @@
GLFW_ICON ICON "raylib.ico"
1 VERSIONINFO
FILEVERSION 2,0,0,0
PRODUCTVERSION 2,0,0,0
FILEVERSION 2,5,0,0
PRODUCTVERSION 2,5,0,0
BEGIN
BLOCK "StringFileInfo"
BEGIN
@ -11,12 +11,12 @@ BEGIN
BEGIN
//VALUE "CompanyName", "raylib technologies"
VALUE "FileDescription", "Created using raylib (www.raylib.com)"
VALUE "FileVersion", "2.0.0"
VALUE "FileVersion", "2.5.0"
VALUE "InternalName", "raylib app"
VALUE "LegalCopyright", "(c) 2018 Ramon Santamaria - @raysan5"
VALUE "LegalCopyright", "(c) 2019 Ramon Santamaria (@raysan5)"
//VALUE "OriginalFilename", "raylib_app.exe"
VALUE "ProductName", "raylib game"
VALUE "ProductVersion", "2.0.0"
VALUE "ProductVersion", "2.5.0"
END
END
BLOCK "VarFileInfo"

View File

@ -440,7 +440,7 @@ RMDEF Vector3 Vector3Transform(Vector3 v, Matrix mat)
result.z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14;
return result;
};
}
// Transform a vector by quaternion rotation
RMDEF Vector3 Vector3RotateByQuaternion(Vector3 v, Quaternion q)

View File

@ -7,7 +7,7 @@
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2017-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2017-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -32,9 +32,6 @@
* #define SUPPORT_VR_SIMULATOR
* Support VR simulation functionality (stereo rendering)
*
* #define SUPPORT_DISTORTION_SHADER
* Include stereo rendering distortion shader (embedded)
*
* DEPENDENCIES:
* raymath - 3D math functionality (Vector3, Matrix, Quaternion)
* GLAD - OpenGL extensions loading (OpenGL 3.3 Core only)
@ -42,7 +39,7 @@
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@ -205,10 +202,10 @@ typedef unsigned char byte;
unsigned short *indices;// vertex indices (in case vertex data comes indexed)
// Animation vertex data
float *baseVertices; // Vertex base position (required to apply bones transformations)
float *baseNormals; // Vertex base normals (required to apply bones transformations)
float *weightBias; // Vertex weight bias
int *weightId; // Vertex weight id
float *animVertices; // Animated vertex positions (after bones transformations)
float *animNormals; // Animated normals (after bones transformations)
int *boneIds; // Vertex bone ids, up to 4 bones influence by vertex (skinning)
float *boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning)
// OpenGL identifiers
unsigned int vaoId; // OpenGL Vertex Array Object id
@ -263,7 +260,6 @@ typedef unsigned char byte;
// VR Stereo rendering configuration for simulator
typedef struct VrStereoConfig {
RenderTexture2D stereoFbo; // VR stereo rendering framebuffer
Shader distortionShader; // VR stereo rendering distortion shader
Matrix eyesProjection[2]; // VR stereo rendering eyes projection matrices
Matrix eyesViewOffset[2]; // VR stereo rendering eyes view offset matrices
@ -386,20 +382,10 @@ typedef unsigned char byte;
MAP_IRRADIANCE, // NOTE: Uses GL_TEXTURE_CUBE_MAP
MAP_PREFILTER, // NOTE: Uses GL_TEXTURE_CUBE_MAP
MAP_BRDF
} TexmapIndex;
} MaterialMapType;
#define MAP_DIFFUSE MAP_ALBEDO
#define MAP_SPECULAR MAP_METALNESS
// VR Head Mounted Display devices
typedef enum {
HMD_DEFAULT_DEVICE = 0,
HMD_OCULUS_RIFT_DK2,
HMD_OCULUS_RIFT_CV1,
HMD_OCULUS_GO,
HMD_VALVE_HTC_VIVE,
HMD_SONY_PSVR
} VrDevice;
#endif
#if defined(__cplusplus)
@ -455,6 +441,8 @@ void rlDeleteVertexArrays(unsigned int id); // Unload vertex data (V
void rlDeleteBuffers(unsigned int id); // Unload vertex data (VBO) from GPU memory
void rlClearColor(byte r, byte g, byte b, byte a); // Clear color buffer with color
void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth)
void rlUpdateBuffer(int bufferId, void *data, int dataSize); // Update GPU buffer with new data
unsigned int rlLoadAttribBuffer(unsigned int vaoId, int shaderLoc, void *buffer, int size, bool dynamic); // Load a new attributes buffer
//------------------------------------------------------------------------------------
// Functions Declaration - rlgl functionality
@ -532,10 +520,10 @@ void BeginBlendMode(int mode); // Begin blending mode (alpha,
void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
// VR control functions
VrDeviceInfo GetVrDeviceInfo(int vrDeviceType); // Get VR device information for some standard devices
void InitVrSimulator(VrDeviceInfo info); // Init VR simulator for selected device parameters
void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
void InitVrSimulator(void); // Init VR simulator for selected device parameters
void CloseVrSimulator(void); // Close VR simulator for current device
void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
void SetVrConfiguration(VrDeviceInfo info, Shader distortion); // Set stereo rendering configuration parameters
bool IsVrSimulatorReady(void); // Detect if VR simulator is ready
void ToggleVrMode(void); // Enable/Disable VR experience
void BeginVrDrawing(void); // Begin VR simulator stereo rendering
@ -559,10 +547,7 @@ int GetPixelDataSize(int width, int height, int format);// Get pixel data size i
#if defined(RLGL_IMPLEMENTATION)
#if defined(RLGL_STANDALONE)
#define SUPPORT_VR_SIMULATOR
#define SUPPORT_DISTORTION_SHADER
#else
#if !defined(RLGL_STANDALONE)
// Check if config flags have been externally provided on compilation line
#if !defined(EXTERNAL_CONFIG_FLAGS)
#include "config.h" // Defines module configuration flags
@ -728,6 +713,7 @@ typedef struct DynamicBuffer {
typedef struct DrawCall {
int mode; // Drawing mode: LINES, TRIANGLES, QUADS
int vertexCount; // Number of vertex of the draw
int vertexAlignment; // Number of vertex required for index alignment (LINES, TRIANGLES)
//unsigned int vaoId; // Vertex Array id to be used on the draw
//unsigned int shaderId; // Shader id to be used on the draw
unsigned int textureId; // Texture id to be used on the draw
@ -737,88 +723,20 @@ typedef struct DrawCall {
//Matrix modelview; // Modelview matrix for this draw
} DrawCall;
#if defined(SUPPORT_VR_SIMULATOR)
// VR Stereo rendering configuration for simulator
typedef struct VrStereoConfig {
Shader distortionShader; // VR stereo rendering distortion shader
Matrix eyesProjection[2]; // VR stereo rendering eyes projection matrices
Matrix eyesViewOffset[2]; // VR stereo rendering eyes view offset matrices
int eyeViewportRight[4]; // VR stereo rendering right eye viewport [x, y, w, h]
int eyeViewportLeft[4]; // VR stereo rendering left eye viewport [x, y, w, h]
} VrStereoConfig;
#endif
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
#if !defined(GRAPHICS_API_OPENGL_11) && defined(SUPPORT_DISTORTION_SHADER)
// Distortion shader embedded
static char distortionFShaderStr[] =
#if defined(GRAPHICS_API_OPENGL_21)
"#version 120 \n"
#elif defined(GRAPHICS_API_OPENGL_ES2)
"#version 100 \n"
"precision mediump float; \n" // precision required for OpenGL ES2 (WebGL)
#endif
#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
"varying vec2 fragTexCoord; \n"
"varying vec4 fragColor; \n"
#elif defined(GRAPHICS_API_OPENGL_33)
"#version 330 \n"
"in vec2 fragTexCoord; \n"
"in vec4 fragColor; \n"
"out vec4 finalColor; \n"
#endif
"uniform sampler2D texture0; \n"
#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
"uniform vec2 leftLensCenter; \n"
"uniform vec2 rightLensCenter; \n"
"uniform vec2 leftScreenCenter; \n"
"uniform vec2 rightScreenCenter; \n"
"uniform vec2 scale; \n"
"uniform vec2 scaleIn; \n"
"uniform vec4 hmdWarpParam; \n"
"uniform vec4 chromaAbParam; \n"
#elif defined(GRAPHICS_API_OPENGL_33)
"uniform vec2 leftLensCenter = vec2(0.288, 0.5); \n"
"uniform vec2 rightLensCenter = vec2(0.712, 0.5); \n"
"uniform vec2 leftScreenCenter = vec2(0.25, 0.5); \n"
"uniform vec2 rightScreenCenter = vec2(0.75, 0.5); \n"
"uniform vec2 scale = vec2(0.25, 0.45); \n"
"uniform vec2 scaleIn = vec2(4, 2.2222); \n"
"uniform vec4 hmdWarpParam = vec4(1, 0.22, 0.24, 0); \n"
"uniform vec4 chromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); \n"
#endif
"void main() \n"
"{ \n"
" vec2 lensCenter = fragTexCoord.x < 0.5? leftLensCenter : rightLensCenter; \n"
" vec2 screenCenter = fragTexCoord.x < 0.5? leftScreenCenter : rightScreenCenter; \n"
" vec2 theta = (fragTexCoord - lensCenter)*scaleIn; \n"
" float rSq = theta.x*theta.x + theta.y*theta.y; \n"
" vec2 theta1 = theta*(hmdWarpParam.x + hmdWarpParam.y*rSq + hmdWarpParam.z*rSq*rSq + hmdWarpParam.w*rSq*rSq*rSq); \n"
" vec2 thetaBlue = theta1*(chromaAbParam.z + chromaAbParam.w*rSq); \n"
" vec2 tcBlue = lensCenter + scale*thetaBlue; \n"
" if (any(bvec2(clamp(tcBlue, screenCenter - vec2(0.25, 0.5), screenCenter + vec2(0.25, 0.5)) - tcBlue))) \n"
" { \n"
#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
" gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); \n"
#elif defined(GRAPHICS_API_OPENGL_33)
" finalColor = vec4(0.0, 0.0, 0.0, 1.0); \n"
#endif
" } \n"
" else \n"
" { \n"
#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
" float blue = texture2D(texture0, tcBlue).b; \n"
" vec2 tcGreen = lensCenter + scale*theta1; \n"
" float green = texture2D(texture0, tcGreen).g; \n"
#elif defined(GRAPHICS_API_OPENGL_33)
" float blue = texture(texture0, tcBlue).b; \n"
" vec2 tcGreen = lensCenter + scale*theta1; \n"
" float green = texture(texture0, tcGreen).g; \n"
#endif
" vec2 thetaRed = theta1*(chromaAbParam.x + chromaAbParam.y*rSq); \n"
" vec2 tcRed = lensCenter + scale*thetaRed; \n"
#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
" float red = texture2D(texture0, tcRed).r; \n"
" gl_FragColor = vec4(red, green, blue, 1.0); \n"
#elif defined(GRAPHICS_API_OPENGL_33)
" float red = texture(texture0, tcRed).r; \n"
" finalColor = vec4(red, green, blue, 1.0); \n"
#endif
" } \n"
"} \n";
#endif
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
static Matrix stack[MAX_MATRIX_STACK_SIZE] = { 0 };
static int stackCounter = 0;
@ -888,6 +806,7 @@ static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays;
#if defined(SUPPORT_VR_SIMULATOR)
// VR global variables
static VrStereoConfig vrConfig = { 0 }; // VR stereo configuration for simulator
static RenderTexture2D stereoFbo; // VR stereo rendering framebuffer
static bool vrSimulatorReady = false; // VR simulator ready flag
static bool vrStereoRender = false; // VR stereo rendering enabled/disabled flag
// NOTE: This flag is useful to render data over stereo image (i.e. FPS)
@ -921,7 +840,6 @@ static void GenDrawCube(void); // Generate and draw cube
static void GenDrawQuad(void); // Generate and draw quad
#if defined(SUPPORT_VR_SIMULATOR)
static VrStereoConfig SetStereoConfig(VrDeviceInfo info, Shader distortion); // Configure stereo rendering (including distortion shader) with HMD device parameters
static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView); // Set internal projection and modelview matrix depending on eye
#endif
@ -1123,7 +1041,27 @@ void rlBegin(int mode)
// NOTE: In all three cases, vertex are accumulated over default internal vertex buffer
if (draws[drawsCounter - 1].mode != mode)
{
if (draws[drawsCounter - 1].vertexCount > 0) drawsCounter++;
if (draws[drawsCounter - 1].vertexCount > 0)
{
// Make sure current draws[i].vertexCount is aligned a multiple of 4,
// that way, following QUADS drawing will keep aligned with index processing
// It implies adding some extra alignment vertex at the end of the draw,
// those vertex are not processed but they are considered as an additional offset
// for the next set of vertex to be drawn
if (draws[drawsCounter - 1].mode == RL_LINES) draws[drawsCounter - 1].vertexAlignment = ((draws[drawsCounter - 1].vertexCount < 4)? draws[drawsCounter - 1].vertexCount : draws[drawsCounter - 1].vertexCount%4);
else if (draws[drawsCounter - 1].mode == RL_TRIANGLES) draws[drawsCounter - 1].vertexAlignment = ((draws[drawsCounter - 1].vertexCount < 4)? 1 : (4 - (draws[drawsCounter - 1].vertexCount%4)));
if (rlCheckBufferLimit(draws[drawsCounter - 1].vertexAlignment)) rlglDraw();
else
{
vertexData[currentBuffer].vCounter += draws[drawsCounter - 1].vertexAlignment;
vertexData[currentBuffer].cCounter += draws[drawsCounter - 1].vertexAlignment;
vertexData[currentBuffer].tcCounter += draws[drawsCounter - 1].vertexAlignment;
drawsCounter++;
}
}
if (drawsCounter >= MAX_DRAWCALL_REGISTERED) rlglDraw();
draws[drawsCounter - 1].mode = mode;
@ -1135,15 +1073,6 @@ void rlBegin(int mode)
// Finish vertex providing
void rlEnd(void)
{
// Make sure current draws[i].vertexCount is multiple of 4, to align with index processing
// NOTE: It implies adding some extra vertex at the end of the draw, those vertex will be
// processed but are placed in a single point to not result in a fragment output...
// TODO: System could be improved (a bit) just storing every draw alignment value
// and adding it to vertexOffset on drawing... maybe in a future...
int vertexCount = draws[drawsCounter - 1].vertexCount;
int vertexToAlign = (vertexCount >= 4)? vertexCount%4 : (4 - vertexCount%4);
for (int i = 0; i < vertexToAlign; i++) rlVertex3f(-1, -1, -1);
// Make sure vertexCount is the same for vertices, texcoords, colors and normals
// NOTE: In OpenGL 1.1, one glColor call can be made for all the subsequent glVertex calls
@ -1283,7 +1212,27 @@ void rlEnableTexture(unsigned int id)
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if (draws[drawsCounter - 1].textureId != id)
{
if (draws[drawsCounter - 1].vertexCount > 0) drawsCounter++;
if (draws[drawsCounter - 1].vertexCount > 0)
{
// Make sure current draws[i].vertexCount is aligned a multiple of 4,
// that way, following QUADS drawing will keep aligned with index processing
// It implies adding some extra alignment vertex at the end of the draw,
// those vertex are not processed but they are considered as an additional offset
// for the next set of vertex to be drawn
if (draws[drawsCounter - 1].mode == RL_LINES) draws[drawsCounter - 1].vertexAlignment = ((draws[drawsCounter - 1].vertexCount < 4)? draws[drawsCounter - 1].vertexCount : draws[drawsCounter - 1].vertexCount%4);
else if (draws[drawsCounter - 1].mode == RL_TRIANGLES) draws[drawsCounter - 1].vertexAlignment = ((draws[drawsCounter - 1].vertexCount < 4)? 1 : (4 - (draws[drawsCounter - 1].vertexCount%4)));
if (rlCheckBufferLimit(draws[drawsCounter - 1].vertexAlignment)) rlglDraw();
else
{
vertexData[currentBuffer].vCounter += draws[drawsCounter - 1].vertexAlignment;
vertexData[currentBuffer].cCounter += draws[drawsCounter - 1].vertexAlignment;
vertexData[currentBuffer].tcCounter += draws[drawsCounter - 1].vertexAlignment;
drawsCounter++;
}
}
if (drawsCounter >= MAX_DRAWCALL_REGISTERED) rlglDraw();
draws[drawsCounter - 1].textureId = id;
@ -1469,6 +1418,13 @@ void rlClearScreenBuffers(void)
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Stencil buffer not used...
}
// Update GPU buffer with new data
void rlUpdateBuffer(int bufferId, void *data, int dataSize)
{
glBindBuffer(GL_ARRAY_BUFFER, bufferId);
glBufferSubData(GL_ARRAY_BUFFER, 0, dataSize, data);
}
//----------------------------------------------------------------------------------
// Module Functions Definition - rlgl Functions
//----------------------------------------------------------------------------------
@ -1682,6 +1638,7 @@ void rlglInit(int width, int height)
{
draws[i].mode = RL_QUADS;
draws[i].vertexCount = 0;
draws[i].vertexAlignment = 0;
//draws[i].vaoId = 0;
//draws[i].shaderId = 0;
draws[i].textureId = defaultTextureId;
@ -1753,8 +1710,12 @@ void rlglClose(void)
void rlglDraw(void)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Only process data if we have data to process
if (vertexData[currentBuffer].vCounter > 0)
{
UpdateBuffersDefault();
DrawBuffersDefault(); // NOTE: Stereo rendering is checked inside
}
#endif
}
@ -1999,6 +1960,8 @@ unsigned int rlLoadTexture(void *data, int width, int height, int format, int mi
unsigned int rlLoadTextureDepth(int width, int height, int bits, bool useRenderBuffer)
{
unsigned int id = 0;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
unsigned int glInternalFormat = GL_DEPTH_COMPONENT16;
if ((bits != 16) && (bits != 24) && (bits != 32)) bits = 16;
@ -2044,6 +2007,7 @@ unsigned int rlLoadTextureDepth(int width, int height, int bits, bool useRenderB
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
#endif
return id;
}
@ -2056,16 +2020,17 @@ unsigned int rlLoadTextureCubemap(void *data, int size, int format)
unsigned int cubemapId = 0;
unsigned int dataSize = GetPixelDataSize(size, size, format);
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glGenTextures(1, &cubemapId);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapId);
unsigned int glInternalFormat, glFormat, glType;
rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType);
if (glInternalFormat != -1)
{
// Load cubemap faces
for (unsigned int i = 0; i < 6; i++)
{
if (glInternalFormat != -1)
{
if (format < COMPRESSED_DXT1_RGB) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, glFormat, glType, (unsigned char *)data + i*dataSize);
#if !defined(GRAPHICS_API_OPENGL_11)
@ -2100,6 +2065,7 @@ unsigned int rlLoadTextureCubemap(void *data, int size, int format)
#endif
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
#endif
return cubemapId;
}
@ -2184,9 +2150,9 @@ RenderTexture2D rlLoadRenderTexture(int width, int height, int format, int depth
{
RenderTexture2D target = { 0 };
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if (useDepthTexture && texDepthSupported) target.depthTexture = true;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Create the framebuffer object
glGenFramebuffers(1, &target.id);
glBindFramebuffer(GL_FRAMEBUFFER, target.id);
@ -2237,6 +2203,7 @@ RenderTexture2D rlLoadRenderTexture(int width, int height, int format, int depth
// NOTE: Attach type: 0-Color, 1-Depth renderbuffer, 2-Depth texture
void rlRenderTextureAttach(RenderTexture2D target, unsigned int id, int attachType)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glBindFramebuffer(GL_FRAMEBUFFER, target.id);
if (attachType == 0) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, id, 0);
@ -2247,11 +2214,15 @@ void rlRenderTextureAttach(RenderTexture2D target, unsigned int id, int attachTy
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
#endif
}
// Verify render texture is complete
bool rlRenderTextureComplete(RenderTexture target)
{
bool result = false;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glBindFramebuffer(GL_FRAMEBUFFER, target.id);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
@ -2272,7 +2243,10 @@ bool rlRenderTextureComplete(RenderTexture target)
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return (status == GL_FRAMEBUFFER_COMPLETE);
result = (status == GL_FRAMEBUFFER_COMPLETE);
#endif
return result;
}
// Generate mipmap data for selected texture
@ -2474,6 +2448,29 @@ void rlLoadMesh(Mesh *mesh, bool dynamic)
#endif
}
// Load a new attributes buffer
unsigned int rlLoadAttribBuffer(unsigned int vaoId, int shaderLoc, void *buffer, int size, bool dynamic)
{
unsigned int id = 0;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
int drawHint = GL_STATIC_DRAW;
if (dynamic) drawHint = GL_DYNAMIC_DRAW;
if (vaoSupported) glBindVertexArray(vaoId);
glGenBuffers(1, &id);
glBindBuffer(GL_ARRAY_BUFFER, id);
glBufferData(GL_ARRAY_BUFFER, size, buffer, drawHint);
glVertexAttribPointer(shaderLoc, 2, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(shaderLoc);
if (vaoSupported) glBindVertexArray(0);
#endif
return id;
}
// Update vertex data on GPU (upload new data to one buffer)
void rlUpdateMesh(Mesh mesh, int buffer, int numVertex)
{
@ -2738,10 +2735,10 @@ void rlUnloadMesh(Mesh *mesh)
free(mesh->texcoords2);
free(mesh->indices);
free(mesh->baseVertices);
free(mesh->baseNormals);
free(mesh->weightBias);
free(mesh->weightId);
free(mesh->animVertices);
free(mesh->animNormals);
free(mesh->boneWeights);
free(mesh->boneIds);
rlDeleteBuffers(mesh->vboId[0]); // vertex
rlDeleteBuffers(mesh->vboId[1]); // texcoords
@ -3087,6 +3084,18 @@ void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat)
#endif
}
// Set shader uniform value for texture
void SetShaderValueTexture(Shader shader, int uniformLoc, Texture2D texture)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glUseProgram(shader.id);
glUniform1i(uniformLoc, texture.id);
//glUseProgram(0);
#endif
}
// Set a custom projection matrix (replaces internal projection matrix)
void SetMatrixProjection(Matrix proj)
{
@ -3483,101 +3492,17 @@ void EndScissorMode(void)
}
#if defined(SUPPORT_VR_SIMULATOR)
// Get VR device information for some standard devices
VrDeviceInfo GetVrDeviceInfo(int vrDeviceType)
{
VrDeviceInfo hmd = { 0 }; // Current VR device info
switch (vrDeviceType)
{
case HMD_DEFAULT_DEVICE:
case HMD_OCULUS_RIFT_CV1:
{
// Oculus Rift CV1 parameters
// NOTE: CV1 represents a complete HMD redesign compared to previous versions,
// new Fresnel-hybrid-asymmetric lenses have been added and, consequently,
// previous parameters (DK2) and distortion shader (DK2) doesn't work any more.
// I just defined a set of parameters for simulator that approximate to CV1 stereo rendering
// but result is not the same obtained with Oculus PC SDK.
hmd.hResolution = 2160; // HMD horizontal resolution in pixels
hmd.vResolution = 1200; // HMD vertical resolution in pixels
hmd.hScreenSize = 0.133793f; // HMD horizontal size in meters
hmd.vScreenSize = 0.0669f; // HMD vertical size in meters
hmd.vScreenCenter = 0.04678f; // HMD screen center in meters
hmd.eyeToScreenDistance = 0.041f; // HMD distance between eye and display in meters
hmd.lensSeparationDistance = 0.07f; // HMD lens separation distance in meters
hmd.interpupillaryDistance = 0.07f; // HMD IPD (distance between pupils) in meters
hmd.lensDistortionValues[0] = 1.0f; // HMD lens distortion constant parameter 0
hmd.lensDistortionValues[1] = 0.22f; // HMD lens distortion constant parameter 1
hmd.lensDistortionValues[2] = 0.24f; // HMD lens distortion constant parameter 2
hmd.lensDistortionValues[3] = 0.0f; // HMD lens distortion constant parameter 3
hmd.chromaAbCorrection[0] = 0.996f; // HMD chromatic aberration correction parameter 0
hmd.chromaAbCorrection[1] = -0.004f; // HMD chromatic aberration correction parameter 1
hmd.chromaAbCorrection[2] = 1.014f; // HMD chromatic aberration correction parameter 2
hmd.chromaAbCorrection[3] = 0.0f; // HMD chromatic aberration correction parameter 3
TraceLog(LOG_INFO, "Initializing VR Simulator (Oculus Rift CV1)");
} break;
case HMD_OCULUS_RIFT_DK2:
{
// Oculus Rift DK2 parameters
hmd.hResolution = 1280; // HMD horizontal resolution in pixels
hmd.vResolution = 800; // HMD vertical resolution in pixels
hmd.hScreenSize = 0.14976f; // HMD horizontal size in meters
hmd.vScreenSize = 0.09356f; // HMD vertical size in meters
hmd.vScreenCenter = 0.04678f; // HMD screen center in meters
hmd.eyeToScreenDistance = 0.041f; // HMD distance between eye and display in meters
hmd.lensSeparationDistance = 0.0635f; // HMD lens separation distance in meters
hmd.interpupillaryDistance = 0.064f; // HMD IPD (distance between pupils) in meters
hmd.lensDistortionValues[0] = 1.0f; // HMD lens distortion constant parameter 0
hmd.lensDistortionValues[1] = 0.22f; // HMD lens distortion constant parameter 1
hmd.lensDistortionValues[2] = 0.24f; // HMD lens distortion constant parameter 2
hmd.lensDistortionValues[3] = 0.0f; // HMD lens distortion constant parameter 3
hmd.chromaAbCorrection[0] = 0.996f; // HMD chromatic aberration correction parameter 0
hmd.chromaAbCorrection[1] = -0.004f; // HMD chromatic aberration correction parameter 1
hmd.chromaAbCorrection[2] = 1.014f; // HMD chromatic aberration correction parameter 2
hmd.chromaAbCorrection[3] = 0.0f; // HMD chromatic aberration correction parameter 3
TraceLog(LOG_INFO, "Initializing VR Simulator (Oculus Rift DK2)");
} break;
case HMD_OCULUS_GO:
{
// TODO: Provide device display and lens parameters
}
case HMD_VALVE_HTC_VIVE:
{
// TODO: Provide device display and lens parameters
}
case HMD_SONY_PSVR:
{
// TODO: Provide device display and lens parameters
}
default: break;
}
return hmd;
}
// Init VR simulator for selected device parameters
// NOTE: It modifies the global variable: VrStereoConfig vrConfig
void InitVrSimulator(VrDeviceInfo info)
// NOTE: It modifies the global variable: stereoFbo
void InitVrSimulator(void)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
Shader distortion = { 0 };
#if defined(SUPPORT_DISTORTION_SHADER)
// Load distortion shader
distortion = LoadShaderCode(NULL, distortionFShaderStr);
if (distortion.id > 0) SetShaderDefaultLocations(&distortion);
#endif
// Set VR configutarion parameters, including distortion shader
vrConfig = SetStereoConfig(info, distortion);
// Initialize framebuffer and textures for stereo rendering
// NOTE: Screen size should match HMD aspect ratio
stereoFbo = rlLoadRenderTexture(screenWidth, screenHeight, UNCOMPRESSED_R8G8B8A8, 24, false);
vrSimulatorReady = true;
#endif
#if defined(GRAPHICS_API_OPENGL_11)
#else
TraceLog(LOG_WARNING, "VR Simulator not supported on OpenGL 1.1");
#endif
}
@ -3593,14 +3518,90 @@ void UpdateVrTracking(Camera *camera)
void CloseVrSimulator(void)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if (vrSimulatorReady)
{
rlDeleteRenderTextures(vrConfig.stereoFbo); // Unload stereo framebuffer and texture
#if defined(SUPPORT_DISTORTION_SHADER)
UnloadShader(vrConfig.distortionShader); // Unload distortion shader
if (vrSimulatorReady) rlDeleteRenderTextures(stereoFbo); // Unload stereo framebuffer and texture
#endif
}
#endif
// Set stereo rendering configuration parameters
void SetVrConfiguration(VrDeviceInfo hmd, Shader distortion)
{
// Reset vrConfig for a new values assignment
memset(&vrConfig, 0, sizeof(vrConfig));
// Assign distortion shader
vrConfig.distortionShader = distortion;
// Compute aspect ratio
float aspect = ((float)hmd.hResolution*0.5f)/(float)hmd.vResolution;
// Compute lens parameters
float lensShift = (hmd.hScreenSize*0.25f - hmd.lensSeparationDistance*0.5f)/hmd.hScreenSize;
float leftLensCenter[2] = { 0.25f + lensShift, 0.5f };
float rightLensCenter[2] = { 0.75f - lensShift, 0.5f };
float leftScreenCenter[2] = { 0.25f, 0.5f };
float rightScreenCenter[2] = { 0.75f, 0.5f };
// Compute distortion scale parameters
// NOTE: To get lens max radius, lensShift must be normalized to [-1..1]
float lensRadius = (float)fabs(-1.0f - 4.0f*lensShift);
float lensRadiusSq = lensRadius*lensRadius;
float distortionScale = hmd.lensDistortionValues[0] +
hmd.lensDistortionValues[1]*lensRadiusSq +
hmd.lensDistortionValues[2]*lensRadiusSq*lensRadiusSq +
hmd.lensDistortionValues[3]*lensRadiusSq*lensRadiusSq*lensRadiusSq;
TraceLog(LOG_DEBUG, "VR: Distortion Scale: %f", distortionScale);
float normScreenWidth = 0.5f;
float normScreenHeight = 1.0f;
float scaleIn[2] = { 2.0f/normScreenWidth, 2.0f/normScreenHeight/aspect };
float scale[2] = { normScreenWidth*0.5f/distortionScale, normScreenHeight*0.5f*aspect/distortionScale };
TraceLog(LOG_DEBUG, "VR: Distortion Shader: LeftLensCenter = { %f, %f }", leftLensCenter[0], leftLensCenter[1]);
TraceLog(LOG_DEBUG, "VR: Distortion Shader: RightLensCenter = { %f, %f }", rightLensCenter[0], rightLensCenter[1]);
TraceLog(LOG_DEBUG, "VR: Distortion Shader: Scale = { %f, %f }", scale[0], scale[1]);
TraceLog(LOG_DEBUG, "VR: Distortion Shader: ScaleIn = { %f, %f }", scaleIn[0], scaleIn[1]);
// Fovy is normally computed with: 2*atan2(hmd.vScreenSize, 2*hmd.eyeToScreenDistance)
// ...but with lens distortion it is increased (see Oculus SDK Documentation)
//float fovy = 2.0f*atan2(hmd.vScreenSize*0.5f*distortionScale, hmd.eyeToScreenDistance); // Really need distortionScale?
float fovy = 2.0f*(float)atan2(hmd.vScreenSize*0.5f, hmd.eyeToScreenDistance);
// Compute camera projection matrices
float projOffset = 4.0f*lensShift; // Scaled to projection space coordinates [-1..1]
Matrix proj = MatrixPerspective(fovy, aspect, 0.01, 1000.0);
vrConfig.eyesProjection[0] = MatrixMultiply(proj, MatrixTranslate(projOffset, 0.0f, 0.0f));
vrConfig.eyesProjection[1] = MatrixMultiply(proj, MatrixTranslate(-projOffset, 0.0f, 0.0f));
// Compute camera transformation matrices
// NOTE: Camera movement might seem more natural if we model the head.
// Our axis of rotation is the base of our head, so we might want to add
// some y (base of head to eye level) and -z (center of head to eye protrusion) to the camera positions.
vrConfig.eyesViewOffset[0] = MatrixTranslate(-hmd.interpupillaryDistance*0.5f, 0.075f, 0.045f);
vrConfig.eyesViewOffset[1] = MatrixTranslate(hmd.interpupillaryDistance*0.5f, 0.075f, 0.045f);
// Compute eyes Viewports
vrConfig.eyeViewportRight[2] = hmd.hResolution/2;
vrConfig.eyeViewportRight[3] = hmd.vResolution;
vrConfig.eyeViewportLeft[0] = hmd.hResolution/2;
vrConfig.eyeViewportLeft[1] = 0;
vrConfig.eyeViewportLeft[2] = hmd.hResolution/2;
vrConfig.eyeViewportLeft[3] = hmd.vResolution;
if (vrConfig.distortionShader.id > 0)
{
// Update distortion shader with lens and distortion-scale parameters
SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "leftLensCenter"), leftLensCenter, UNIFORM_VEC2);
SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "rightLensCenter"), rightLensCenter, UNIFORM_VEC2);
SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "leftScreenCenter"), leftScreenCenter, UNIFORM_VEC2);
SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "rightScreenCenter"), rightScreenCenter, UNIFORM_VEC2);
SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "scale"), scale, UNIFORM_VEC2);
SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "scaleIn"), scaleIn, UNIFORM_VEC2);
SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "hmdWarpParam"), hmd.lensDistortionValues, UNIFORM_VEC4);
SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "chromaAbParam"), hmd.chromaAbCorrection, UNIFORM_VEC4);
}
}
// Detect if VR simulator is running
@ -3639,7 +3640,7 @@ void BeginVrDrawing(void)
if (vrSimulatorReady)
{
// Setup framebuffer for stereo rendering
rlEnableRenderTexture(vrConfig.stereoFbo.id);
rlEnableRenderTexture(stereoFbo.id);
// NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA)
// and performs linear-to-gamma conversion in GLSL or does not care about gamma-correction, then:
@ -3677,13 +3678,11 @@ void EndVrDrawing(void)
rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix
rlLoadIdentity(); // Reset internal modelview matrix
#if defined(SUPPORT_DISTORTION_SHADER)
// Draw RenderTexture (stereoFbo) using distortion shader
currentShader = vrConfig.distortionShader;
#else
currentShader = GetShaderDefault();
#endif
rlEnableTexture(vrConfig.stereoFbo.texture.id);
// Draw RenderTexture (stereoFbo) using distortion shader if available
if (vrConfig.distortionShader.id > 0) currentShader = vrConfig.distortionShader;
else currentShader = GetShaderDefault();
rlEnableTexture(stereoFbo.texture.id);
rlPushMatrix();
rlBegin(RL_QUADS);
@ -3696,15 +3695,15 @@ void EndVrDrawing(void)
// Bottom-right corner for texture and quad
rlTexCoord2f(0.0f, 0.0f);
rlVertex2f(0.0f, (float)vrConfig.stereoFbo.texture.height);
rlVertex2f(0.0f, (float)stereoFbo.texture.height);
// Top-right corner for texture and quad
rlTexCoord2f(1.0f, 0.0f);
rlVertex2f( (float)vrConfig.stereoFbo.texture.width, (float)vrConfig.stereoFbo.texture.height);
rlVertex2f( (float)stereoFbo.texture.width, (float)stereoFbo.texture.height);
// Top-left corner for texture and quad
rlTexCoord2f(1.0f, 1.0f);
rlVertex2f( (float)vrConfig.stereoFbo.texture.width, 0.0f);
rlVertex2f( (float)stereoFbo.texture.width, 0.0f);
rlEnd();
rlPopMatrix();
@ -4191,7 +4190,7 @@ static void DrawBuffersDefault(void)
#endif
}
vertexOffset += draws[i].vertexCount;
vertexOffset += (draws[i].vertexCount + draws[i].vertexAlignment);
}
if (!vaoSupported)
@ -4378,87 +4377,6 @@ static void GenDrawCube(void)
}
#if defined(SUPPORT_VR_SIMULATOR)
// Configure stereo rendering (including distortion shader) with HMD device parameters
static VrStereoConfig SetStereoConfig(VrDeviceInfo hmd, Shader distortion)
{
VrStereoConfig config = { 0 };
// Initialize framebuffer and textures for stereo rendering
// NOTE: Screen size should match HMD aspect ratio
config.stereoFbo = rlLoadRenderTexture(screenWidth, screenHeight, UNCOMPRESSED_R8G8B8A8, 24, false);
// Assign distortion shader
config.distortionShader = distortion;
// Compute aspect ratio
float aspect = ((float)hmd.hResolution*0.5f)/(float)hmd.vResolution;
// Compute lens parameters
float lensShift = (hmd.hScreenSize*0.25f - hmd.lensSeparationDistance*0.5f)/hmd.hScreenSize;
float leftLensCenter[2] = { 0.25f + lensShift, 0.5f };
float rightLensCenter[2] = { 0.75f - lensShift, 0.5f };
float leftScreenCenter[2] = { 0.25f, 0.5f };
float rightScreenCenter[2] = { 0.75f, 0.5f };
// Compute distortion scale parameters
// NOTE: To get lens max radius, lensShift must be normalized to [-1..1]
float lensRadius = (float)fabs(-1.0f - 4.0f*lensShift);
float lensRadiusSq = lensRadius*lensRadius;
float distortionScale = hmd.lensDistortionValues[0] +
hmd.lensDistortionValues[1]*lensRadiusSq +
hmd.lensDistortionValues[2]*lensRadiusSq*lensRadiusSq +
hmd.lensDistortionValues[3]*lensRadiusSq*lensRadiusSq*lensRadiusSq;
TraceLog(LOG_DEBUG, "VR: Distortion Scale: %f", distortionScale);
float normScreenWidth = 0.5f;
float normScreenHeight = 1.0f;
float scaleIn[2] = { 2.0f/normScreenWidth, 2.0f/normScreenHeight/aspect };
float scale[2] = { normScreenWidth*0.5f/distortionScale, normScreenHeight*0.5f*aspect/distortionScale };
TraceLog(LOG_DEBUG, "VR: Distortion Shader: LeftLensCenter = { %f, %f }", leftLensCenter[0], leftLensCenter[1]);
TraceLog(LOG_DEBUG, "VR: Distortion Shader: RightLensCenter = { %f, %f }", rightLensCenter[0], rightLensCenter[1]);
TraceLog(LOG_DEBUG, "VR: Distortion Shader: Scale = { %f, %f }", scale[0], scale[1]);
TraceLog(LOG_DEBUG, "VR: Distortion Shader: ScaleIn = { %f, %f }", scaleIn[0], scaleIn[1]);
// Fovy is normally computed with: 2*atan2(hmd.vScreenSize, 2*hmd.eyeToScreenDistance)
// ...but with lens distortion it is increased (see Oculus SDK Documentation)
//float fovy = 2.0f*atan2(hmd.vScreenSize*0.5f*distortionScale, hmd.eyeToScreenDistance); // Really need distortionScale?
float fovy = 2.0f*(float)atan2(hmd.vScreenSize*0.5f, hmd.eyeToScreenDistance);
// Compute camera projection matrices
float projOffset = 4.0f*lensShift; // Scaled to projection space coordinates [-1..1]
Matrix proj = MatrixPerspective(fovy, aspect, 0.01, 1000.0);
config.eyesProjection[0] = MatrixMultiply(proj, MatrixTranslate(projOffset, 0.0f, 0.0f));
config.eyesProjection[1] = MatrixMultiply(proj, MatrixTranslate(-projOffset, 0.0f, 0.0f));
// Compute camera transformation matrices
// NOTE: Camera movement might seem more natural if we model the head.
// Our axis of rotation is the base of our head, so we might want to add
// some y (base of head to eye level) and -z (center of head to eye protrusion) to the camera positions.
config.eyesViewOffset[0] = MatrixTranslate(-hmd.interpupillaryDistance*0.5f, 0.075f, 0.045f);
config.eyesViewOffset[1] = MatrixTranslate(hmd.interpupillaryDistance*0.5f, 0.075f, 0.045f);
// Compute eyes Viewports
//config.eyeViewportRight[0] = (int[4]){ 0, 0, hmd.hResolution/2, hmd.vResolution };
//config.eyeViewportLeft[0] = (int[4]){ hmd.hResolution/2, 0, hmd.hResolution/2, hmd.vResolution };
#if defined(SUPPORT_DISTORTION_SHADER)
// Update distortion shader with lens and distortion-scale parameters
SetShaderValue(config.distortionShader, GetShaderLocation(config.distortionShader, "leftLensCenter"), leftLensCenter, UNIFORM_VEC2);
SetShaderValue(config.distortionShader, GetShaderLocation(config.distortionShader, "rightLensCenter"), rightLensCenter, UNIFORM_VEC2);
SetShaderValue(config.distortionShader, GetShaderLocation(config.distortionShader, "leftScreenCenter"), leftScreenCenter, UNIFORM_VEC2);
SetShaderValue(config.distortionShader, GetShaderLocation(config.distortionShader, "rightScreenCenter"), rightScreenCenter, UNIFORM_VEC2);
SetShaderValue(config.distortionShader, GetShaderLocation(config.distortionShader, "scale"), scale, UNIFORM_VEC2);
SetShaderValue(config.distortionShader, GetShaderLocation(config.distortionShader, "scaleIn"), scaleIn, UNIFORM_VEC2);
SetShaderValue(config.distortionShader, GetShaderLocation(config.distortionShader, "hmdWarpParam"), hmd.lensDistortionValues, UNIFORM_VEC4);
SetShaderValue(config.distortionShader, GetShaderLocation(config.distortionShader, "chromaAbParam"), hmd.chromaAbCorrection, UNIFORM_VEC4);
#endif
return config;
}
// Set internal projection and modelview matrix depending on eyes tracking data
static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView)
{

View File

@ -14,7 +14,7 @@
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@ -183,18 +183,42 @@ void DrawCircle(int centerX, int centerY, float radius, Color color)
}
// Draw a piece of a circle
// TODO: Support better angle resolution (now limited to CIRCLE_SECTOR_LENGTH)
void DrawCircleSector(Vector2 center, float radius, int startAngle, int endAngle, Color color)
void DrawCircleSector(Vector2 center, float radius, int startAngle, int endAngle, int segments, Color color)
{
#define CIRCLE_SECTOR_LENGTH 10
if (radius <= 0.0f) radius = 0.1f; // Avoid div by zero
// Function expects (endAngle > startAngle)
if (endAngle < startAngle)
{
// Swap values
int tmp = startAngle;
startAngle = endAngle;
endAngle = tmp;
}
if (segments < 4)
{
// Calculate how many segments we need to draw a smooth circle, taken from https://stackoverflow.com/a/2244088
#define CIRCLE_ERROR_RATE 0.5f
// Calculate the maximum angle between segments based on the error rate.
float th = acosf(2*powf(1 - CIRCLE_ERROR_RATE/radius, 2) - 1);
segments = (endAngle - startAngle)*ceilf(2*PI/th)/360;
if (segments <= 0) segments = 4;
}
float stepLength = (float)(endAngle - startAngle)/(float)segments;
float angle = startAngle;
#if defined(SUPPORT_QUADS_DRAW_MODE)
if (rlCheckBufferLimit(4*((360/CIRCLE_SECTOR_LENGTH)/2))) rlglDraw();
if (rlCheckBufferLimit(4*segments/2)) rlglDraw();
rlEnableTexture(GetShapesTexture().id);
rlBegin(RL_QUADS);
for (int i = startAngle; i < endAngle; i += CIRCLE_SECTOR_LENGTH*2)
// NOTE: Every QUAD actually represents two segments
for (int i = 0; i < segments/2; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
@ -202,33 +226,119 @@ void DrawCircleSector(Vector2 center, float radius, int startAngle, int endAngle
rlVertex2f(center.x, center.y);
rlTexCoord2f(recTexShapes.x/texShapes.width, (recTexShapes.y + recTexShapes.height)/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*i)*radius, center.y + cosf(DEG2RAD*i)*radius);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
rlTexCoord2f((recTexShapes.x + recTexShapes.width)/texShapes.width, (recTexShapes.y + recTexShapes.height)/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*(i + CIRCLE_SECTOR_LENGTH))*radius, center.y + cosf(DEG2RAD*(i + CIRCLE_SECTOR_LENGTH))*radius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
rlTexCoord2f((recTexShapes.x + recTexShapes.width)/texShapes.width, recTexShapes.y/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*(i + CIRCLE_SECTOR_LENGTH*2))*radius, center.y + cosf(DEG2RAD*(i + CIRCLE_SECTOR_LENGTH*2))*radius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength*2))*radius, center.y + cosf(DEG2RAD*(angle + stepLength*2))*radius);
angle += (stepLength*2);
}
// NOTE: In case number of segments is odd, we add one last piece to the cake
if (segments%2)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(recTexShapes.x/texShapes.width, recTexShapes.y/texShapes.height);
rlVertex2f(center.x, center.y);
rlTexCoord2f(recTexShapes.x/texShapes.width, (recTexShapes.y + recTexShapes.height)/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
rlTexCoord2f((recTexShapes.x + recTexShapes.width)/texShapes.width, (recTexShapes.y + recTexShapes.height)/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
rlTexCoord2f((recTexShapes.x + recTexShapes.width)/texShapes.width, recTexShapes.y/texShapes.height);
rlVertex2f(center.x, center.y);
}
rlEnd();
rlDisableTexture();
#else
if (rlCheckBufferLimit(3*((360/CIRCLE_SECTOR_LENGTH)/2))) rlglDraw();
if (rlCheckBufferLimit(3*segments)) rlglDraw();
rlBegin(RL_TRIANGLES);
for (int i = startAngle; i < endAngle; i += CIRCLE_SECTOR_LENGTH)
for (int i = 0; i < segments; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(center.x, center.y);
rlVertex2f(center.x + sinf(DEG2RAD*i)*radius, center.y + cosf(DEG2RAD*i)*radius);
rlVertex2f(center.x + sinf(DEG2RAD*(i + CIRCLE_SECTOR_LENGTH))*radius, center.y + cosf(DEG2RAD*(i + CIRCLE_SECTOR_LENGTH))*radius);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
angle += stepLength;
}
rlEnd();
#endif
}
void DrawCircleSectorLines(Vector2 center, float radius, int startAngle, int endAngle, int segments, Color color)
{
if (radius <= 0.0f) radius = 0.1f; // Avoid div by zero issue
// Function expects (endAngle > startAngle)
if (endAngle < startAngle)
{
// Swap values
int tmp = startAngle;
startAngle = endAngle;
endAngle = tmp;
}
if (segments < 4)
{
// Calculate how many segments we need to draw a smooth circle, taken from https://stackoverflow.com/a/2244088
#ifndef CIRCLE_ERROR_RATE
#define CIRCLE_ERROR_RATE 0.5f
#endif
// Calculate the maximum angle between segments based on the error rate.
float th = acosf(2*powf(1 - CIRCLE_ERROR_RATE/radius, 2) - 1);
segments = (endAngle - startAngle)*ceilf(2*PI/th)/360;
if (segments <= 0) segments = 4;
}
float stepLength = (float)(endAngle - startAngle)/(float)segments;
float angle = startAngle;
// Hide the cap lines when the circle is full
bool showCapLines = true;
int limit = 2*(segments + 2);
if ((endAngle - startAngle)%360 == 0) { limit = 2*segments; showCapLines = false; }
if (rlCheckBufferLimit(limit)) rlglDraw();
rlBegin(RL_LINES);
if (showCapLines)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(center.x, center.y);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
}
for (int i = 0; i < segments; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
angle += stepLength;
}
if (showCapLines)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(center.x, center.y);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
}
rlEnd();
}
// Draw a gradient-filled circle
// NOTE: Gradient goes from center (color1) to border (color2)
void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2)
@ -239,7 +349,7 @@ void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Co
for (int i = 0; i < 360; i += 10)
{
rlColor4ub(color1.r, color1.g, color1.b, color1.a);
rlVertex2i(centerX, centerY);
rlVertex2f(centerX, centerY);
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
rlVertex2f(centerX + sinf(DEG2RAD*i)*radius, centerY + cosf(DEG2RAD*i)*radius);
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
@ -252,7 +362,7 @@ void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Co
// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues (view rlglDraw)
void DrawCircleV(Vector2 center, float radius, Color color)
{
DrawCircleSector(center, radius, 0, 360, color);
DrawCircleSector(center, radius, 0, 360, 36, color);
}
// Draw circle outline
@ -272,6 +382,184 @@ void DrawCircleLines(int centerX, int centerY, float radius, Color color)
rlEnd();
}
void DrawRing(Vector2 center, float innerRadius, float outerRadius, int startAngle, int endAngle, int segments, Color color)
{
if (startAngle == endAngle) return;
// Function expects (outerRadius > innerRadius)
if (outerRadius < innerRadius)
{
float tmp = outerRadius;
outerRadius = innerRadius;
innerRadius = tmp;
if (outerRadius <= 0.0f) outerRadius = 0.1f;
}
// Function expects (endAngle > startAngle)
if (endAngle < startAngle)
{
// Swap values
int tmp = startAngle;
startAngle = endAngle;
endAngle = tmp;
}
if (segments < 4)
{
// Calculate how many segments we need to draw a smooth circle, taken from https://stackoverflow.com/a/2244088
#ifndef CIRCLE_ERROR_RATE
#define CIRCLE_ERROR_RATE 0.5f
#endif
// Calculate the maximum angle between segments based on the error rate.
float th = acosf(2*powf(1 - CIRCLE_ERROR_RATE/outerRadius, 2) - 1);
segments = (endAngle - startAngle)*ceilf(2*PI/th)/360;
if (segments <= 0) segments = 4;
}
// Not a ring
if (innerRadius <= 0.0f)
{
DrawCircleSector(center, outerRadius, startAngle, endAngle, segments, color);
return;
}
float stepLength = (float)(endAngle - startAngle)/(float)segments;
float angle = startAngle;
#if defined(SUPPORT_QUADS_DRAW_MODE)
if (rlCheckBufferLimit(4*segments)) rlglDraw();
rlEnableTexture(GetShapesTexture().id);
rlBegin(RL_QUADS);
for (int i = 0; i < segments; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(recTexShapes.x/texShapes.width, recTexShapes.y/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius);
rlTexCoord2f(recTexShapes.x/texShapes.width, (recTexShapes.y + recTexShapes.height)/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
rlTexCoord2f((recTexShapes.x + recTexShapes.width)/texShapes.width, (recTexShapes.y + recTexShapes.height)/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*outerRadius);
rlTexCoord2f((recTexShapes.x + recTexShapes.width)/texShapes.width, recTexShapes.y/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius);
angle += stepLength;
}
rlEnd();
rlDisableTexture();
#else
if (rlCheckBufferLimit(6*segments)) rlglDraw();
rlBegin(RL_TRIANGLES);
for (int i = 0; i < segments; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*outerRadius);
angle += stepLength;
}
rlEnd();
#endif
}
void DrawRingLines(Vector2 center, float innerRadius, float outerRadius, int startAngle, int endAngle, int segments, Color color)
{
if (startAngle == endAngle) return;
// Function expects (outerRadius > innerRadius)
if (outerRadius < innerRadius)
{
float tmp = outerRadius;
outerRadius = innerRadius;
innerRadius = tmp;
if (outerRadius <= 0.0f) outerRadius = 0.1f;
}
// Function expects (endAngle > startAngle)
if (endAngle < startAngle)
{
// Swap values
int tmp = startAngle;
startAngle = endAngle;
endAngle = tmp;
}
if (segments < 4)
{
// Calculate how many segments we need to draw a smooth circle, taken from https://stackoverflow.com/a/2244088
#ifndef CIRCLE_ERROR_RATE
#define CIRCLE_ERROR_RATE 0.5f
#endif
// Calculate the maximum angle between segments based on the error rate.
float th = acosf(2*powf(1 - CIRCLE_ERROR_RATE/outerRadius, 2) - 1);
segments = (endAngle - startAngle)*ceilf(2*PI/th)/360;
if (segments <= 0) segments = 4;
}
if (innerRadius <= 0.0f)
{
DrawCircleSectorLines(center, outerRadius, startAngle, endAngle, segments, color);
return;
}
float stepLength = (float)(endAngle - startAngle)/(float)segments;
float angle = startAngle;
bool showCapLines = true;
int limit = 4*(segments + 1);
if ((endAngle - startAngle)%360 == 0) { limit = 4*segments; showCapLines = false; }
if (rlCheckBufferLimit(limit)) rlglDraw();
rlBegin(RL_LINES);
if (showCapLines)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius);
}
for (int i = 0; i < segments; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*outerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius);
angle += stepLength;
}
if (showCapLines)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius);
}
rlEnd();
}
// Draw a color-filled rectangle
void DrawRectangle(int posX, int posY, int width, int height, Color color)
{
@ -410,6 +698,413 @@ void DrawRectangleLinesEx(Rectangle rec, int lineThick, Color color)
DrawRectangle( (int)rec.x, (int)(rec.y + lineThick), lineThick, (int)(rec.height - lineThick*2), color);
}
// Draw rectangle with rounded edges
void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color color)
{
// Not a rounded rectangle
if ((roundness <= 0.0f) || (rec.width < 1) || (rec.height < 1 ))
{
DrawRectangleRec(rec, color);
return;
}
if (roundness >= 1.0f) roundness = 1.0f;
// Calculate corner radius
float radius = (rec.width > rec.height)? (rec.height*roundness)/2 : (rec.width*roundness)/2;
if (radius <= 0.0f) return;
// Calculate number of segments to use for the corners
if (segments < 4)
{
// Calculate how many segments we need to draw a smooth circle, taken from https://stackoverflow.com/a/2244088
#ifndef CIRCLE_ERROR_RATE
#define CIRCLE_ERROR_RATE 0.5f
#endif
// Calculate the maximum angle between segments based on the error rate.
float th = acosf(2*powf(1 - CIRCLE_ERROR_RATE/radius, 2) - 1);
segments = ceilf(2*PI/th)/4;
if (segments <= 0) segments = 4;
}
float stepLength = 90.0f/(float)segments;
/* Quick sketch to make sense of all of this (there are 9 parts to draw, also mark the 12 points we'll use below)
* Not my best attempt at ASCII art, just preted it's rounded rectangle :)
* P0 P1
* ____________________
* /| |\
* /1| 2 |3\
*P7 /__|____________________|__\ P2
* | |P8 P9| |
* | 8 | 9 | 4 |
* | __|____________________|__ |
*P6 \ |P11 P10| / P3
* \7| 6 |5/
* \|____________________|/
* P5 P4
*/
const Vector2 point[12] = { // coordinates of the 12 points that define the rounded rect (the idea here is to make things easier)
{(float)rec.x + radius, rec.y}, {(float)(rec.x + rec.width) - radius, rec.y}, { rec.x + rec.width, (float)rec.y + radius }, // PO, P1, P2
{rec.x + rec.width, (float)(rec.y + rec.height) - radius}, {(float)(rec.x + rec.width) - radius, rec.y + rec.height}, // P3, P4
{(float)rec.x + radius, rec.y + rec.height}, { rec.x, (float)(rec.y + rec.height) - radius}, {rec.x, (float)rec.y + radius}, // P5, P6, P7
{(float)rec.x + radius, (float)rec.y + radius}, {(float)(rec.x + rec.width) - radius, (float)rec.y + radius}, // P8, P9
{(float)(rec.x + rec.width) - radius, (float)(rec.y + rec.height) - radius}, {(float)rec.x + radius, (float)(rec.y + rec.height) - radius} // P10, P11
};
const Vector2 centers[4] = { point[8], point[9], point[10], point[11] };
const float angles[4] = { 180.0f, 90.0f, 0.0f, 270.0f };
#if defined(SUPPORT_QUADS_DRAW_MODE)
if (rlCheckBufferLimit(16*segments/2 + 5*4)) rlglDraw();
rlBegin(RL_QUADS);
// Draw all of the 4 corners: [1] Upper Left Corner, [3] Upper Right Corner, [5] Lower Right Corner, [7] Lower Left Corner
for (int k = 0; k < 4; ++k) // Hope the compiler is smart enough to unroll this loop
{
float angle = angles[k];
const Vector2 center = centers[k];
// NOTE: Every QUAD actually represents two segments
for (int i = 0; i < segments/2; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(center.x, center.y);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength*2))*radius, center.y + cosf(DEG2RAD*(angle + stepLength*2))*radius);
angle += (stepLength*2);
}
// NOTE: In case number of segments is odd, we add one last piece to the cake
if (segments%2)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(center.x, center.y);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
rlVertex2f(center.x, center.y);
}
}
// [2] Upper Rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[0].x, point[0].y);
rlVertex2f(point[8].x, point[8].y);
rlVertex2f(point[9].x, point[9].y);
rlVertex2f(point[1].x, point[1].y);
// [4] Right Rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[2].x, point[2].y);
rlVertex2f(point[9].x, point[9].y);
rlVertex2f(point[10].x, point[10].y);
rlVertex2f(point[3].x, point[3].y);
// [6] Bottom Rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[11].x, point[11].y);
rlVertex2f(point[5].x, point[5].y);
rlVertex2f(point[4].x, point[4].y);
rlVertex2f(point[10].x, point[10].y);
// [8] Left Rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[7].x, point[7].y);
rlVertex2f(point[6].x, point[6].y);
rlVertex2f(point[11].x, point[11].y);
rlVertex2f(point[8].x, point[8].y);
// [9] Middle Rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[8].x, point[8].y);
rlVertex2f(point[11].x, point[11].y);
rlVertex2f(point[10].x, point[10].y);
rlVertex2f(point[9].x, point[9].y);
rlEnd();
#else
if (rlCheckBufferLimit(12*segments + 5*6)) rlglDraw(); // 4 corners with 3 vertices per segment + 5 rectangles with 6 vertices each
rlBegin(RL_TRIANGLES);
// Draw all of the 4 corners: [1] Upper Left Corner, [3] Upper Right Corner, [5] Lower Right Corner, [7] Lower Left Corner
for (int k = 0; k < 4; ++k) // Hope the compiler is smart enough to unroll this loop
{
float angle = angles[k];
const Vector2 center = centers[k];
for (int i = 0; i < segments; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(center.x, center.y);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
angle += stepLength;
}
}
// [2] Upper Rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[0].x, point[0].y);
rlVertex2f(point[8].x, point[8].y);
rlVertex2f(point[9].x, point[9].y);
rlVertex2f(point[1].x, point[1].y);
rlVertex2f(point[0].x, point[0].y);
rlVertex2f(point[9].x, point[9].y);
// [4] Right Rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[9].x, point[9].y);
rlVertex2f(point[10].x, point[10].y);
rlVertex2f(point[3].x, point[3].y);
rlVertex2f(point[2].x, point[2].y);
rlVertex2f(point[9].x, point[9].y);
rlVertex2f(point[3].x, point[3].y);
// [6] Bottom Rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[11].x, point[11].y);
rlVertex2f(point[5].x, point[5].y);
rlVertex2f(point[4].x, point[4].y);
rlVertex2f(point[10].x, point[10].y);
rlVertex2f(point[11].x, point[11].y);
rlVertex2f(point[4].x, point[4].y);
// [8] Left Rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[7].x, point[7].y);
rlVertex2f(point[6].x, point[6].y);
rlVertex2f(point[11].x, point[11].y);
rlVertex2f(point[8].x, point[8].y);
rlVertex2f(point[7].x, point[7].y);
rlVertex2f(point[11].x, point[11].y);
// [9] Middle Rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[8].x, point[8].y);
rlVertex2f(point[11].x, point[11].y);
rlVertex2f(point[10].x, point[10].y);
rlVertex2f(point[9].x, point[9].y);
rlVertex2f(point[8].x, point[8].y);
rlVertex2f(point[10].x, point[10].y);
rlEnd();
#endif
}
// Draw rectangle with rounded edges outline
void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, int lineThick, Color color)
{
if (lineThick < 0) lineThick = 0;
// Not a rounded rectangle
if (roundness <= 0.0f)
{
DrawRectangleLinesEx((Rectangle){rec.x-lineThick, rec.y-lineThick, rec.width+2*lineThick, rec.height+2*lineThick}, lineThick, color);
return;
}
if (roundness >= 1.0f) roundness = 1.0f;
// Calculate corner radius
float radius = (rec.width > rec.height)? (rec.height*roundness)/2 : (rec.width*roundness)/2;
if (radius <= 0.0f) return;
// Calculate number of segments to use for the corners
if (segments < 4)
{
// Calculate how many segments we need to draw a smooth circle, taken from https://stackoverflow.com/a/2244088
#ifndef CIRCLE_ERROR_RATE
#define CIRCLE_ERROR_RATE 0.5f
#endif
// Calculate the maximum angle between segments based on the error rate.
float th = acosf(2*powf(1 - CIRCLE_ERROR_RATE/radius, 2) - 1);
segments = ceilf(2*PI/th)/2;
if (segments <= 0) segments = 4;
}
float stepLength = 90.0f/(float)segments;
const float outerRadius = radius + (float)lineThick, innerRadius = radius;
/* Quick sketch to make sense of all of this (mark the 16 + 4(corner centers P16-19) points we'll use below)
* Not my best attempt at ASCII art, just preted it's rounded rectangle :)
* P0 P1
* ====================
* // P8 P9 \\
* // \\
*P7 // P15 P10 \\ P2
* || *P16 P17* ||
* || ||
* || P14 P11 ||
*P6 \\ *P19 P18* // P3
* \\ //
* \\ P13 P12 //
* ====================
* P5 P4
*/
const Vector2 point[16] = {
{(float)rec.x + innerRadius, rec.y - lineThick}, {(float)(rec.x + rec.width) - innerRadius, rec.y - lineThick}, { rec.x + rec.width + lineThick, (float)rec.y + innerRadius }, // PO, P1, P2
{rec.x + rec.width + lineThick, (float)(rec.y + rec.height) - innerRadius}, {(float)(rec.x + rec.width) - innerRadius, rec.y + rec.height + lineThick}, // P3, P4
{(float)rec.x + innerRadius, rec.y + rec.height + lineThick}, { rec.x - lineThick, (float)(rec.y + rec.height) - innerRadius}, {rec.x - lineThick, (float)rec.y + innerRadius}, // P5, P6, P7
{(float)rec.x + innerRadius, rec.y}, {(float)(rec.x + rec.width) - innerRadius, rec.y}, // P8, P9
{ rec.x + rec.width, (float)rec.y + innerRadius }, {rec.x + rec.width, (float)(rec.y + rec.height) - innerRadius}, // P10, P11
{(float)(rec.x + rec.width) - innerRadius, rec.y + rec.height}, {(float)rec.x + innerRadius, rec.y + rec.height}, // P12, P13
{ rec.x, (float)(rec.y + rec.height) - innerRadius}, {rec.x, (float)rec.y + innerRadius} // P14, P15
};
const Vector2 centers[4] = {
{(float)rec.x + innerRadius, (float)rec.y + innerRadius}, {(float)(rec.x + rec.width) - innerRadius, (float)rec.y + innerRadius}, // P16, P17
{(float)(rec.x + rec.width) - innerRadius, (float)(rec.y + rec.height) - innerRadius}, {(float)rec.x + innerRadius, (float)(rec.y + rec.height) - innerRadius} // P18, P19
};
const float angles[4] = { 180.0f, 90.0f, 0.0f, 270.0f };
if (lineThick > 1)
{
#if defined(SUPPORT_QUADS_DRAW_MODE)
if (rlCheckBufferLimit(4*4*segments + 4*4)) rlglDraw(); // 4 corners with 4 vertices for each segment + 4 rectangles with 4 vertices each
rlBegin(RL_QUADS);
// Draw all of the 4 corners first: Upper Left Corner, Upper Right Corner, Lower Right Corner, Lower Left Corner
for (int k = 0; k < 4; ++k) // Hope the compiler is smart enough to unroll this loop
{
float angle = angles[k];
const Vector2 center = centers[k];
for (int i = 0; i < segments; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*outerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius);
angle += stepLength;
}
}
// Upper rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[0].x, point[0].y);
rlVertex2f(point[8].x, point[8].y);
rlVertex2f(point[9].x, point[9].y);
rlVertex2f(point[1].x, point[1].y);
// Right rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[2].x, point[2].y);
rlVertex2f(point[10].x, point[10].y);
rlVertex2f(point[11].x, point[11].y);
rlVertex2f(point[3].x, point[3].y);
// Lower rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[13].x, point[13].y);
rlVertex2f(point[5].x, point[5].y);
rlVertex2f(point[4].x, point[4].y);
rlVertex2f(point[12].x, point[12].y);
// Left rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[15].x, point[15].y);
rlVertex2f(point[7].x, point[7].y);
rlVertex2f(point[6].x, point[6].y);
rlVertex2f(point[14].x, point[14].y);
rlEnd();
#else
if (rlCheckBufferLimit(4*6*segments + 4*6)) rlglDraw(); // 4 corners with 6(2*3) vertices for each segment + 4 rectangles with 6 vertices each
rlBegin(RL_TRIANGLES);
// Draw all of the 4 corners first: Upper Left Corner, Upper Right Corner, Lower Right Corner, Lower Left Corner
for (int k = 0; k < 4; ++k) // Hope the compiler is smart enough to unroll this loop
{
float angle = angles[k];
const Vector2 center = centers[k];
for (int i = 0; i < segments; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*outerRadius);
angle += stepLength;
}
}
// Upper rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[0].x, point[0].y);
rlVertex2f(point[8].x, point[8].y);
rlVertex2f(point[9].x, point[9].y);
rlVertex2f(point[1].x, point[1].y);
rlVertex2f(point[0].x, point[0].y);
rlVertex2f(point[9].x, point[9].y);
// Right rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[10].x, point[10].y);
rlVertex2f(point[11].x, point[11].y);
rlVertex2f(point[3].x, point[3].y);
rlVertex2f(point[2].x, point[2].y);
rlVertex2f(point[10].x, point[10].y);
rlVertex2f(point[3].x, point[3].y);
// Lower rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[13].x, point[13].y);
rlVertex2f(point[5].x, point[5].y);
rlVertex2f(point[4].x, point[4].y);
rlVertex2f(point[12].x, point[12].y);
rlVertex2f(point[13].x, point[13].y);
rlVertex2f(point[4].x, point[4].y);
// Left rectangle
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[7].x, point[7].y);
rlVertex2f(point[6].x, point[6].y);
rlVertex2f(point[14].x, point[14].y);
rlVertex2f(point[15].x, point[15].y);
rlVertex2f(point[7].x, point[7].y);
rlVertex2f(point[14].x, point[14].y);
rlEnd();
#endif
}
else
{
// Use LINES to draw the outline
if (rlCheckBufferLimit(8*segments + 4*2)) rlglDraw(); // 4 corners with 2 vertices for each segment + 4 rectangles with 2 vertices each
rlBegin(RL_LINES);
// Draw all of the 4 corners first: Upper Left Corner, Upper Right Corner, Lower Right Corner, Lower Left Corner
for (int k = 0; k < 4; ++k) // Hope the compiler is smart enough to unroll this loop
{
float angle = angles[k];
const Vector2 center = centers[k];
for (int i = 0; i < segments; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*outerRadius);
angle += stepLength;
}
}
// And now the remaining 4 lines
for(int i = 0; i < 8; i += 2)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[i].x, point[i].y);
rlVertex2f(point[i + 1].x, point[i + 1].y);
}
rlEnd();
}
}
// Draw a triangle
void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
{

View File

@ -17,7 +17,7 @@
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -38,7 +38,7 @@
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@ -1206,12 +1206,9 @@ TextureCubemap LoadTextureCubemap(Image image, int layoutType)
cubemap.height = cubemap.width;
}
int size = cubemap.width;
if (layoutType != CUBEMAP_AUTO_DETECT)
{
//unsigned int dataSize = GetPixelDataSize(size, size, format);
//void *facesData = malloc(size*size*dataSize*6); // Get memory for 6 faces in a column
int size = cubemap.width;
Image faces = { 0 }; // Vertical column image
Rectangle faceRecs[6] = { 0 }; // Face source rectangles
@ -1225,6 +1222,7 @@ TextureCubemap LoadTextureCubemap(Image image, int layoutType)
else if (layoutType == CUBEMAP_PANORAMA)
{
// TODO: Convert panorama image to square faces...
// Ref: https://github.com/denivip/panorama/blob/master/panorama.cpp
}
else
{

View File

@ -11,7 +11,7 @@
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -5,7 +5,7 @@
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -2,7 +2,7 @@
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
# Copyright (c) 2013-2018 Ramon Santamaria (@raysan5)
# Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.

View File

@ -8,7 +8,7 @@
* This game has been created using raylib (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
********************************************************************************************/

View File

@ -4,7 +4,7 @@
*
* Ending Screen Functions Definitions (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -4,7 +4,7 @@
*
* Gameplay Screen Functions Definitions (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -4,7 +4,7 @@
*
* Logo Screen Functions Definitions (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

View File

@ -4,7 +4,7 @@
*
* Options Screen Functions Definitions (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.

Some files were not shown because too many files have changed in this diff Show More