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.
///
/// \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
/// of the two vectors for both eyes.
/// \param[out] outEyePoses If outEyePoses are used for rendering, they should be passed to
/// ovr_SubmitFrame in ovrLayerEyeFov::RenderPose or ovrLayerEyeFovDepth::RenderPose.
///
OVR_PUBLIC_FUNCTION(void) ovr_CalcEyePoses(ovrPosef headPose,
const ovrVector3f HmdToEyeOffset[2],
const ovrVector3f hmdToEyeOffset[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] frameIndex Specifies the targeted frame index, or 0 to refer to one frame after
/// 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
/// the "App-to-Mid-Photon" latency timer starts from. If a given ovrLayer
/// 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] 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,
const ovrVector3f HmdToEyeOffset[2],
const ovrVector3f hmdToEyeOffset[2],
ovrPosef outEyePoses[2],
double* outSensorSampleTime);

View File

@ -1,7 +1,7 @@
/********************************************************************************//**
\file OVR_Math.h
\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
@ -1754,7 +1754,7 @@ public:
: Rotation(s.Rotation), Translation(s.Translation)
{
// 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();
}

View File

@ -1,7 +1,7 @@
/********************************************************************************//**
\file OVR_CAPI.h
\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.
@ -687,6 +687,11 @@ typedef enum ovrTextureMiscFlags_
/// call. This flag requires that RenderTarget binding also be specified.
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.
} ovrTextureFlags;
@ -695,7 +700,7 @@ typedef enum ovrTextureMiscFlags_
/// \see ovr_CreateTextureSwapChainDX
/// \see ovr_CreateTextureSwapChainGL
///
typedef struct
typedef struct ovrTextureSwapChainDesc_
{
ovrTextureType Type;
ovrTextureFormat Format;
@ -705,7 +710,7 @@ typedef struct
int MipLevels;
int SampleCount; ///< Current only supported on depth textures
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.
} ovrTextureSwapChainDesc;
@ -714,12 +719,12 @@ typedef struct
/// \see ovr_CreateMirrorTextureDX
/// \see ovr_CreateMirrorTextureGL
///
typedef struct
typedef struct ovrMirrorTextureDesc_
{
ovrTextureFormat Format;
int Width;
int Height;
unsigned int MiscFlags; ///< ovrTextureMiscFlags
unsigned int MiscFlags; ///< ovrTextureFlags
} ovrMirrorTextureDesc;
typedef struct ovrTextureSwapChainData* ovrTextureSwapChain;
@ -987,8 +992,8 @@ extern "C" {
/// Initializes LibOVR
///
/// 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
/// unless ovr_Initialize succeeds. A successful call to ovr_Initialize must be eventually
/// shared library. No LibOVR API functions, other than ovr_GetLastErrorInfo and ovr_Detect, can
/// 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.
/// Calling ovr_Initialize twice does not require two matching calls to ovr_Shutdown.
/// 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
/// to display pixels at the center of distortion. 1.0 is the default value. Lower
/// 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.
///
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>
/// \code{.cpp}
/// ovr_GetTextureSwapChainBuffer(session, chain, 0, IID_ID3D11Texture2D, &d3d11Texture);
/// ovr_GetTextureSwapChainBuffer(session, chain, 1, IID_PPV_ARGS(&dxgiResource));
/// ovr_GetTextureSwapChainBufferDX(session, chain, 0, IID_ID3D11Texture2D, &d3d11Texture);
/// ovr_GetTextureSwapChainBufferDX(session, chain, 1, IID_PPV_ARGS(&dxgiResource));
/// \endcode
///
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
/// 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_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
/// 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,
ovrMirrorTexture mirrorTexture,
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_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_ServiceDeadlockDetected = -1014, ///< The service watchdog discovered a deadlock.
/* Audio error range, reserved for Audio errors. */
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_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_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_TrackerFirmwareMismatch = -4101, ///< The sensor Firmware is out of date and is unacceptable.
ovrError_BootloaderDeviceDetected = -4102, ///< A bootloader HMD is detected by the service.
ovrError_TrackerCalibrationError = -4103, ///< The sensor calibration is missing or incorrect.
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_IMURateError = -4201, ///< IMU rate is outside of the expected range.
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 */
ovrError_Incomplete = -5000, ///<Requested async work not yet complete.
ovrError_Abandoned = -5001, ///<Requested async work was abandoned and result is incomplete.
ovrError_Incomplete = -5000, ///< Requested async work not yet complete.
ovrError_Abandoned = -5001, ///< Requested async work was abandoned and result is incomplete.
/* Rendering errors */
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_TextureSwapChainInvalid = -6002, ///<The ovrTextureSwapChain is in an incomplete or inconsistent state. Ensure ovr_CommitTextureSwapChain was called at least once first.
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_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 */
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
#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_MINOR_VERSION 3 //
#define OVR_MINOR_VERSION 4 //
#define OVR_PATCH_VERSION 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]
*
* Compile rlgl using:
* Compile rlgl module 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
* 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)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
@ -21,72 +21,103 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#define GLAD_IMPLEMENTATION
#include "glad.h" // Extensions loading library
#include <GLFW/glfw3.h> // Windows/Context and inputs management
#include "OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL
#define RLGL_STANDALONE
#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
ovrSession session;
ovrHmdDesc hmdDesc;
ovrGraphicsLuid luid;
#endif
// OVR OpenGL required variables
GLuint fbo = 0;
GLuint depthBuffer = 0;
ovrTextureSwapChain eyeTexture;
unsigned int frameIndex = 0;
GLuint mirrorFbo = 0;
ovrMirrorTexture mirrorTexture;
ovrEyeRenderDesc eyeRenderDescs[2];
Matrix eyeProjections[2];
ovrLayerEyeFov eyeLayer;
ovrViewScaleDesc viewScaleDesc;
Vector2 renderTargetSize = { 0, 0 };
Vector2 mirrorSize;
unsigned int frame = 0;
// GLFW variables
GLFWwindow *window = NULL;
#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
//----------------------------------------------------------------------------------
// 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;
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
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 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);
#if defined(PLATFORM_OCULUS)
// Oculus Rift functions
static Matrix FromOvrMatrix(ovrMatrix4f ovrM);
void DrawGrid(int slices, float spacing);
void DrawCube(Vector3 position, float width, float height, float length, Color color);
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 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
//----------------------------------------------------------------------------------
int main()
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 1080;
int screenHeight = 600;
#if defined(PLATFORM_OCULUS)
ovrResult result = ovr_Initialize(NULL);
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: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h);
viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f;
memset(&eyeLayer, 0, sizeof(ovrLayerEyeFov));
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;
screenWidth = hmdDesc.Resolution.w/2;
screenHeight = hmdDesc.Resolution.h/2;
#endif
// GLFW3 Initialization + OpenGL 3.3 Context + Extensions
//--------------------------------------------------------
glfwSetErrorCallback(ErrorCallback);
if (!glfwInit())
{
TraceLog(LOG_WARNING, "GLFW3: Can not initialize GLFW");
@ -149,9 +157,8 @@ int main()
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
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? --> NO
window = glfwCreateWindow(mirrorSize.x, mirrorSize.y, "raylib oculus sample", NULL, NULL);
GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight, "raylib oculus sample", NULL, NULL);
if (!window)
{
@ -160,146 +167,129 @@ int main()
}
else TraceLog(LOG_INFO, "GLFW3: Window created successfully");
glfwSetErrorCallback(ErrorCallback);
glfwSetKeyCallback(window, KeyCallback);
glfwMakeContextCurrent(window);
glfwSwapInterval(0);
// 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 OVR OpenGL swap chain textures
ovrTextureSwapChainDesc desc = {};
desc.Type = ovrTexture_2D;
desc.ArraySize = 1;
desc.Width = renderTargetSize.x;
desc.Height = renderTargetSize.y;
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);
#if defined(PLATFORM_OCULUS)
// Initialize Oculus Buffers
OculusLayer layer = InitOculusLayer(session);
OculusBuffer buffer = LoadOculusBuffer(session, layer.width, layer.height);
OculusMirror mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2);
layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain);
// Recenter OVR tracking origin
ovr_RecenterTrackingOrigin(session);
#endif
// Initialize rlgl internal buffers and OpenGL state
rlglInit();
rlglInitGraphics(0, 0, mirrorSize.x, mirrorSize.y);
rlClearColor(245, 245, 245, 255); // Define clear color
glEnable(GL_DEPTH_TEST);
rlglInitGraphics(0, 0, screenWidth, screenHeight);
rlClearColor(245, 245, 245, 255); // Define clear color
rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
Vector2 position = { mirrorSize.x/2 - 100, mirrorSize.y/2 - 100 };
Vector2 size = { 200, 200 };
Color color = { 180, 20, 20, 255 };
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
//----------------------------------------------------------------------------------
frame++;
#if defined(PLATFORM_OCULUS)
frameIndex++;
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
//----------------------------------------------------------------------------------
int curIndex;
ovr_GetTextureSwapChainCurrentIndex(session, eyeTexture, &curIndex);
GLuint curTexId;
ovr_GetTextureSwapChainBufferGL(session, eyeTexture, curIndex, &curTexId);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, curTexId, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#if defined(PLATFORM_OCULUS)
SetOculusBuffer(session, buffer);
#endif
rlClearScreenBuffers(); // Clear current framebuffers
#if defined(PLATFORM_OCULUS)
for (int eye = 0; eye < 2; eye++)
{
glViewport(eyeLayer.Viewport[eye].Pos.x, eyeLayer.Viewport[eye].Pos.y,
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));
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);
// NOTE: Nothing is drawn until rlglDraw()
DrawRectangleV(position, size, color);
//DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, color);
//DrawGrid(10, 1.0f);
// NOTE: rlglDraw() must be modified to support an external modelview-projection matrix
// TODO: Still working on it (now uses internal mvp)
Quaternion eyeRPose = (Quaternion){ eyePoses[eye].Orientation.x, eyePoses[eye].Orientation.y, eyePoses[eye].Orientation.z, eyePoses[eye].Orientation.w };
QuaternionInvert(&eyeRPose);
Matrix eyeOrientation = QuaternionToMatrix(eyeRPose);
Matrix eyeTranslation = MatrixTranslate(-eyePoses[eye].Position.x, -eyePoses[eye].Position.y, -eyePoses[eye].Position.z);
Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation);
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);
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);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
ovr_CommitTextureSwapChain(session, eyeTexture);
ovrLayerHeader *headerList = &eyeLayer.Header;
ovr_SubmitFrame(session, frame, &viewScaleDesc, &headerList, 1);
UnsetOculusBuffer(buffer);
ovr_CommitTextureSwapChain(session, buffer.textureChain);
ovrLayerHeader *layers = &layer.eyeLayer.Header;
ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1);
// Blit mirror texture to back buffer
GLuint mirrorTextureId;
ovr_GetMirrorTextureBufferGL(session, mirrorTexture, &mirrorTextureId);
glBindFramebuffer(GL_READ_FRAMEBUFFER, mirrorFbo);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mirrorTextureId, 0);
glBlitFramebuffer(0, 0, mirrorSize.x, mirrorSize.y, 0, mirrorSize.y, mirrorSize.x, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
BlitOculusMirror(session, mirror);
// 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);
#endif
glfwSwapBuffers(window);
glfwPollEvents();
//----------------------------------------------------------------------------------
@ -307,20 +297,20 @@ int main()
// De-Initialization
//--------------------------------------------------------------------------------------
if (mirrorFbo) glDeleteFramebuffers(1, &mirrorFbo);
if (mirrorTexture) ovr_DestroyMirrorTexture(session, mirrorTexture);
#if defined(PLATFORM_OCULUS)
UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer
UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers
#endif
if (fbo) glDeleteFramebuffers(1, &fbo);
if (depthBuffer) glDeleteTextures(1, &depthBuffer);
if (eyeTexture) ovr_DestroyTextureSwapChain(session, eyeTexture);
rlglClose();
rlglClose(); // Unload rlgl internal buffers and default shader/texture
glfwDestroyWindow(window);
glfwTerminate();
#if defined(PLATFORM_OCULUS)
ovr_Destroy(session); // Must be called after glfwTerminate()
ovr_Shutdown();
#endif
//--------------------------------------------------------------------------------------
return 0;
@ -330,24 +320,22 @@ int main()
// Module specific Functions Definitions
//----------------------------------------------------------------------------------
// Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally)
static void DrawRectangleV(Vector2 position, Vector2 size, Color color)
// GLFW3: Error callback
static void ErrorCallback(int error, const char* description)
{
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
TraceLog(LOG_ERROR, description);
}
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();
// GLFW3: Keyboard callback
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);
}
}
// 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;
@ -370,30 +358,52 @@ static void TraceLog(int msgType, const char *text, ...)
//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;
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;
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();
}
// 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
@ -471,34 +481,279 @@ void DrawCube(Vector3 position, float width, float height, float length, Color c
rlPopMatrix();
}
// Draw a grid centered at (0, 0, 0)
void DrawGrid(int slices, float spacing)
// Draw cube wires
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);
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);
}
rlPushMatrix();
rlVertex3f((float)i*spacing, 0.0f, (float)-halfSlices*spacing);
rlVertex3f((float)i*spacing, 0.0f, (float)halfSlices*spacing);
rlTranslatef(position.x, position.y, position.z);
//rlRotatef(45, 0, 1, 0);
rlVertex3f((float)-halfSlices*spacing, 0.0f, (float)i*spacing);
rlVertex3f((float)halfSlices*spacing, 0.0f, (float)i*spacing);
}
rlEnd();
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();
}
#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
*
* 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)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
@ -18,23 +18,168 @@
*
********************************************************************************************/
#include "glad.h"
#include <GLFW/glfw3.h>
#define GLAD_IMPLEMENTATION
#include "glad.h" // Extensions loading library
#include <GLFW/glfw3.h> // Windows/Context and inputs management
#define RLGL_STANDALONE
#include "rlgl.h"
#include <stdlib.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
//----------------------------------------------------------------------------------
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)
{
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);
//----------------------------------------------------------------------------------
// Main Entry point
//----------------------------------------------------------------------------------
int main(void)
// Output a trace log message
static void TraceLog(int msgType, const char *text, ...)
{
const int screenWidth = 800;
const int screenHeight = 450;
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);
va_list args;
va_start(args, text);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
switch(msgType)
{
printf("Cannot load GL extensions.\n");
exit(1);
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;
}
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 };
while (!glfwWindowShouldClose(window))
{
rlClearScreenBuffers();
DrawRectangleV(position, size, color);
rlglDraw();
glfwSwapBuffers(window);
glfwPollEvents();
}
rlglClose();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
vfprintf(stdout, text, args);
fprintf(stdout, "\n");
va_end(args);
//if (msgType == LOG_ERROR) exit(1);
}
//----------------------------------------------------------------------------------
// Module specific Functions Definitions
//----------------------------------------------------------------------------------
void DrawRectangleV(Vector2 position, Vector2 size, Color color)
// 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);
@ -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);
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)
// Vector2 type
// Vector2 type
typedef struct Vector2 {
float x;
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 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 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
@ -908,6 +909,23 @@ RMDEF void QuaternionNormalize(Quaternion *q)
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
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_8x8_RGBA // 2 bpp
} TextureFormat;
// Bounding box type
typedef struct BoundingBox {
Vector3 min;
Vector3 max;
} BoundingBox;
// Mesh with vertex data type
// NOTE: If using OpenGL 1.1, data loaded in CPU; if OpenGL 3.3+ data loaded in GPU (vaoId)
// Vertex data definning a mesh
typedef struct Mesh {
int vertexCount; // num vertices
float *vertices; // vertex position (XYZ - 3 components per vertex)
float *texcoords; // vertex texture coordinates (UV - 2 components per vertex)
float *texcoords2; // vertex second texture coordinates (useful for lightmaps)
float *normals; // vertex normals (XYZ - 3 components per vertex)
float *tangents; // vertex tangents (XYZ - 3 components per vertex)
unsigned char *colors; // vertex colors (RGBA - 4 components per vertex)
BoundingBox bounds; // mesh limits defined by min and max points
unsigned int vaoId; // OpenGL Vertex Array Object id
unsigned int vboId[6]; // OpenGL Vertex Buffer Objects id (6 types of vertex data)
int vertexCount; // number of vertices stored in arrays
int triangleCount; // number of triangles stored (indexed or not)
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 *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
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 short *indices;// vertex indices (in case vertex data comes indexed)
unsigned int vaoId; // OpenGL Vertex Array Object id
unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
} Mesh;
// Shader type
// Shader type (generic shader)
typedef struct Shader {
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)
unsigned int id; // Shader program id
int mapDiffuseLoc; // Diffuse map texture uniform location point (fragment shader)
int mapNormalLoc; // Normal map texture uniform location point (fragment shader)
int mapSpecularLoc; // Specular map texture uniform location point (fragment shader)
// Vertex attributes locations (default locations)
int vertexLoc; // Vertex attribute location point (default-location = 0)
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;
// Texture2D type
@ -192,27 +188,46 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
// Material type
typedef struct Material {
Shader shader;
Shader shader; // Standard shader (supports 3 map types: diffuse, normal, specular)
Texture2D texDiffuse; // Diffuse texture
Texture2D texNormal; // Normal texture
Texture2D texSpecular; // Specular texture
Texture2D texDiffuse; // Diffuse texture
Texture2D texNormal; // Normal texture
Texture2D texSpecular; // Specular texture
Color colDiffuse; // Diffuse color
Color colAmbient; // Ambient color
Color colSpecular; // Specular color
Color colDiffuse;
Color colAmbient;
Color colSpecular;
float glossiness;
float normalDepth;
float glossiness; // Glossiness level (Ranges from 0 to 1000)
} 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)
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
#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 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 rlViewport(int x, int y, int width, int height); // Set the viewport area
//------------------------------------------------------------------------------------
// 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 rlEnableDepthTest(void); // Enable 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 rlDeleteRenderTextures(RenderTexture2D target); // Delete render textures (fbo) 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 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)
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 rlglGenerateMipmaps(Texture2D texture); // Generate mipmap data for selected texture
// 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
Model rlglLoadModel(Mesh mesh); // Upload vertex data into GPU and provided VAO/VBO ids
void rlglDrawModel(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color color, bool wires);
void rlglLoadMesh(Mesh *mesh, bool dynamic); // Upload vertex data into GPU and provided VAO/VBO ids
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
void rlglUnloadMesh(Mesh *mesh); // Unload mesh data from CPU and GPU
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)
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)
//------------------------------------------------------------------------------------
// Shaders System Functions (Module: rlgl)
// NOTE: This functions are useless when using OpenGL 1.1
//------------------------------------------------------------------------------------
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 SetCustomShader(Shader shader); // Set custom shader to be used in batch draw
void SetDefaultShader(void); // Set default shader to be used in batch draw
void SetModelShader(Model *model, Shader shader); // Link a shader to a model
Shader GetDefaultShader(void); // Get default shader
Shader GetStandardShader(void); // Get default shader
Texture2D GetDefaultTexture(void); // Get default texture
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 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 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
#ifdef __cplusplus

View File

@ -6,7 +6,7 @@ in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 fragTintColor;
uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
@ -16,7 +16,7 @@ out vec4 finalColor;
void main()
{
// 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
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 texture2;
uniform vec4 colTint;
uniform vec4 colAmbient;
uniform vec4 colDiffuse;
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;
}
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)
@ -74,7 +73,7 @@ vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s)
}
// 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)
@ -89,8 +88,10 @@ vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s)
// Spot attenuation
float attenuation = clamp(dot(n, lightToSurface), 0.0, 1.0);
attenuation = dot(lightToSurface, -lightDir);
float lightToSurfaceAngle = degrees(acos(attenuation));
if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0;
float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle;
// 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;
}
return falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb);
return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));
}
void main()
@ -123,7 +124,7 @@ void main()
vec3 lighting = colAmbient.rgb;
// 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 = normalize(n);
@ -131,7 +132,7 @@ void main()
// Calculate specular texture color fetching or set to maximum specular value by default
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++)
{
@ -150,5 +151,5 @@ void main()
}
// 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 };
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
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)
SetCustomShader(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);
SetDefaultShader();
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);
EndShaderMode();
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 };
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
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)
SetCustomShader(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);
SetDefaultShader();
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);
EndShaderMode();
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
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);
DrawRectangleGradient(250 - 90, 170, 180, 130, MAROON, GOLD);
DrawRectangleLines(250 - 40, 320, 80, 60, ORANGE);
DrawRectangle(250 - 60, 90, 120, 60, RED);
DrawRectangleGradient(250 - 90, 170, 180, 130, MAROON, GOLD);
DrawRectangleLines(250 - 40, 320, 80, 60, ORANGE);
// Activate our default shader for next drawings
SetDefaultShader();
EndShaderMode();
DrawText("USING DEFAULT SHADER", 370, 40, 10, RED);
@ -89,12 +89,12 @@ int main()
DrawPoly((Vector2){430, 320}, 6, 80, 0, BROWN);
// 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
SetDefaultShader();
EndShaderMode();
EndDrawing();
//----------------------------------------------------------------------------------

View File

@ -40,9 +40,9 @@ int main()
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.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.colSpecular = (Color){255, 255, 255, 255};
material.colSpecular = WHITE;
material.glossiness = 50.0f;
dwarf.material = material; // Apply material to model

View File

@ -102,20 +102,22 @@ int main()
ClearBackground(DARKGRAY);
SetBlendMode(blending);
BeginBlendMode(blending);
// Draw active particles
for (int i = 0; i < MAX_PARTICLES; i++)
{
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 },
(Vector2){ smoke.width*mouseTail[i].size/2, smoke.height*mouseTail[i].size/2 }, mouseTail[i].rotation,
Fade(mouseTail[i].color, mouseTail[i].alpha));
}
// Draw active particles
for (int i = 0; i < MAX_PARTICLES; i++)
{
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 },
(Vector2){ smoke.width*mouseTail[i].size/2, smoke.height*mouseTail[i].size/2 }, mouseTail[i].rotation,
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);
EndDrawing();

View File

@ -69,12 +69,13 @@ else
endif
# define compiler flags:
# -O1 defines optimization level
# -Wall turns on most, but not all, compiler warnings
# -std=c99 defines C language mode (standard C from 1999 revision)
# -std=gnu99 defines C language mode (GNU C from 1999 revision)
# -fgnu89-inline declaring inline functions support (GCC optimized, faster)
CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline
# -O1 defines optimization level
# -Wall turns on most, but not all, compiler warnings
# -std=c99 defines C language mode (standard C from 1999 revision)
# -std=gnu99 defines C language mode (GNU C from 1999 revision)
# -fgnu89-inline declaring inline functions support (GCC optimized, faster)
# -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

View File

@ -37,24 +37,24 @@
#include "AL/al.h" // OpenAL basic header
#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 <string.h> // Required for strcmp()
#include <stdio.h> // Used for .WAV loading
#include <stdlib.h> // Required for: malloc(), free()
#include <string.h> // Required for: strcmp(), strncmp()
#include <stdio.h> // Required for: FILE, fopen(), fclose(), fread()
#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
#include "utils.h" // rRES data decompression utility function
// NOTE: Includes Android fopen function map
#include "utils.h" // Required for: DecompressData()
// NOTE: Includes Android fopen() function map
#endif
//#define STB_VORBIS_HEADER_ONLY
#include "stb_vorbis.h" // OGG loading functions
#define JAR_XM_IMPLEMENTATION
#include "jar_xm.h" // For playing .xm files
#include "jar_xm.h" // XM loading functions
#define JAR_MOD_IMPLEMENTATION
#include "jar_mod.h" // For playing .mod files

View File

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

View File

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

View File

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

View File

@ -26,16 +26,16 @@
#include "raylib.h"
#if defined(PLATFORM_ANDROID)
#include "utils.h" // Android fopen function map
#include "utils.h" // Android fopen function map
#endif
#include <stdio.h> // Standard input/output functions, used to read model files data
#include <stdlib.h> // Declares malloc() and free() for memory management
#include <string.h> // Required for strcmp()
#include <math.h> // Used for sin, cos, tan
#include <stdio.h> // Required for: FILE, fopen(), fclose(), fscanf(), feof(), rewind(), fgets()
#include <stdlib.h> // Required for: malloc(), free()
#include <string.h> // Required for: strcmp()
#include <math.h> // Required for: sin(), cos()
#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 "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
#include "raymath.h" // Matrix data type and Matrix functions
//----------------------------------------------------------------------------------
// 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?
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);
if (model.mesh.vertexCount == 0) TraceLog(WARNING, "Model could not be loaded");
@ -764,7 +764,7 @@ Material LoadMaterial(const char *fileName)
{
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);
return material;
@ -779,8 +779,7 @@ Material LoadDefaultMaterial(void)
material.texDiffuse = GetDefaultTexture(); // White texture (1x1 pixel)
//material.texNormal; // NOTE: By default, not set
//material.texSpecular; // NOTE: By default, not set
material.colTint = WHITE; // Tint color
material.colDiffuse = WHITE; // Diffuse color
material.colAmbient = WHITE; // Ambient 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
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);
}

View File

@ -29,8 +29,8 @@
#include "raylib.h"
#endif
#include <stdlib.h> // Declares malloc() and free() for memory management
#include <math.h> // Declares cos(), sin(), abs() and fminf() for math operations
#include <stdlib.h> // Required for: malloc(), free()
#include <math.h> // Required for: cos(), sin(), abs(), fminf()
//----------------------------------------------------------------------------------
// 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 <math.h>
#include <stdio.h>
#include <stdlib.h> // Required for malloc(), free()
#include <string.h> // Required for strcmp()
#include <stdio.h> // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf()
// NOTE: Those functions are only used in SaveGuiStyle() and LoadGuiStyle()
#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
//----------------------------------------------------------------------------------
//...
#if defined(RAYGUI_STANDALONE)
#define KEY_LEFT 263
#define KEY_RIGHT 262
#define MOUSE_LEFT_BUTTON 0
#endif
//----------------------------------------------------------------------------------
// Types and Structures Definition
@ -50,7 +63,7 @@ typedef enum { SLIDER_DEFAULT, SLIDER_HOVER, SLIDER_ACTIVE } SliderState;
// Global Variables Definition
//----------------------------------------------------------------------------------
//Current GUI style (default light)
// Current GUI style (default light)
static int style[NUM_PROPERTIES] = {
0xf5f5f5ff, // GLOBAL_BASE_COLOR,
0xf5f5f5ff, // GLOBAL_BORDER_COLOR,
@ -157,6 +170,30 @@ static int style[NUM_PROPERTIES] = {
//----------------------------------------------------------------------------------
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
//----------------------------------------------------------------------------------
@ -164,7 +201,9 @@ static Color ColorMultiply(Color baseColor, float value);
// Label element, show 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
@ -173,7 +212,7 @@ void GuiLabelEx(Rectangle bounds, const char *text, Color textColor, Color borde
// Update control
//--------------------------------------------------------------------
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.height < textHeight) bounds.height = textHeight + style[LABEL_TEXT_PADDING]/2;
@ -194,7 +233,7 @@ bool GuiButton(Rectangle bounds, const char *text)
Vector2 mousePoint = GetMousePosition();
int textWidth = MeasureText(text, style[GLOBAL_TEXT_FONTSIZE]);
int textHeight = GetDefaultFont().size;
int textHeight = style[GLOBAL_TEXT_FONTSIZE];
// Update control
//--------------------------------------------------------------------
@ -252,7 +291,7 @@ bool GuiToggleButton(Rectangle bounds, const char *text, bool toggle)
Vector2 mousePoint = GetMousePosition();
int textWidth = MeasureText(text, style[GLOBAL_TEXT_FONTSIZE]);
int textHeight = GetDefaultFont().size;
int textHeight = style[GLOBAL_TEXT_FONTSIZE];
// 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] };
Vector2 mousePoint = GetMousePosition();
int textHeight = GetDefaultFont().size;
int textHeight = style[GLOBAL_TEXT_FONTSIZE];
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 };
Vector2 mousePoint = GetMousePosition();
int textHeight = GetDefaultFont().size;
int textWidth = MeasureText(FormatText("%i", value), style[GLOBAL_TEXT_FONTSIZE]);
int textHeight = style[GLOBAL_TEXT_FONTSIZE];
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]));
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;
@ -1051,4 +1090,50 @@ static Color ColorMultiply(Color baseColor, float value)
multColor.b += (255 - multColor.b)*value;
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
#define RAYGUI_H
#include "raylib.h"
//#include "raylib.h"
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
#define NUM_PROPERTIES 98
#define NUM_PROPERTIES 98
//----------------------------------------------------------------------------------
// 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 {
GLOBAL_BASE_COLOR = 0,
GLOBAL_BORDER_COLOR,

View File

@ -350,7 +350,7 @@ 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; // Field-Of-View apperture in Y (degrees)
float fovy; // Camera field-of-view apperture in Y (degrees)
} Camera;
// Camera2D type, defines a 2d camera
@ -363,87 +363,84 @@ typedef struct Camera2D {
// Bounding box type
typedef struct BoundingBox {
Vector3 min;
Vector3 max;
Vector3 min; // minimum vertex box-corner
Vector3 max; // maximum vertex box-corner
} BoundingBox;
// Vertex data definning a mesh
typedef struct Mesh {
int vertexCount; // number of vertices stored in arrays
int triangleCount; // number of triangles stored (indexed or not)
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 *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
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 short *indices; // vertex indices (in case vertex data comes indexed)
int vertexCount; // number of vertices stored in arrays
int triangleCount; // number of triangles stored (indexed or not)
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 *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
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 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;
// Shader type (generic shader)
typedef struct Shader {
unsigned int id; // Shader program id
unsigned int id; // Shader program id
// Vertex attributes locations (default locations)
int vertexLoc; // Vertex attribute location point (default-location = 0)
int texcoordLoc; // Texcoord attribute location point (default-location = 1)
int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5)
int normalLoc; // Normal attribute location point (default-location = 2)
int tangentLoc; // Tangent attribute location point (default-location = 4)
int colorLoc; // Color attibute location point (default-location = 3)
int vertexLoc; // Vertex attribute location point (default-location = 0)
int texcoordLoc; // Texcoord attribute location point (default-location = 1)
int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5)
int normalLoc; // Normal attribute location point (default-location = 2)
int tangentLoc; // Tangent attribute location point (default-location = 4)
int colorLoc; // Color attibute location point (default-location = 3)
// Uniform locations
int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
int tintColorLoc; // Diffuse color uniform location point (fragment shader)
int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
int tintColorLoc; // Diffuse 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)
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;
// Material type
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 texNormal; // Normal texture (binded to shader mapTexture1Loc)
Texture2D texSpecular; // Specular texture (binded to shader mapTexture2Loc)
Texture2D texDiffuse; // Diffuse texture (binded to shader mapTexture0Loc)
Texture2D texNormal; // Normal texture (binded to shader mapTexture1Loc)
Texture2D texSpecular; // Specular texture (binded to shader mapTexture2Loc)
Color colTint; // Tint color
Color colDiffuse; // Diffuse color
Color colAmbient; // Ambient color
Color colSpecular; // Specular color
Color colDiffuse; // Diffuse color
Color colAmbient; // Ambient color
Color colSpecular; // Specular color
float glossiness; // Glossiness level (Ranges from 0 to 1000)
float glossiness; // Glossiness level (Ranges from 0 to 1000)
} Material;
// Model type
typedef struct Model {
Mesh mesh; // Vertex data buffers (RAM and VRAM)
Matrix transform; // Local transform matrix
Material material; // Shader and textures data
Mesh mesh; // Vertex data buffers (RAM and VRAM)
Matrix transform; // Local transform matrix
Material material; // Shader and textures data
} Model;
// Light type
typedef struct LightData {
unsigned int id; // Light id
int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
bool enabled; // Light enabled
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)
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
Color diffuse; // Light diffuse color
float intensity; // Light intensity level
float coneAngle; // Light cone max angle: LIGHT_SPOT
float coneAngle; // Light cone max angle: LIGHT_SPOT
} LightData, *Light;
// 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
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 GetStandardShader(void); // Get default shader
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 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

View File

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

View File

@ -28,41 +28,41 @@
#include "rlgl.h"
#include <stdio.h> // Standard input / output lib
#include <stdlib.h> // Declares malloc() and free() for memory management, rand()
#include <string.h> // Declares strcmp(), strlen(), strtok()
#include <stdio.h> // Standard input / output lib
#include <stdlib.h> // Required for: malloc(), free(), rand()
#include <string.h> // Required for: strcmp(), strlen(), strtok()
#ifndef RLGL_STANDALONE
#include "raymath.h" // Required for Vector3 and Matrix functions
#include "raymath.h" // Required for Vector3 and Matrix functions
#endif
#if defined(GRAPHICS_API_OPENGL_11)
#ifdef __APPLE__ // OpenGL include for OSX
#include <OpenGL/gl.h>
#ifdef __APPLE__
#include <OpenGL/gl.h> // OpenGL 1.1 library for OSX
#else
#include <GL/gl.h> // Basic OpenGL include
#include <GL/gl.h> // OpenGL 1.1 library
#endif
#endif
#if defined(GRAPHICS_API_OPENGL_33)
#ifdef __APPLE__ // OpenGL include for OSX
#include <OpenGL/gl3.h>
#ifdef __APPLE__
#include <OpenGL/gl3.h> // OpenGL 3 library for OSX
#else
//#define GLEW_STATIC
//#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
#if defined(GRAPHICS_API_OPENGL_ES2)
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <EGL/egl.h> // EGL library
#include <GLES2/gl2.h> // OpenGL ES 2.0 library
#include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library
#endif
#if defined(RLGL_STANDALONE)
#include <stdarg.h> // Used for functions with variable number of parameters (TraceLog())
#endif
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
#endif // NOTE: Used on TraceLog()
//----------------------------------------------------------------------------------
// 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 void LoadDefaultShaderLocations(Shader *shader); // Bind default shader locations (attributes and uniforms)
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 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)
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
//----------------------------------------------------------------------------------
@ -1545,10 +1545,10 @@ void rlglLoadMesh(Mesh *mesh, bool dynamic)
mesh->vboId[5] = 0; // Vertex texcoords2 VBO
mesh->vboId[6] = 0; // Vertex indices VBO
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
int drawHint = GL_STATIC_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 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)
void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Activate mesh VAO
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);
// Now we can modify vertices
//glUnmapBuffer(GL_ARRAY_BUFFER);
#endif
}
// 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
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
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
void SetCustomShader(Shader shader)
void BeginShaderMode(Shader shader)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if (currentShader.id != shader.id)
@ -2169,10 +2168,10 @@ void SetCustomShader(Shader shader)
}
// 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)
SetCustomShader(defaultShader);
BeginShaderMode(defaultShader);
#endif
}
@ -2254,9 +2253,9 @@ void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat)
#endif
}
// Set blending mode (alpha, additive, multiplied)
// NOTE: Only 3 blending modes predefined
void SetBlendMode(int mode)
// Begin blending mode (alpha, additive, multiplied)
// NOTE: Only 3 blending modes supported, default blend mode is alpha
void BeginBlendMode(int mode)
{
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
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
Light light = (Light)malloc(sizeof(LightData));
light = (Light)malloc(sizeof(LightData));
// Initialize light values with generic values
light->id = lightsCount;
@ -2295,13 +2303,18 @@ Light CreateLight(int type, Vector3 position, Color diffuse)
// Increase enabled lights count
lightsCount++;
#else
// TODO: Support OpenGL 1.1 lighting system
TraceLog(WARNING, "Lighting currently not supported on OpenGL 1.1");
#endif
return light;
}
// Destroy a light and take it out of the list
void DestroyLight(Light light)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Free dynamic memory allocation
free(lights[light->id]);
@ -2319,6 +2332,7 @@ void DestroyLight(Light light)
// Decrease enabled physic objects count
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)
{
unsigned int program = 0;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
GLuint vertexShader;
GLuint fragmentShader;

View File

@ -32,15 +32,15 @@
//#define RLGL_STANDALONE // NOTE: To use rlgl as standalone lib, just uncomment this line
#ifndef RLGL_STANDALONE
#include "raylib.h" // Required for typedef(s): Model, Shader, Texture2D
#include "utils.h" // Required for function TraceLog()
#include "raylib.h" // Required for: Model, Shader, Texture2D
#include "utils.h" // Required for: TraceLog()
#endif
#ifdef RLGL_STANDALONE
#define RAYMATH_STANDALONE
#endif
#include "raymath.h" // Required for types: Vector3, Matrix
#include "raymath.h" // Required for: Vector3, Matrix
// Select desired OpenGL version
// 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_8x8_RGBA // 2 bpp
} TextureFormat;
// Bounding box type
typedef struct BoundingBox {
Vector3 min;
Vector3 max;
} BoundingBox;
// Vertex data definning a mesh
typedef struct Mesh {
int vertexCount; // number of vertices stored in arrays
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 *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
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 short *indices; // vertex indices (in case vertex data comes indexed)
int triangleCount; // number of triangles stored (indexed or not)
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)
int vertexCount; // number of vertices stored in arrays
int triangleCount; // number of triangles stored (indexed or not)
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 *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
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 short *indices;// vertex indices (in case vertex data comes indexed)
unsigned int vaoId; // OpenGL Vertex Array Object id
unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
} Mesh;
// Shader type (generic shader)
typedef struct Shader {
unsigned int id; // Shader program id
unsigned int id; // Shader program id
// Vertex attributes locations (default locations)
int vertexLoc; // Vertex attribute location point (default-location = 0)
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)
int vertexLoc; // Vertex attribute location point (default-location = 0)
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)
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)
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;
// Texture2D type
@ -196,36 +188,46 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
// Material type
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 texNormal; // Normal texture
Texture2D texSpecular; // Specular texture
Texture2D texDiffuse; // Diffuse texture
Texture2D texNormal; // Normal texture
Texture2D texSpecular; // Specular texture
Color colDiffuse; // Diffuse color
Color colAmbient; // Ambient color
Color colSpecular; // Specular color
Color colTint; // Tint color
Color colDiffuse; // Diffuse color
Color colAmbient; // Ambient color
Color colSpecular; // Specular color
float glossiness; // Glossiness level (Ranges from 0 to 1000)
float glossiness; // Glossiness level (Ranges from 0 to 1000)
} 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 {
int id;
int type; // LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
bool enabled;
unsigned int id; // Light unique id
int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
bool enabled; // Light enabled
Vector3 position;
Vector3 target; // Used on LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target)
float radius; // Lost of light intensity with distance (world distance)
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; // Use Vector3 diffuse
float intensity;
Color diffuse; // Light diffuse color
float intensity; // Light intensity level
float coneAngle; // Spot light max angle
float coneAngle; // Light cone max angle: LIGHT_SPOT
} LightData, *Light;
// Light types
typedef enum { LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT } LightType;
// Color blending modes (pre-defined)
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
#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
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 GetStandardShader(void); // Get default shader
Texture2D GetDefaultTexture(void); // Get default texture
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 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

View File

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

View File

@ -25,16 +25,16 @@
#include "raylib.h"
#include <stdlib.h> // Declares malloc() and free() for memory management
#include <string.h> // String management functions (just strlen() is used)
#include <stdarg.h> // Used for functions with variable number of parameters (FormatText())
#include <stdio.h> // Standard input / output lib
#include <stdlib.h> // Required for: malloc(), free()
#include <string.h> // Required for: strlen()
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
#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()
#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"
#include "stb_truetype.h" // Required for: stbtt_BakeFontBitmap()
// Rectangle packing functions (not used at the moment)
//#define STB_RECT_PACK_IMPLEMENTATION

View File

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

View File

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

View File

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