Merge remote-tracking branch 'refs/remotes/raysan5/develop' into develop

This commit is contained in:
Joshua Reisenauer 2016-06-01 20:17:39 -07:00
commit ae6adb173b
43 changed files with 10243 additions and 9573 deletions

View File

@ -137,14 +137,14 @@ OVR_PUBLIC_FUNCTION(ovrMatrix4f) ovrMatrix4f_OrthoSubProjection(ovrMatrix4f proj
/// Computes offset eye poses based on headPose returned by ovrTrackingState. /// Computes offset eye poses based on headPose returned by ovrTrackingState.
/// ///
/// \param[in] headPose Indicates the HMD position and orientation to use for the calculation. /// \param[in] headPose Indicates the HMD position and orientation to use for the calculation.
/// \param[in] HmdToEyeOffset Can be ovrEyeRenderDesc.HmdToEyeOffset returned from /// \param[in] hmdToEyeOffset Can be ovrEyeRenderDesc.HmdToEyeOffset returned from
/// ovr_GetRenderDesc. For monoscopic rendering, use a vector that is the average /// ovr_GetRenderDesc. For monoscopic rendering, use a vector that is the average
/// of the two vectors for both eyes. /// of the two vectors for both eyes.
/// \param[out] outEyePoses If outEyePoses are used for rendering, they should be passed to /// \param[out] outEyePoses If outEyePoses are used for rendering, they should be passed to
/// ovr_SubmitFrame in ovrLayerEyeFov::RenderPose or ovrLayerEyeFovDepth::RenderPose. /// ovr_SubmitFrame in ovrLayerEyeFov::RenderPose or ovrLayerEyeFovDepth::RenderPose.
/// ///
OVR_PUBLIC_FUNCTION(void) ovr_CalcEyePoses(ovrPosef headPose, OVR_PUBLIC_FUNCTION(void) ovr_CalcEyePoses(ovrPosef headPose,
const ovrVector3f HmdToEyeOffset[2], const ovrVector3f hmdToEyeOffset[2],
ovrPosef outEyePoses[2]); ovrPosef outEyePoses[2]);
@ -158,17 +158,17 @@ OVR_PUBLIC_FUNCTION(void) ovr_CalcEyePoses(ovrPosef headPose,
/// \param[in] hmd Specifies an ovrSession previously returned by ovr_Create. /// \param[in] hmd Specifies an ovrSession previously returned by ovr_Create.
/// \param[in] frameIndex Specifies the targeted frame index, or 0 to refer to one frame after /// \param[in] frameIndex Specifies the targeted frame index, or 0 to refer to one frame after
/// the last time ovr_SubmitFrame was called. /// the last time ovr_SubmitFrame was called.
/// \param[in] HmdToEyeOffset Can be ovrEyeRenderDesc.HmdToEyeOffset returned from
/// ovr_GetRenderDesc. For monoscopic rendering, use a vector that is the average
/// of the two vectors for both eyes.
/// \param[in] latencyMarker Specifies that this call is the point in time where /// \param[in] latencyMarker Specifies that this call is the point in time where
/// the "App-to-Mid-Photon" latency timer starts from. If a given ovrLayer /// the "App-to-Mid-Photon" latency timer starts from. If a given ovrLayer
/// provides "SensorSampleTimestamp", that will override the value stored here. /// provides "SensorSampleTimestamp", that will override the value stored here.
/// \param[in] hmdToEyeOffset Can be ovrEyeRenderDesc.HmdToEyeOffset returned from
/// ovr_GetRenderDesc. For monoscopic rendering, use a vector that is the average
/// of the two vectors for both eyes.
/// \param[out] outEyePoses The predicted eye poses. /// \param[out] outEyePoses The predicted eye poses.
/// \param[out] outSensorSampleTime The time when this function was called. May be NULL, in which case it is ignored. /// \param[out] outSensorSampleTime The time when this function was called. May be NULL, in which case it is ignored.
/// ///
OVR_PUBLIC_FUNCTION(void) ovr_GetEyePoses(ovrSession session, long long frameIndex, ovrBool latencyMarker, OVR_PUBLIC_FUNCTION(void) ovr_GetEyePoses(ovrSession session, long long frameIndex, ovrBool latencyMarker,
const ovrVector3f HmdToEyeOffset[2], const ovrVector3f hmdToEyeOffset[2],
ovrPosef outEyePoses[2], ovrPosef outEyePoses[2],
double* outSensorSampleTime); double* outSensorSampleTime);

View File

@ -1,7 +1,7 @@
/********************************************************************************//** /********************************************************************************//**
\file OVR_Math.h \file OVR_Math.h
\brief Implementation of 3D primitives such as vectors, matrices. \brief Implementation of 3D primitives such as vectors, matrices.
\copyright Copyright 2015 Oculus VR, LLC All Rights reserved. \copyright Copyright 2014-2016 Oculus VR, LLC All Rights reserved.
*************************************************************************************/ *************************************************************************************/
#ifndef OVR_Math_h #ifndef OVR_Math_h
@ -1754,7 +1754,7 @@ public:
: Rotation(s.Rotation), Translation(s.Translation) : Rotation(s.Rotation), Translation(s.Translation)
{ {
// Ensure normalized rotation if converting from float to double // Ensure normalized rotation if converting from float to double
if (sizeof(T) > sizeof(Math<T>::OtherFloatType)) if (sizeof(T) > sizeof(typename Math<T>::OtherFloatType))
Rotation.Normalize(); Rotation.Normalize();
} }

View File

@ -1,7 +1,7 @@
/********************************************************************************//** /********************************************************************************//**
\file OVR_CAPI.h \file OVR_CAPI.h
\brief C Interface to the Oculus PC SDK tracking and rendering library. \brief C Interface to the Oculus PC SDK tracking and rendering library.
\copyright Copyright 2014-2016 Oculus VR, LLC All Rights reserved. \copyright Copyright 2014 Oculus VR, LLC All Rights reserved.
************************************************************************************/ ************************************************************************************/
#ifndef OVR_CAPI_h // We don't use version numbers within this name, as all versioned variations of this file are currently mutually exclusive. #ifndef OVR_CAPI_h // We don't use version numbers within this name, as all versioned variations of this file are currently mutually exclusive.
@ -687,6 +687,11 @@ typedef enum ovrTextureMiscFlags_
/// call. This flag requires that RenderTarget binding also be specified. /// call. This flag requires that RenderTarget binding also be specified.
ovrTextureMisc_AllowGenerateMips = 0x0002, ovrTextureMisc_AllowGenerateMips = 0x0002,
/// Texture swap chain contains protected content, and requires
/// HDCP connection in order to display to HMD. Also prevents
/// mirroring or other redirection of any frame containing this contents
ovrTextureMisc_ProtectedContent = 0x0004,
ovrTextureMisc_EnumSize = 0x7fffffff ///< \internal Force type int32_t. ovrTextureMisc_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
} ovrTextureFlags; } ovrTextureFlags;
@ -695,7 +700,7 @@ typedef enum ovrTextureMiscFlags_
/// \see ovr_CreateTextureSwapChainDX /// \see ovr_CreateTextureSwapChainDX
/// \see ovr_CreateTextureSwapChainGL /// \see ovr_CreateTextureSwapChainGL
/// ///
typedef struct typedef struct ovrTextureSwapChainDesc_
{ {
ovrTextureType Type; ovrTextureType Type;
ovrTextureFormat Format; ovrTextureFormat Format;
@ -705,7 +710,7 @@ typedef struct
int MipLevels; int MipLevels;
int SampleCount; ///< Current only supported on depth textures int SampleCount; ///< Current only supported on depth textures
ovrBool StaticImage; ///< Not buffered in a chain. For images that don't change ovrBool StaticImage; ///< Not buffered in a chain. For images that don't change
unsigned int MiscFlags; ///< ovrTextureMiscFlags unsigned int MiscFlags; ///< ovrTextureFlags
unsigned int BindFlags; ///< ovrTextureBindFlags. Not used for GL. unsigned int BindFlags; ///< ovrTextureBindFlags. Not used for GL.
} ovrTextureSwapChainDesc; } ovrTextureSwapChainDesc;
@ -714,12 +719,12 @@ typedef struct
/// \see ovr_CreateMirrorTextureDX /// \see ovr_CreateMirrorTextureDX
/// \see ovr_CreateMirrorTextureGL /// \see ovr_CreateMirrorTextureGL
/// ///
typedef struct typedef struct ovrMirrorTextureDesc_
{ {
ovrTextureFormat Format; ovrTextureFormat Format;
int Width; int Width;
int Height; int Height;
unsigned int MiscFlags; ///< ovrTextureMiscFlags unsigned int MiscFlags; ///< ovrTextureFlags
} ovrMirrorTextureDesc; } ovrMirrorTextureDesc;
typedef struct ovrTextureSwapChainData* ovrTextureSwapChain; typedef struct ovrTextureSwapChainData* ovrTextureSwapChain;
@ -987,8 +992,8 @@ extern "C" {
/// Initializes LibOVR /// Initializes LibOVR
/// ///
/// Initialize LibOVR for application usage. This includes finding and loading the LibOVRRT /// Initialize LibOVR for application usage. This includes finding and loading the LibOVRRT
/// shared library. No LibOVR API functions, other than ovr_GetLastErrorInfo, can be called /// shared library. No LibOVR API functions, other than ovr_GetLastErrorInfo and ovr_Detect, can
/// unless ovr_Initialize succeeds. A successful call to ovr_Initialize must be eventually /// be called unless ovr_Initialize succeeds. A successful call to ovr_Initialize must be eventually
/// followed by a call to ovr_Shutdown. ovr_Initialize calls are idempotent. /// followed by a call to ovr_Shutdown. ovr_Initialize calls are idempotent.
/// Calling ovr_Initialize twice does not require two matching calls to ovr_Shutdown. /// Calling ovr_Initialize twice does not require two matching calls to ovr_Shutdown.
/// If already initialized, the return value is ovr_Success. /// If already initialized, the return value is ovr_Success.
@ -1696,6 +1701,14 @@ OVR_PUBLIC_FUNCTION(void) ovr_DestroyMirrorTexture(ovrSession session, ovrMirror
/// \param[in] pixelsPerDisplayPixel Specifies the ratio of the number of render target pixels /// \param[in] pixelsPerDisplayPixel Specifies the ratio of the number of render target pixels
/// to display pixels at the center of distortion. 1.0 is the default value. Lower /// to display pixels at the center of distortion. 1.0 is the default value. Lower
/// values can improve performance, higher values give improved quality. /// values can improve performance, higher values give improved quality.
///
/// <b>Example code</b>
/// \code{.cpp}
/// ovrHmdDesc hmdDesc = ovr_GetHmdDesc(session);
/// ovrSizei eyeSizeLeft = ovr_GetFovTextureSize(session, ovrEye_Left, hmdDesc.DefaultEyeFov[ovrEye_Left], 1.0f);
/// ovrSizei eyeSizeRight = ovr_GetFovTextureSize(session, ovrEye_Right, hmdDesc.DefaultEyeFov[ovrEye_Right], 1.0f);
/// \endcode
///
/// \return Returns the texture width and height size. /// \return Returns the texture width and height size.
/// ///
OVR_PUBLIC_FUNCTION(ovrSizei) ovr_GetFovTextureSize(ovrSession session, ovrEyeType eye, ovrFovPort fov, OVR_PUBLIC_FUNCTION(ovrSizei) ovr_GetFovTextureSize(ovrSession session, ovrEyeType eye, ovrFovPort fov,

View File

@ -67,8 +67,8 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateTextureSwapChainDX(ovrSession session,
/// ///
/// <b>Example code</b> /// <b>Example code</b>
/// \code{.cpp} /// \code{.cpp}
/// ovr_GetTextureSwapChainBuffer(session, chain, 0, IID_ID3D11Texture2D, &d3d11Texture); /// ovr_GetTextureSwapChainBufferDX(session, chain, 0, IID_ID3D11Texture2D, &d3d11Texture);
/// ovr_GetTextureSwapChainBuffer(session, chain, 1, IID_PPV_ARGS(&dxgiResource)); /// ovr_GetTextureSwapChainBufferDX(session, chain, 1, IID_PPV_ARGS(&dxgiResource));
/// \endcode /// \endcode
/// ///
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainBufferDX(ovrSession session, OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainBufferDX(ovrSession session,
@ -102,6 +102,21 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainBufferDX(ovrSession sessio
/// compositor continues to treat is as sRGB. Failure to do so will cause the compositor to apply unexpected gamma conversions leading to /// compositor continues to treat is as sRGB. Failure to do so will cause the compositor to apply unexpected gamma conversions leading to
/// gamma-curve artifacts. /// gamma-curve artifacts.
/// ///
///
/// <b>Example code</b>
/// \code{.cpp}
/// ovrMirrorTexture mirrorTexture = nullptr;
/// ovrMirrorTextureDesc mirrorDesc = {};
/// mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
/// mirrorDesc.Width = mirrorWindowWidth;
/// mirrorDesc.Height = mirrorWindowHeight;
/// ovrResult result = ovr_CreateMirrorTextureDX(session, d3d11Device, &mirrorDesc, &mirrorTexture);
/// [...]
/// // Destroy the texture when done with it.
/// ovr_DestroyMirrorTexture(session, mirrorTexture);
/// mirrorTexture = nullptr;
/// \endcode
///
/// \see ovr_GetMirrorTextureBufferDX /// \see ovr_GetMirrorTextureBufferDX
/// \see ovr_DestroyMirrorTexture /// \see ovr_DestroyMirrorTexture
/// ///
@ -120,6 +135,15 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateMirrorTextureDX(ovrSession session,
/// \return Returns an ovrResult indicating success or failure. In the case of failure, use /// \return Returns an ovrResult indicating success or failure. In the case of failure, use
/// ovr_GetLastErrorInfo to get more information. /// ovr_GetLastErrorInfo to get more information.
/// ///
/// <b>Example code</b>
/// \code{.cpp}
/// ID3D11Texture2D* d3d11Texture = nullptr;
/// ovr_GetMirrorTextureBufferDX(session, mirrorTexture, IID_PPV_ARGS(&d3d11Texture));
/// d3d11DeviceContext->CopyResource(d3d11TextureBackBuffer, d3d11Texture);
/// d3d11Texture->Release();
/// dxgiSwapChain->Present(0, 0);
/// \endcode
///
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetMirrorTextureBufferDX(ovrSession session, OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetMirrorTextureBufferDX(ovrSession session,
ovrMirrorTexture mirrorTexture, ovrMirrorTexture mirrorTexture,
IID iid, IID iid,

View File

@ -91,6 +91,7 @@ typedef enum ovrErrorType_
ovrError_InvalidHeadsetOrientation = -1011, ///< The headset was in an invalid orientation for the requested operation (e.g. vertically oriented during ovr_RecenterPose). ovrError_InvalidHeadsetOrientation = -1011, ///< The headset was in an invalid orientation for the requested operation (e.g. vertically oriented during ovr_RecenterPose).
ovrError_ClientSkippedDestroy = -1012, ///< The client failed to call ovr_Destroy on an active session before calling ovr_Shutdown. Or the client crashed. ovrError_ClientSkippedDestroy = -1012, ///< The client failed to call ovr_Destroy on an active session before calling ovr_Shutdown. Or the client crashed.
ovrError_ClientSkippedShutdown = -1013, ///< The client failed to call ovr_Shutdown or the client crashed. ovrError_ClientSkippedShutdown = -1013, ///< The client failed to call ovr_Shutdown or the client crashed.
ovrError_ServiceDeadlockDetected = -1014, ///< The service watchdog discovered a deadlock.
/* Audio error range, reserved for Audio errors. */ /* Audio error range, reserved for Audio errors. */
ovrError_AudioReservedBegin = -2000, ///< First Audio error. ovrError_AudioReservedBegin = -2000, ///< First Audio error.
@ -140,25 +141,42 @@ typedef enum ovrErrorType_
ovrError_NordicEnabledNoSync = -4015, ///< The nordic indicates that sync is enabled but it is not sending sync pulses ovrError_NordicEnabledNoSync = -4015, ///< The nordic indicates that sync is enabled but it is not sending sync pulses
ovrError_NordicSyncNoFrames = -4016, ///< It looks like we're getting a sync signal, but no camera frames have been received ovrError_NordicSyncNoFrames = -4016, ///< It looks like we're getting a sync signal, but no camera frames have been received
ovrError_CatastrophicFailure = -4017, ///< A catastrophic failure has occurred. We will attempt to recover by resetting the device ovrError_CatastrophicFailure = -4017, ///< A catastrophic failure has occurred. We will attempt to recover by resetting the device
ovrError_CatastrophicTimeout = -4018, ///< The catastrophic recovery has timed out.
ovrError_RepeatCatastrophicFail = -4019, ///< Catastrophic failure has repeated too many times.
ovrError_USBOpenDeviceFailure = -4020, ///< Could not open handle for Rift device (likely already in use by another process).
ovrError_HMDGeneralFailure = -4021, ///< Unexpected HMD issues that don't fit a specific bucket.
ovrError_HMDFirmwareMismatch = -4100, ///< The HMD Firmware is out of date and is unacceptable. ovrError_HMDFirmwareMismatch = -4100, ///< The HMD Firmware is out of date and is unacceptable.
ovrError_TrackerFirmwareMismatch = -4101, ///< The sensor Firmware is out of date and is unacceptable. ovrError_TrackerFirmwareMismatch = -4101, ///< The sensor Firmware is out of date and is unacceptable.
ovrError_BootloaderDeviceDetected = -4102, ///< A bootloader HMD is detected by the service. ovrError_BootloaderDeviceDetected = -4102, ///< A bootloader HMD is detected by the service.
ovrError_TrackerCalibrationError = -4103, ///< The sensor calibration is missing or incorrect. ovrError_TrackerCalibrationError = -4103, ///< The sensor calibration is missing or incorrect.
ovrError_ControllerFirmwareMismatch = -4104, ///< The controller firmware is out of date and is unacceptable. ovrError_ControllerFirmwareMismatch = -4104, ///< The controller firmware is out of date and is unacceptable.
ovrError_DevManDeviceDetected = -4105, ///< A DeviceManagement mode HMD is detected by the service.
ovrError_RebootedBootloaderDevice = -4106, ///< Had to reboot bootloader device, which succeeded.
ovrError_FailedRebootBootloaderDev = -4107, ///< Had to reboot bootloader device, which failed. Device is stuck in bootloader mode.
ovrError_IMUTooManyLostSamples = -4200, ///< Too many lost IMU samples. ovrError_IMUTooManyLostSamples = -4200, ///< Too many lost IMU samples.
ovrError_IMURateError = -4201, ///< IMU rate is outside of the expected range. ovrError_IMURateError = -4201, ///< IMU rate is outside of the expected range.
ovrError_FeatureReportFailure = -4202, ///< A feature report has failed. ovrError_FeatureReportFailure = -4202, ///< A feature report has failed.
ovrError_HMDWirelessTimeout = -4203, ///< HMD wireless interface never returned from busy state.
ovrError_BootloaderAssertLog = -4300, ///< HMD Bootloader Assert Log was not empty.
ovrError_AppAssertLog = -4301, ///< HMD App Assert Log was not empty.
/* Synchronization errors */ /* Synchronization errors */
ovrError_Incomplete = -5000, ///<Requested async work not yet complete. ovrError_Incomplete = -5000, ///< Requested async work not yet complete.
ovrError_Abandoned = -5001, ///<Requested async work was abandoned and result is incomplete. ovrError_Abandoned = -5001, ///< Requested async work was abandoned and result is incomplete.
/* Rendering errors */ /* Rendering errors */
ovrError_DisplayLost = -6000, ///<In the event of a system-wide graphics reset or cable unplug this is returned to the app. ovrError_DisplayLost = -6000, ///< In the event of a system-wide graphics reset or cable unplug this is returned to the app.
ovrError_TextureSwapChainFull = -6001, ///<ovr_CommitTextureSwapChain was called too many times on a texture swapchain without calling submit to use the chain. ovrError_TextureSwapChainFull = -6001, ///< ovr_CommitTextureSwapChain was called too many times on a texture swapchain without calling submit to use the chain.
ovrError_TextureSwapChainInvalid = -6002, ///<The ovrTextureSwapChain is in an incomplete or inconsistent state. Ensure ovr_CommitTextureSwapChain was called at least once first. ovrError_TextureSwapChainInvalid = -6002, ///< The ovrTextureSwapChain is in an incomplete or inconsistent state. Ensure ovr_CommitTextureSwapChain was called at least once first.
ovrError_GraphicsDeviceReset = -6003, ///< Graphics device has been reset (TDR, etc...)
ovrError_DisplayRemoved = -6004, ///< HMD removed from the display adapter
ovrError_ContentProtectionNotAvailable = -6005,///<Content protection is not available for the display
ovrError_ApplicationInvisible = -6006, ///< Application declared itself as an invisible type and is not allowed to submit frames.
ovrError_Disallowed = -6007, ///< The given request is disallowed under the current conditions.
ovrError_DisplayPluggedIncorrectly = -6008, ///< Display portion of HMD is plugged into an incompatible port (ex: IGP)
/* Fatal errors */ /* Fatal errors */
ovrError_RuntimeException = -7000, ///< A runtime exception occurred. The application is required to shutdown LibOVR and re-initialize it before this error state will be cleared. ovrError_RuntimeException = -7000, ///< A runtime exception occurred. The application is required to shutdown LibOVR and re-initialize it before this error state will be cleared.

View File

@ -19,7 +19,7 @@
// Master version numbers // Master version numbers
#define OVR_PRODUCT_VERSION 1 // Product version doesn't participate in semantic versioning. #define OVR_PRODUCT_VERSION 1 // Product version doesn't participate in semantic versioning.
#define OVR_MAJOR_VERSION 1 // If you change these values then you need to also make sure to change LibOVR/Projects/Windows/LibOVR.props in parallel. #define OVR_MAJOR_VERSION 1 // If you change these values then you need to also make sure to change LibOVR/Projects/Windows/LibOVR.props in parallel.
#define OVR_MINOR_VERSION 3 // #define OVR_MINOR_VERSION 4 //
#define OVR_PATCH_VERSION 0 #define OVR_PATCH_VERSION 0
#define OVR_BUILD_NUMBER 0 #define OVR_BUILD_NUMBER 0

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -4,11 +4,11 @@
* *
* NOTE: This example requires raylib module [rlgl] * NOTE: This example requires raylib module [rlgl]
* *
* Compile rlgl using: * Compile rlgl module using:
* gcc -c rlgl.c -Wall -std=c99 -DRLGL_STANDALONE -DRAYMATH_IMPLEMENTATION -DGRAPHICS_API_OPENGL_33 * gcc -c rlgl.c -Wall -std=c99 -DRLGL_STANDALONE -DRAYMATH_IMPLEMENTATION -DGRAPHICS_API_OPENGL_33
* *
* Compile example using: * Compile example using:
* gcc -o oculus_glfw_sample.exe oculus_glfw_sample.c rlgl.o glad.o -L. -lLibOVRRT32_1 -lglfw3 -lopengl32 -lgdi32 -std=c99 * gcc -o oculus_glfw_sample.exe oculus_glfw_sample.c rlgl.o -L. -lLibOVRRT32_1 -lglfw3 -lopengl32 -lgdi32 -std=c99
* *
* This example has been created using raylib 1.5 (www.raylib.com) * This example has been created using raylib 1.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
@ -21,72 +21,103 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <math.h>
#define GLAD_IMPLEMENTATION
#include "glad.h" // Extensions loading library #include "glad.h" // Extensions loading library
#include <GLFW/glfw3.h> // Windows/Context and inputs management #include <GLFW/glfw3.h> // Windows/Context and inputs management
#include "OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL
#define RLGL_STANDALONE #define RLGL_STANDALONE
#include "rlgl.h" #include "rlgl.h"
//#define PLATFORM_OCULUS
#if defined(PLATFORM_OCULUS)
#include "OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL
#endif
#if defined(PLATFORM_OCULUS)
// OVR device variables // OVR device variables
ovrSession session; ovrSession session;
ovrHmdDesc hmdDesc; ovrHmdDesc hmdDesc;
ovrGraphicsLuid luid; ovrGraphicsLuid luid;
#endif
// OVR OpenGL required variables unsigned int frameIndex = 0;
GLuint fbo = 0;
GLuint depthBuffer = 0;
ovrTextureSwapChain eyeTexture;
GLuint mirrorFbo = 0; #define RED (Color){ 230, 41, 55, 255 } // Red
ovrMirrorTexture mirrorTexture; #define MAROON (Color){ 190, 33, 55, 255 } // Maroon
ovrEyeRenderDesc eyeRenderDescs[2]; #define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
Matrix eyeProjections[2]; #define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
ovrLayerEyeFov eyeLayer;
ovrViewScaleDesc viewScaleDesc;
Vector2 renderTargetSize = { 0, 0 };
Vector2 mirrorSize;
unsigned int frame = 0;
// GLFW variables
GLFWwindow *window = NULL;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#if defined(PLATFORM_OCULUS)
typedef struct OculusBuffer {
ovrTextureSwapChain textureChain;
GLuint depthId;
GLuint fboId;
int width;
int height;
} OculusBuffer;
typedef struct OculusMirror {
ovrMirrorTexture texture;
GLuint fboId;
int width;
int height;
} OculusMirror;
typedef struct OculusLayer {
ovrViewScaleDesc viewScaleDesc;
ovrLayerEyeFov eyeLayer; // layer 0
//ovrLayerQuad quadLayer; // layer 1
Matrix eyeProjections[2];
int width;
int height;
} OculusLayer;
#endif
typedef enum { LOG_INFO = 0, LOG_ERROR, LOG_WARNING, LOG_DEBUG, LOG_OTHER } TraceLogType; typedef enum { LOG_INFO = 0, LOG_ERROR, LOG_WARNING, LOG_DEBUG, LOG_OTHER } TraceLogType;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module specific Functions Declaration // Module specific Functions Declaration
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
static void ErrorCallback(int error, const char* description) static void ErrorCallback(int error, const char* description);
{ static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
fputs(description, stderr);
}
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GL_TRUE);
}
}
static void DrawRectangleV(Vector2 position, Vector2 size, Color color);
static void TraceLog(int msgType, const char *text, ...); static void TraceLog(int msgType, const char *text, ...);
// Drawing functions (uses rlgl functionality)
static void DrawGrid(int slices, float spacing);
static void DrawCube(Vector3 position, float width, float height, float length, Color color);
static void DrawCubeWires(Vector3 position, float width, float height, float length, Color color);
static void DrawRectangleV(Vector2 position, Vector2 size, Color color);
#if defined(PLATFORM_OCULUS)
// Oculus Rift functions
static Matrix FromOvrMatrix(ovrMatrix4f ovrM); static Matrix FromOvrMatrix(ovrMatrix4f ovrM);
void DrawGrid(int slices, float spacing); static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height);
void DrawCube(Vector3 position, float width, float height, float length, Color color); static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer);
static void SetOculusBuffer(ovrSession session, OculusBuffer buffer);
static void UnsetOculusBuffer(OculusBuffer buffer);
static OculusMirror LoadOculusMirror(ovrSession session, int width, int height); // Load Oculus mirror buffers
static void UnloadOculusMirror(ovrSession session, OculusMirror mirror); // Unload Oculus mirror buffers
static void BlitOculusMirror(ovrSession session, OculusMirror mirror);
static OculusLayer InitOculusLayer(ovrSession session);
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Main Entry point // Main Entry point
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
int main() int main(void)
{ {
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 1080;
int screenHeight = 600;
#if defined(PLATFORM_OCULUS)
ovrResult result = ovr_Initialize(NULL); ovrResult result = ovr_Initialize(NULL);
if (OVR_FAILURE(result)) TraceLog(LOG_ERROR, "OVR: Could not initialize Oculus device"); if (OVR_FAILURE(result)) TraceLog(LOG_ERROR, "OVR: Could not initialize Oculus device");
@ -106,37 +137,14 @@ int main()
TraceLog(LOG_INFO, "OVR: Serian Number: %s", hmdDesc.SerialNumber); TraceLog(LOG_INFO, "OVR: Serian Number: %s", hmdDesc.SerialNumber);
TraceLog(LOG_INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); TraceLog(LOG_INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h);
screenWidth = hmdDesc.Resolution.w/2;
viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f; screenHeight = hmdDesc.Resolution.h/2;
memset(&eyeLayer, 0, sizeof(ovrLayerEyeFov)); #endif
eyeLayer.Header.Type = ovrLayerType_EyeFov;
eyeLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft;
for (int eye = 0; eye < 2; eye++)
{
eyeRenderDescs[eye] = ovr_GetRenderDesc(session, eye, hmdDesc.DefaultEyeFov[eye]);
ovrMatrix4f ovrPerspectiveProjection = ovrMatrix4f_Projection(eyeRenderDescs[eye].Fov, 0.01f, 1000.0f, ovrProjection_ClipRangeOpenGL);
// NOTE struct ovrMatrix4f { float M[4][4] }
eyeProjections[eye] = FromOvrMatrix(ovrPerspectiveProjection);
viewScaleDesc.HmdToEyeOffset[eye] = eyeRenderDescs[eye].HmdToEyeOffset;
eyeLayer.Fov[eye] = eyeRenderDescs[eye].Fov;
ovrSizei eyeSize = ovr_GetFovTextureSize(session, eye, eyeLayer.Fov[eye], 1.0f);
eyeLayer.Viewport[eye].Size = eyeSize;
eyeLayer.Viewport[eye].Pos.x = renderTargetSize.x;
eyeLayer.Viewport[eye].Pos.y = 0;
renderTargetSize.y = eyeSize.h; //std::max(renderTargetSize.y, (uint32_t)eyeSize.h);
renderTargetSize.x += eyeSize.w;
}
// Make the on screen window 1/2 the resolution of the device
mirrorSize.x = hmdDesc.Resolution.w/2;
mirrorSize.y = hmdDesc.Resolution.h/2;
// GLFW3 Initialization + OpenGL 3.3 Context + Extensions // GLFW3 Initialization + OpenGL 3.3 Context + Extensions
//-------------------------------------------------------- //--------------------------------------------------------
glfwSetErrorCallback(ErrorCallback);
if (!glfwInit()) if (!glfwInit())
{ {
TraceLog(LOG_WARNING, "GLFW3: Can not initialize GLFW"); TraceLog(LOG_WARNING, "GLFW3: Can not initialize GLFW");
@ -149,9 +157,8 @@ int main()
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
//glfwWindowHint(GLFW_DECORATED, GL_FALSE); // Mandatory on Oculus Rift to avoid program crash? --> NO
window = glfwCreateWindow(mirrorSize.x, mirrorSize.y, "raylib oculus sample", NULL, NULL); GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight, "raylib oculus sample", NULL, NULL);
if (!window) if (!window)
{ {
@ -160,146 +167,129 @@ int main()
} }
else TraceLog(LOG_INFO, "GLFW3: Window created successfully"); else TraceLog(LOG_INFO, "GLFW3: Window created successfully");
glfwSetErrorCallback(ErrorCallback);
glfwSetKeyCallback(window, KeyCallback); glfwSetKeyCallback(window, KeyCallback);
glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);
glfwSwapInterval(0); glfwSwapInterval(0);
// Load OpenGL 3.3 extensions
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{ {
TraceLog(LOG_WARNING, "GLAD: Cannot load OpenGL extensions"); TraceLog(LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
exit(1); exit(1);
} }
else TraceLog(LOG_INFO, "GLAD: OpenGL extensions loaded successfully"); else TraceLog(LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
//--------------------------------------------------------
// Initialize OVR OpenGL swap chain textures #if defined(PLATFORM_OCULUS)
ovrTextureSwapChainDesc desc = {}; // Initialize Oculus Buffers
desc.Type = ovrTexture_2D; OculusLayer layer = InitOculusLayer(session);
desc.ArraySize = 1; OculusBuffer buffer = LoadOculusBuffer(session, layer.width, layer.height);
desc.Width = renderTargetSize.x; OculusMirror mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2);
desc.Height = renderTargetSize.y; layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain);
desc.MipLevels = 1;
desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.SampleCount = 1;
desc.StaticImage = ovrFalse;
result = ovr_CreateTextureSwapChainGL(session, &desc, &eyeTexture);
eyeLayer.ColorTexture[0] = eyeTexture;
if (!OVR_SUCCESS(result)) TraceLog(LOG_WARNING, "Failed to create swap textures");
int length = 0;
result = ovr_GetTextureSwapChainLength(session, eyeTexture, &length);
if (!OVR_SUCCESS(result) || !length) TraceLog(LOG_WARNING, "Unable to count swap chain textures");
for (int i = 0; i < length; ++i)
{
GLuint chainTexId;
ovr_GetTextureSwapChainBufferGL(session, eyeTexture, i, &chainTexId);
glBindTexture(GL_TEXTURE_2D, chainTexId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
glBindTexture(GL_TEXTURE_2D, 0);
// Setup framebuffer object
glGenFramebuffers(1, &fbo);
glGenRenderbuffers(1, &depthBuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, renderTargetSize.x, renderTargetSize.y);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
// Setup mirror texture
ovrMirrorTextureDesc mirrorDesc;
memset(&mirrorDesc, 0, sizeof(mirrorDesc));
mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
mirrorDesc.Width = mirrorSize.x;
mirrorDesc.Height = mirrorSize.y;
if (!OVR_SUCCESS(ovr_CreateMirrorTextureGL(session, &mirrorDesc, &mirrorTexture))) TraceLog(LOG_WARNING, "Could not create mirror texture");
glGenFramebuffers(1, &mirrorFbo);
// Recenter OVR tracking origin // Recenter OVR tracking origin
ovr_RecenterTrackingOrigin(session); ovr_RecenterTrackingOrigin(session);
#endif
// Initialize rlgl internal buffers and OpenGL state // Initialize rlgl internal buffers and OpenGL state
rlglInit(); rlglInit();
rlglInitGraphics(0, 0, mirrorSize.x, mirrorSize.y); rlglInitGraphics(0, 0, screenWidth, screenHeight);
rlClearColor(245, 245, 245, 255); // Define clear color rlClearColor(245, 245, 245, 255); // Define clear color
glEnable(GL_DEPTH_TEST); rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
Vector2 position = { mirrorSize.x/2 - 100, mirrorSize.y/2 - 100 };
Vector2 size = { 200, 200 }; Vector2 size = { 200, 200 };
Color color = { 180, 20, 20, 255 };
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f }; Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
Camera camera;
camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position
camera.target = (Vector3){ 0.0f, 0.0f, 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
//--------------------------------------------------------------------------------------
// Main game loop
while (!glfwWindowShouldClose(window)) while (!glfwWindowShouldClose(window))
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
frame++; #if defined(PLATFORM_OCULUS)
frameIndex++;
ovrPosef eyePoses[2]; ovrPosef eyePoses[2];
ovr_GetEyePoses(session, frame, ovrTrue, viewScaleDesc.HmdToEyeOffset, eyePoses, &eyeLayer.SensorSampleTime); ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime);
layer.eyeLayer.RenderPose[0] = eyePoses[0];
layer.eyeLayer.RenderPose[1] = eyePoses[1];
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
int curIndex; #if defined(PLATFORM_OCULUS)
ovr_GetTextureSwapChainCurrentIndex(session, eyeTexture, &curIndex); SetOculusBuffer(session, buffer);
GLuint curTexId; #endif
ovr_GetTextureSwapChainBufferGL(session, eyeTexture, curIndex, &curTexId);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); rlClearScreenBuffers(); // Clear current framebuffers
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, curTexId, 0);
#if defined(PLATFORM_OCULUS)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (int eye = 0; eye < 2; eye++) for (int eye = 0; eye < 2; eye++)
{ {
glViewport(eyeLayer.Viewport[eye].Pos.x, eyeLayer.Viewport[eye].Pos.y, glViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h);
eyeLayer.Viewport[eye].Size.w, eyeLayer.Viewport[eye].Size.h);
eyeLayer.RenderPose[eye] = eyePoses[eye];
// Convert struct ovrPosef { ovrQuatf Orientation; ovrVector3f Position; } to Matrix
// TODO: Review maths!
Matrix eyeOrientation = QuaternionToMatrix((Quaternion){ -eyePoses[eye].Orientation.x, -eyePoses[eye].Orientation.y, -eyePoses[eye].Orientation.z, -eyePoses[eye].Orientation.w });
Matrix eyePosition = MatrixTranslate(-eyePoses[eye].Position.x, -eyePoses[eye].Position.y, -eyePoses[eye].Position.z);
Matrix mvp = MatrixMultiply(eyeProjections[eye], MatrixMultiply(eyeOrientation, eyePosition));
// NOTE: Nothing is drawn until rlglDraw() Quaternion eyeRPose = (Quaternion){ eyePoses[eye].Orientation.x, eyePoses[eye].Orientation.y, eyePoses[eye].Orientation.z, eyePoses[eye].Orientation.w };
DrawRectangleV(position, size, color); QuaternionInvert(&eyeRPose);
//DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, color); Matrix eyeOrientation = QuaternionToMatrix(eyeRPose);
//DrawGrid(10, 1.0f); Matrix eyeTranslation = MatrixTranslate(-eyePoses[eye].Position.x, -eyePoses[eye].Position.y, -eyePoses[eye].Position.z);
// NOTE: rlglDraw() must be modified to support an external modelview-projection matrix Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation);
// TODO: Still working on it (now uses internal mvp) Matrix modelview = MatrixMultiply(matView, eyeView);
Matrix mvp = MatrixMultiply(modelview, layer.eyeProjections[eye]);
#else
// Calculate projection matrix (from perspective) and view matrix from camera look at
Matrix matProj = MatrixPerspective(camera.fovy, (double)screenWidth/(double)screenHeight, 0.01, 1000.0);
MatrixTranspose(&matProj);
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
Matrix mvp = MatrixMultiply(matView, matProj);
#endif
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, RAYWHITE);
DrawGrid(10, 1.0f);
// NOTE: Internal buffers drawing (3D data)
rlglDraw(mvp); rlglDraw(mvp);
matProj = MatrixOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0);
MatrixTranspose(&matProj);
matView = MatrixIdentity();
mvp = MatrixMultiply(matView, matProj);
// TODO: 2D drawing on Oculus Rift: requires an ovrLayerQuad layer
DrawRectangleV((Vector2){ 10.0f, 10.0f }, (Vector2){ 300.0f, 20.0f }, DARKGRAY);
// NOTE: Internal buffers drawing (2D data)
rlglDraw(mvp);
#if defined(PLATFORM_OCULUS)
} }
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); UnsetOculusBuffer(buffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
ovr_CommitTextureSwapChain(session, eyeTexture); ovr_CommitTextureSwapChain(session, buffer.textureChain);
ovrLayerHeader *headerList = &eyeLayer.Header;
ovr_SubmitFrame(session, frame, &viewScaleDesc, &headerList, 1); ovrLayerHeader *layers = &layer.eyeLayer.Header;
ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1);
// Blit mirror texture to back buffer // Blit mirror texture to back buffer
GLuint mirrorTextureId; BlitOculusMirror(session, mirror);
ovr_GetMirrorTextureBufferGL(session, mirrorTexture, &mirrorTextureId);
glBindFramebuffer(GL_READ_FRAMEBUFFER, mirrorFbo); // Get session status information
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mirrorTextureId, 0); ovrSessionStatus sessionStatus;
glBlitFramebuffer(0, 0, mirrorSize.x, mirrorSize.y, 0, mirrorSize.y, mirrorSize.x, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST); ovr_GetSessionStatus(session, &sessionStatus);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); if (sessionStatus.ShouldQuit) TraceLog(LOG_WARNING, "OVR: Session should quit...");
if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session);
#endif
glfwSwapBuffers(window); glfwSwapBuffers(window);
glfwPollEvents(); glfwPollEvents();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -307,20 +297,20 @@ int main()
// De-Initialization // De-Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
if (mirrorFbo) glDeleteFramebuffers(1, &mirrorFbo); #if defined(PLATFORM_OCULUS)
if (mirrorTexture) ovr_DestroyMirrorTexture(session, mirrorTexture); UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer
UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers
#endif
if (fbo) glDeleteFramebuffers(1, &fbo); rlglClose(); // Unload rlgl internal buffers and default shader/texture
if (depthBuffer) glDeleteTextures(1, &depthBuffer);
if (eyeTexture) ovr_DestroyTextureSwapChain(session, eyeTexture);
rlglClose();
glfwDestroyWindow(window); glfwDestroyWindow(window);
glfwTerminate(); glfwTerminate();
#if defined(PLATFORM_OCULUS)
ovr_Destroy(session); // Must be called after glfwTerminate() ovr_Destroy(session); // Must be called after glfwTerminate()
ovr_Shutdown(); ovr_Shutdown();
#endif
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;
@ -330,24 +320,22 @@ int main()
// Module specific Functions Definitions // Module specific Functions Definitions
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally) // GLFW3: Error callback
static void DrawRectangleV(Vector2 position, Vector2 size, Color color) static void ErrorCallback(int error, const char* description)
{ {
rlBegin(RL_TRIANGLES); TraceLog(LOG_ERROR, description);
rlColor4ub(color.r, color.g, color.b, color.a); }
rlVertex2i(position.x, position.y); // GLFW3: Keyboard callback
rlVertex2i(position.x, position.y + size.y); static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
rlVertex2i(position.x + size.x, position.y + size.y); {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
rlVertex2i(position.x, position.y); {
rlVertex2i(position.x + size.x, position.y + size.y); glfwSetWindowShouldClose(window, GL_TRUE);
rlVertex2i(position.x + size.x, position.y); }
rlEnd();
} }
// Output a trace log message // Output a trace log message
// NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning
static void TraceLog(int msgType, const char *text, ...) static void TraceLog(int msgType, const char *text, ...)
{ {
va_list args; va_list args;
@ -370,30 +358,52 @@ static void TraceLog(int msgType, const char *text, ...)
//if (msgType == LOG_ERROR) exit(1); //if (msgType == LOG_ERROR) exit(1);
} }
static Matrix FromOvrMatrix(ovrMatrix4f ovrmat) // Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally)
static void DrawRectangleV(Vector2 position, Vector2 size, Color color)
{ {
Matrix rmat; rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
rmat.m0 = ovrmat.M[0][0];
rmat.m1 = ovrmat.M[1][0]; rlVertex2i(position.x, position.y);
rmat.m2 = ovrmat.M[2][0]; rlVertex2i(position.x, position.y + size.y);
rmat.m3 = ovrmat.M[3][0]; rlVertex2i(position.x + size.x, position.y + size.y);
rmat.m4 = ovrmat.M[0][1];
rmat.m5 = ovrmat.M[1][1]; rlVertex2i(position.x, position.y);
rmat.m6 = ovrmat.M[2][1]; rlVertex2i(position.x + size.x, position.y + size.y);
rmat.m7 = ovrmat.M[3][1]; rlVertex2i(position.x + size.x, position.y);
rmat.m8 = ovrmat.M[0][2]; rlEnd();
rmat.m9 = ovrmat.M[1][2]; }
rmat.m10 = ovrmat.M[2][2];
rmat.m11 = ovrmat.M[3][2]; // Draw a grid centered at (0, 0, 0)
rmat.m12 = ovrmat.M[0][3]; static void DrawGrid(int slices, float spacing)
rmat.m13 = ovrmat.M[1][3]; {
rmat.m14 = ovrmat.M[2][3]; int halfSlices = slices / 2;
rmat.m15 = ovrmat.M[3][3];
rlBegin(RL_LINES);
//MatrixTranspose(&rmat); for(int i = -halfSlices; i <= halfSlices; i++)
{
return rmat; if (i == 0)
{
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
}
else
{
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
}
rlVertex3f((float)i*spacing, 0.0f, (float)-halfSlices*spacing);
rlVertex3f((float)i*spacing, 0.0f, (float)halfSlices*spacing);
rlVertex3f((float)-halfSlices*spacing, 0.0f, (float)i*spacing);
rlVertex3f((float)halfSlices*spacing, 0.0f, (float)i*spacing);
}
rlEnd();
} }
// Draw cube // Draw cube
@ -471,34 +481,279 @@ void DrawCube(Vector3 position, float width, float height, float length, Color c
rlPopMatrix(); rlPopMatrix();
} }
// Draw a grid centered at (0, 0, 0) // Draw cube wires
void DrawGrid(int slices, float spacing) void DrawCubeWires(Vector3 position, float width, float height, float length, Color color)
{ {
int halfSlices = slices / 2; float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
rlBegin(RL_LINES); rlPushMatrix();
for(int i = -halfSlices; i <= halfSlices; i++)
{
if (i == 0)
{
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
}
else
{
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
}
rlVertex3f((float)i*spacing, 0.0f, (float)-halfSlices*spacing); rlTranslatef(position.x, position.y, position.z);
rlVertex3f((float)i*spacing, 0.0f, (float)halfSlices*spacing); //rlRotatef(45, 0, 1, 0);
rlVertex3f((float)-halfSlices*spacing, 0.0f, (float)i*spacing); rlBegin(RL_LINES);
rlVertex3f((float)halfSlices*spacing, 0.0f, (float)i*spacing); rlColor4ub(color.r, color.g, color.b, color.a);
}
rlEnd(); // Front Face -----------------------------------------------------
// Bottom Line
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
// Left Line
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right
// Top Line
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
// Right Line
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
// Back Face ------------------------------------------------------
// Bottom Line
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
// Left Line
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
// Top Line
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
// Right Line
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left
// Top Face -------------------------------------------------------
// Left Line
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left Front
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left Back
// Right Line
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right Front
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right Back
// Bottom Face ---------------------------------------------------
// Left Line
rlVertex3f(x-width/2, y-height/2, z+length/2); // Top Left Front
rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Left Back
// Right Line
rlVertex3f(x+width/2, y-height/2, z+length/2); // Top Right Front
rlVertex3f(x+width/2, y-height/2, z-length/2); // Top Right Back
rlEnd();
rlPopMatrix();
} }
#if defined(PLATFORM_OCULUS)
// Convert from Oculus ovrMatrix4f struct to raymath Matrix struct
static Matrix FromOvrMatrix(ovrMatrix4f ovrmat)
{
Matrix rmat;
rmat.m0 = ovrmat.M[0][0];
rmat.m1 = ovrmat.M[1][0];
rmat.m2 = ovrmat.M[2][0];
rmat.m3 = ovrmat.M[3][0];
rmat.m4 = ovrmat.M[0][1];
rmat.m5 = ovrmat.M[1][1];
rmat.m6 = ovrmat.M[2][1];
rmat.m7 = ovrmat.M[3][1];
rmat.m8 = ovrmat.M[0][2];
rmat.m9 = ovrmat.M[1][2];
rmat.m10 = ovrmat.M[2][2];
rmat.m11 = ovrmat.M[3][2];
rmat.m12 = ovrmat.M[0][3];
rmat.m13 = ovrmat.M[1][3];
rmat.m14 = ovrmat.M[2][3];
rmat.m15 = ovrmat.M[3][3];
MatrixTranspose(&rmat);
return rmat;
}
// Load Oculus required buffers: texture-swap-chain, fbo, texture-depth
static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height)
{
OculusBuffer buffer;
buffer.width = width;
buffer.height = height;
// Create OVR texture chain
ovrTextureSwapChainDesc desc = {};
desc.Type = ovrTexture_2D;
desc.ArraySize = 1;
desc.Width = width;
desc.Height = height;
desc.MipLevels = 1;
desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.SampleCount = 1;
desc.StaticImage = ovrFalse;
ovrResult result = ovr_CreateTextureSwapChainGL(session, &desc, &buffer.textureChain);
//eyeLayer.ColorTexture[0] = buffer.textureChain; // <------------------- ???
if (!OVR_SUCCESS(result)) TraceLog(LOG_WARNING, "OVR: Failed to create swap textures buffer");
int textureCount = 0;
ovr_GetTextureSwapChainLength(session, buffer.textureChain, &textureCount);
if (!OVR_SUCCESS(result) || !textureCount) TraceLog(LOG_WARNING, "OVR: Unable to count swap chain textures");
for (int i = 0; i < textureCount; ++i)
{
GLuint chainTexId;
ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, i, &chainTexId);
glBindTexture(GL_TEXTURE_2D, chainTexId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
glBindTexture(GL_TEXTURE_2D, 0);
/*
// Setup framebuffer object (using depth texture)
glGenFramebuffers(1, &buffer.fboId);
glGenTextures(1, &buffer.depthId);
glBindTexture(GL_TEXTURE_2D, buffer.depthId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, buffer.width, buffer.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
*/
// Setup framebuffer object (using depth renderbuffer)
glGenFramebuffers(1, &buffer.fboId);
glGenRenderbuffers(1, &buffer.depthId);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId);
glBindRenderbuffer(GL_RENDERBUFFER, buffer.depthId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, buffer.width, buffer.height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, buffer.depthId);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
return buffer;
}
// Unload texture required buffers
static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer)
{
if (buffer.textureChain)
{
ovr_DestroyTextureSwapChain(session, buffer.textureChain);
buffer.textureChain = NULL;
}
if (buffer.depthId != 0) glDeleteTextures(1, &buffer.depthId);
if (buffer.fboId != 0) glDeleteFramebuffers(1, &buffer.fboId);
}
// Set current Oculus buffer
static void SetOculusBuffer(ovrSession session, OculusBuffer buffer)
{
GLuint currentTexId;
int currentIndex;
ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, &currentIndex);
ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, &currentTexId);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0);
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0); // Already binded
//glViewport(0, 0, buffer.width, buffer.height);
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glEnable(GL_FRAMEBUFFER_SRGB);
}
// Unset Oculus buffer
static void UnsetOculusBuffer(OculusBuffer buffer)
{
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
// Load Oculus mirror buffers
static OculusMirror LoadOculusMirror(ovrSession session, int width, int height)
{
OculusMirror mirror;
mirror.width = width;
mirror.height = height;
ovrMirrorTextureDesc mirrorDesc;
memset(&mirrorDesc, 0, sizeof(mirrorDesc));
mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
mirrorDesc.Width = mirror.width;
mirrorDesc.Height = mirror.height;
if (!OVR_SUCCESS(ovr_CreateMirrorTextureGL(session, &mirrorDesc, &mirror.texture))) TraceLog(LOG_WARNING, "Could not create mirror texture");
glGenFramebuffers(1, &mirror.fboId);
return mirror;
}
// Unload Oculus mirror buffers
static void UnloadOculusMirror(ovrSession session, OculusMirror mirror)
{
if (mirror.fboId != 0) glDeleteFramebuffers(1, &mirror.fboId);
if (mirror.texture) ovr_DestroyMirrorTexture(session, mirror.texture);
}
static void BlitOculusMirror(ovrSession session, OculusMirror mirror)
{
GLuint mirrorTextureId;
ovr_GetMirrorTextureBufferGL(session, mirror.texture, &mirrorTextureId);
glBindFramebuffer(GL_READ_FRAMEBUFFER, mirror.fboId);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mirrorTextureId, 0);
glBlitFramebuffer(0, 0, mirror.width, mirror.height, 0, mirror.height, mirror.width, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}
// Requires: session, hmdDesc
static OculusLayer InitOculusLayer(ovrSession session)
{
OculusLayer layer = { 0 };
layer.viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f;
memset(&layer.eyeLayer, 0, sizeof(ovrLayerEyeFov));
layer.eyeLayer.Header.Type = ovrLayerType_EyeFov;
layer.eyeLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft;
ovrEyeRenderDesc eyeRenderDescs[2];
for (int eye = 0; eye < 2; eye++)
{
eyeRenderDescs[eye] = ovr_GetRenderDesc(session, eye, hmdDesc.DefaultEyeFov[eye]);
ovrMatrix4f ovrPerspectiveProjection = ovrMatrix4f_Projection(eyeRenderDescs[eye].Fov, 0.01f, 10000.0f, ovrProjection_None); //ovrProjection_ClipRangeOpenGL);
layer.eyeProjections[eye] = FromOvrMatrix(ovrPerspectiveProjection); // NOTE: struct ovrMatrix4f { float M[4][4] } --> struct Matrix
layer.viewScaleDesc.HmdToEyeOffset[eye] = eyeRenderDescs[eye].HmdToEyeOffset;
layer.eyeLayer.Fov[eye] = eyeRenderDescs[eye].Fov;
ovrSizei eyeSize = ovr_GetFovTextureSize(session, eye, layer.eyeLayer.Fov[eye], 1.0f);
layer.eyeLayer.Viewport[eye].Size = eyeSize;
layer.eyeLayer.Viewport[eye].Pos.x = layer.width;
layer.eyeLayer.Viewport[eye].Pos.y = 0;
layer.height = eyeSize.h; //std::max(renderTargetSize.y, (uint32_t)eyeSize.h);
layer.width += eyeSize.w;
}
return layer;
}
#endif

View File

@ -1,498 +0,0 @@
/*******************************************************************************************
*
* raylib Oculus minimum sample (OpenGL 3.3 Core)
*
* NOTE: This example requires raylib module [rlgl]
*
* Compile rlgl using:
* gcc -c rlgl.c -Wall -std=c99 -DRLGL_STANDALONE -DRAYMATH_IMPLEMENTATION -DGRAPHICS_API_OPENGL_33
*
* Compile example using:
* gcc -o oculus_glfw_sample.exe oculus_glfw_sample.c rlgl.o glad.o -L. -lLibOVRRT32_1 -lglfw3 -lopengl32 -lgdi32 -std=c99
*
* This example has been created using raylib 1.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#if defined(_WIN32)
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#define OVR_OS_WIN32
#elif defined(__APPLE__)
#define GLFW_EXPOSE_NATIVE_COCOA
#define GLFW_EXPOSE_NATIVE_NSGL
#define OVR_OS_MAC
#elif defined(__linux__)
#define GLFW_EXPOSE_NATIVE_X11
#define GLFW_EXPOSE_NATIVE_GLX
#define OVR_OS_LINUX
#endif
#include "glad.h" // Extensions loading library
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
#include "OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL
//#include "GL/CAPI_GLE.h" // stripped-down GLEW/GLAD library to manage extensions (really required?)
//#include "Extras/OVR_Math.h" // math utilities C++ (really required?)
#define RLGL_STANDALONE
#include "rlgl.h"
#include <stdlib.h>
#include <stdio.h>
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef struct OculusBuffer {
ovrTextureSwapChain textureChain;
GLuint depthId;
GLuint fboId;
int width;
int height;
} OculusBuffer;
typedef enum { LOG_INFO = 0, LOG_ERROR, LOG_WARNING, LOG_DEBUG, LOG_OTHER } TraceLogType;
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height);
static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer);
static void SetOculusBuffer(ovrSession session, OculusBuffer buffer);
static void UnsetOculusBuffer(OculusBuffer buffer);
static void ErrorCallback(int error, const char* description)
{
fputs(description, stderr);
}
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GL_TRUE);
}
}
static void DrawRectangleV(Vector2 position, Vector2 size, Color color);
static void TraceLog(int msgType, const char *text, ...);
//----------------------------------------------------------------------------------
// Main Entry point
//----------------------------------------------------------------------------------
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
ovrSession session;
ovrGraphicsLuid luid; // Useless for OpenGL since SDK 0.7
ovrHmdDesc hmdDesc;
ovrResult result = ovr_Initialize(NULL);
if (OVR_FAILURE(result)) TraceLog(LOG_ERROR, "OVR: Could not initialize Oculus device");
result = ovr_Create(&session, &luid);
if (OVR_FAILURE(result))
{
TraceLog(LOG_WARNING, "OVR: Could not create Oculus session");
ovr_Shutdown();
}
hmdDesc = ovr_GetHmdDesc(session);
TraceLog(LOG_INFO, "OVR: Product Name: %s", hmdDesc.ProductName);
TraceLog(LOG_INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer);
TraceLog(LOG_INFO, "OVR: Product ID: %i", hmdDesc.ProductId);
TraceLog(LOG_INFO, "OVR: Product Type: %i", hmdDesc.Type);
TraceLog(LOG_INFO, "OVR: Serian Number: %s", hmdDesc.SerialNumber);
TraceLog(LOG_INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h);
int screenWidth = hmdDesc.Resolution.w/2 + 100; // Added 100 pixels for testing
int screenHeight = hmdDesc.Resolution.h/2 + 100; // Added 100 pixels for testing
// GLFW3 Initialization + OpenGL 3.3 Context + Extensions
//--------------------------------------------------------
GLFWwindow *window;
glfwSetErrorCallback(ErrorCallback);
if (!glfwInit())
{
TraceLog(LOG_WARNING, "GLFW3: Can not initialize GLFW");
exit(EXIT_FAILURE);
}
else TraceLog(LOG_INFO, "GLFW3: GLFW initialized successfully");
glfwWindowHint(GLFW_DEPTH_BITS, 16);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
glfwWindowHint(GLFW_DECORATED, GL_FALSE); // Mandatory on Oculus Rift to avoid program crash!
window = glfwCreateWindow(screenWidth, screenHeight, "rlgl standalone", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
else TraceLog(LOG_INFO, "GLFW3: Window created successfully");
glfwSetKeyCallback(window, KeyCallback);
glfwMakeContextCurrent(window);
glfwSwapInterval(0);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
TraceLog(LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
exit(1);
}
else TraceLog(LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
rlglInit();
rlglInitGraphics(0, 0, screenWidth, screenHeight);
rlClearColor(245, 245, 245, 255); // Define clear color
Vector2 position = { screenWidth/2 - 100, screenHeight/2 - 100 };
Vector2 size = { 200, 200 };
Color color = { 180, 20, 20, 255 };
//---------------------------------------------------------------------------
OculusBuffer eyeRenderBuffer[2];
GLuint mirrorFBO = 0;
ovrMirrorTexture mirrorTexture = NULL;
bool isVisible = true;
long long frameIndex = 0;
// Make eyes render buffers
ovrSizei recommendedTexSizeLeft = ovr_GetFovTextureSize(session, ovrEye_Left, hmdDesc.DefaultEyeFov[0], 1.0f);
eyeRenderBuffer[0] = LoadOculusBuffer(session, recommendedTexSizeLeft.w, recommendedTexSizeLeft.h);
ovrSizei recommendedTexSizeRight = ovr_GetFovTextureSize(session, ovrEye_Right, hmdDesc.DefaultEyeFov[1], 1.0f);
eyeRenderBuffer[1] = LoadOculusBuffer(session, recommendedTexSizeRight.w, recommendedTexSizeRight.h);
// Note: the mirror window can be any size, for this sample we use 1/2 the HMD resolution
ovrSizei windowSize = { hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2 };
// Define mirror texture descriptor
ovrMirrorTextureDesc mirrorDesc;
memset(&mirrorDesc, 0, sizeof(mirrorDesc));
mirrorDesc.Width = windowSize.w;
mirrorDesc.Height = windowSize.h;
mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
// Create mirror texture and an FBO used to copy mirror texture to back buffer
result = ovr_CreateMirrorTextureGL(session, &mirrorDesc, &mirrorTexture);
if (!OVR_SUCCESS(result)) TraceLog(LOG_WARNING, "OVR: Failed to create mirror texture");
// Configure the mirror read buffer
GLuint texId;
ovr_GetMirrorTextureBufferGL(session, mirrorTexture, &texId);
glGenFramebuffers(1, &mirrorFBO);
glBindFramebuffer(GL_READ_FRAMEBUFFER, mirrorFBO);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0);
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
glDeleteFramebuffers(1, &mirrorFBO);
TraceLog(LOG_WARNING, "OVR: Could not initialize mirror framebuffers");
}
glClearColor(1.0f, 0.1f, 0.1f, 0.0f);
glEnable(GL_DEPTH_TEST);
ovr_RecenterTrackingOrigin(session);
// FloorLevel will give tracking poses where the floor height is 0
ovr_SetTrackingOriginType(session, ovrTrackingOrigin_FloorLevel);
//--------------------------------------------------------------------------------------
// Main loop
while (!glfwWindowShouldClose(window))
{
// Update
//----------------------------------------------------------------------------------
frameIndex++;
// TODO: Update game here!
// Call ovr_GetRenderDesc each frame to get the ovrEyeRenderDesc, as the returned values (e.g. HmdToEyeOffset) may change at runtime.
ovrEyeRenderDesc eyeRenderDesc[2];
eyeRenderDesc[0] = ovr_GetRenderDesc(session, ovrEye_Left, hmdDesc.DefaultEyeFov[0]);
eyeRenderDesc[1] = ovr_GetRenderDesc(session, ovrEye_Right, hmdDesc.DefaultEyeFov[1]);
// Get eye poses, feeding in correct IPD offset
ovrPosef eyeRenderPose[2];
ovrVector3f hmdToEyeOffset[2] = { eyeRenderDesc[0].HmdToEyeOffset, eyeRenderDesc[1].HmdToEyeOffset };
double sensorSampleTime; // sensorSampleTime is fed into the layer later
ovr_GetEyePoses(session, frameIndex, ovrTrue, hmdToEyeOffset, eyeRenderPose, &sensorSampleTime);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
// Clear screen to red color
glClearColor(1.0f, 0.1f, 0.1f, 0.0f);
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (isVisible)
{
for (int eye = 0; eye < 2; ++eye)
{
SetOculusBuffer(session, eyeRenderBuffer[eye]);
// TODO: Get view and projection matrices for the eye
// Sample using Oculus OVR_Math.h (C++)
/*
Matrix4f projection[eye] = Matrix4f(ovrMatrix4f_Projection(eyeRenderDesc[eye].Fov, 0.01f, 10000.0f, ovrProjection_None));
Matrix4f eyeOrientation[eye] = Matrix4f(Quatf(eyeRenderPose[eye].Orientation).Inverted());
Matrix4f eyePose[eye] = Matrix4f::Translation(-Vector3f(eyeRenderPose[eye].Position));
Matrix4f mvp = projection[eye]*eyeOrientation[eye]*eyePose[eye];
*/
// Sample using custom raymath.h (C) -INCOMPLETE-
/*
Matrix projection = MatrixPerspective(eyeRenderDesc[eye].Fov, ((double)screenWidth/(double)screenHeight), 0.01, 1000.0);
Matrix eyeOrientation = QuaternionToMatrix((Quaternion){ -eyeRenderPose[eye].Orientation.x, -eyeRenderPose[eye].Orientation.y,
-eyeRenderPose[eye].Orientation.z, -eyeRenderPose[eye].Orientation.w });
Matrix eyePose = MatrixTranslate(-eyeRenderPose[eye].Position.x, -eyeRenderPose[eye].Position.y, -eyeRenderPose[eye].Position.z);
Matrix mvp = MatrixMultiply(projection, MatrixMultiply(eyeOrientation, eyePose));
*/
// Render everything
// TODO: Pass calculated mvp matrix to default shader to consider projection and orientation!
//DrawRectangleV(position, size, color);
//rlglDraw();
UnsetOculusBuffer(eyeRenderBuffer[eye]);
// Commit changes to the textures so they get picked up frame
ovr_CommitTextureSwapChain(session, eyeRenderBuffer[eye].textureChain);
}
}
// Set up positional data
ovrViewScaleDesc viewScaleDesc;
viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f;
viewScaleDesc.HmdToEyeOffset[0] = hmdToEyeOffset[0];
viewScaleDesc.HmdToEyeOffset[1] = hmdToEyeOffset[1];
// Create the main eye layer
ovrLayerEyeFov eyeLayer;
eyeLayer.Header.Type = ovrLayerType_EyeFov;
eyeLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft; // Because OpenGL
for (int eye = 0; eye < 2; eye++)
{
eyeLayer.ColorTexture[eye] = eyeRenderBuffer[eye].textureChain;
eyeLayer.Viewport[eye] = (ovrRecti){ eyeRenderBuffer[eye].width, eyeRenderBuffer[eye].height };
eyeLayer.Fov[eye] = hmdDesc.DefaultEyeFov[eye];
eyeLayer.RenderPose[eye] = eyeRenderPose[eye];
eyeLayer.SensorSampleTime = sensorSampleTime;
}
// Append all the layers to global list
ovrLayerHeader *layerList = &eyeLayer.Header;
ovrResult result = ovr_SubmitFrame(session, frameIndex, NULL, &layerList, 1);
// exit the rendering loop if submit returns an error, will retry on ovrError_DisplayLost
if (!OVR_SUCCESS(result)) return 1;
isVisible = (result == ovrSuccess);
// Get session status information
ovrSessionStatus sessionStatus;
ovr_GetSessionStatus(session, &sessionStatus);
if (sessionStatus.ShouldQuit) TraceLog(LOG_WARNING, "OVR: Session should quit.");
if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session);
// Blit mirror texture to back buffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, mirrorFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
GLint w = mirrorDesc.Width;
GLint h = mirrorDesc.Height;
glBlitFramebuffer(0, h, w, 0, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glfwSwapBuffers(window);
glfwPollEvents();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
if (mirrorFBO) glDeleteFramebuffers(1, &mirrorFBO);
if (mirrorTexture) ovr_DestroyMirrorTexture(session, mirrorTexture);
for (int eye = 0; eye < 2; eye++) UnloadOculusBuffer(session, eyeRenderBuffer[eye]);
rlglClose();
glfwDestroyWindow(window);
glfwTerminate();
ovr_Destroy(session); // Must be called after glfwTerminate()
ovr_Shutdown();
//--------------------------------------------------------------------------------------
return 0;
}
//----------------------------------------------------------------------------------
// Module specific Functions Definitions
//----------------------------------------------------------------------------------
// Load Oculus required buffers: texture-swap-chain, fbo, texture-depth
static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height)
{
OculusBuffer buffer;
buffer.width = width;
buffer.height = height;
// Create OVR texture chain
ovrTextureSwapChainDesc desc = {};
desc.Type = ovrTexture_2D;
desc.ArraySize = 1;
desc.Width = width;
desc.Height = height;
desc.MipLevels = 1;
desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.SampleCount = 1;
desc.StaticImage = ovrFalse;
ovrResult result = ovr_CreateTextureSwapChainGL(session, &desc, &buffer.textureChain);
int textureCount = 0;
ovr_GetTextureSwapChainLength(session, buffer.textureChain, &textureCount);
if (OVR_SUCCESS(result))
{
for (int i = 0; i < textureCount; ++i)
{
GLuint chainTexId;
ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, i, &chainTexId);
glBindTexture(GL_TEXTURE_2D, chainTexId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
}
// Generate framebuffer
glGenFramebuffers(1, &buffer.fboId);
// Create Depth texture
glGenTextures(1, &buffer.depthId);
glBindTexture(GL_TEXTURE_2D, buffer.depthId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, buffer.width, buffer.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
return buffer;
}
// Unload texture required buffers
static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer)
{
if (buffer.textureChain)
{
ovr_DestroyTextureSwapChain(session, buffer.textureChain);
buffer.textureChain = NULL;
}
if (buffer.depthId)
{
glDeleteTextures(1, &buffer.depthId);
buffer.depthId = 0;
}
if (buffer.fboId)
{
glDeleteFramebuffers(1, &buffer.fboId);
buffer.fboId = 0;
}
}
// Set current Oculus buffer
static void SetOculusBuffer(ovrSession session, OculusBuffer buffer)
{
GLuint currentTexId;
int currentIndex;
ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, &currentIndex);
ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, &currentTexId);
glBindFramebuffer(GL_FRAMEBUFFER, buffer.fboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0);
glViewport(0, 0, buffer.width, buffer.height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_FRAMEBUFFER_SRGB);
}
// Unset Oculus buffer
static void UnsetOculusBuffer(OculusBuffer buffer)
{
glBindFramebuffer(GL_FRAMEBUFFER, buffer.fboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
}
// Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally)
static void DrawRectangleV(Vector2 position, Vector2 size, Color color)
{
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(position.x, position.y);
rlVertex2i(position.x, position.y + size.y);
rlVertex2i(position.x + size.x, position.y + size.y);
rlVertex2i(position.x, position.y);
rlVertex2i(position.x + size.x, position.y + size.y);
rlVertex2i(position.x + size.x, position.y);
rlEnd();
}
// Output a trace log message
// NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning
static void TraceLog(int msgType, const char *text, ...)
{
va_list args;
va_start(args, text);
switch(msgType)
{
case LOG_INFO: fprintf(stdout, "INFO: "); break;
case LOG_ERROR: fprintf(stdout, "ERROR: "); break;
case LOG_WARNING: fprintf(stdout, "WARNING: "); break;
case LOG_DEBUG: fprintf(stdout, "DEBUG: "); break;
default: break;
}
vfprintf(stdout, text, args);
fprintf(stdout, "\n");
va_end(args);
//if (msgType == LOG_ERROR) exit(1);
}

View File

Before

Width:  |  Height:  |  Size: 213 KiB

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

View File

@ -9,7 +9,7 @@
* gcc -c rlgl.c -Wall -std=c99 -DRLGL_STANDALONE -DRAYMATH_IMPLEMENTATION -DGRAPHICS_API_OPENGL_33 * gcc -c rlgl.c -Wall -std=c99 -DRLGL_STANDALONE -DRAYMATH_IMPLEMENTATION -DGRAPHICS_API_OPENGL_33
* *
* Compile example using: * Compile example using:
* gcc -o $(NAME_PART).exe $(FILE_NAME) rlgl.o glad.o -lglfw3 -lopengl32 -lgdi32 -std=c99 * gcc -o $(NAME_PART).exe $(FILE_NAME) rlgl.o -lglfw3 -lopengl32 -lgdi32 -std=c99
* *
* This example has been created using raylib 1.5 (www.raylib.com) * This example has been created using raylib 1.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
@ -18,23 +18,168 @@
* *
********************************************************************************************/ ********************************************************************************************/
#include "glad.h" #define GLAD_IMPLEMENTATION
#include <GLFW/glfw3.h> #include "glad.h" // Extensions loading library
#include <GLFW/glfw3.h> // Windows/Context and inputs management
#define RLGL_STANDALONE #define RLGL_STANDALONE
#include "rlgl.h" #include "rlgl.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h>
#define RED (Color){ 230, 41, 55, 255 } // Red
#define MAROON (Color){ 190, 33, 55, 255 } // Maroon
#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
//----------------------------------------------------------------------------------
typedef enum { LOG_INFO = 0, LOG_ERROR, LOG_WARNING, LOG_DEBUG, LOG_OTHER } TraceLogType;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module specific Functions Declaration // Module specific Functions Declaration
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
static void ErrorCallback(int error, const char* description) static void ErrorCallback(int error, const char* description);
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
static void TraceLog(int msgType, const char *text, ...);
// Drawing functions (uses rlgl functionality)
static void DrawGrid(int slices, float spacing);
static void DrawCube(Vector3 position, float width, float height, float length, Color color);
static void DrawCubeWires(Vector3 position, float width, float height, float length, Color color);
static void DrawRectangleV(Vector2 position, Vector2 size, Color color);
//----------------------------------------------------------------------------------
// Main Entry point
//----------------------------------------------------------------------------------
int main(void)
{ {
fputs(description, stderr); // Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
// GLFW3 Initialization + OpenGL 3.3 Context + Extensions
//--------------------------------------------------------
glfwSetErrorCallback(ErrorCallback);
if (!glfwInit())
{
TraceLog(LOG_WARNING, "GLFW3: Can not initialize GLFW");
exit(EXIT_FAILURE);
}
else TraceLog(LOG_INFO, "GLFW3: GLFW initialized successfully");
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_DEPTH_BITS, 16);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight, "rlgl standalone", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
else TraceLog(LOG_INFO, "GLFW3: Window created successfully");
glfwSetKeyCallback(window, KeyCallback);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
// Load OpenGL 3.3 extensions
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
TraceLog(LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
exit(1);
}
else TraceLog(LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
//--------------------------------------------------------
// Initialize rlgl internal buffers and OpenGL state
rlglInit();
rlglInitGraphics(0, 0, screenWidth, screenHeight);
rlClearColor(245, 245, 245, 255); // Define clear color
rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
Vector2 size = { 200, 200 };
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
Camera camera;
camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position
camera.target = (Vector3){ 0.0f, 0.0f, 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
//--------------------------------------------------------------------------------------
// Main game loop
while (!glfwWindowShouldClose(window))
{
// Update
//----------------------------------------------------------------------------------
// ...
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
rlClearScreenBuffers(); // Clear current framebuffer
// Calculate projection matrix (from perspective) and view matrix from camera look at
Matrix matProj = MatrixPerspective(camera.fovy, (double)screenWidth/(double)screenHeight, 0.01, 1000.0);
MatrixTranspose(&matProj);
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
Matrix mvp = MatrixMultiply(matView, matProj);
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, RAYWHITE);
DrawGrid(10, 1.0f);
// NOTE: Internal buffers drawing (3D data)
rlglDraw(mvp);
matProj = MatrixOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0);
MatrixTranspose(&matProj);
matView = MatrixIdentity();
mvp = MatrixMultiply(matView, matProj);
// TODO: 2D drawing on Oculus Rift: requires an ovrLayerQuad layer
DrawRectangleV((Vector2){ 10.0f, 10.0f }, (Vector2){ 300.0f, 20.0f }, DARKGRAY);
// NOTE: Internal buffers drawing (2D data)
rlglDraw(mvp);
glfwSwapBuffers(window);
glfwPollEvents();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
rlglClose(); // Unload rlgl internal buffers and default shader/texture
glfwDestroyWindow(window);
glfwTerminate();
//--------------------------------------------------------------------------------------
return 0;
} }
//----------------------------------------------------------------------------------
// Module specific Functions Definitions
//----------------------------------------------------------------------------------
// GLFW3: Error callback
static void ErrorCallback(int error, const char* description)
{
TraceLog(LOG_ERROR, description);
}
// GLFW3: Keyboard callback
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{ {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
@ -43,79 +188,31 @@ static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, i
} }
} }
void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Output a trace log message
static void TraceLog(int msgType, const char *text, ...)
//----------------------------------------------------------------------------------
// Main Entry point
//----------------------------------------------------------------------------------
int main(void)
{ {
const int screenWidth = 800; va_list args;
const int screenHeight = 450; va_start(args, text);
GLFWwindow *window;
glfwSetErrorCallback(ErrorCallback);
if (!glfwInit()) exit(EXIT_FAILURE);
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(screenWidth, screenHeight, "rlgl standalone", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwSetKeyCallback(window, KeyCallback);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) switch(msgType)
{ {
printf("Cannot load GL extensions.\n"); case LOG_INFO: fprintf(stdout, "INFO: "); break;
exit(1); case LOG_ERROR: fprintf(stdout, "ERROR: "); break;
case LOG_WARNING: fprintf(stdout, "WARNING: "); break;
case LOG_DEBUG: fprintf(stdout, "DEBUG: "); break;
default: break;
} }
rlglInit(); vfprintf(stdout, text, args);
rlglInitGraphics(0, 0, screenWidth, screenHeight); fprintf(stdout, "\n");
rlClearColor(245, 245, 245, 255); // Define clear color
va_end(args);
Vector2 position = { screenWidth/2 - 100, screenHeight/2 - 100 };
Vector2 size = { 200, 200 }; //if (msgType == LOG_ERROR) exit(1);
Color color = { 180, 20, 20, 255 };
while (!glfwWindowShouldClose(window))
{
rlClearScreenBuffers();
DrawRectangleV(position, size, color);
rlglDraw();
glfwSwapBuffers(window);
glfwPollEvents();
}
rlglClose();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
} }
//---------------------------------------------------------------------------------- // Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally)
// Module specific Functions Definitions static void DrawRectangleV(Vector2 position, Vector2 size, Color color)
//----------------------------------------------------------------------------------
void DrawRectangleV(Vector2 position, Vector2 size, Color color)
{ {
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -128,4 +225,181 @@ void DrawRectangleV(Vector2 position, Vector2 size, Color color)
rlVertex2i(position.x + size.x, position.y + size.y); rlVertex2i(position.x + size.x, position.y + size.y);
rlVertex2i(position.x + size.x, position.y); rlVertex2i(position.x + size.x, position.y);
rlEnd(); rlEnd();
} }
// Draw a grid centered at (0, 0, 0)
static void DrawGrid(int slices, float spacing)
{
int halfSlices = slices / 2;
rlBegin(RL_LINES);
for(int i = -halfSlices; i <= halfSlices; i++)
{
if (i == 0)
{
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
}
else
{
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
}
rlVertex3f((float)i*spacing, 0.0f, (float)-halfSlices*spacing);
rlVertex3f((float)i*spacing, 0.0f, (float)halfSlices*spacing);
rlVertex3f((float)-halfSlices*spacing, 0.0f, (float)i*spacing);
rlVertex3f((float)halfSlices*spacing, 0.0f, (float)i*spacing);
}
rlEnd();
}
// Draw cube
// NOTE: Cube position is the center position
void DrawCube(Vector3 position, float width, float height, float length, Color color)
{
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
rlPushMatrix();
// NOTE: Be careful! Function order matters (rotate -> scale -> translate)
rlTranslatef(position.x, position.y, position.z);
//rlScalef(2.0f, 2.0f, 2.0f);
//rlRotatef(45, 0, 1, 0);
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
// Front Face -----------------------------------------------------
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
// Back Face ------------------------------------------------------
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
// Top Face -------------------------------------------------------
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
rlVertex3f(x-width/2, y+height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y+height/2, z+length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
rlVertex3f(x+width/2, y+height/2, z+length/2); // Bottom Right
// Bottom Face ----------------------------------------------------
rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z-length/2); // Top Right
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Left
// Right face -----------------------------------------------------
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Left
// Left Face ------------------------------------------------------
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Right
rlEnd();
rlPopMatrix();
}
// Draw cube wires
void DrawCubeWires(Vector3 position, float width, float height, float length, Color color)
{
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
rlPushMatrix();
rlTranslatef(position.x, position.y, position.z);
//rlRotatef(45, 0, 1, 0);
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
// Front Face -----------------------------------------------------
// Bottom Line
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
// Left Line
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right
// Top Line
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
// Right Line
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
// Back Face ------------------------------------------------------
// Bottom Line
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
// Left Line
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
// Top Line
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
// Right Line
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left
// Top Face -------------------------------------------------------
// Left Line
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left Front
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left Back
// Right Line
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right Front
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right Back
// Bottom Face ---------------------------------------------------
// Left Line
rlVertex3f(x-width/2, y-height/2, z+length/2); // Top Left Front
rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Left Back
// Right Line
rlVertex3f(x+width/2, y-height/2, z+length/2); // Top Right Front
rlVertex3f(x+width/2, y-height/2, z-length/2); // Top Right Back
rlEnd();
rlPopMatrix();
}

View File

@ -73,7 +73,7 @@
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#if defined(RAYMATH_STANDALONE) #if defined(RAYMATH_STANDALONE)
// Vector2 type // Vector2 type
typedef struct Vector2 { typedef struct Vector2 {
float x; float x;
float y; float y;
@ -158,6 +158,7 @@ RMDEF void PrintMatrix(Matrix m); // Print matrix ut
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
RMDEF float QuaternionLength(Quaternion quat); // Compute the length of a quaternion RMDEF float QuaternionLength(Quaternion quat); // Compute the length of a quaternion
RMDEF void QuaternionNormalize(Quaternion *q); // Normalize provided quaternion RMDEF void QuaternionNormalize(Quaternion *q); // Normalize provided quaternion
RMDEF void QuaternionInvert(Quaternion *quat); // Invert provided quaternion
RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2); // Calculate two quaternion multiplication RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2); // Calculate two quaternion multiplication
RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float slerp); // Calculates spherical linear interpolation between two quaternions RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float slerp); // Calculates spherical linear interpolation between two quaternions
RMDEF Quaternion QuaternionFromMatrix(Matrix matrix); // Returns a quaternion for a given rotation matrix RMDEF Quaternion QuaternionFromMatrix(Matrix matrix); // Returns a quaternion for a given rotation matrix
@ -908,6 +909,23 @@ RMDEF void QuaternionNormalize(Quaternion *q)
q->w *= ilength; q->w *= ilength;
} }
// Invert provided quaternion
RMDEF void QuaternionInvert(Quaternion *quat)
{
float length = QuaternionLength(*quat);
float lengthSq = length*length;
if (lengthSq != 0.0)
{
float i = 1.0f/lengthSq;
quat->x *= -i;
quat->y *= -i;
quat->z *= -i;
quat->w *= i;
}
}
// Calculate two quaternion multiplication // Calculate two quaternion multiplication
RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2) RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2)
{ {

File diff suppressed because it is too large Load Diff

View File

@ -130,47 +130,43 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
COMPRESSED_ASTC_4x4_RGBA, // 8 bpp COMPRESSED_ASTC_4x4_RGBA, // 8 bpp
COMPRESSED_ASTC_8x8_RGBA // 2 bpp COMPRESSED_ASTC_8x8_RGBA // 2 bpp
} TextureFormat; } TextureFormat;
// Bounding box type
typedef struct BoundingBox {
Vector3 min;
Vector3 max;
} BoundingBox;
// Mesh with vertex data type // Vertex data definning a mesh
// NOTE: If using OpenGL 1.1, data loaded in CPU; if OpenGL 3.3+ data loaded in GPU (vaoId)
typedef struct Mesh { typedef struct Mesh {
int vertexCount; // num vertices int vertexCount; // number of vertices stored in arrays
float *vertices; // vertex position (XYZ - 3 components per vertex) int triangleCount; // number of triangles stored (indexed or not)
float *texcoords; // vertex texture coordinates (UV - 2 components per vertex) float *vertices; // vertex position (XYZ - 3 components per vertex) (shader-location = 0)
float *texcoords2; // vertex second texture coordinates (useful for lightmaps) float *texcoords; // vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
float *normals; // vertex normals (XYZ - 3 components per vertex) float *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
float *tangents; // vertex tangents (XYZ - 3 components per vertex) float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
unsigned char *colors; // vertex colors (RGBA - 4 components per vertex) float *tangents; // vertex tangents (XYZ - 3 components per vertex) (shader-location = 4)
unsigned char *colors; // vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
BoundingBox bounds; // mesh limits defined by min and max points unsigned short *indices;// vertex indices (in case vertex data comes indexed)
unsigned int vaoId; // OpenGL Vertex Array Object id unsigned int vaoId; // OpenGL Vertex Array Object id
unsigned int vboId[6]; // OpenGL Vertex Buffer Objects id (6 types of vertex data) unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
} Mesh; } Mesh;
// Shader type // Shader type (generic shader)
typedef struct Shader { typedef struct Shader {
unsigned int id; // Shader program id unsigned int id; // Shader program id
// Variable attributes
int vertexLoc; // Vertex attribute location point (vertex shader)
int texcoordLoc; // Texcoord attribute location point (vertex shader)
int normalLoc; // Normal attribute location point (vertex shader)
int colorLoc; // Color attibute location point (vertex shader)
// Uniforms
int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
int tintColorLoc; // Color uniform location point (fragment shader)
int mapDiffuseLoc; // Diffuse map texture uniform location point (fragment shader) // Vertex attributes locations (default locations)
int mapNormalLoc; // Normal map texture uniform location point (fragment shader) int vertexLoc; // Vertex attribute location point (default-location = 0)
int mapSpecularLoc; // Specular map texture uniform location point (fragment shader) int texcoordLoc; // Texcoord attribute location point (default-location = 1)
int normalLoc; // Normal attribute location point (default-location = 2)
int colorLoc; // Color attibute location point (default-location = 3)
int tangentLoc; // Tangent attribute location point (default-location = 4)
int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5)
// Uniform locations
int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
int tintColorLoc; // Color uniform location point (fragment shader)
// Texture map locations (generic for any kind of map)
int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0)
int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1)
int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2)
} Shader; } Shader;
// Texture2D type // Texture2D type
@ -192,27 +188,46 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
// Material type // Material type
typedef struct Material { typedef struct Material {
Shader shader; Shader shader; // Standard shader (supports 3 map types: diffuse, normal, specular)
Texture2D texDiffuse; // Diffuse texture Texture2D texDiffuse; // Diffuse texture
Texture2D texNormal; // Normal texture Texture2D texNormal; // Normal texture
Texture2D texSpecular; // Specular texture Texture2D texSpecular; // Specular texture
Color colDiffuse; // Diffuse color
Color colAmbient; // Ambient color
Color colSpecular; // Specular color
Color colDiffuse; float glossiness; // Glossiness level (Ranges from 0 to 1000)
Color colAmbient;
Color colSpecular;
float glossiness;
float normalDepth;
} Material; } Material;
// Camera type, defines a camera position/orientation in 3d space
typedef struct Camera {
Vector3 position; // Camera position
Vector3 target; // Camera target it looks-at
Vector3 up; // Camera up vector (rotation over its axis)
float fovy; // Camera field-of-view apperture in Y (degrees)
} Camera;
// Light type
typedef struct LightData {
unsigned int id; // Light unique id
int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
bool enabled; // Light enabled
Vector3 position; // Light position
Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target)
float radius; // Light attenuation radius light intensity reduced with distance (world distance)
Color diffuse; // Light diffuse color
float intensity; // Light intensity level
float coneAngle; // Light cone max angle: LIGHT_SPOT
} LightData, *Light;
// Light types
typedef enum { LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT } LightType;
// 3d Model type
typedef struct Model {
Mesh mesh;
Matrix transform;
Material material;
} Model;
// Color blending modes (pre-defined) // Color blending modes (pre-defined)
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode; typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
#endif #endif
@ -234,6 +249,7 @@ void rlScalef(float x, float y, float z); // Multiply the current matrix b
void rlMultMatrixf(float *mat); // Multiply the current matrix by another matrix void rlMultMatrixf(float *mat); // Multiply the current matrix by another matrix
void rlFrustum(double left, double right, double bottom, double top, double near, double far); void rlFrustum(double left, double right, double bottom, double top, double near, double far);
void rlOrtho(double left, double right, double bottom, double top, double near, double far); void rlOrtho(double left, double right, double bottom, double top, double near, double far);
void rlViewport(int x, int y, int width, int height); // Set the viewport area
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Functions Declaration - Vertex level operations // Functions Declaration - Vertex level operations
@ -259,6 +275,8 @@ void rlEnableRenderTexture(unsigned int id); // Enable render texture (fbo)
void rlDisableRenderTexture(void); // Disable render texture (fbo), return to default framebuffer void rlDisableRenderTexture(void); // Disable render texture (fbo), return to default framebuffer
void rlEnableDepthTest(void); // Enable depth test void rlEnableDepthTest(void); // Enable depth test
void rlDisableDepthTest(void); // Disable depth test void rlDisableDepthTest(void); // Disable depth test
void rlEnableWireMode(void); // Enable wire mode
void rlDisableWireMode(void); // Disable wire mode
void rlDeleteTextures(unsigned int id); // Delete OpenGL texture from GPU void rlDeleteTextures(unsigned int id); // Delete OpenGL texture from GPU
void rlDeleteRenderTextures(RenderTexture2D target); // Delete render textures (fbo) from GPU void rlDeleteRenderTextures(RenderTexture2D target); // Delete render textures (fbo) from GPU
void rlDeleteShader(unsigned int id); // Delete OpenGL shader program from GPU void rlDeleteShader(unsigned int id); // Delete OpenGL shader program from GPU
@ -273,7 +291,7 @@ int rlGetVersion(void); // Returns current OpenGL versio
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
void rlglInit(void); // Initialize rlgl (shaders, VAO, VBO...) void rlglInit(void); // Initialize rlgl (shaders, VAO, VBO...)
void rlglClose(void); // De-init rlgl void rlglClose(void); // De-init rlgl
void rlglDraw(Matrix mvp); // Draw VAO/VBO void rlglDraw(Matrix mvp); // Draw VAO/VBO
void rlglInitGraphics(int offsetX, int offsetY, int width, int height); // Initialize Graphics (OpenGL stuff) void rlglInitGraphics(int offsetX, int offsetY, int width, int height); // Initialize Graphics (OpenGL stuff)
unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load texture in GPU unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load texture in GPU
@ -281,35 +299,43 @@ RenderTexture2D rlglLoadRenderTexture(int width, int height); // Load a textur
void rlglUpdateTexture(unsigned int id, int width, int height, int format, void *data); // Update GPU texture with new data void rlglUpdateTexture(unsigned int id, int width, int height, int format, void *data); // Update GPU texture with new data
void rlglGenerateMipmaps(Texture2D texture); // Generate mipmap data for selected texture void rlglGenerateMipmaps(Texture2D texture); // Generate mipmap data for selected texture
// NOTE: There is a set of shader related functions that are available to end user, void rlglLoadMesh(Mesh *mesh, bool dynamic); // Upload vertex data into GPU and provided VAO/VBO ids
// to avoid creating function wrappers through core module, they have been directly declared in raylib.h void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex); // Update vertex data on GPU (upload new data to one buffer)
void rlglDrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform
Model rlglLoadModel(Mesh mesh); // Upload vertex data into GPU and provided VAO/VBO ids void rlglUnloadMesh(Mesh *mesh); // Unload mesh data from CPU and GPU
void rlglDrawModel(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color color, bool wires);
Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates
unsigned char *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer) unsigned char *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
void *rlglReadTexturePixels(Texture2D texture); // Read texture pixel data void *rlglReadTexturePixels(Texture2D texture); // Read texture pixel data
// NOTE: There is a set of shader related functions that are available to end user,
// to avoid creating function wrappers through core module, they have been directly declared in raylib.h
#if defined(RLGL_STANDALONE) #if defined(RLGL_STANDALONE)
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Shaders System Functions (Module: rlgl) // Shaders System Functions (Module: rlgl)
// NOTE: This functions are useless when using OpenGL 1.1 // NOTE: This functions are useless when using OpenGL 1.1
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations
unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr); // Load custom shader strings and return program id
void UnloadShader(Shader shader); // Unload a custom shader from memory void UnloadShader(Shader shader); // Unload a custom shader from memory
void SetCustomShader(Shader shader); // Set custom shader to be used in batch draw
void SetDefaultShader(void); // Set default shader to be used in batch draw Shader GetDefaultShader(void); // Get default shader
void SetModelShader(Model *model, Shader shader); // Link a shader to a model Shader GetStandardShader(void); // Get default shader
Texture2D GetDefaultTexture(void); // Get default texture
int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float) void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int) void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4) void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied) void BeginShaderMode(Shader shader); // Begin custom shader drawing
void EndShaderMode(void); // End custom shader drawing (use default shader)
void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)
void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool
void DestroyLight(Light light); // Destroy a light and take it out of the list
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -6,7 +6,7 @@ in vec4 fragColor;
// Input uniform values // Input uniform values
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 fragTintColor; uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
@ -16,7 +16,7 @@ out vec4 finalColor;
void main() void main()
{ {
// Texel color fetching from texture sampler // Texel color fetching from texture sampler
vec4 texelColor = texture(texture0, fragTexCoord)*fragTintColor*fragColor; vec4 texelColor = texture(texture0, fragTexCoord)*colDiffuse*fragColor;
// Convert texel color to grayscale using NTSC conversion weights // Convert texel color to grayscale using NTSC conversion weights
float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114));

View File

@ -11,7 +11,6 @@ uniform sampler2D texture0;
uniform sampler2D texture1; uniform sampler2D texture1;
uniform sampler2D texture2; uniform sampler2D texture2;
uniform vec4 colTint;
uniform vec4 colAmbient; uniform vec4 colAmbient;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
uniform vec4 colSpecular; uniform vec4 colSpecular;
@ -55,7 +54,7 @@ vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s)
spec = pow(dot(n, h), 3 + glossiness)*s; spec = pow(dot(n, h), 3 + glossiness)*s;
} }
return (diff*l.diffuse.rgb*colDiffuse.rgb + spec*colSpecular.rgb); return (diff*l.diffuse.rgb + spec*colSpecular.rgb);
} }
vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s) vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s)
@ -74,7 +73,7 @@ vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s)
} }
// Combine results // Combine results
return (diff*l.intensity*l.diffuse.rgb*colDiffuse.rgb + spec*colSpecular.rgb); return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb);
} }
vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s) vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s)
@ -89,8 +88,10 @@ vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s)
// Spot attenuation // Spot attenuation
float attenuation = clamp(dot(n, lightToSurface), 0.0, 1.0); float attenuation = clamp(dot(n, lightToSurface), 0.0, 1.0);
attenuation = dot(lightToSurface, -lightDir); attenuation = dot(lightToSurface, -lightDir);
float lightToSurfaceAngle = degrees(acos(attenuation)); float lightToSurfaceAngle = degrees(acos(attenuation));
if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0; if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0;
float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle; float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle;
// Combine diffuse and attenuation // Combine diffuse and attenuation
@ -104,7 +105,7 @@ vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s)
spec = pow(dot(n, h), 3 + glossiness)*s; spec = pow(dot(n, h), 3 + glossiness)*s;
} }
return falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb); return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));
} }
void main() void main()
@ -123,7 +124,7 @@ void main()
vec3 lighting = colAmbient.rgb; vec3 lighting = colAmbient.rgb;
// Calculate normal texture color fetching or set to maximum normal value by default // Calculate normal texture color fetching or set to maximum normal value by default
if(useNormal == 1) if (useNormal == 1)
{ {
n *= texture(texture1, fragTexCoord).rgb; n *= texture(texture1, fragTexCoord).rgb;
n = normalize(n); n = normalize(n);
@ -131,7 +132,7 @@ void main()
// Calculate specular texture color fetching or set to maximum specular value by default // Calculate specular texture color fetching or set to maximum specular value by default
float spec = 1.0; float spec = 1.0;
if(useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r); if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r);
for (int i = 0; i < lightsCount; i++) for (int i = 0; i < lightsCount; i++)
{ {
@ -150,5 +151,5 @@ void main()
} }
// Calculate final fragment color // Calculate final fragment color
finalColor = vec4(texelColor.rgb*lighting*colTint.rgb, texelColor.a*colTint.a); finalColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a);
} }

View File

@ -33,7 +33,7 @@ int main()
Camera camera = {{ 3.0f, 3.0f, 3.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f }; Camera camera = {{ 3.0f, 3.0f, 3.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model
Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture (diffuse map)
SetModelTexture(&dwarf, texture); // Bind texture to model SetModelTexture(&dwarf, texture); // Bind texture to model
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
@ -94,10 +94,12 @@ int main()
EndTextureMode(); // End drawing to texture (now we have a texture available for next passes) EndTextureMode(); // End drawing to texture (now we have a texture available for next passes)
SetCustomShader(shader); BeginShaderMode(shader);
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE); // NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
SetDefaultShader(); DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE);
EndShaderMode();
DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY); DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY);

View File

@ -33,7 +33,7 @@ int main()
Camera camera = {{ 3.0f, 3.0f, 3.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f }; Camera camera = {{ 3.0f, 3.0f, 3.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model
Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture (diffuse map)
SetModelTexture(&dwarf, texture); // Bind texture to model SetModelTexture(&dwarf, texture); // Bind texture to model
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
@ -80,10 +80,12 @@ int main()
EndTextureMode(); // End drawing to texture (now we have a texture available for next passes) EndTextureMode(); // End drawing to texture (now we have a texture available for next passes)
SetCustomShader(shader); BeginShaderMode(shader);
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE); // NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
SetDefaultShader(); DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE);
EndShaderMode();
DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, DARKGRAY); DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, DARKGRAY);

View File

@ -65,16 +65,16 @@ int main()
// Activate our custom shader to be applied on next shapes/textures drawings // Activate our custom shader to be applied on next shapes/textures drawings
SetCustomShader(shader); BeginShaderMode(shader);
DrawText("USING CUSTOM SHADER", 190, 40, 10, RED); DrawText("USING CUSTOM SHADER", 190, 40, 10, RED);
DrawRectangle(250 - 60, 90, 120, 60, RED); DrawRectangle(250 - 60, 90, 120, 60, RED);
DrawRectangleGradient(250 - 90, 170, 180, 130, MAROON, GOLD); DrawRectangleGradient(250 - 90, 170, 180, 130, MAROON, GOLD);
DrawRectangleLines(250 - 40, 320, 80, 60, ORANGE); DrawRectangleLines(250 - 40, 320, 80, 60, ORANGE);
// Activate our default shader for next drawings // Activate our default shader for next drawings
SetDefaultShader(); EndShaderMode();
DrawText("USING DEFAULT SHADER", 370, 40, 10, RED); DrawText("USING DEFAULT SHADER", 370, 40, 10, RED);
@ -89,12 +89,12 @@ int main()
DrawPoly((Vector2){430, 320}, 6, 80, 0, BROWN); DrawPoly((Vector2){430, 320}, 6, 80, 0, BROWN);
// Activate our custom shader to be applied on next shapes/textures drawings // Activate our custom shader to be applied on next shapes/textures drawings
SetCustomShader(shader); BeginShaderMode(shader);
DrawTexture(sonic, 380, -10, WHITE); // Using custom shader DrawTexture(sonic, 380, -10, WHITE); // Using custom shader
// Activate our default shader for next drawings // Activate our default shader for next drawings
SetDefaultShader(); EndShaderMode();
EndDrawing(); EndDrawing();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@ -40,9 +40,9 @@ int main()
material.texDiffuse = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model diffuse texture material.texDiffuse = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model diffuse texture
material.texNormal = LoadTexture("resources/model/dwarf_normal.png"); // Load model normal texture material.texNormal = LoadTexture("resources/model/dwarf_normal.png"); // Load model normal texture
material.texSpecular = LoadTexture("resources/model/dwarf_specular.png"); // Load model specular texture material.texSpecular = LoadTexture("resources/model/dwarf_specular.png"); // Load model specular texture
material.colDiffuse = (Color){255, 255, 255, 255}; material.colDiffuse = WHITE;
material.colAmbient = (Color){0, 0, 10, 255}; material.colAmbient = (Color){0, 0, 10, 255};
material.colSpecular = (Color){255, 255, 255, 255}; material.colSpecular = WHITE;
material.glossiness = 50.0f; material.glossiness = 50.0f;
dwarf.material = material; // Apply material to model dwarf.material = material; // Apply material to model

View File

@ -102,20 +102,22 @@ int main()
ClearBackground(DARKGRAY); ClearBackground(DARKGRAY);
SetBlendMode(blending); BeginBlendMode(blending);
// Draw active particles // Draw active particles
for (int i = 0; i < MAX_PARTICLES; i++) for (int i = 0; i < MAX_PARTICLES; i++)
{ {
if (mouseTail[i].active) DrawTexturePro(smoke, (Rectangle){ 0, 0, smoke.width, smoke.height }, if (mouseTail[i].active) DrawTexturePro(smoke, (Rectangle){ 0, 0, smoke.width, smoke.height },
(Rectangle){ mouseTail[i].position.x, mouseTail[i].position.y, smoke.width*mouseTail[i].size, smoke.height*mouseTail[i].size }, (Rectangle){ mouseTail[i].position.x, mouseTail[i].position.y, smoke.width*mouseTail[i].size, smoke.height*mouseTail[i].size },
(Vector2){ smoke.width*mouseTail[i].size/2, smoke.height*mouseTail[i].size/2 }, mouseTail[i].rotation, (Vector2){ smoke.width*mouseTail[i].size/2, smoke.height*mouseTail[i].size/2 }, mouseTail[i].rotation,
Fade(mouseTail[i].color, mouseTail[i].alpha)); Fade(mouseTail[i].color, mouseTail[i].alpha));
} }
DrawText("PRESS SPACE to CHANGE BLENDING MODE", 180, 20, 20, RAYWHITE); EndBlendMode();
if (blending == BLEND_ALPHA) DrawText("ALPHA BLENDING", 290, screenHeight - 40, 20, RAYWHITE); DrawText("PRESS SPACE to CHANGE BLENDING MODE", 180, 20, 20, BLACK);
if (blending == BLEND_ALPHA) DrawText("ALPHA BLENDING", 290, screenHeight - 40, 20, BLACK);
else DrawText("ADDITIVE BLENDING", 280, screenHeight - 40, 20, RAYWHITE); else DrawText("ADDITIVE BLENDING", 280, screenHeight - 40, 20, RAYWHITE);
EndDrawing(); EndDrawing();

View File

@ -69,12 +69,13 @@ else
endif endif
# define compiler flags: # define compiler flags:
# -O1 defines optimization level # -O1 defines optimization level
# -Wall turns on most, but not all, compiler warnings # -Wall turns on most, but not all, compiler warnings
# -std=c99 defines C language mode (standard C from 1999 revision) # -std=c99 defines C language mode (standard C from 1999 revision)
# -std=gnu99 defines C language mode (GNU C from 1999 revision) # -std=gnu99 defines C language mode (GNU C from 1999 revision)
# -fgnu89-inline declaring inline functions support (GCC optimized, faster) # -fgnu89-inline declaring inline functions support (GCC optimized, faster)
CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline # -Wno-missing-braces ignore invalid warning (GCC bug 53119)
CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline -Wno-missing-braces
#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes #CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes

View File

@ -37,24 +37,24 @@
#include "AL/al.h" // OpenAL basic header #include "AL/al.h" // OpenAL basic header
#include "AL/alc.h" // OpenAL context header (like OpenGL, OpenAL requires a context to work) #include "AL/alc.h" // OpenAL context header (like OpenGL, OpenAL requires a context to work)
#include "AL/alext.h" // extensions for other format types #include "AL/alext.h" // OpenAL extensions for other format types
#include <stdlib.h> // Declares malloc() and free() for memory management #include <stdlib.h> // Required for: malloc(), free()
#include <string.h> // Required for strcmp() #include <string.h> // Required for: strcmp(), strncmp()
#include <stdio.h> // Used for .WAV loading #include <stdio.h> // Required for: FILE, fopen(), fclose(), fread()
#if defined(AUDIO_STANDALONE) #if defined(AUDIO_STANDALONE)
#include <stdarg.h> // Used for functions with variable number of parameters (TraceLog()) #include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
#else #else
#include "utils.h" // rRES data decompression utility function #include "utils.h" // Required for: DecompressData()
// NOTE: Includes Android fopen function map // NOTE: Includes Android fopen() function map
#endif #endif
//#define STB_VORBIS_HEADER_ONLY //#define STB_VORBIS_HEADER_ONLY
#include "stb_vorbis.h" // OGG loading functions #include "stb_vorbis.h" // OGG loading functions
#define JAR_XM_IMPLEMENTATION #define JAR_XM_IMPLEMENTATION
#include "jar_xm.h" // For playing .xm files #include "jar_xm.h" // XM loading functions
#define JAR_MOD_IMPLEMENTATION #define JAR_MOD_IMPLEMENTATION
#include "jar_mod.h" // For playing .mod files #include "jar_mod.h" // For playing .mod files

View File

@ -30,7 +30,7 @@
#include "raylib.h" #include "raylib.h"
#endif #endif
#include <math.h> #include <math.h> // Required for: sqrt(), sin(), cos()
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros

View File

@ -2078,10 +2078,10 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int
gestureEvent.position[0] = GetMousePosition(); gestureEvent.position[0] = GetMousePosition();
// Normalize gestureEvent.position[0] for screenWidth and screenHeight // Normalize gestureEvent.position[0] for screenWidth and screenHeight
gestureEvent.position[0].x /= (float)GetScreenWidth(); gestureEvent.position[0].x /= (float)GetScreenWidth();
gestureEvent.position[0].y /= (float)GetScreenHeight(); gestureEvent.position[0].y /= (float)GetScreenHeight();
// Gesture data is sent to gestures system for processing // Gesture data is sent to gestures system for processing
ProcessGestureEvent(gestureEvent); ProcessGestureEvent(gestureEvent);
#endif #endif
} }
@ -2223,10 +2223,10 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
// Load default font for convenience // Load default font for convenience
// NOTE: External function (defined in module: text) // NOTE: External function (defined in module: text)
LoadDefaultFont(); LoadDefaultFont();
// TODO: GPU assets reload in case of lost focus (lost context) // TODO: GPU assets reload in case of lost focus (lost context)
// NOTE: This problem has been solved just unbinding and rebinding context from display // NOTE: This problem has been solved just unbinding and rebinding context from display
/* /*
if (assetsReloadRequired) if (assetsReloadRequired)
{ {
for (int i = 0; i < assetsCount; i++) for (int i = 0; i < assetsCount; i++)
@ -2759,9 +2759,9 @@ static void *GamepadThread(void *arg)
}; };
// Read gamepad event // Read gamepad event
struct js_event gamepadEvent; struct js_event gamepadEvent;
while (1) while (1)
{ {
for (int i = 0; i < MAX_GAMEPADS; i++) for (int i = 0; i < MAX_GAMEPADS; i++)
{ {
@ -2792,8 +2792,8 @@ static void *GamepadThread(void *arg)
} }
} }
} }
} }
return NULL; return NULL;
} }
#endif #endif

View File

@ -28,19 +28,19 @@
#if defined(GESTURES_STANDALONE) #if defined(GESTURES_STANDALONE)
#include "gestures.h" #include "gestures.h"
#else #else
#include "raylib.h" // Required for typedef(s): Vector2, Gestures #include "raylib.h" // Required for: Vector2, Gestures
#endif #endif
#include <math.h> // Used for: atan2(), sqrt() #include <math.h> // Required for: atan2(), sqrt()
#include <stdint.h> // Defines int32_t, int64_t #include <stdint.h> // Required for: uint64_t
#if defined(_WIN32) #if defined(_WIN32)
// Functions required to query time on Windows // Functions required to query time on Windows
int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount); int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount);
int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency); int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency);
#elif defined(__linux) #elif defined(__linux)
#include <sys/time.h> // Declares storage size of now #include <sys/time.h> // Required for: timespec
#include <time.h> // Used for clock functions #include <time.h> // Required for: clock_gettime()
#endif #endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@ -26,16 +26,16 @@
#include "raylib.h" #include "raylib.h"
#if defined(PLATFORM_ANDROID) #if defined(PLATFORM_ANDROID)
#include "utils.h" // Android fopen function map #include "utils.h" // Android fopen function map
#endif #endif
#include <stdio.h> // Standard input/output functions, used to read model files data #include <stdio.h> // Required for: FILE, fopen(), fclose(), fscanf(), feof(), rewind(), fgets()
#include <stdlib.h> // Declares malloc() and free() for memory management #include <stdlib.h> // Required for: malloc(), free()
#include <string.h> // Required for strcmp() #include <string.h> // Required for: strcmp()
#include <math.h> // Used for sin, cos, tan #include <math.h> // Required for: sin(), cos()
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2 #include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
#include "raymath.h" // Required for data type Matrix and Matrix functions #include "raymath.h" // Matrix data type and Matrix functions
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
@ -605,7 +605,7 @@ Model LoadModel(const char *fileName)
// TODO: Initialize default data for model in case loading fails, maybe a cube? // TODO: Initialize default data for model in case loading fails, maybe a cube?
if (strcmp(GetExtension(fileName),"obj") == 0) model.mesh = LoadOBJ(fileName); if (strcmp(GetExtension(fileName), "obj") == 0) model.mesh = LoadOBJ(fileName);
else TraceLog(WARNING, "[%s] Model extension not recognized, it can't be loaded", fileName); else TraceLog(WARNING, "[%s] Model extension not recognized, it can't be loaded", fileName);
if (model.mesh.vertexCount == 0) TraceLog(WARNING, "Model could not be loaded"); if (model.mesh.vertexCount == 0) TraceLog(WARNING, "Model could not be loaded");
@ -764,7 +764,7 @@ Material LoadMaterial(const char *fileName)
{ {
Material material = { 0 }; Material material = { 0 };
if (strcmp(GetExtension(fileName),"mtl") == 0) material = LoadMTL(fileName); if (strcmp(GetExtension(fileName), "mtl") == 0) material = LoadMTL(fileName);
else TraceLog(WARNING, "[%s] Material extension not recognized, it can't be loaded", fileName); else TraceLog(WARNING, "[%s] Material extension not recognized, it can't be loaded", fileName);
return material; return material;
@ -779,8 +779,7 @@ Material LoadDefaultMaterial(void)
material.texDiffuse = GetDefaultTexture(); // White texture (1x1 pixel) material.texDiffuse = GetDefaultTexture(); // White texture (1x1 pixel)
//material.texNormal; // NOTE: By default, not set //material.texNormal; // NOTE: By default, not set
//material.texSpecular; // NOTE: By default, not set //material.texSpecular; // NOTE: By default, not set
material.colTint = WHITE; // Tint color
material.colDiffuse = WHITE; // Diffuse color material.colDiffuse = WHITE; // Diffuse color
material.colAmbient = WHITE; // Ambient color material.colAmbient = WHITE; // Ambient color
material.colSpecular = WHITE; // Specular color material.colSpecular = WHITE; // Specular color
@ -1298,7 +1297,7 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
//Matrix matModel = MatrixMultiply(model.transform, matTransform); // Transform to world-space coordinates //Matrix matModel = MatrixMultiply(model.transform, matTransform); // Transform to world-space coordinates
model.transform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation); model.transform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation);
model.material.colTint = tint; model.material.colDiffuse = tint; // TODO: Multiply tint color by diffuse color?
rlglDrawMesh(model.mesh, model.material, model.transform); rlglDrawMesh(model.mesh, model.material, model.transform);
} }

View File

@ -29,8 +29,8 @@
#include "raylib.h" #include "raylib.h"
#endif #endif
#include <stdlib.h> // Declares malloc() and free() for memory management #include <stdlib.h> // Required for: malloc(), free()
#include <math.h> // Declares cos(), sin(), abs() and fminf() for math operations #include <math.h> // Required for: cos(), sin(), abs(), fminf()
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros

View File

@ -22,17 +22,30 @@
* *
**********************************************************************************************/ **********************************************************************************************/
//#define RAYGUI_STANDALONE // To use the raygui module as standalone lib, just uncomment this line
// NOTE: Some external funtions are required for drawing and input management
#if !defined(RAYGUI_STANDALONE)
#include "raylib.h"
#endif
#include "raygui.h" #include "raygui.h"
#include <math.h> #include <stdio.h> // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf()
#include <stdio.h> // NOTE: Those functions are only used in SaveGuiStyle() and LoadGuiStyle()
#include <stdlib.h> // Required for malloc(), free()
#include <string.h> // Required for strcmp() #include <stdlib.h> // Required for: malloc(), free()
#include <string.h> // Required for: strcmp()
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
//... #if defined(RAYGUI_STANDALONE)
#define KEY_LEFT 263
#define KEY_RIGHT 262
#define MOUSE_LEFT_BUTTON 0
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
@ -50,7 +63,7 @@ typedef enum { SLIDER_DEFAULT, SLIDER_HOVER, SLIDER_ACTIVE } SliderState;
// Global Variables Definition // Global Variables Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
//Current GUI style (default light) // Current GUI style (default light)
static int style[NUM_PROPERTIES] = { static int style[NUM_PROPERTIES] = {
0xf5f5f5ff, // GLOBAL_BASE_COLOR, 0xf5f5f5ff, // GLOBAL_BASE_COLOR,
0xf5f5f5ff, // GLOBAL_BORDER_COLOR, 0xf5f5f5ff, // GLOBAL_BORDER_COLOR,
@ -157,6 +170,30 @@ static int style[NUM_PROPERTIES] = {
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
static Color ColorMultiply(Color baseColor, float value); static Color ColorMultiply(Color baseColor, float value);
#if defined RAYGUI_STANDALONE
static Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
static int GetHexValue(Color color); // Returns hexadecimal value for a Color
static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
static const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
// NOTE: raygui depend on some raylib input and drawing functions
// TODO: Set your own functions
static Vector2 GetMousePosition() { return (Vector2){ 0.0f, 0.0f }; }
static int IsMouseButtonDown(int button) { return 0; }
static int IsMouseButtonPressed(int button) { return 0; }
static int IsMouseButtonReleased(int button) { return 0; }
static int IsMouseButtonUp(int button) { return 0; }
static int GetKeyPressed(void) { return 0; } // NOTE: Only used by GuiTextBox()
static int IsKeyDown(int key) { return 0; } // NOTE: Only used by GuiSpinner()
static int MeasureText(const char *text, int fontSize) { return 0; }
static void DrawText(const char *text, int posX, int posY, int fontSize, Color color) { }
static void DrawRectangleRec(Rectangle rec, Color color) { }
static void DrawRectangle(int posX, int posY, int width, int height, Color color) { DrawRectangleRec((Rectangle){ posX, posY, width, height }, color); }
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Definition // Module Functions Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -164,7 +201,9 @@ static Color ColorMultiply(Color baseColor, float value);
// Label element, show text // Label element, show text
void GuiLabel(Rectangle bounds, const char *text) void GuiLabel(Rectangle bounds, const char *text)
{ {
GuiLabelEx(bounds,text, GetColor(style[LABEL_TEXT_COLOR]), BLANK, BLANK); #define BLANK (Color){ 0, 0, 0, 0 } // Blank (Transparent)
GuiLabelEx(bounds, text, GetColor(style[LABEL_TEXT_COLOR]), BLANK, BLANK);
} }
// Label element extended, configurable colors // Label element extended, configurable colors
@ -173,7 +212,7 @@ void GuiLabelEx(Rectangle bounds, const char *text, Color textColor, Color borde
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
int textWidth = MeasureText(text, style[GLOBAL_TEXT_FONTSIZE]); int textWidth = MeasureText(text, style[GLOBAL_TEXT_FONTSIZE]);
int textHeight = GetDefaultFont().size; int textHeight = style[GLOBAL_TEXT_FONTSIZE];
if (bounds.width < textWidth) bounds.width = textWidth + style[LABEL_TEXT_PADDING]; if (bounds.width < textWidth) bounds.width = textWidth + style[LABEL_TEXT_PADDING];
if (bounds.height < textHeight) bounds.height = textHeight + style[LABEL_TEXT_PADDING]/2; if (bounds.height < textHeight) bounds.height = textHeight + style[LABEL_TEXT_PADDING]/2;
@ -194,7 +233,7 @@ bool GuiButton(Rectangle bounds, const char *text)
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
int textWidth = MeasureText(text, style[GLOBAL_TEXT_FONTSIZE]); int textWidth = MeasureText(text, style[GLOBAL_TEXT_FONTSIZE]);
int textHeight = GetDefaultFont().size; int textHeight = style[GLOBAL_TEXT_FONTSIZE];
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@ -252,7 +291,7 @@ bool GuiToggleButton(Rectangle bounds, const char *text, bool toggle)
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
int textWidth = MeasureText(text, style[GLOBAL_TEXT_FONTSIZE]); int textWidth = MeasureText(text, style[GLOBAL_TEXT_FONTSIZE]);
int textHeight = GetDefaultFont().size; int textHeight = style[GLOBAL_TEXT_FONTSIZE];
// Update control // Update control
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@ -337,7 +376,7 @@ int GuiComboBox(Rectangle bounds, int comboNum, char **comboText, int comboActiv
Rectangle click = { bounds.x + bounds.width + style[COMBOBOX_PADDING], bounds.y, style[COMBOBOX_BUTTON_WIDTH], style[COMBOBOX_BUTTON_HEIGHT] }; Rectangle click = { bounds.x + bounds.width + style[COMBOBOX_PADDING], bounds.y, style[COMBOBOX_BUTTON_WIDTH], style[COMBOBOX_BUTTON_HEIGHT] };
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
int textHeight = GetDefaultFont().size; int textHeight = style[GLOBAL_TEXT_FONTSIZE];
for (int i = 0; i < comboNum; i++) for (int i = 0; i < comboNum; i++)
{ {
@ -627,9 +666,8 @@ int GuiSpinner(Rectangle bounds, int value, int minValue, int maxValue)
Rectangle rightButtonBound = { bounds.x + bounds.width - bounds.width/4 + 1, bounds.y, bounds.width/4, bounds.height }; Rectangle rightButtonBound = { bounds.x + bounds.width - bounds.width/4 + 1, bounds.y, bounds.width/4, bounds.height };
Vector2 mousePoint = GetMousePosition(); Vector2 mousePoint = GetMousePosition();
int textHeight = GetDefaultFont().size;
int textWidth = MeasureText(FormatText("%i", value), style[GLOBAL_TEXT_FONTSIZE]); int textWidth = MeasureText(FormatText("%i", value), style[GLOBAL_TEXT_FONTSIZE]);
int textHeight = style[GLOBAL_TEXT_FONTSIZE];
int buttonSide = 0; int buttonSide = 0;
@ -864,10 +902,11 @@ char *GuiTextBox(Rectangle bounds, char *text)
DrawText(FormatText("%c", text[i]), initPos, bounds.y + style[TEXTBOX_TEXT_FONTSIZE], style[TEXTBOX_TEXT_FONTSIZE], GetColor(style[TEXTBOX_TEXT_COLOR])); DrawText(FormatText("%c", text[i]), initPos, bounds.y + style[TEXTBOX_TEXT_FONTSIZE], style[TEXTBOX_TEXT_FONTSIZE], GetColor(style[TEXTBOX_TEXT_COLOR]));
initPos += ((GetDefaultFont().charRecs[(int)text[i] - 32].width + 2)); initPos += (MeasureText(FormatText("%c", text[i]), style[GLOBAL_TEXT_FONTSIZE]) + 2);
//initPos += ((GetDefaultFont().charRecs[(int)text[i] - 32].width + 2));
} }
if ((framesCounter/20)%2 && CheckCollisionPointRec(mousePoint, bounds)) DrawLine(initPos + 2, bounds.y + 5, initPos + 2, bounds.y + 10 + 15, GetColor(style[TEXTBOX_LINE_COLOR])); if ((framesCounter/20)%2 && CheckCollisionPointRec(mousePoint, bounds)) DrawRectangle(initPos + 2, bounds.y + 5, 1, 20, GetColor(style[TEXTBOX_LINE_COLOR]));
//-------------------------------------------------------------------- //--------------------------------------------------------------------
return text; return text;
@ -1051,4 +1090,50 @@ static Color ColorMultiply(Color baseColor, float value)
multColor.b += (255 - multColor.b)*value; multColor.b += (255 - multColor.b)*value;
return multColor; return multColor;
} }
#if defined (RAYGUI_STANDALONE)
// Returns a Color struct from hexadecimal value
static Color GetColor(int hexValue)
{
Color color;
color.r = (unsigned char)(hexValue >> 24) & 0xFF;
color.g = (unsigned char)(hexValue >> 16) & 0xFF;
color.b = (unsigned char)(hexValue >> 8) & 0xFF;
color.a = (unsigned char)hexValue & 0xFF;
return color;
}
// Returns hexadecimal value for a Color
static int GetHexValue(Color color)
{
return (((int)color.r << 24) | ((int)color.g << 16) | ((int)color.b << 8) | (int)color.a);
}
// Check if point is inside rectangle
static bool CheckCollisionPointRec(Vector2 point, Rectangle rec)
{
bool collision = false;
if ((point.x >= rec.x) && (point.x <= (rec.x + rec.width)) && (point.y >= rec.y) && (point.y <= (rec.y + rec.height))) collision = true;
return collision;
}
// Formatting of text with variables to 'embed'
static const char *FormatText(const char *text, ...)
{
#define MAX_FORMATTEXT_LENGTH 64
static char buffer[MAX_FORMATTEXT_LENGTH];
va_list args;
va_start(args, text);
vsprintf(buffer, text, args);
va_end(args);
return buffer;
}
#endif

View File

@ -23,16 +23,49 @@
#ifndef RAYGUI_H #ifndef RAYGUI_H
#define RAYGUI_H #define RAYGUI_H
#include "raylib.h" //#include "raylib.h"
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#define NUM_PROPERTIES 98 #define NUM_PROPERTIES 98
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
// NOTE: Some types are required for RAYGUI_STANDALONE usage
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#if defined(RAYGUI_STANDALONE)
#ifndef __cplusplus
// Boolean type
#ifndef true
typedef enum { false, true } bool;
#endif
#endif
// Vector2 type
typedef struct Vector2 {
float x;
float y;
} Vector2;
// Color type, RGBA (32bit)
typedef struct Color {
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
} Color;
// Rectangle type
typedef struct Rectangle {
int x;
int y;
int width;
int height;
} Rectangle;
#endif
// Gui properties enumeration
typedef enum GuiProperty { typedef enum GuiProperty {
GLOBAL_BASE_COLOR = 0, GLOBAL_BASE_COLOR = 0,
GLOBAL_BORDER_COLOR, GLOBAL_BORDER_COLOR,

View File

@ -350,7 +350,7 @@ typedef struct Camera {
Vector3 position; // Camera position Vector3 position; // Camera position
Vector3 target; // Camera target it looks-at Vector3 target; // Camera target it looks-at
Vector3 up; // Camera up vector (rotation over its axis) Vector3 up; // Camera up vector (rotation over its axis)
float fovy; // Field-Of-View apperture in Y (degrees) float fovy; // Camera field-of-view apperture in Y (degrees)
} Camera; } Camera;
// Camera2D type, defines a 2d camera // Camera2D type, defines a 2d camera
@ -363,87 +363,84 @@ typedef struct Camera2D {
// Bounding box type // Bounding box type
typedef struct BoundingBox { typedef struct BoundingBox {
Vector3 min; Vector3 min; // minimum vertex box-corner
Vector3 max; Vector3 max; // maximum vertex box-corner
} BoundingBox; } BoundingBox;
// Vertex data definning a mesh // Vertex data definning a mesh
typedef struct Mesh { typedef struct Mesh {
int vertexCount; // number of vertices stored in arrays int vertexCount; // number of vertices stored in arrays
int triangleCount; // number of triangles stored (indexed or not) int triangleCount; // number of triangles stored (indexed or not)
float *vertices; // vertex position (XYZ - 3 components per vertex) (shader-location = 0) float *vertices; // vertex position (XYZ - 3 components per vertex) (shader-location = 0)
float *texcoords; // vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) float *texcoords; // vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
float *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5) float *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2) float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
float *tangents; // vertex tangents (XYZ - 3 components per vertex) (shader-location = 4) float *tangents; // vertex tangents (XYZ - 3 components per vertex) (shader-location = 4)
unsigned char *colors; // vertex colors (RGBA - 4 components per vertex) (shader-location = 3) unsigned char *colors; // vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
unsigned short *indices; // vertex indices (in case vertex data comes indexed) unsigned short *indices;// vertex indices (in case vertex data comes indexed)
BoundingBox bounds; // mesh limits defined by min and max points unsigned int vaoId; // OpenGL Vertex Array Object id
unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
unsigned int vaoId; // OpenGL Vertex Array Object id
unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
} Mesh; } Mesh;
// Shader type (generic shader) // Shader type (generic shader)
typedef struct Shader { typedef struct Shader {
unsigned int id; // Shader program id unsigned int id; // Shader program id
// Vertex attributes locations (default locations) // Vertex attributes locations (default locations)
int vertexLoc; // Vertex attribute location point (default-location = 0) int vertexLoc; // Vertex attribute location point (default-location = 0)
int texcoordLoc; // Texcoord attribute location point (default-location = 1) int texcoordLoc; // Texcoord attribute location point (default-location = 1)
int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5) int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5)
int normalLoc; // Normal attribute location point (default-location = 2) int normalLoc; // Normal attribute location point (default-location = 2)
int tangentLoc; // Tangent attribute location point (default-location = 4) int tangentLoc; // Tangent attribute location point (default-location = 4)
int colorLoc; // Color attibute location point (default-location = 3) int colorLoc; // Color attibute location point (default-location = 3)
// Uniform locations // Uniform locations
int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader) int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
int tintColorLoc; // Diffuse color uniform location point (fragment shader) int tintColorLoc; // Diffuse color uniform location point (fragment shader)
// Texture map locations (generic for any kind of map) // Texture map locations (generic for any kind of map)
int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0) int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0)
int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1) int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1)
int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2) int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2)
} Shader; } Shader;
// Material type // Material type
typedef struct Material { typedef struct Material {
Shader shader; // Standard shader (supports 3 map textures) Shader shader; // Standard shader (supports 3 map textures)
Texture2D texDiffuse; // Diffuse texture (binded to shader mapTexture0Loc) Texture2D texDiffuse; // Diffuse texture (binded to shader mapTexture0Loc)
Texture2D texNormal; // Normal texture (binded to shader mapTexture1Loc) Texture2D texNormal; // Normal texture (binded to shader mapTexture1Loc)
Texture2D texSpecular; // Specular texture (binded to shader mapTexture2Loc) Texture2D texSpecular; // Specular texture (binded to shader mapTexture2Loc)
Color colTint; // Tint color Color colDiffuse; // Diffuse color
Color colDiffuse; // Diffuse color Color colAmbient; // Ambient color
Color colAmbient; // Ambient color Color colSpecular; // Specular color
Color colSpecular; // Specular color
float glossiness; // Glossiness level (Ranges from 0 to 1000) float glossiness; // Glossiness level (Ranges from 0 to 1000)
} Material; } Material;
// Model type // Model type
typedef struct Model { typedef struct Model {
Mesh mesh; // Vertex data buffers (RAM and VRAM) Mesh mesh; // Vertex data buffers (RAM and VRAM)
Matrix transform; // Local transform matrix Matrix transform; // Local transform matrix
Material material; // Shader and textures data Material material; // Shader and textures data
} Model; } Model;
// Light type // Light type
typedef struct LightData { typedef struct LightData {
unsigned int id; // Light id unsigned int id; // Light unique id
int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
bool enabled; // Light enabled bool enabled; // Light enabled
Vector3 position; // Light position Vector3 position; // Light position
Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target) Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target)
float radius; // Light attenuation radius light intensity reduced with distance (world distance) float radius; // Light attenuation radius light intensity reduced with distance (world distance)
Color diffuse; // Light diffuse color Color diffuse; // Light diffuse color
float intensity; // Light intensity level float intensity; // Light intensity level
float coneAngle; // Light cone max angle: LIGHT_SPOT float coneAngle; // Light cone max angle: LIGHT_SPOT
} LightData, *Light; } LightData, *Light;
// Light types // Light types
@ -861,8 +858,7 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations
void UnloadShader(Shader shader); // Unload a custom shader from memory void UnloadShader(Shader shader); // Unload a custom shader from memory
void SetDefaultShader(void); // Set default shader to be used in batch draw
void SetCustomShader(Shader shader); // Set custom shader to be used in batch draw
Shader GetDefaultShader(void); // Get default shader Shader GetDefaultShader(void); // Get default shader
Shader GetStandardShader(void); // Get default shader Shader GetStandardShader(void); // Get default shader
Texture2D GetDefaultTexture(void); // Get default texture Texture2D GetDefaultTexture(void); // Get default texture
@ -872,7 +868,10 @@ void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // S
void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int) void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4) void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied) void BeginShaderMode(Shader shader); // Begin custom shader drawing
void EndShaderMode(void); // End custom shader drawing (use default shader)
void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)
void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool
void DestroyLight(Light light); // Destroy a light and take it out of the list void DestroyLight(Light light); // Destroy a light and take it out of the list

View File

@ -73,7 +73,7 @@
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#if defined(RAYMATH_STANDALONE) #if defined(RAYMATH_STANDALONE)
// Vector2 type // Vector2 type
typedef struct Vector2 { typedef struct Vector2 {
float x; float x;
float y; float y;

View File

@ -28,41 +28,41 @@
#include "rlgl.h" #include "rlgl.h"
#include <stdio.h> // Standard input / output lib #include <stdio.h> // Standard input / output lib
#include <stdlib.h> // Declares malloc() and free() for memory management, rand() #include <stdlib.h> // Required for: malloc(), free(), rand()
#include <string.h> // Declares strcmp(), strlen(), strtok() #include <string.h> // Required for: strcmp(), strlen(), strtok()
#ifndef RLGL_STANDALONE #ifndef RLGL_STANDALONE
#include "raymath.h" // Required for Vector3 and Matrix functions #include "raymath.h" // Required for Vector3 and Matrix functions
#endif #endif
#if defined(GRAPHICS_API_OPENGL_11) #if defined(GRAPHICS_API_OPENGL_11)
#ifdef __APPLE__ // OpenGL include for OSX #ifdef __APPLE__
#include <OpenGL/gl.h> #include <OpenGL/gl.h> // OpenGL 1.1 library for OSX
#else #else
#include <GL/gl.h> // Basic OpenGL include #include <GL/gl.h> // OpenGL 1.1 library
#endif #endif
#endif #endif
#if defined(GRAPHICS_API_OPENGL_33) #if defined(GRAPHICS_API_OPENGL_33)
#ifdef __APPLE__ // OpenGL include for OSX #ifdef __APPLE__
#include <OpenGL/gl3.h> #include <OpenGL/gl3.h> // OpenGL 3 library for OSX
#else #else
//#define GLEW_STATIC //#define GLEW_STATIC
//#include <GL/glew.h> // GLEW header, includes OpenGL headers //#include <GL/glew.h> // GLEW header, includes OpenGL headers
#include "glad.h" // glad header, includes OpenGL headers #include "glad.h" // GLAD library, includes OpenGL headers
#endif #endif
#endif #endif
#if defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_ES2)
#include <EGL/egl.h> #include <EGL/egl.h> // EGL library
#include <GLES2/gl2.h> #include <GLES2/gl2.h> // OpenGL ES 2.0 library
#include <GLES2/gl2ext.h> #include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library
#endif #endif
#if defined(RLGL_STANDALONE) #if defined(RLGL_STANDALONE)
#include <stdarg.h> // Used for functions with variable number of parameters (TraceLog()) #include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
#endif #endif // NOTE: Used on TraceLog()
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
@ -237,7 +237,7 @@ static Shader LoadDefaultShader(void); // Load default shader (just vertex
static Shader LoadStandardShader(void); // Load standard shader (support materials and lighting) static Shader LoadStandardShader(void); // Load standard shader (support materials and lighting)
static void LoadDefaultShaderLocations(Shader *shader); // Bind default shader locations (attributes and uniforms) static void LoadDefaultShaderLocations(Shader *shader); // Bind default shader locations (attributes and uniforms)
static void UnloadDefaultShader(void); // Unload default shader static void UnloadDefaultShader(void); // Unload default shader
static void UnloadStandardShader(void); // Unload standard shader static void UnloadStandardShader(void); // Unload standard shader
static void LoadDefaultBuffers(void); // Load default internal buffers (lines, triangles, quads) static void LoadDefaultBuffers(void); // Load default internal buffers (lines, triangles, quads)
static void UpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data static void UpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data
@ -256,7 +256,7 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight);
#if defined(RLGL_STANDALONE) #if defined(RLGL_STANDALONE)
static void TraceLog(int msgType, const char *text, ...); static void TraceLog(int msgType, const char *text, ...);
float *MatrixToFloat(Matrix mat); // Converts Matrix to float array float *MatrixToFloat(Matrix mat); // Converts Matrix to float array
#endif #endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -1545,10 +1545,10 @@ void rlglLoadMesh(Mesh *mesh, bool dynamic)
mesh->vboId[5] = 0; // Vertex texcoords2 VBO mesh->vboId[5] = 0; // Vertex texcoords2 VBO
mesh->vboId[6] = 0; // Vertex indices VBO mesh->vboId[6] = 0; // Vertex indices VBO
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
int drawHint = GL_STATIC_DRAW; int drawHint = GL_STATIC_DRAW;
if (dynamic) drawHint = GL_DYNAMIC_DRAW; if (dynamic) drawHint = GL_DYNAMIC_DRAW;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
GLuint vaoId = 0; // Vertex Array Objects (VAO) GLuint vaoId = 0; // Vertex Array Objects (VAO)
GLuint vboId[7]; // Vertex Buffer Objects (VBOs) GLuint vboId[7]; // Vertex Buffer Objects (VBOs)
@ -1674,6 +1674,7 @@ void rlglLoadMesh(Mesh *mesh, bool dynamic)
// Update vertex data on GPU (upload new data to one buffer) // Update vertex data on GPU (upload new data to one buffer)
void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex) void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Activate mesh VAO // Activate mesh VAO
if (vaoSupported) glBindVertexArray(mesh.vaoId); if (vaoSupported) glBindVertexArray(mesh.vaoId);
@ -1729,6 +1730,7 @@ void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex)
//mesh.vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); //mesh.vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
// Now we can modify vertices // Now we can modify vertices
//glUnmapBuffer(GL_ARRAY_BUFFER); //glUnmapBuffer(GL_ARRAY_BUFFER);
#endif
} }
// Draw a 3d mesh with material and transform // Draw a 3d mesh with material and transform
@ -1800,9 +1802,6 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
// Setup shader uniforms for lights // Setup shader uniforms for lights
SetShaderLights(material.shader); SetShaderLights(material.shader);
// Upload to shader material.colSpecular
glUniform4f(glGetUniformLocation(material.shader.id, "colTint"), (float)material.colTint.r/255, (float)material.colTint.g/255, (float)material.colTint.b/255, (float)material.colTint.a/255);
// Upload to shader material.colAmbient // Upload to shader material.colAmbient
glUniform4f(glGetUniformLocation(material.shader.id, "colAmbient"), (float)material.colAmbient.r/255, (float)material.colAmbient.g/255, (float)material.colAmbient.b/255, (float)material.colAmbient.a/255); glUniform4f(glGetUniformLocation(material.shader.id, "colAmbient"), (float)material.colAmbient.r/255, (float)material.colAmbient.g/255, (float)material.colAmbient.b/255, (float)material.colAmbient.a/255);
@ -2157,7 +2156,7 @@ void UnloadShader(Shader shader)
} }
// Set custom shader to be used on batch draw // Set custom shader to be used on batch draw
void SetCustomShader(Shader shader) void BeginShaderMode(Shader shader)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if (currentShader.id != shader.id) if (currentShader.id != shader.id)
@ -2169,10 +2168,10 @@ void SetCustomShader(Shader shader)
} }
// Set default shader to be used in batch draw // Set default shader to be used in batch draw
void SetDefaultShader(void) void EndShaderMode(void)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
SetCustomShader(defaultShader); BeginShaderMode(defaultShader);
#endif #endif
} }
@ -2254,9 +2253,9 @@ void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat)
#endif #endif
} }
// Set blending mode (alpha, additive, multiplied) // Begin blending mode (alpha, additive, multiplied)
// NOTE: Only 3 blending modes predefined // NOTE: Only 3 blending modes supported, default blend mode is alpha
void SetBlendMode(int mode) void BeginBlendMode(int mode)
{ {
if ((blendMode != mode) && (mode < 3)) if ((blendMode != mode) && (mode < 3))
{ {
@ -2274,11 +2273,20 @@ void SetBlendMode(int mode)
} }
} }
// End blending mode (reset to default: alpha blending)
void EndBlendMode(void)
{
BeginBlendMode(BLEND_ALPHA);
}
// Create a new light, initialize it and add to pool // Create a new light, initialize it and add to pool
Light CreateLight(int type, Vector3 position, Color diffuse) Light CreateLight(int type, Vector3 position, Color diffuse)
{ {
Light light = NULL;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Allocate dynamic memory // Allocate dynamic memory
Light light = (Light)malloc(sizeof(LightData)); light = (Light)malloc(sizeof(LightData));
// Initialize light values with generic values // Initialize light values with generic values
light->id = lightsCount; light->id = lightsCount;
@ -2295,13 +2303,18 @@ Light CreateLight(int type, Vector3 position, Color diffuse)
// Increase enabled lights count // Increase enabled lights count
lightsCount++; lightsCount++;
#else
// TODO: Support OpenGL 1.1 lighting system
TraceLog(WARNING, "Lighting currently not supported on OpenGL 1.1");
#endif
return light; return light;
} }
// Destroy a light and take it out of the list // Destroy a light and take it out of the list
void DestroyLight(Light light) void DestroyLight(Light light)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Free dynamic memory allocation // Free dynamic memory allocation
free(lights[light->id]); free(lights[light->id]);
@ -2319,6 +2332,7 @@ void DestroyLight(Light light)
// Decrease enabled physic objects count // Decrease enabled physic objects count
lightsCount--; lightsCount--;
#endif
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -2366,7 +2380,7 @@ static void LoadCompressedTexture(unsigned char *data, int width, int height, in
static unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr) static unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr)
{ {
unsigned int program = 0; unsigned int program = 0;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
GLuint vertexShader; GLuint vertexShader;
GLuint fragmentShader; GLuint fragmentShader;

View File

@ -32,15 +32,15 @@
//#define RLGL_STANDALONE // NOTE: To use rlgl as standalone lib, just uncomment this line //#define RLGL_STANDALONE // NOTE: To use rlgl as standalone lib, just uncomment this line
#ifndef RLGL_STANDALONE #ifndef RLGL_STANDALONE
#include "raylib.h" // Required for typedef(s): Model, Shader, Texture2D #include "raylib.h" // Required for: Model, Shader, Texture2D
#include "utils.h" // Required for function TraceLog() #include "utils.h" // Required for: TraceLog()
#endif #endif
#ifdef RLGL_STANDALONE #ifdef RLGL_STANDALONE
#define RAYMATH_STANDALONE #define RAYMATH_STANDALONE
#endif #endif
#include "raymath.h" // Required for types: Vector3, Matrix #include "raymath.h" // Required for: Vector3, Matrix
// Select desired OpenGL version // Select desired OpenGL version
// NOTE: Those preprocessor defines are only used on rlgl module, // NOTE: Those preprocessor defines are only used on rlgl module,
@ -130,51 +130,43 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
COMPRESSED_ASTC_4x4_RGBA, // 8 bpp COMPRESSED_ASTC_4x4_RGBA, // 8 bpp
COMPRESSED_ASTC_8x8_RGBA // 2 bpp COMPRESSED_ASTC_8x8_RGBA // 2 bpp
} TextureFormat; } TextureFormat;
// Bounding box type
typedef struct BoundingBox {
Vector3 min;
Vector3 max;
} BoundingBox;
// Vertex data definning a mesh // Vertex data definning a mesh
typedef struct Mesh { typedef struct Mesh {
int vertexCount; // number of vertices stored in arrays int vertexCount; // number of vertices stored in arrays
float *vertices; // vertex position (XYZ - 3 components per vertex) (shader-location = 0) int triangleCount; // number of triangles stored (indexed or not)
float *texcoords; // vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) float *vertices; // vertex position (XYZ - 3 components per vertex) (shader-location = 0)
float *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5) float *texcoords; // vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2) float *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
float *tangents; // vertex tangents (XYZ - 3 components per vertex) (shader-location = 4) float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
unsigned char *colors; // vertex colors (RGBA - 4 components per vertex) (shader-location = 3) float *tangents; // vertex tangents (XYZ - 3 components per vertex) (shader-location = 4)
unsigned short *indices; // vertex indices (in case vertex data comes indexed) unsigned char *colors; // vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
int triangleCount; // number of triangles stored (indexed or not) unsigned short *indices;// vertex indices (in case vertex data comes indexed)
BoundingBox bounds; // mesh limits defined by min and max points unsigned int vaoId; // OpenGL Vertex Array Object id
unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
unsigned int vaoId; // OpenGL Vertex Array Object id
unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
} Mesh; } Mesh;
// Shader type (generic shader) // Shader type (generic shader)
typedef struct Shader { typedef struct Shader {
unsigned int id; // Shader program id unsigned int id; // Shader program id
// Vertex attributes locations (default locations) // Vertex attributes locations (default locations)
int vertexLoc; // Vertex attribute location point (default-location = 0) int vertexLoc; // Vertex attribute location point (default-location = 0)
int texcoordLoc; // Texcoord attribute location point (default-location = 1) int texcoordLoc; // Texcoord attribute location point (default-location = 1)
int normalLoc; // Normal attribute location point (default-location = 2) int normalLoc; // Normal attribute location point (default-location = 2)
int colorLoc; // Color attibute location point (default-location = 3) int colorLoc; // Color attibute location point (default-location = 3)
int tangentLoc; // Tangent attribute location point (default-location = 4) int tangentLoc; // Tangent attribute location point (default-location = 4)
int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5) int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5)
// Uniform locations // Uniform locations
int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader) int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
int tintColorLoc; // Color uniform location point (fragment shader) int tintColorLoc; // Color uniform location point (fragment shader)
// Texture map locations (generic for any kind of map) // Texture map locations (generic for any kind of map)
int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0) int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0)
int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1) int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1)
int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2) int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2)
} Shader; } Shader;
// Texture2D type // Texture2D type
@ -196,36 +188,46 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
// Material type // Material type
typedef struct Material { typedef struct Material {
Shader shader; // Standard shader (supports 3 map types: diffuse, normal, specular) Shader shader; // Standard shader (supports 3 map types: diffuse, normal, specular)
Texture2D texDiffuse; // Diffuse texture Texture2D texDiffuse; // Diffuse texture
Texture2D texNormal; // Normal texture Texture2D texNormal; // Normal texture
Texture2D texSpecular; // Specular texture Texture2D texSpecular; // Specular texture
Color colDiffuse; // Diffuse color
Color colAmbient; // Ambient color
Color colSpecular; // Specular color
Color colTint; // Tint color float glossiness; // Glossiness level (Ranges from 0 to 1000)
Color colDiffuse; // Diffuse color
Color colAmbient; // Ambient color
Color colSpecular; // Specular color
float glossiness; // Glossiness level (Ranges from 0 to 1000)
} Material; } Material;
// Camera type, defines a camera position/orientation in 3d space
typedef struct Camera {
Vector3 position; // Camera position
Vector3 target; // Camera target it looks-at
Vector3 up; // Camera up vector (rotation over its axis)
float fovy; // Camera field-of-view apperture in Y (degrees)
} Camera;
// Light type // Light type
typedef struct LightData { typedef struct LightData {
int id; unsigned int id; // Light unique id
int type; // LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
bool enabled; bool enabled; // Light enabled
Vector3 position; Vector3 position; // Light position
Vector3 target; // Used on LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target) Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target)
float radius; // Lost of light intensity with distance (world distance) float radius; // Light attenuation radius light intensity reduced with distance (world distance)
Color diffuse; // Use Vector3 diffuse Color diffuse; // Light diffuse color
float intensity; float intensity; // Light intensity level
float coneAngle; // Spot light max angle float coneAngle; // Light cone max angle: LIGHT_SPOT
} LightData, *Light; } LightData, *Light;
// Light types
typedef enum { LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT } LightType;
// Color blending modes (pre-defined) // Color blending modes (pre-defined)
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode; typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
#endif #endif
@ -317,9 +319,9 @@ void *rlglReadTexturePixels(Texture2D texture); // Read text
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations
void UnloadShader(Shader shader); // Unload a custom shader from memory void UnloadShader(Shader shader); // Unload a custom shader from memory
void SetCustomShader(Shader shader); // Set custom shader to be used in batch draw
void SetDefaultShader(void); // Set default shader to be used in batch draw
Shader GetDefaultShader(void); // Get default shader Shader GetDefaultShader(void); // Get default shader
Shader GetStandardShader(void); // Get default shader
Texture2D GetDefaultTexture(void); // Get default texture Texture2D GetDefaultTexture(void); // Get default texture
int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
@ -327,7 +329,10 @@ void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // S
void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int) void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4) void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied) void BeginShaderMode(Shader shader); // Begin custom shader drawing
void EndShaderMode(void); // End custom shader drawing (use default shader)
void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)
void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool
void DestroyLight(Light light); // Destroy a light and take it out of the list void DestroyLight(Light light); // Destroy a light and take it out of the list

View File

@ -489,7 +489,7 @@ Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2)
retRec.height = rec2.height - dyy; retRec.height = rec2.height - dyy;
} }
} }
if (rec1.width > rec2.width) if (rec1.width > rec2.width)
{ {
if (retRec.width >= rec2.width) retRec.width = rec2.width; if (retRec.width >= rec2.width) retRec.width = rec2.width;

View File

@ -25,16 +25,16 @@
#include "raylib.h" #include "raylib.h"
#include <stdlib.h> // Declares malloc() and free() for memory management #include <stdlib.h> // Required for: malloc(), free()
#include <string.h> // String management functions (just strlen() is used) #include <string.h> // Required for: strlen()
#include <stdarg.h> // Used for functions with variable number of parameters (FormatText()) #include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
#include <stdio.h> // Standard input / output lib #include <stdio.h> // Required for: FILE, fopen(), fclose(), fscanf(), feof(), rewind(), fgets()
#include "utils.h" // Required for function GetExtension() #include "utils.h" // Required for: GetExtension()
// Following libs are used on LoadTTF() // Following libs are used on LoadTTF()
#define STB_TRUETYPE_IMPLEMENTATION #define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h" #include "stb_truetype.h" // Required for: stbtt_BakeFontBitmap()
// Rectangle packing functions (not used at the moment) // Rectangle packing functions (not used at the moment)
//#define STB_RECT_PACK_IMPLEMENTATION //#define STB_RECT_PACK_IMPLEMENTATION

View File

@ -29,8 +29,8 @@
#include "raylib.h" #include "raylib.h"
#include <stdlib.h> // Declares malloc() and free() for memory management #include <stdlib.h> // Required for: malloc(), free()
#include <string.h> // Required for strcmp(), strrchr(), strncmp() #include <string.h> // Required for: strcmp(), strrchr(), strncmp()
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2 #include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2
// Required: rlglLoadTexture() rlDeleteTextures(), // Required: rlglLoadTexture() rlDeleteTextures(),
@ -40,10 +40,12 @@
// NOTE: Includes Android fopen function map // NOTE: Includes Android fopen function map
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" // Used to read image data (multiple formats support) #include "stb_image.h" // Required for: stbi_load()
// NOTE: Used to read image data (multiple formats support)
#define STB_IMAGE_RESIZE_IMPLEMENTATION #define STB_IMAGE_RESIZE_IMPLEMENTATION
#include "stb_image_resize.h" // Used on image scaling function: ImageResize() #include "stb_image_resize.h" // Required for: stbir_resize_uint8()
// NOTE: Used for image scaling on ImageResize()
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
@ -1394,39 +1396,43 @@ void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Co
// NOTE: origin is relative to destination rectangle size // NOTE: origin is relative to destination rectangle size
void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint) void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint)
{ {
if (sourceRec.width < 0) sourceRec.x -= sourceRec.width; // Check if texture is valid
if (sourceRec.height < 0) sourceRec.y -= sourceRec.height; if (texture.id != 0)
{
rlEnableTexture(texture.id); if (sourceRec.width < 0) sourceRec.x -= sourceRec.width;
if (sourceRec.height < 0) sourceRec.y -= sourceRec.height;
rlEnableTexture(texture.id);
rlPushMatrix(); rlPushMatrix();
rlTranslatef(destRec.x, destRec.y, 0); rlTranslatef(destRec.x, destRec.y, 0);
rlRotatef(rotation, 0, 0, 1); rlRotatef(rotation, 0, 0, 1);
rlTranslatef(-origin.x, -origin.y, 0); rlTranslatef(-origin.x, -origin.y, 0);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
rlColor4ub(tint.r, tint.g, tint.b, tint.a); rlColor4ub(tint.r, tint.g, tint.b, tint.a);
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
// Bottom-left corner for texture and quad // Bottom-left corner for texture and quad
rlTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height); rlTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
rlVertex2f(0.0f, 0.0f); rlVertex2f(0.0f, 0.0f);
// Bottom-right corner for texture and quad // Bottom-right corner for texture and quad
rlTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height); rlTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
rlVertex2f(0.0f, destRec.height); rlVertex2f(0.0f, destRec.height);
// Top-right corner for texture and quad // Top-right corner for texture and quad
rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height); rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
rlVertex2f(destRec.width, destRec.height); rlVertex2f(destRec.width, destRec.height);
// Top-left corner for texture and quad // Top-left corner for texture and quad
rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height); rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
rlVertex2f(destRec.width, 0.0f); rlVertex2f(destRec.width, 0.0f);
rlEnd(); rlEnd();
rlPopMatrix(); rlPopMatrix();
rlDisableTexture(); rlDisableTexture();
}
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@ -35,14 +35,14 @@
#include <android/asset_manager.h> #include <android/asset_manager.h>
#endif #endif
#include <stdlib.h> // malloc(), free() #include <stdlib.h> // Required for: malloc(), free()
#include <stdio.h> // printf(), fprintf() #include <stdio.h> // Required for: fopen(), fclose(), fputc(), fwrite(), printf(), fprintf(), funopen()
#include <stdarg.h> // Used for functions with variable number of parameters (TraceLog()) #include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
//#include <string.h> // String management functions: strlen(), strrchr(), strcmp() //#include <string.h> // Required for: strlen(), strrchr(), strcmp()
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
#define STB_IMAGE_WRITE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h" // Create PNG file #include "stb_image_write.h" // Required for: stbi_write_png()
#endif #endif
#include "tinfl.c" #include "tinfl.c"

View File

@ -27,8 +27,8 @@
#define UTILS_H #define UTILS_H
#if defined(PLATFORM_ANDROID) #if defined(PLATFORM_ANDROID)
#include <stdio.h> // Defines FILE struct #include <stdio.h> // Required for: FILE
#include <android/asset_manager.h> // defines AAssetManager struct #include <android/asset_manager.h> // Required for: AAssetManager
#endif #endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------