Merge remote-tracking branch 'refs/remotes/raysan5/develop' into develop
This commit is contained in:
commit
4f1bee3165
119 changed files with 41193 additions and 3061 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -62,3 +62,6 @@ xcuserdata/
|
|||
DerivedData/
|
||||
*.dll
|
||||
src/libraylib.a
|
||||
|
||||
# oculus example
|
||||
!examples/oculus_glfw_sample/LibOVRRT32_1.dll
|
|
@ -85,13 +85,13 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
|||
# add standard directories for GNU/Linux
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
INCLUDES = -I. -I../src -I/usr/local/include/raylib/
|
||||
else ifeq ($(PLATFORM_OS),OSX)
|
||||
INCLUDES = -I. -I../src
|
||||
else
|
||||
INCLUDES = -I. -I../../src -IC:/raylib/raylib/src
|
||||
# external libraries headers
|
||||
# GLFW3
|
||||
INCLUDES += -I../../external/glfw3/include
|
||||
# GLEW - Not required any more, replaced by GLAD
|
||||
#INCLUDES += -I../external/glew/include
|
||||
# OpenAL Soft
|
||||
INCLUDES += -I../../external/openal_soft/include
|
||||
endif
|
||||
|
@ -105,6 +105,8 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
|||
# add standard directories for GNU/Linux
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
LFLAGS = -L. -L../../src
|
||||
else ifeq ($(PLATFORM_OS),OSX)
|
||||
LFLAGS = -L. -L../src
|
||||
else
|
||||
LFLAGS = -L. -L../../src -LC:/raylib/raylib/src
|
||||
# external libraries to link with
|
||||
|
@ -113,30 +115,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
|||
ifneq ($(PLATFORM_OS),OSX)
|
||||
# OpenAL Soft
|
||||
LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH)
|
||||
# GLEW: Not used, replaced by GLAD
|
||||
#LFLAGS += -L../../external/glew/lib/$(LIBPATH)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# define library paths containing required libs
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
# add standard directories for GNU/Linux
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
LFLAGS = -L. -L../../src
|
||||
else
|
||||
LFLAGS = -L. -L../../src -LC:/raylib/raylib/src
|
||||
# external libraries to link with
|
||||
# GLFW3
|
||||
LFLAGS += -L../../external/glfw3/lib/$(LIBPATH)
|
||||
ifneq ($(PLATFORM_OS),OSX)
|
||||
# OpenAL Soft
|
||||
LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH)
|
||||
# GLEW
|
||||
LFLAGS += -L../../external/glew/lib/$(LIBPATH)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
@ -147,15 +125,15 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
|||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# libraries for Debian GNU/Linux desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
# libglfw3-dev libopenal-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw3 -lGL -lopenal -lm -pthread -ldl -lX11 \
|
||||
-lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# libraries for OS X 10.9 desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -framework OpenGL -framework OpenAl -framework Cocoa
|
||||
# libglfw3-dev libopenal-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw3 -framework OpenGL -framework OpenAl -framework Cocoa
|
||||
else
|
||||
# libraries for Windows desktop compiling
|
||||
# NOTE: GLFW3 and OpenAL Soft libraries should be installed
|
||||
|
|
|
@ -22,11 +22,14 @@ int main()
|
|||
|
||||
Camera2D camera;
|
||||
|
||||
camera.position = (Vector2){ 0, 0 };
|
||||
camera.origin = (Vector2){ 100, 100 };
|
||||
camera.offset = (Vector2){ 0, 0 };
|
||||
camera.target = (Vector2){ 400, 200 };
|
||||
camera.rotation = 0.0f;
|
||||
camera.zoom = 1.0f;
|
||||
|
||||
Rectangle player = { 400, 200, 40, 40 };
|
||||
camera.target = (Vector2){ player.x + 20, player.y + 20 };
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -35,16 +38,28 @@ int main()
|
|||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyDown(KEY_RIGHT)) camera.position.x--;
|
||||
else if (IsKeyDown(KEY_LEFT)) camera.position.x++;
|
||||
else if (IsKeyDown(KEY_UP)) camera.position.y++;
|
||||
else if (IsKeyDown(KEY_DOWN)) camera.position.y--;
|
||||
if (IsKeyDown(KEY_RIGHT)) player.x -= 2;
|
||||
else if (IsKeyDown(KEY_LEFT)) player.x += 2;
|
||||
else if (IsKeyDown(KEY_UP)) player.y -= 2;
|
||||
else if (IsKeyDown(KEY_DOWN)) player.y += 2;
|
||||
|
||||
// Camera target follows player
|
||||
camera.target = (Vector2){ player.x + 20, player.y + 20 };
|
||||
|
||||
if (IsKeyDown(KEY_R)) camera.rotation--;
|
||||
else if (IsKeyDown(KEY_F)) camera.rotation++;
|
||||
|
||||
if (IsKeyDown(KEY_W)) camera.zoom += 0.005f;
|
||||
if (IsKeyDown(KEY_S)) camera.zoom -= 0.005f;
|
||||
// Camera controls
|
||||
if (IsKeyDown(KEY_R)) camera.rotation--;
|
||||
else if (IsKeyDown(KEY_F)) camera.rotation++;
|
||||
|
||||
camera.zoom += ((float)GetMouseWheelMove()*0.05f);
|
||||
|
||||
if (IsKeyPressed(KEY_Z))
|
||||
{
|
||||
camera.zoom = 1.0f;
|
||||
camera.rotation = 0.0f;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
|
@ -56,7 +71,10 @@ int main()
|
|||
DrawText("2D CAMERA TEST", 20, 20, 20, GRAY);
|
||||
|
||||
DrawRectangle(0, 300, screenWidth, 50, GRAY);
|
||||
DrawRectangle(400, 250, 40, 40, RED);
|
||||
DrawRectangleRec(player, RED);
|
||||
|
||||
DrawRectangle(camera.origin.x, 0, 1, screenHeight, GREEN);
|
||||
DrawRectangle(0, camera.origin.y, screenWidth, 1, GREEN);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
|
@ -34,7 +34,7 @@ int main()
|
|||
|
||||
//SetGesturesEnabled(0b0000000000001001); // Enable only some gestures to be detected
|
||||
|
||||
SetTargetFPS(30);
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
|
@ -43,12 +43,11 @@ int main()
|
|||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
lastGesture = currentGesture;
|
||||
currentGesture = GetGestureDetected();
|
||||
touchPosition = GetTouchPosition(0);
|
||||
|
||||
if (CheckCollisionPointRec(touchPosition, touchArea) && IsGestureDetected())
|
||||
if (CheckCollisionPointRec(touchPosition, touchArea) && (currentGesture != GESTURE_NONE))
|
||||
{
|
||||
currentGesture = GetGestureType();
|
||||
|
||||
if (currentGesture != lastGesture)
|
||||
{
|
||||
// Store gesture string
|
||||
|
@ -62,6 +61,8 @@ int main()
|
|||
case GESTURE_SWIPE_LEFT: strcpy(gestureStrings[gesturesCount], "GESTURE SWIPE LEFT"); break;
|
||||
case GESTURE_SWIPE_UP: strcpy(gestureStrings[gesturesCount], "GESTURE SWIPE UP"); break;
|
||||
case GESTURE_SWIPE_DOWN: strcpy(gestureStrings[gesturesCount], "GESTURE SWIPE DOWN"); break;
|
||||
case GESTURE_PINCH_IN: strcpy(gestureStrings[gesturesCount], "GESTURE PINCH IN"); break;
|
||||
case GESTURE_PINCH_OUT: strcpy(gestureStrings[gesturesCount], "GESTURE PINCH OUT"); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
@ -76,7 +77,6 @@ int main()
|
|||
}
|
||||
}
|
||||
}
|
||||
else currentGesture = GESTURE_NONE;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
|
|
|
@ -43,7 +43,7 @@ int main()
|
|||
UpdateCamera(&camera); // Update internal camera and our camera
|
||||
|
||||
// Calculate cube screen space position (with a little offset to be in top)
|
||||
cubeScreenPosition = WorldToScreen((Vector3){cubePosition.x, cubePosition.y + 2.5f, cubePosition.z}, camera);
|
||||
cubeScreenPosition = GetWorldToScreen((Vector3){cubePosition.x, cubePosition.y + 2.5f, cubePosition.z}, camera);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 49 KiB |
BIN
examples/oculus_glfw_sample/LibOVRRT32_1.dll
Normal file
BIN
examples/oculus_glfw_sample/LibOVRRT32_1.dll
Normal file
Binary file not shown.
|
@ -0,0 +1,196 @@
|
|||
/********************************************************************************//**
|
||||
\file OVR_CAPI_Util.h
|
||||
\brief This header provides LibOVR utility function declarations
|
||||
\copyright Copyright 2015-2016 Oculus VR, LLC All Rights reserved.
|
||||
*************************************************************************************/
|
||||
|
||||
#ifndef OVR_CAPI_Util_h
|
||||
#define OVR_CAPI_Util_h
|
||||
|
||||
|
||||
#include "../OVR_CAPI.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/// Enumerates modifications to the projection matrix based on the application's needs.
|
||||
///
|
||||
/// \see ovrMatrix4f_Projection
|
||||
///
|
||||
typedef enum ovrProjectionModifier_
|
||||
{
|
||||
/// Use for generating a default projection matrix that is:
|
||||
/// * Right-handed.
|
||||
/// * Near depth values stored in the depth buffer are smaller than far depth values.
|
||||
/// * Both near and far are explicitly defined.
|
||||
/// * With a clipping range that is (0 to w).
|
||||
ovrProjection_None = 0x00,
|
||||
|
||||
/// Enable if using left-handed transformations in your application.
|
||||
ovrProjection_LeftHanded = 0x01,
|
||||
|
||||
/// After the projection transform is applied, far values stored in the depth buffer will be less than closer depth values.
|
||||
/// NOTE: Enable only if the application is using a floating-point depth buffer for proper precision.
|
||||
ovrProjection_FarLessThanNear = 0x02,
|
||||
|
||||
/// When this flag is used, the zfar value pushed into ovrMatrix4f_Projection() will be ignored
|
||||
/// NOTE: Enable only if ovrProjection_FarLessThanNear is also enabled where the far clipping plane will be pushed to infinity.
|
||||
ovrProjection_FarClipAtInfinity = 0x04,
|
||||
|
||||
/// Enable if the application is rendering with OpenGL and expects a projection matrix with a clipping range of (-w to w).
|
||||
/// Ignore this flag if your application already handles the conversion from D3D range (0 to w) to OpenGL.
|
||||
ovrProjection_ClipRangeOpenGL = 0x08,
|
||||
} ovrProjectionModifier;
|
||||
|
||||
|
||||
/// Return values for ovr_Detect.
|
||||
///
|
||||
/// \see ovr_Detect
|
||||
///
|
||||
typedef struct OVR_ALIGNAS(8) ovrDetectResult_
|
||||
{
|
||||
/// Is ovrFalse when the Oculus Service is not running.
|
||||
/// This means that the Oculus Service is either uninstalled or stopped.
|
||||
/// IsOculusHMDConnected will be ovrFalse in this case.
|
||||
/// Is ovrTrue when the Oculus Service is running.
|
||||
/// This means that the Oculus Service is installed and running.
|
||||
/// IsOculusHMDConnected will reflect the state of the HMD.
|
||||
ovrBool IsOculusServiceRunning;
|
||||
|
||||
/// Is ovrFalse when an Oculus HMD is not detected.
|
||||
/// If the Oculus Service is not running, this will be ovrFalse.
|
||||
/// Is ovrTrue when an Oculus HMD is detected.
|
||||
/// This implies that the Oculus Service is also installed and running.
|
||||
ovrBool IsOculusHMDConnected;
|
||||
|
||||
OVR_UNUSED_STRUCT_PAD(pad0, 6) ///< \internal struct padding
|
||||
|
||||
} ovrDetectResult;
|
||||
|
||||
OVR_STATIC_ASSERT(sizeof(ovrDetectResult) == 8, "ovrDetectResult size mismatch");
|
||||
|
||||
|
||||
/// Detects Oculus Runtime and Device Status
|
||||
///
|
||||
/// Checks for Oculus Runtime and Oculus HMD device status without loading the LibOVRRT
|
||||
/// shared library. This may be called before ovr_Initialize() to help decide whether or
|
||||
/// not to initialize LibOVR.
|
||||
///
|
||||
/// \param[in] timeoutMilliseconds Specifies a timeout to wait for HMD to be attached or 0 to poll.
|
||||
///
|
||||
/// \return Returns an ovrDetectResult object indicating the result of detection.
|
||||
///
|
||||
/// \see ovrDetectResult
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrDetectResult) ovr_Detect(int timeoutMilliseconds);
|
||||
|
||||
// On the Windows platform,
|
||||
#ifdef _WIN32
|
||||
/// This is the Windows Named Event name that is used to check for HMD connected state.
|
||||
#define OVR_HMD_CONNECTED_EVENT_NAME L"OculusHMDConnected"
|
||||
#endif // _WIN32
|
||||
|
||||
|
||||
/// Used to generate projection from ovrEyeDesc::Fov.
|
||||
///
|
||||
/// \param[in] fov Specifies the ovrFovPort to use.
|
||||
/// \param[in] znear Distance to near Z limit.
|
||||
/// \param[in] zfar Distance to far Z limit.
|
||||
/// \param[in] projectionModFlags A combination of the ovrProjectionModifier flags.
|
||||
///
|
||||
/// \return Returns the calculated projection matrix.
|
||||
///
|
||||
/// \see ovrProjectionModifier
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrMatrix4f) ovrMatrix4f_Projection(ovrFovPort fov, float znear, float zfar, unsigned int projectionModFlags);
|
||||
|
||||
|
||||
/// Extracts the required data from the result of ovrMatrix4f_Projection.
|
||||
///
|
||||
/// \param[in] projection Specifies the project matrix from which to extract ovrTimewarpProjectionDesc.
|
||||
/// \param[in] projectionModFlags A combination of the ovrProjectionModifier flags.
|
||||
/// \return Returns the extracted ovrTimewarpProjectionDesc.
|
||||
/// \see ovrTimewarpProjectionDesc
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrTimewarpProjectionDesc) ovrTimewarpProjectionDesc_FromProjection(ovrMatrix4f projection, unsigned int projectionModFlags);
|
||||
|
||||
|
||||
/// Generates an orthographic sub-projection.
|
||||
///
|
||||
/// Used for 2D rendering, Y is down.
|
||||
///
|
||||
/// \param[in] projection The perspective matrix that the orthographic matrix is derived from.
|
||||
/// \param[in] orthoScale Equal to 1.0f / pixelsPerTanAngleAtCenter.
|
||||
/// \param[in] orthoDistance Equal to the distance from the camera in meters, such as 0.8m.
|
||||
/// \param[in] HmdToEyeOffsetX Specifies the offset of the eye from the center.
|
||||
///
|
||||
/// \return Returns the calculated projection matrix.
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrMatrix4f) ovrMatrix4f_OrthoSubProjection(ovrMatrix4f projection, ovrVector2f orthoScale,
|
||||
float orthoDistance, float HmdToEyeOffsetX);
|
||||
|
||||
|
||||
|
||||
/// 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
|
||||
/// 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],
|
||||
ovrPosef outEyePoses[2]);
|
||||
|
||||
|
||||
/// Returns the predicted head pose in outHmdTrackingState and offset eye poses in outEyePoses.
|
||||
///
|
||||
/// This is a thread-safe function where caller should increment frameIndex with every frame
|
||||
/// and pass that index where applicable to functions called on the rendering thread.
|
||||
/// Assuming outEyePoses are used for rendering, it should be passed as a part of ovrLayerEyeFov.
|
||||
/// The caller does not need to worry about applying HmdToEyeOffset to the returned outEyePoses variables.
|
||||
///
|
||||
/// \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[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],
|
||||
ovrPosef outEyePoses[2],
|
||||
double* outSensorSampleTime);
|
||||
|
||||
|
||||
|
||||
/// Tracking poses provided by the SDK come in a right-handed coordinate system. If an application
|
||||
/// is passing in ovrProjection_LeftHanded into ovrMatrix4f_Projection, then it should also use
|
||||
/// this function to flip the HMD tracking poses to be left-handed.
|
||||
///
|
||||
/// While this utility function is intended to convert a left-handed ovrPosef into a right-handed
|
||||
/// coordinate system, it will also work for converting right-handed to left-handed since the
|
||||
/// flip operation is the same for both cases.
|
||||
///
|
||||
/// \param[in] inPose that is right-handed
|
||||
/// \param[out] outPose that is requested to be left-handed (can be the same pointer to inPose)
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(void) ovrPosef_FlipHandedness(const ovrPosef* inPose, ovrPosef* outPose);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif // Header include guard
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,70 @@
|
|||
/************************************************************************************
|
||||
|
||||
Filename : OVR_StereoProjection.h
|
||||
Content : Stereo projection functions
|
||||
Created : November 30, 2013
|
||||
Authors : Tom Fosyth
|
||||
|
||||
Copyright : Copyright 2014-2016 Oculus VR, LLC All Rights reserved.
|
||||
|
||||
Licensed under the Oculus VR Rift SDK License Version 3.3 (the "License");
|
||||
you may not use the Oculus VR Rift SDK except in compliance with the License,
|
||||
which is provided at the time of installation or download, or which
|
||||
otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.oculusvr.com/licenses/LICENSE-3.3
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Oculus VR SDK
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*************************************************************************************/
|
||||
|
||||
#ifndef OVR_StereoProjection_h
|
||||
#define OVR_StereoProjection_h
|
||||
|
||||
|
||||
#include "Extras/OVR_Math.h"
|
||||
|
||||
|
||||
namespace OVR {
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
// ***** Stereo Enumerations
|
||||
|
||||
// StereoEye specifies which eye we are rendering for; it is used to
|
||||
// retrieve StereoEyeParams.
|
||||
enum StereoEye
|
||||
{
|
||||
StereoEye_Left,
|
||||
StereoEye_Right,
|
||||
StereoEye_Center
|
||||
};
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
// ***** Propjection functions
|
||||
|
||||
Matrix4f CreateProjection ( bool rightHanded, bool isOpenGL, FovPort fov, StereoEye eye,
|
||||
float zNear = 0.01f, float zFar = 10000.0f,
|
||||
bool flipZ = false, bool farAtInfinity = false);
|
||||
|
||||
Matrix4f CreateOrthoSubProjection ( bool rightHanded, StereoEye eyeType,
|
||||
float tanHalfFovX, float tanHalfFovY,
|
||||
float unitsX, float unitsY, float distanceFromCamera,
|
||||
float interpupillaryDistance, Matrix4f const &projection,
|
||||
float zNear = 0.0f, float zFar = 0.0f,
|
||||
bool flipZ = false, bool farAtInfinity = false);
|
||||
|
||||
ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov ( FovPort fov );
|
||||
|
||||
|
||||
} //namespace OVR
|
||||
|
||||
#endif // OVR_StereoProjection_h
|
2103
examples/oculus_glfw_sample/OculusSDK/LibOVR/Include/OVR_CAPI.h
Normal file
2103
examples/oculus_glfw_sample/OculusSDK/LibOVR/Include/OVR_CAPI.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,76 @@
|
|||
/********************************************************************************//**
|
||||
\file OVR_CAPI_Audio.h
|
||||
\brief CAPI audio functions.
|
||||
\copyright Copyright 2015 Oculus VR, LLC. All Rights reserved.
|
||||
************************************************************************************/
|
||||
|
||||
|
||||
#ifndef OVR_CAPI_Audio_h
|
||||
#define OVR_CAPI_Audio_h
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include "OVR_CAPI.h"
|
||||
#define OVR_AUDIO_MAX_DEVICE_STR_SIZE 128
|
||||
|
||||
/// Gets the ID of the preferred VR audio output device.
|
||||
///
|
||||
/// \param[out] deviceOutId The ID of the user's preferred VR audio device to use, which will be valid upon a successful return value, else it will be WAVE_MAPPER.
|
||||
///
|
||||
/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
|
||||
/// ovr_GetLastErrorInfo to get more information.
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutWaveId(UINT* deviceOutId);
|
||||
|
||||
/// Gets the ID of the preferred VR audio input device.
|
||||
///
|
||||
/// \param[out] deviceInId The ID of the user's preferred VR audio device to use, which will be valid upon a successful return value, else it will be WAVE_MAPPER.
|
||||
///
|
||||
/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
|
||||
/// ovr_GetLastErrorInfo to get more information.
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInWaveId(UINT* deviceInId);
|
||||
|
||||
|
||||
/// Gets the GUID of the preferred VR audio device as a string.
|
||||
///
|
||||
/// \param[out] deviceOutStrBuffer A buffer where the GUID string for the device will copied to.
|
||||
///
|
||||
/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
|
||||
/// ovr_GetLastErrorInfo to get more information.
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutGuidStr(WCHAR deviceOutStrBuffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE]);
|
||||
|
||||
|
||||
/// Gets the GUID of the preferred VR audio device.
|
||||
///
|
||||
/// \param[out] deviceOutGuid The GUID of the user's preferred VR audio device to use, which will be valid upon a successful return value, else it will be NULL.
|
||||
///
|
||||
/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
|
||||
/// ovr_GetLastErrorInfo to get more information.
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutGuid(GUID* deviceOutGuid);
|
||||
|
||||
|
||||
/// Gets the GUID of the preferred VR microphone device as a string.
|
||||
///
|
||||
/// \param[out] deviceInStrBuffer A buffer where the GUID string for the device will copied to.
|
||||
///
|
||||
/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
|
||||
/// ovr_GetLastErrorInfo to get more information.
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInGuidStr(WCHAR deviceInStrBuffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE]);
|
||||
|
||||
|
||||
/// Gets the GUID of the preferred VR microphone device.
|
||||
///
|
||||
/// \param[out] deviceInGuid The GUID of the user's preferred VR audio device to use, which will be valid upon a successful return value, else it will be NULL.
|
||||
///
|
||||
/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
|
||||
/// ovr_GetLastErrorInfo to get more information.
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInGuid(GUID* deviceInGuid);
|
||||
|
||||
#endif //OVR_OS_MS
|
||||
|
||||
#endif // OVR_CAPI_Audio_h
|
|
@ -0,0 +1,131 @@
|
|||
/********************************************************************************//**
|
||||
\file OVR_CAPI_D3D.h
|
||||
\brief D3D specific structures used by the CAPI interface.
|
||||
\copyright Copyright 2014-2016 Oculus VR, LLC All Rights reserved.
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef OVR_CAPI_D3D_h
|
||||
#define OVR_CAPI_D3D_h
|
||||
|
||||
#include "OVR_CAPI.h"
|
||||
#include "OVR_Version.h"
|
||||
|
||||
|
||||
#if defined (_WIN32)
|
||||
#include <Unknwn.h>
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
// ***** Direct3D Specific
|
||||
|
||||
/// Create Texture Swap Chain suitable for use with Direct3D 11 and 12.
|
||||
///
|
||||
/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
|
||||
/// \param[in] d3dPtr Specifies the application's D3D11Device to create resources with or the D3D12CommandQueue
|
||||
/// which must be the same one the application renders to the eye textures with.
|
||||
/// \param[in] desc Specifies requested texture properties. See notes for more info about texture format.
|
||||
/// \param[in] bindFlags Specifies what ovrTextureBindFlags the application requires for this texture chain.
|
||||
/// \param[out] out_TextureSwapChain Returns the created ovrTextureSwapChain, which will be valid upon a successful return value, else it will be NULL.
|
||||
/// This texture chain must be eventually destroyed via ovr_DestroyTextureSwapChain before destroying the HMD with ovr_Destroy.
|
||||
///
|
||||
/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
|
||||
/// ovr_GetLastErrorInfo to get more information.
|
||||
///
|
||||
/// \note The texture format provided in \a desc should be thought of as the format the distortion-compositor will use for the
|
||||
/// ShaderResourceView when reading the contents of the texture. To that end, it is highly recommended that the application
|
||||
/// requests texture swapchain formats that are in sRGB-space (e.g. OVR_FORMAT_R8G8B8A8_UNORM_SRGB) as the compositor
|
||||
/// does sRGB-correct rendering. As such, the compositor relies on the GPU's hardware sampler to do the sRGB-to-linear
|
||||
/// conversion. If the application still prefers to render to a linear format (e.g. OVR_FORMAT_R8G8B8A8_UNORM) while handling the
|
||||
/// linear-to-gamma conversion via HLSL code, then the application must still request the corresponding sRGB format and also use
|
||||
/// the \a ovrTextureMisc_DX_Typeless flag in the ovrTextureSwapChainDesc's Flag field. This will allow the application to create
|
||||
/// a RenderTargetView that is the desired linear format while the compositor continues to treat it as sRGB. Failure to do so
|
||||
/// will cause the compositor to apply unexpected gamma conversions leading to gamma-curve artifacts. The \a ovrTextureMisc_DX_Typeless
|
||||
/// flag for depth buffer formats (e.g. OVR_FORMAT_D32_FLOAT) is ignored as they are always converted to be typeless.
|
||||
///
|
||||
/// \see ovr_GetTextureSwapChainLength
|
||||
/// \see ovr_GetTextureSwapChainCurrentIndex
|
||||
/// \see ovr_GetTextureSwapChainDesc
|
||||
/// \see ovr_GetTextureSwapChainBufferDX
|
||||
/// \see ovr_DestroyTextureSwapChain
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateTextureSwapChainDX(ovrSession session,
|
||||
IUnknown* d3dPtr,
|
||||
const ovrTextureSwapChainDesc* desc,
|
||||
ovrTextureSwapChain* out_TextureSwapChain);
|
||||
|
||||
|
||||
/// Get a specific buffer within the chain as any compatible COM interface (similar to QueryInterface)
|
||||
///
|
||||
/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
|
||||
/// \param[in] chain Specifies an ovrTextureSwapChain previously returned by ovr_CreateTextureSwapChainDX
|
||||
/// \param[in] index Specifies the index within the chain to retrieve. Must be between 0 and length (see ovr_GetTextureSwapChainLength),
|
||||
/// or may pass -1 to get the buffer at the CurrentIndex location. (Saving a call to GetTextureSwapChainCurrentIndex)
|
||||
/// \param[in] iid Specifies the interface ID of the interface pointer to query the buffer for.
|
||||
/// \param[out] out_Buffer Returns the COM interface pointer retrieved.
|
||||
///
|
||||
/// \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}
|
||||
/// ovr_GetTextureSwapChainBuffer(session, chain, 0, IID_ID3D11Texture2D, &d3d11Texture);
|
||||
/// ovr_GetTextureSwapChainBuffer(session, chain, 1, IID_PPV_ARGS(&dxgiResource));
|
||||
/// \endcode
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainBufferDX(ovrSession session,
|
||||
ovrTextureSwapChain chain,
|
||||
int index,
|
||||
IID iid,
|
||||
void** out_Buffer);
|
||||
|
||||
|
||||
/// Create Mirror Texture which is auto-refreshed to mirror Rift contents produced by this application.
|
||||
///
|
||||
/// A second call to ovr_CreateMirrorTextureDX for a given ovrSession before destroying the first one
|
||||
/// is not supported and will result in an error return.
|
||||
///
|
||||
/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
|
||||
/// \param[in] d3dPtr Specifies the application's D3D11Device to create resources with or the D3D12CommandQueue
|
||||
/// which must be the same one the application renders to the textures with.
|
||||
/// \param[in] desc Specifies requested texture properties. See notes for more info about texture format.
|
||||
/// \param[out] out_MirrorTexture Returns the created ovrMirrorTexture, which will be valid upon a successful return value, else it will be NULL.
|
||||
/// This texture must be eventually destroyed via ovr_DestroyMirrorTexture before destroying the HMD with ovr_Destroy.
|
||||
///
|
||||
/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
|
||||
/// ovr_GetLastErrorInfo to get more information.
|
||||
///
|
||||
/// \note The texture format provided in \a desc should be thought of as the format the compositor will use for the RenderTargetView when
|
||||
/// writing into mirror texture. To that end, it is highly recommended that the application requests a mirror texture format that is
|
||||
/// in sRGB-space (e.g. OVR_FORMAT_R8G8B8A8_UNORM_SRGB) as the compositor does sRGB-correct rendering. If however the application wants
|
||||
/// to still read the mirror texture as a linear format (e.g. OVR_FORMAT_R8G8B8A8_UNORM) and handle the sRGB-to-linear conversion in
|
||||
/// HLSL code, then it is recommended the application still requests an sRGB format and also use the \a ovrTextureMisc_DX_Typeless flag in the
|
||||
/// ovrMirrorTextureDesc's Flags field. This will allow the application to bind a ShaderResourceView that is a linear format while the
|
||||
/// 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.
|
||||
///
|
||||
/// \see ovr_GetMirrorTextureBufferDX
|
||||
/// \see ovr_DestroyMirrorTexture
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateMirrorTextureDX(ovrSession session,
|
||||
IUnknown* d3dPtr,
|
||||
const ovrMirrorTextureDesc* desc,
|
||||
ovrMirrorTexture* out_MirrorTexture);
|
||||
|
||||
/// Get a the underlying buffer as any compatible COM interface (similar to QueryInterface)
|
||||
///
|
||||
/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
|
||||
/// \param[in] mirrorTexture Specifies an ovrMirrorTexture previously returned by ovr_CreateMirrorTextureDX
|
||||
/// \param[in] iid Specifies the interface ID of the interface pointer to query the buffer for.
|
||||
/// \param[out] out_Buffer Returns the COM interface pointer retrieved.
|
||||
///
|
||||
/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
|
||||
/// ovr_GetLastErrorInfo to get more information.
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetMirrorTextureBufferDX(ovrSession session,
|
||||
ovrMirrorTexture mirrorTexture,
|
||||
IID iid,
|
||||
void** out_Buffer);
|
||||
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
#endif // OVR_CAPI_D3D_h
|
|
@ -0,0 +1,99 @@
|
|||
/********************************************************************************//**
|
||||
\file OVR_CAPI_GL.h
|
||||
\brief OpenGL-specific structures used by the CAPI interface.
|
||||
\copyright Copyright 2015 Oculus VR, LLC. All Rights reserved.
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef OVR_CAPI_GL_h
|
||||
#define OVR_CAPI_GL_h
|
||||
|
||||
#include "OVR_CAPI.h"
|
||||
|
||||
/// Creates a TextureSwapChain suitable for use with OpenGL.
|
||||
///
|
||||
/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
|
||||
/// \param[in] desc Specifies the requested texture properties. See notes for more info about texture format.
|
||||
/// \param[out] out_TextureSwapChain Returns the created ovrTextureSwapChain, which will be valid upon
|
||||
/// a successful return value, else it will be NULL. This texture swap chain must be eventually
|
||||
/// destroyed via ovr_DestroyTextureSwapChain before destroying the HMD with ovr_Destroy.
|
||||
///
|
||||
/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
|
||||
/// ovr_GetLastErrorInfo to get more information.
|
||||
///
|
||||
/// \note The \a format provided should be thought of as the format the distortion compositor will use when reading
|
||||
/// the contents of the texture. To that end, it is highly recommended that the application requests texture swap chain
|
||||
/// formats that are in sRGB-space (e.g. OVR_FORMAT_R8G8B8A8_UNORM_SRGB) as the distortion compositor does sRGB-correct
|
||||
/// rendering. Furthermore, the app should then make sure "glEnable(GL_FRAMEBUFFER_SRGB);" is called before rendering
|
||||
/// into these textures. Even though it is not recommended, if the application would like to treat the texture as a linear
|
||||
/// format and do linear-to-gamma conversion in GLSL, then the application can avoid calling "glEnable(GL_FRAMEBUFFER_SRGB);",
|
||||
/// but should still pass in an sRGB variant for the \a format. Failure to do so will cause the distortion compositor
|
||||
/// to apply incorrect gamma conversions leading to gamma-curve artifacts.
|
||||
///
|
||||
/// \see ovr_GetTextureSwapChainLength
|
||||
/// \see ovr_GetTextureSwapChainCurrentIndex
|
||||
/// \see ovr_GetTextureSwapChainDesc
|
||||
/// \see ovr_GetTextureSwapChainBufferGL
|
||||
/// \see ovr_DestroyTextureSwapChain
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateTextureSwapChainGL(ovrSession session,
|
||||
const ovrTextureSwapChainDesc* desc,
|
||||
ovrTextureSwapChain* out_TextureSwapChain);
|
||||
|
||||
/// Get a specific buffer within the chain as a GL texture name
|
||||
///
|
||||
/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
|
||||
/// \param[in] chain Specifies an ovrTextureSwapChain previously returned by ovr_CreateTextureSwapChainGL
|
||||
/// \param[in] index Specifies the index within the chain to retrieve. Must be between 0 and length (see ovr_GetTextureSwapChainLength)
|
||||
/// or may pass -1 to get the buffer at the CurrentIndex location. (Saving a call to GetTextureSwapChainCurrentIndex)
|
||||
/// \param[out] out_TexId Returns the GL texture object name associated with the specific index requested
|
||||
///
|
||||
/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
|
||||
/// ovr_GetLastErrorInfo to get more information.
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainBufferGL(ovrSession session,
|
||||
ovrTextureSwapChain chain,
|
||||
int index,
|
||||
unsigned int* out_TexId);
|
||||
|
||||
|
||||
/// Creates a Mirror Texture which is auto-refreshed to mirror Rift contents produced by this application.
|
||||
///
|
||||
/// A second call to ovr_CreateMirrorTextureGL for a given ovrSession before destroying the first one
|
||||
/// is not supported and will result in an error return.
|
||||
///
|
||||
/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
|
||||
/// \param[in] desc Specifies the requested mirror texture description.
|
||||
/// \param[out] out_MirrorTexture Specifies the created ovrMirrorTexture, which will be valid upon a successful return value, else it will be NULL.
|
||||
/// This texture must be eventually destroyed via ovr_DestroyMirrorTexture before destroying the HMD with ovr_Destroy.
|
||||
///
|
||||
/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
|
||||
/// ovr_GetLastErrorInfo to get more information.
|
||||
///
|
||||
/// \note The \a format provided should be thought of as the format the distortion compositor will use when writing into the mirror
|
||||
/// texture. It is highly recommended that mirror textures are requested as sRGB formats because the distortion compositor
|
||||
/// does sRGB-correct rendering. If the application requests a non-sRGB format (e.g. R8G8B8A8_UNORM) as the mirror texture,
|
||||
/// then the application might have to apply a manual linear-to-gamma conversion when reading from the mirror texture.
|
||||
/// Failure to do so can result in incorrect gamma conversions leading to gamma-curve artifacts and color banding.
|
||||
///
|
||||
/// \see ovr_GetMirrorTextureBufferGL
|
||||
/// \see ovr_DestroyMirrorTexture
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateMirrorTextureGL(ovrSession session,
|
||||
const ovrMirrorTextureDesc* desc,
|
||||
ovrMirrorTexture* out_MirrorTexture);
|
||||
|
||||
/// Get a the underlying buffer as a GL texture name
|
||||
///
|
||||
/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
|
||||
/// \param[in] mirrorTexture Specifies an ovrMirrorTexture previously returned by ovr_CreateMirrorTextureGL
|
||||
/// \param[out] out_TexId Specifies the GL texture object name associated with the mirror texture
|
||||
///
|
||||
/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
|
||||
/// ovr_GetLastErrorInfo to get more information.
|
||||
///
|
||||
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetMirrorTextureBufferGL(ovrSession session,
|
||||
ovrMirrorTexture mirrorTexture,
|
||||
unsigned int* out_TexId);
|
||||
|
||||
|
||||
#endif // OVR_CAPI_GL_h
|
|
@ -0,0 +1,53 @@
|
|||
/********************************************************************************//**
|
||||
\file OVR_CAPI.h
|
||||
\brief Keys for CAPI proprty function calls
|
||||
\copyright Copyright 2015 Oculus VR, LLC All Rights reserved.
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef OVR_CAPI_Keys_h
|
||||
#define OVR_CAPI_Keys_h
|
||||
|
||||
#include "OVR_Version.h"
|
||||
|
||||
|
||||
|
||||
#define OVR_KEY_USER "User" // string
|
||||
|
||||
#define OVR_KEY_NAME "Name" // string
|
||||
|
||||
#define OVR_KEY_GENDER "Gender" // string "Male", "Female", or "Unknown"
|
||||
#define OVR_DEFAULT_GENDER "Unknown"
|
||||
|
||||
#define OVR_KEY_PLAYER_HEIGHT "PlayerHeight" // float meters
|
||||
#define OVR_DEFAULT_PLAYER_HEIGHT 1.778f
|
||||
|
||||
#define OVR_KEY_EYE_HEIGHT "EyeHeight" // float meters
|
||||
#define OVR_DEFAULT_EYE_HEIGHT 1.675f
|
||||
|
||||
#define OVR_KEY_NECK_TO_EYE_DISTANCE "NeckEyeDistance" // float[2] meters
|
||||
#define OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL 0.0805f
|
||||
#define OVR_DEFAULT_NECK_TO_EYE_VERTICAL 0.075f
|
||||
|
||||
|
||||
#define OVR_KEY_EYE_TO_NOSE_DISTANCE "EyeToNoseDist" // float[2] meters
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define OVR_PERF_HUD_MODE "PerfHudMode" // int, allowed values are defined in enum ovrPerfHudMode
|
||||
|
||||
#define OVR_LAYER_HUD_MODE "LayerHudMode" // int, allowed values are defined in enum ovrLayerHudMode
|
||||
#define OVR_LAYER_HUD_CURRENT_LAYER "LayerHudCurrentLayer" // int, The layer to show
|
||||
#define OVR_LAYER_HUD_SHOW_ALL_LAYERS "LayerHudShowAll" // bool, Hide other layers when the hud is enabled
|
||||
|
||||
#define OVR_DEBUG_HUD_STEREO_MODE "DebugHudStereoMode" // int, allowed values are defined in enum ovrDebugHudStereoMode
|
||||
#define OVR_DEBUG_HUD_STEREO_GUIDE_INFO_ENABLE "DebugHudStereoGuideInfoEnable" // bool
|
||||
#define OVR_DEBUG_HUD_STEREO_GUIDE_SIZE "DebugHudStereoGuideSize2f" // float[2]
|
||||
#define OVR_DEBUG_HUD_STEREO_GUIDE_POSITION "DebugHudStereoGuidePosition3f" // float[3]
|
||||
#define OVR_DEBUG_HUD_STEREO_GUIDE_YAWPITCHROLL "DebugHudStereoGuideYawPitchRoll3f" // float[3]
|
||||
#define OVR_DEBUG_HUD_STEREO_GUIDE_COLOR "DebugHudStereoGuideColor4f" // float[4]
|
||||
|
||||
|
||||
|
||||
#endif // OVR_CAPI_Keys_h
|
|
@ -0,0 +1,191 @@
|
|||
/********************************************************************************//**
|
||||
\file OVR_ErrorCode.h
|
||||
\brief This header provides LibOVR error code declarations.
|
||||
\copyright Copyright 2015-2016 Oculus VR, LLC All Rights reserved.
|
||||
*************************************************************************************/
|
||||
|
||||
#ifndef OVR_ErrorCode_h
|
||||
#define OVR_ErrorCode_h
|
||||
|
||||
|
||||
#include "OVR_Version.h"
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef OVR_RESULT_DEFINED
|
||||
#define OVR_RESULT_DEFINED ///< Allows ovrResult to be independently defined.
|
||||
/// API call results are represented at the highest level by a single ovrResult.
|
||||
typedef int32_t ovrResult;
|
||||
#endif
|
||||
|
||||
|
||||
/// \brief Indicates if an ovrResult indicates success.
|
||||
///
|
||||
/// Some functions return additional successful values other than ovrSucces and
|
||||
/// require usage of this macro to indicate successs.
|
||||
///
|
||||
#if !defined(OVR_SUCCESS)
|
||||
#define OVR_SUCCESS(result) (result >= 0)
|
||||
#endif
|
||||
|
||||
|
||||
/// \brief Indicates if an ovrResult indicates an unqualified success.
|
||||
///
|
||||
/// This is useful for indicating that the code intentionally wants to
|
||||
/// check for result == ovrSuccess as opposed to OVR_SUCCESS(), which
|
||||
/// checks for result >= ovrSuccess.
|
||||
///
|
||||
#if !defined(OVR_UNQUALIFIED_SUCCESS)
|
||||
#define OVR_UNQUALIFIED_SUCCESS(result) (result == ovrSuccess)
|
||||
#endif
|
||||
|
||||
|
||||
/// \brief Indicates if an ovrResult indicates failure.
|
||||
///
|
||||
#if !defined(OVR_FAILURE)
|
||||
#define OVR_FAILURE(result) (!OVR_SUCCESS(result))
|
||||
#endif
|
||||
|
||||
|
||||
// Success is a value greater or equal to 0, while all error types are negative values.
|
||||
#ifndef OVR_SUCCESS_DEFINED
|
||||
#define OVR_SUCCESS_DEFINED ///< Allows ovrResult to be independently defined.
|
||||
typedef enum ovrSuccessType_
|
||||
{
|
||||
/// This is a general success result. Use OVR_SUCCESS to test for success.
|
||||
ovrSuccess = 0,
|
||||
|
||||
/// Returned from a call to SubmitFrame. The call succeeded, but what the app
|
||||
/// rendered will not be visible on the HMD. Ideally the app should continue
|
||||
/// calling SubmitFrame, but not do any rendering. When the result becomes
|
||||
/// ovrSuccess, rendering should continue as usual.
|
||||
ovrSuccess_NotVisible = 1000,
|
||||
|
||||
ovrSuccess_HMDFirmwareMismatch = 4100, ///< The HMD Firmware is out of date but is acceptable.
|
||||
ovrSuccess_TrackerFirmwareMismatch = 4101, ///< The Tracker Firmware is out of date but is acceptable.
|
||||
ovrSuccess_ControllerFirmwareMismatch = 4104, ///< The controller firmware is out of date but is acceptable.
|
||||
ovrSuccess_TrackerDriverNotFound = 4105, ///< The tracker driver interface was not found. Can be a temporary error
|
||||
|
||||
} ovrSuccessType;
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum ovrErrorType_
|
||||
{
|
||||
/* General errors */
|
||||
ovrError_MemoryAllocationFailure = -1000, ///< Failure to allocate memory.
|
||||
ovrError_SocketCreationFailure = -1001, ///< Failure to create a socket.
|
||||
ovrError_InvalidSession = -1002, ///< Invalid ovrSession parameter provided.
|
||||
ovrError_Timeout = -1003, ///< The operation timed out.
|
||||
ovrError_NotInitialized = -1004, ///< The system or component has not been initialized.
|
||||
ovrError_InvalidParameter = -1005, ///< Invalid parameter provided. See error info or log for details.
|
||||
ovrError_ServiceError = -1006, ///< Generic service error. See error info or log for details.
|
||||
ovrError_NoHmd = -1007, ///< The given HMD doesn't exist.
|
||||
ovrError_Unsupported = -1009, ///< Function call is not supported on this hardware/software
|
||||
ovrError_DeviceUnavailable = -1010, ///< Specified device type isn't available.
|
||||
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.
|
||||
|
||||
/* Audio error range, reserved for Audio errors. */
|
||||
ovrError_AudioReservedBegin = -2000, ///< First Audio error.
|
||||
ovrError_AudioDeviceNotFound = -2001, ///< Failure to find the specified audio device.
|
||||
ovrError_AudioComError = -2002, ///< Generic COM error.
|
||||
ovrError_AudioReservedEnd = -2999, ///< Last Audio error.
|
||||
|
||||
/* Initialization errors. */
|
||||
ovrError_Initialize = -3000, ///< Generic initialization error.
|
||||
ovrError_LibLoad = -3001, ///< Couldn't load LibOVRRT.
|
||||
ovrError_LibVersion = -3002, ///< LibOVRRT version incompatibility.
|
||||
ovrError_ServiceConnection = -3003, ///< Couldn't connect to the OVR Service.
|
||||
ovrError_ServiceVersion = -3004, ///< OVR Service version incompatibility.
|
||||
ovrError_IncompatibleOS = -3005, ///< The operating system version is incompatible.
|
||||
ovrError_DisplayInit = -3006, ///< Unable to initialize the HMD display.
|
||||
ovrError_ServerStart = -3007, ///< Unable to start the server. Is it already running?
|
||||
ovrError_Reinitialization = -3008, ///< Attempting to re-initialize with a different version.
|
||||
ovrError_MismatchedAdapters = -3009, ///< Chosen rendering adapters between client and service do not match
|
||||
ovrError_LeakingResources = -3010, ///< Calling application has leaked resources
|
||||
ovrError_ClientVersion = -3011, ///< Client version too old to connect to service
|
||||
ovrError_OutOfDateOS = -3012, ///< The operating system is out of date.
|
||||
ovrError_OutOfDateGfxDriver = -3013, ///< The graphics driver is out of date.
|
||||
ovrError_IncompatibleGPU = -3014, ///< The graphics hardware is not supported
|
||||
ovrError_NoValidVRDisplaySystem = -3015, ///< No valid VR display system found.
|
||||
ovrError_Obsolete = -3016, ///< Feature or API is obsolete and no longer supported.
|
||||
ovrError_DisabledOrDefaultAdapter = -3017, ///< No supported VR display system found, but disabled or driverless adapter found.
|
||||
ovrError_HybridGraphicsNotSupported = -3018, ///< The system is using hybrid graphics (Optimus, etc...), which is not support.
|
||||
ovrError_DisplayManagerInit = -3019, ///< Initialization of the DisplayManager failed.
|
||||
ovrError_TrackerDriverInit = -3020, ///< Failed to get the interface for an attached tracker
|
||||
|
||||
/* Hardware errors */
|
||||
ovrError_InvalidBundleAdjustment = -4000, ///< Headset has no bundle adjustment data.
|
||||
ovrError_USBBandwidth = -4001, ///< The USB hub cannot handle the camera frame bandwidth.
|
||||
ovrError_USBEnumeratedSpeed = -4002, ///< The USB camera is not enumerating at the correct device speed.
|
||||
ovrError_ImageSensorCommError = -4003, ///< Unable to communicate with the image sensor.
|
||||
ovrError_GeneralTrackerFailure = -4004, ///< We use this to report various sensor issues that don't fit in an easily classifiable bucket.
|
||||
ovrError_ExcessiveFrameTruncation = -4005, ///< A more than acceptable number of frames are coming back truncated.
|
||||
ovrError_ExcessiveFrameSkipping = -4006, ///< A more than acceptable number of frames have been skipped.
|
||||
ovrError_SyncDisconnected = -4007, ///< The sensor is not receiving the sync signal (cable disconnected?).
|
||||
ovrError_TrackerMemoryReadFailure = -4008, ///< Failed to read memory from the sensor.
|
||||
ovrError_TrackerMemoryWriteFailure = -4009, ///< Failed to write memory from the sensor.
|
||||
ovrError_TrackerFrameTimeout = -4010, ///< Timed out waiting for a camera frame.
|
||||
ovrError_TrackerTruncatedFrame = -4011, ///< Truncated frame returned from sensor.
|
||||
ovrError_TrackerDriverFailure = -4012, ///< The sensor driver has encountered a problem.
|
||||
ovrError_TrackerNRFFailure = -4013, ///< The sensor wireless subsystem has encountered a problem.
|
||||
ovrError_HardwareGone = -4014, ///< The hardware has been unplugged
|
||||
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_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_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.
|
||||
|
||||
/* Synchronization errors */
|
||||
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.
|
||||
|
||||
/* Fatal errors */
|
||||
ovrError_RuntimeException = -7000, ///< A runtime exception occurred. The application is required to shutdown LibOVR and re-initialize it before this error state will be cleared.
|
||||
|
||||
|
||||
ovrError_MetricsUnknownApp = -90000,
|
||||
ovrError_MetricsDuplicateApp = -90001,
|
||||
ovrError_MetricsNoEvents = -90002,
|
||||
ovrError_MetricsRuntime = -90003,
|
||||
ovrError_MetricsFile = -90004,
|
||||
ovrError_MetricsNoClientInfo = -90005,
|
||||
ovrError_MetricsNoAppMetaData = -90006,
|
||||
ovrError_MetricsNoApp = -90007,
|
||||
ovrError_MetricsOafFailure = -90008,
|
||||
ovrError_MetricsSessionAlreadyActive = -90009,
|
||||
ovrError_MetricsSessionNotActive = -90010,
|
||||
|
||||
} ovrErrorType;
|
||||
|
||||
|
||||
|
||||
/// Provides information about the last error.
|
||||
/// \see ovr_GetLastErrorInfo
|
||||
typedef struct ovrErrorInfo_
|
||||
{
|
||||
ovrResult Result; ///< The result from the last API call that generated an error ovrResult.
|
||||
char ErrorString[512]; ///< A UTF8-encoded null-terminated English string describing the problem. The format of this string is subject to change in future versions.
|
||||
} ovrErrorInfo;
|
||||
|
||||
#endif /* OVR_ErrorCode_h */
|
|
@ -0,0 +1,60 @@
|
|||
/********************************************************************************//**
|
||||
\file OVR_Version.h
|
||||
\brief This header provides LibOVR version identification.
|
||||
\copyright Copyright 2014-2016 Oculus VR, LLC All Rights reserved.
|
||||
*************************************************************************************/
|
||||
|
||||
#ifndef OVR_Version_h
|
||||
#define OVR_Version_h
|
||||
|
||||
|
||||
|
||||
/// Conventional string-ification macro.
|
||||
#if !defined(OVR_STRINGIZE)
|
||||
#define OVR_STRINGIZEIMPL(x) #x
|
||||
#define OVR_STRINGIZE(x) OVR_STRINGIZEIMPL(x)
|
||||
#endif
|
||||
|
||||
|
||||
// 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_PATCH_VERSION 0
|
||||
#define OVR_BUILD_NUMBER 0
|
||||
|
||||
// This is the ((product * 100) + major) version of the service that the DLL is compatible with.
|
||||
// When we backport changes to old versions of the DLL we update the old DLLs
|
||||
// to move this version number up to the latest version.
|
||||
// The DLL is responsible for checking that the service is the version it supports
|
||||
// and returning an appropriate error message if it has not been made compatible.
|
||||
#define OVR_DLL_COMPATIBLE_VERSION 101
|
||||
|
||||
#define OVR_FEATURE_VERSION 0
|
||||
|
||||
|
||||
/// "Major.Minor.Patch"
|
||||
#if !defined(OVR_VERSION_STRING)
|
||||
#define OVR_VERSION_STRING OVR_STRINGIZE(OVR_MAJOR_VERSION.OVR_MINOR_VERSION.OVR_PATCH_VERSION)
|
||||
#endif
|
||||
|
||||
|
||||
/// "Major.Minor.Patch.Build"
|
||||
#if !defined(OVR_DETAILED_VERSION_STRING)
|
||||
#define OVR_DETAILED_VERSION_STRING OVR_STRINGIZE(OVR_MAJOR_VERSION.OVR_MINOR_VERSION.OVR_PATCH_VERSION.OVR_BUILD_NUMBER)
|
||||
#endif
|
||||
|
||||
|
||||
/// \brief file description for version info
|
||||
/// This appears in the user-visible file properties. It is intended to convey publicly
|
||||
/// available additional information such as feature builds.
|
||||
#if !defined(OVR_FILE_DESCRIPTION_STRING)
|
||||
#if defined(_DEBUG)
|
||||
#define OVR_FILE_DESCRIPTION_STRING "dev build debug"
|
||||
#else
|
||||
#define OVR_FILE_DESCRIPTION_STRING "dev build"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif // OVR_Version_h
|
7684
examples/oculus_glfw_sample/glad.c
Normal file
7684
examples/oculus_glfw_sample/glad.c
Normal file
File diff suppressed because one or more lines are too long
14241
examples/oculus_glfw_sample/glad.h
Normal file
14241
examples/oculus_glfw_sample/glad.h
Normal file
File diff suppressed because one or more lines are too long
504
examples/oculus_glfw_sample/oculus_glfw_sample.c
Normal file
504
examples/oculus_glfw_sample/oculus_glfw_sample.c
Normal file
|
@ -0,0 +1,504 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#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"
|
||||
|
||||
// OVR device variables
|
||||
ovrSession session;
|
||||
ovrHmdDesc hmdDesc;
|
||||
ovrGraphicsLuid luid;
|
||||
|
||||
// OVR OpenGL required variables
|
||||
GLuint fbo = 0;
|
||||
GLuint depthBuffer = 0;
|
||||
ovrTextureSwapChain eyeTexture;
|
||||
|
||||
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;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
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 TraceLog(int msgType, const char *text, ...);
|
||||
static Matrix FromOvrMatrix(ovrMatrix4f ovrM);
|
||||
void DrawGrid(int slices, float spacing);
|
||||
void DrawCube(Vector3 position, float width, float height, float length, Color color);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Main Entry point
|
||||
//----------------------------------------------------------------------------------
|
||||
int main()
|
||||
{
|
||||
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);
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
// GLFW3 Initialization + OpenGL 3.3 Context + Extensions
|
||||
//--------------------------------------------------------
|
||||
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_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);
|
||||
|
||||
if (!window)
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else TraceLog(LOG_INFO, "GLFW3: Window created successfully");
|
||||
|
||||
glfwSetErrorCallback(ErrorCallback);
|
||||
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");
|
||||
|
||||
// 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);
|
||||
|
||||
// Recenter OVR tracking origin
|
||||
ovr_RecenterTrackingOrigin(session);
|
||||
|
||||
// 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);
|
||||
|
||||
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 };
|
||||
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
frame++;
|
||||
|
||||
ovrPosef eyePoses[2];
|
||||
ovr_GetEyePoses(session, frame, ovrTrue, viewScaleDesc.HmdToEyeOffset, eyePoses, &eyeLayer.SensorSampleTime);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// 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);
|
||||
|
||||
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));
|
||||
|
||||
// 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)
|
||||
rlglDraw(mvp);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// 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);
|
||||
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
if (mirrorFbo) glDeleteFramebuffers(1, &mirrorFbo);
|
||||
if (mirrorTexture) ovr_DestroyMirrorTexture(session, mirrorTexture);
|
||||
|
||||
if (fbo) glDeleteFramebuffers(1, &fbo);
|
||||
if (depthBuffer) glDeleteTextures(1, &depthBuffer);
|
||||
if (eyeTexture) ovr_DestroyTextureSwapChain(session, eyeTexture);
|
||||
|
||||
rlglClose();
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
|
||||
ovr_Destroy(session); // Must be called after glfwTerminate()
|
||||
ovr_Shutdown();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// 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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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 a grid centered at (0, 0, 0)
|
||||
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();
|
||||
}
|
498
examples/oculus_glfw_sample/oculus_glfw_sample.old.c
Normal file
498
examples/oculus_glfw_sample/oculus_glfw_sample.old.c
Normal file
|
@ -0,0 +1,498 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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, ¤tIndex);
|
||||
ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, ¤tTexId);
|
||||
|
||||
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);
|
||||
}
|
BIN
examples/oculus_glfw_sample/raylib_OculusRiftCV1.png
Normal file
BIN
examples/oculus_glfw_sample/raylib_OculusRiftCV1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 213 KiB |
131
examples/oculus_glfw_sample/raylib_rlgl_standalone.c
Normal file
131
examples/oculus_glfw_sample/raylib_rlgl_standalone.c
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [rlgl] example - Using rlgl module as standalone module
|
||||
*
|
||||
* NOTE: This example requires OpenGL 3.3 or ES2 versions for shaders support,
|
||||
* OpenGL 1.1 does not support shaders but it can also be used.
|
||||
*
|
||||
* Compile rlgl module using:
|
||||
* 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
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "glad.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#define RLGL_STANDALONE
|
||||
#include "rlgl.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawRectangleV(Vector2 position, Vector2 size, Color color);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Main Entry point
|
||||
//----------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
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);
|
||||
|
||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
||||
{
|
||||
printf("Cannot load GL extensions.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Definitions
|
||||
//----------------------------------------------------------------------------------
|
||||
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();
|
||||
}
|
1128
examples/oculus_glfw_sample/raymath.h
Normal file
1128
examples/oculus_glfw_sample/raymath.h
Normal file
File diff suppressed because it is too large
Load diff
2955
examples/oculus_glfw_sample/rlgl.c
Normal file
2955
examples/oculus_glfw_sample/rlgl.c
Normal file
File diff suppressed because it is too large
Load diff
319
examples/oculus_glfw_sample/rlgl.h
Normal file
319
examples/oculus_glfw_sample/rlgl.h
Normal file
|
@ -0,0 +1,319 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* rlgl - raylib OpenGL abstraction layer
|
||||
*
|
||||
* raylib now uses OpenGL 1.1 style functions (rlVertex) that are mapped to selected OpenGL version:
|
||||
* OpenGL 1.1 - Direct map rl* -> gl*
|
||||
* OpenGL 3.3 - Vertex data is stored in VAOs, call rlglDraw() to render
|
||||
* OpenGL ES 2 - Vertex data is stored in VBOs or VAOs (when available), call rlglDraw() to render
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||
* in the product documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||
* as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef RLGL_H
|
||||
#define RLGL_H
|
||||
|
||||
//#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()
|
||||
#endif
|
||||
|
||||
#ifdef RLGL_STANDALONE
|
||||
#define RAYMATH_STANDALONE
|
||||
#endif
|
||||
|
||||
#include "raymath.h" // Required for types: Vector3, Matrix
|
||||
|
||||
// Select desired OpenGL version
|
||||
// NOTE: Those preprocessor defines are only used on rlgl module,
|
||||
// if OpenGL version is required by any other module, it uses rlGetVersion()
|
||||
|
||||
// Choose opengl version here or just define it at compile time: -DGRAPHICS_API_OPENGL_33
|
||||
//#define GRAPHICS_API_OPENGL_11 // Only available on PLATFORM_DESKTOP
|
||||
//#define GRAPHICS_API_OPENGL_33 // Only available on PLATFORM_DESKTOP
|
||||
//#define GRAPHICS_API_OPENGL_ES2 // Only available on PLATFORM_ANDROID or PLATFORM_RPI or PLATFORM_WEB
|
||||
|
||||
// Security check in case no GRAPHICS_API_OPENGL_* defined
|
||||
#if !defined(GRAPHICS_API_OPENGL_11) && !defined(GRAPHICS_API_OPENGL_33) && !defined(GRAPHICS_API_OPENGL_ES2)
|
||||
#define GRAPHICS_API_OPENGL_11
|
||||
#endif
|
||||
|
||||
// Security check in case multiple GRAPHICS_API_OPENGL_* defined
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
#if defined(GRAPHICS_API_OPENGL_33)
|
||||
#undef GRAPHICS_API_OPENGL_33
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
#undef GRAPHICS_API_OPENGL_ES2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
|
||||
// NOTE: This is the maximum amount of lines, triangles and quads per frame, be careful!
|
||||
#define MAX_LINES_BATCH 8192
|
||||
#define MAX_TRIANGLES_BATCH 4096
|
||||
#define MAX_QUADS_BATCH 4096
|
||||
#elif defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// NOTE: Reduce memory sizes for embedded systems (RPI and HTML5)
|
||||
// NOTE: On HTML5 (emscripten) this is allocated on heap, by default it's only 16MB!...just take care...
|
||||
#define MAX_LINES_BATCH 1024 // Critical for wire shapes (sphere)
|
||||
#define MAX_TRIANGLES_BATCH 2048 // Critical for some shapes (sphere)
|
||||
#define MAX_QUADS_BATCH 1024 // Be careful with text, every letter maps a quad
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef enum { RL_PROJECTION, RL_MODELVIEW, RL_TEXTURE } MatrixMode;
|
||||
|
||||
typedef enum { RL_LINES, RL_TRIANGLES, RL_QUADS } DrawMode;
|
||||
|
||||
typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
|
||||
|
||||
#if defined(RLGL_STANDALONE)
|
||||
#ifndef __cplusplus
|
||||
// Boolean type
|
||||
typedef enum { false, true } bool;
|
||||
#endif
|
||||
|
||||
// byte type
|
||||
typedef unsigned char byte;
|
||||
|
||||
// Color type, RGBA (32bit)
|
||||
typedef struct Color {
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
unsigned char a;
|
||||
} Color;
|
||||
|
||||
// Texture formats (support depends on OpenGL version)
|
||||
typedef enum {
|
||||
UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha)
|
||||
UNCOMPRESSED_GRAY_ALPHA,
|
||||
UNCOMPRESSED_R5G6B5, // 16 bpp
|
||||
UNCOMPRESSED_R8G8B8, // 24 bpp
|
||||
UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha)
|
||||
UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha)
|
||||
UNCOMPRESSED_R8G8B8A8, // 32 bpp
|
||||
COMPRESSED_DXT1_RGB, // 4 bpp (no alpha)
|
||||
COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha)
|
||||
COMPRESSED_DXT3_RGBA, // 8 bpp
|
||||
COMPRESSED_DXT5_RGBA, // 8 bpp
|
||||
COMPRESSED_ETC1_RGB, // 4 bpp
|
||||
COMPRESSED_ETC2_RGB, // 4 bpp
|
||||
COMPRESSED_ETC2_EAC_RGBA, // 8 bpp
|
||||
COMPRESSED_PVRT_RGB, // 4 bpp
|
||||
COMPRESSED_PVRT_RGBA, // 4 bpp
|
||||
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)
|
||||
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)
|
||||
} Mesh;
|
||||
|
||||
// Shader type
|
||||
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)
|
||||
|
||||
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)
|
||||
} Shader;
|
||||
|
||||
// Texture2D type
|
||||
// NOTE: Data stored in GPU memory
|
||||
typedef struct Texture2D {
|
||||
unsigned int id; // OpenGL texture id
|
||||
int width; // Texture base width
|
||||
int height; // Texture base height
|
||||
int mipmaps; // Mipmap levels, 1 by default
|
||||
int format; // Data format (TextureFormat)
|
||||
} Texture2D;
|
||||
|
||||
// RenderTexture2D type, for texture rendering
|
||||
typedef struct RenderTexture2D {
|
||||
unsigned int id; // Render texture (fbo) id
|
||||
Texture2D texture; // Color buffer attachment texture
|
||||
Texture2D depth; // Depth buffer attachment texture
|
||||
} RenderTexture2D;
|
||||
|
||||
// Material type
|
||||
typedef struct Material {
|
||||
Shader shader;
|
||||
|
||||
Texture2D texDiffuse; // Diffuse texture
|
||||
Texture2D texNormal; // Normal texture
|
||||
Texture2D texSpecular; // Specular texture
|
||||
|
||||
Color colDiffuse;
|
||||
Color colAmbient;
|
||||
Color colSpecular;
|
||||
|
||||
float glossiness;
|
||||
float normalDepth;
|
||||
} Material;
|
||||
|
||||
// 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
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Functions Declaration - Matrix operations
|
||||
//------------------------------------------------------------------------------------
|
||||
void rlMatrixMode(int mode); // Choose the current matrix to be transformed
|
||||
void rlPushMatrix(void); // Push the current matrix to stack
|
||||
void rlPopMatrix(void); // Pop lattest inserted matrix from stack
|
||||
void rlLoadIdentity(void); // Reset current matrix to identity matrix
|
||||
void rlTranslatef(float x, float y, float z); // Multiply the current matrix by a translation matrix
|
||||
void rlRotatef(float angleDeg, float x, float y, float z); // Multiply the current matrix by a rotation matrix
|
||||
void rlScalef(float x, float y, float z); // Multiply the current matrix by a scaling matrix
|
||||
void rlMultMatrixf(float *mat); // Multiply the current matrix by another matrix
|
||||
void rlFrustum(double left, double right, double bottom, double top, double near, double far);
|
||||
void rlOrtho(double left, double right, double bottom, double top, double near, double far);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Functions Declaration - Vertex level operations
|
||||
//------------------------------------------------------------------------------------
|
||||
void rlBegin(int mode); // Initialize drawing mode (how to organize vertex)
|
||||
void rlEnd(void); // Finish vertex providing
|
||||
void rlVertex2i(int x, int y); // Define one vertex (position) - 2 int
|
||||
void rlVertex2f(float x, float y); // Define one vertex (position) - 2 float
|
||||
void rlVertex3f(float x, float y, float z); // Define one vertex (position) - 3 float
|
||||
void rlTexCoord2f(float x, float y); // Define one vertex (texture coordinate) - 2 float
|
||||
void rlNormal3f(float x, float y, float z); // Define one vertex (normal) - 3 float
|
||||
void rlColor4ub(byte r, byte g, byte b, byte a); // Define one vertex (color) - 4 byte
|
||||
void rlColor3f(float x, float y, float z); // Define one vertex (color) - 3 float
|
||||
void rlColor4f(float x, float y, float z, float w); // Define one vertex (color) - 4 float
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Functions Declaration - OpenGL equivalent functions (common to 1.1, 3.3+, ES2)
|
||||
// NOTE: This functions are used to completely abstract raylib code from OpenGL layer
|
||||
//------------------------------------------------------------------------------------
|
||||
void rlEnableTexture(unsigned int id); // Enable texture usage
|
||||
void rlDisableTexture(void); // Disable texture usage
|
||||
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 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
|
||||
void rlDeleteVertexArrays(unsigned int id); // Unload vertex data (VAO) from GPU memory
|
||||
void rlDeleteBuffers(unsigned int id); // Unload vertex data (VBO) from GPU memory
|
||||
void rlClearColor(byte r, byte g, byte b, byte a); // Clear color buffer with color
|
||||
void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth)
|
||||
int rlGetVersion(void); // Returns current OpenGL version
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Functions Declaration - rlgl functionality
|
||||
//------------------------------------------------------------------------------------
|
||||
void rlglInit(void); // Initialize rlgl (shaders, VAO, VBO...)
|
||||
void rlglClose(void); // De-init rlgl
|
||||
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
|
||||
RenderTexture2D rlglLoadRenderTexture(int width, int height); // Load a texture to be used for rendering (fbo with color and depth attachments)
|
||||
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);
|
||||
|
||||
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
|
||||
|
||||
#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
|
||||
|
||||
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)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // RLGL_H
|
|
@ -30,26 +30,26 @@ int main()
|
|||
bool isDebug = false;
|
||||
|
||||
// Create rectangle physic object
|
||||
PhysicObject *rectangle = CreatePhysicObject((Vector2){ screenWidth*0.25f, screenHeight/2 }, 0.0f, (Vector2){ 75, 50 });
|
||||
PhysicObject rectangle = CreatePhysicObject((Vector2){ screenWidth*0.25f, screenHeight/2 }, 0.0f, (Vector2){ 75, 50 });
|
||||
rectangle->rigidbody.enabled = true; // Enable physic object rigidbody behaviour
|
||||
rectangle->rigidbody.applyGravity = true;
|
||||
rectangle->rigidbody.friction = 0.1f;
|
||||
rectangle->rigidbody.bounciness = 6.0f;
|
||||
|
||||
// Create square physic object
|
||||
PhysicObject *square = CreatePhysicObject((Vector2){ screenWidth*0.75f, screenHeight/2 }, 0.0f, (Vector2){ 50, 50 });
|
||||
PhysicObject square = CreatePhysicObject((Vector2){ screenWidth*0.75f, screenHeight/2 }, 0.0f, (Vector2){ 50, 50 });
|
||||
square->rigidbody.enabled = true; // Enable physic object rigidbody behaviour
|
||||
square->rigidbody.applyGravity = true;
|
||||
square->rigidbody.friction = 0.1f;
|
||||
|
||||
// Create walls physic objects
|
||||
PhysicObject *floor = CreatePhysicObject((Vector2){ screenWidth/2, screenHeight*0.95f }, 0.0f, (Vector2){ screenWidth*0.9f, 100 });
|
||||
PhysicObject *leftWall = CreatePhysicObject((Vector2){ 0.0f, screenHeight/2 }, 0.0f, (Vector2){ screenWidth*0.1f, screenHeight });
|
||||
PhysicObject *rightWall = CreatePhysicObject((Vector2){ screenWidth, screenHeight/2 }, 0.0f, (Vector2){ screenWidth*0.1f, screenHeight });
|
||||
PhysicObject *roof = CreatePhysicObject((Vector2){ screenWidth/2, screenHeight*0.05f }, 0.0f, (Vector2){ screenWidth*0.9f, 100 });
|
||||
PhysicObject floor = CreatePhysicObject((Vector2){ screenWidth/2, screenHeight*0.95f }, 0.0f, (Vector2){ screenWidth*0.9f, 100 });
|
||||
PhysicObject leftWall = CreatePhysicObject((Vector2){ 0.0f, screenHeight/2 }, 0.0f, (Vector2){ screenWidth*0.1f, screenHeight });
|
||||
PhysicObject rightWall = CreatePhysicObject((Vector2){ screenWidth, screenHeight/2 }, 0.0f, (Vector2){ screenWidth*0.1f, screenHeight });
|
||||
PhysicObject roof = CreatePhysicObject((Vector2){ screenWidth/2, screenHeight*0.05f }, 0.0f, (Vector2){ screenWidth*0.9f, 100 });
|
||||
|
||||
// Create pplatform physic object
|
||||
PhysicObject *platform = CreatePhysicObject((Vector2){ screenWidth/2, screenHeight*0.7f }, 0.0f, (Vector2){ screenWidth*0.25f, 20 });
|
||||
PhysicObject platform = CreatePhysicObject((Vector2){ screenWidth/2, screenHeight*0.7f }, 0.0f, (Vector2){ screenWidth*0.25f, 20 });
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -114,7 +114,8 @@ int main()
|
|||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
ClosePhysics(); // Unitialize physics module
|
||||
ClosePhysics(); // Unitialize physics (including all loaded objects)
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#define LINE_LENGTH 75
|
||||
#define TRIANGLE_LENGTH 12
|
||||
|
||||
void DrawRigidbodyCircle(PhysicObject *obj, Color color);
|
||||
void DrawRigidbodyCircle(PhysicObject obj, Color color);
|
||||
|
||||
int main()
|
||||
{
|
||||
|
@ -36,7 +36,7 @@ int main()
|
|||
bool isDebug = false;
|
||||
|
||||
// Create rectangle physic objects
|
||||
PhysicObject *rectangles[3];
|
||||
PhysicObject rectangles[3];
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
rectangles[i] = CreatePhysicObject((Vector2){ screenWidth/4*(i+1), (((i % 2) == 0) ? (screenHeight/3) : (screenHeight/1.5f)) }, 0.0f, (Vector2){ 50, 50 });
|
||||
|
@ -46,7 +46,7 @@ int main()
|
|||
|
||||
// Create circles physic objects
|
||||
// NOTE: when creating circle physic objects, transform.scale must be { 0, 0 } and object radius must be defined in collider.radius and use this value to draw the circle.
|
||||
PhysicObject *circles[3];
|
||||
PhysicObject circles[3];
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
circles[i] = CreatePhysicObject((Vector2){ screenWidth/4*(i+1), (((i % 2) == 0) ? (screenHeight/1.5f) : (screenHeight/4)) }, 0.0f, (Vector2){ 0, 0 });
|
||||
|
@ -57,10 +57,10 @@ int main()
|
|||
}
|
||||
|
||||
// Create walls physic objects
|
||||
PhysicObject *leftWall = CreatePhysicObject((Vector2){ -25, screenHeight/2 }, 0.0f, (Vector2){ 50, screenHeight });
|
||||
PhysicObject *rightWall = CreatePhysicObject((Vector2){ screenWidth + 25, screenHeight/2 }, 0.0f, (Vector2){ 50, screenHeight });
|
||||
PhysicObject *topWall = CreatePhysicObject((Vector2){ screenWidth/2, -25 }, 0.0f, (Vector2){ screenWidth, 50 });
|
||||
PhysicObject *bottomWall = CreatePhysicObject((Vector2){ screenWidth/2, screenHeight + 25 }, 0.0f, (Vector2){ screenWidth, 50 });
|
||||
PhysicObject leftWall = CreatePhysicObject((Vector2){ -25, screenHeight/2 }, 0.0f, (Vector2){ 50, screenHeight });
|
||||
PhysicObject rightWall = CreatePhysicObject((Vector2){ screenWidth + 25, screenHeight/2 }, 0.0f, (Vector2){ 50, screenHeight });
|
||||
PhysicObject topWall = CreatePhysicObject((Vector2){ screenWidth/2, -25 }, 0.0f, (Vector2){ screenWidth, 50 });
|
||||
PhysicObject bottomWall = CreatePhysicObject((Vector2){ screenWidth/2, screenHeight + 25 }, 0.0f, (Vector2){ screenWidth, 50 });
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
#version 330
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sum = vec4(0);
|
||||
vec4 tc = vec4(0);
|
||||
|
||||
for (int i = -4; i < 4; i++)
|
||||
{
|
||||
for (int j = -3; j < 3; j++)
|
||||
{
|
||||
sum += texture2D(texture0, fragTexCoord + vec2(j, i)*0.004) * 0.25;
|
||||
}
|
||||
}
|
||||
|
||||
if (texture2D(texture0, fragTexCoord).r < 0.3)
|
||||
{
|
||||
tc = sum*sum*0.012 + texture2D(texture0, fragTexCoord);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (texture2D(texture0, fragTexCoord).r < 0.5)
|
||||
{
|
||||
tc = sum*sum*0.009 + texture2D(texture0, fragTexCoord);
|
||||
}
|
||||
else
|
||||
{
|
||||
tc = sum*sum*0.0075 + texture2D(texture0, fragTexCoord);
|
||||
}
|
||||
}
|
||||
|
||||
fragColor = tc;
|
||||
}
|
|
@ -1,20 +1,26 @@
|
|||
#version 100
|
||||
|
||||
// Input vertex attributes
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec3 vertexNormal;
|
||||
attribute vec4 vertexColor;
|
||||
|
||||
varying vec2 fragTexCoord;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvpMatrix;
|
||||
|
||||
// Output vertex attributes (to fragment shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 normal = vertexNormal;
|
||||
|
||||
// Send vertex attributes to fragment shader
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragColor = vertexColor;
|
||||
|
||||
// Calculate final vertex position
|
||||
gl_Position = mvpMatrix*vec4(vertexPosition, 1.0);
|
||||
}
|
|
@ -2,8 +2,11 @@
|
|||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
|
@ -22,21 +25,13 @@ void main()
|
|||
}
|
||||
}
|
||||
|
||||
if (texture2D(texture0, fragTexCoord).r < 0.3)
|
||||
{
|
||||
tc = sum*sum*0.012 + texture2D(texture0, fragTexCoord);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (texture2D(texture0, fragTexCoord).r < 0.5)
|
||||
{
|
||||
tc = sum*sum*0.009 + texture2D(texture0, fragTexCoord);
|
||||
}
|
||||
else
|
||||
{
|
||||
tc = sum*sum*0.0075 + texture2D(texture0, fragTexCoord);
|
||||
}
|
||||
}
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||
|
||||
// Calculate final fragment color
|
||||
if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor;
|
||||
else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor;
|
||||
else tc = sum*sum*0.0075 + texelColor;
|
||||
|
||||
gl_FragColor = tc;
|
||||
}
|
25
examples/resources/shaders/glsl100/grayscale.fs
Normal file
25
examples/resources/shaders/glsl100/grayscale.fs
Normal file
|
@ -0,0 +1,25 @@
|
|||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = texture(texture0, fragTexCoord)*fragTintColor*fragColor;
|
||||
|
||||
// Convert texel color to grayscale using NTSC conversion weights
|
||||
float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114));
|
||||
|
||||
// Calculate final fragment color
|
||||
gl_FragColor = vec4(gray, gray, gray, texelColor.a);
|
||||
}
|
|
@ -1,9 +1,12 @@
|
|||
#version 330
|
||||
#version 100
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
precision mediump float;
|
||||
|
||||
out vec4 fragColor;
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
|
@ -17,11 +20,12 @@ float angle = 0.8;
|
|||
|
||||
uniform vec2 center = vec2(200.0, 200.0);
|
||||
|
||||
void main (void)
|
||||
void main()
|
||||
{
|
||||
vec2 texSize = vec2(renderWidth, renderHeight);
|
||||
vec2 tc = fragTexCoord*texSize;
|
||||
tc -= center;
|
||||
|
||||
float dist = length(tc);
|
||||
|
||||
if (dist < radius)
|
||||
|
@ -37,5 +41,5 @@ void main (void)
|
|||
tc += center;
|
||||
vec3 color = texture2D(texture0, tc/texSize).rgb;
|
||||
|
||||
fragColor = vec4(color, 1.0);;
|
||||
gl_FragColor = vec4(color, 1.0);;
|
||||
}
|
|
@ -1,18 +1,26 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes
|
||||
in vec3 vertexPosition;
|
||||
in vec2 vertexTexCoord;
|
||||
in vec3 vertexNormal;
|
||||
in vec4 vertexColor;
|
||||
|
||||
out vec2 fragTexCoord;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvpMatrix;
|
||||
|
||||
// Output vertex attributes (to fragment shader)
|
||||
out vec2 fragTexCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
// Send vertex attributes to fragment shader
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragColor = vertexColor;
|
||||
|
||||
// Calculate final vertex position
|
||||
gl_Position = mvpMatrix*vec4(vertexPosition, 1.0);
|
||||
}
|
38
examples/resources/shaders/glsl330/bloom.fs
Normal file
38
examples/resources/shaders/glsl330/bloom.fs
Normal file
|
@ -0,0 +1,38 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sum = vec4(0);
|
||||
vec4 tc = vec4(0);
|
||||
|
||||
for (int i = -4; i < 4; i++)
|
||||
{
|
||||
for (int j = -3; j < 3; j++)
|
||||
{
|
||||
sum += texture(texture0, fragTexCoord + vec2(j, i)*0.004)*0.25;
|
||||
}
|
||||
}
|
||||
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||
|
||||
// Calculate final fragment color
|
||||
if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor;
|
||||
else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor;
|
||||
else tc = sum*sum*0.0075 + texelColor;
|
||||
|
||||
finalColor = tc;
|
||||
}
|
27
examples/resources/shaders/glsl330/depth.fs
Normal file
27
examples/resources/shaders/glsl330/depth.fs
Normal file
|
@ -0,0 +1,27 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0; // Depth texture
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
float zNear = 0.01; // camera z near
|
||||
float zFar = 10.0; // camera z far
|
||||
float z = texture(texture0, fragTexCoord).x;
|
||||
|
||||
// Linearize depth value
|
||||
float depth = (2.0*zNear)/(zFar + zNear - z*(zFar - zNear));
|
||||
|
||||
// Calculate final fragment color
|
||||
finalColor = vec4(depth, depth, depth, 1.0f);
|
||||
}
|
26
examples/resources/shaders/glsl330/grayscale.fs
Normal file
26
examples/resources/shaders/glsl330/grayscale.fs
Normal file
|
@ -0,0 +1,26 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = texture(texture0, fragTexCoord)*fragTintColor*fragColor;
|
||||
|
||||
// Convert texel color to grayscale using NTSC conversion weights
|
||||
float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114));
|
||||
|
||||
// Calculate final fragment color
|
||||
finalColor = vec4(gray, gray, gray, texelColor.a);
|
||||
}
|
85
examples/resources/shaders/glsl330/phong.fs
Normal file
85
examples/resources/shaders/glsl330/phong.fs
Normal file
|
@ -0,0 +1,85 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec3 fragNormal;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
// Light uniform values
|
||||
uniform vec3 lightAmbientColor = vec3(0.6, 0.3, 0.0);
|
||||
uniform vec3 lightDiffuseColor = vec3(1.0, 0.5, 0.0);
|
||||
uniform vec3 lightSpecularColor = vec3(0.0, 1.0, 0.0);
|
||||
uniform float lightIntensity = 1.0;
|
||||
uniform float lightSpecIntensity = 1.0;
|
||||
|
||||
// Material uniform values
|
||||
uniform vec3 matAmbientColor = vec3(1.0, 1.0, 1.0);
|
||||
uniform vec3 matSpecularColor = vec3(1.0, 1.0, 1.0);
|
||||
uniform float matGlossiness = 50.0;
|
||||
|
||||
// World uniform values
|
||||
uniform vec3 lightPosition;
|
||||
uniform vec3 cameraPosition;
|
||||
|
||||
// Fragment shader output data
|
||||
out vec4 fragColor;
|
||||
|
||||
// Calculate ambient lighting component
|
||||
vec3 AmbientLighting()
|
||||
{
|
||||
return (matAmbientColor*lightAmbientColor);
|
||||
}
|
||||
|
||||
// Calculate diffuse lighting component
|
||||
vec3 DiffuseLighting(in vec3 N, in vec3 L)
|
||||
{
|
||||
// Lambertian reflection calculation
|
||||
float diffuse = clamp(dot(N, L), 0, 1);
|
||||
|
||||
return (fragTintColor.xyz*lightDiffuseColor*lightIntensity*diffuse);
|
||||
}
|
||||
|
||||
// Calculate specular lighting component
|
||||
vec3 SpecularLighting(in vec3 N, in vec3 L, in vec3 V)
|
||||
{
|
||||
float specular = 0.0;
|
||||
|
||||
// Calculate specular reflection only if the surface is oriented to the light source
|
||||
if (dot(N, L) > 0)
|
||||
{
|
||||
// Calculate half vector
|
||||
vec3 H = normalize(L + V);
|
||||
|
||||
// Calculate specular intensity
|
||||
specular = pow(dot(N, H), 3 + matGlossiness);
|
||||
}
|
||||
|
||||
return (matSpecularColor*lightSpecularColor*lightSpecIntensity*specular);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// Normalize input vectors
|
||||
vec3 L = normalize(lightPosition);
|
||||
vec3 V = normalize(cameraPosition);
|
||||
vec3 N = normalize(fragNormal);
|
||||
|
||||
// Calculate lighting components
|
||||
vec3 ambient = AmbientLighting();
|
||||
vec3 diffuse = DiffuseLighting(N, L);
|
||||
vec3 specular = SpecularLighting(N, L, V);
|
||||
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||
|
||||
// Calculate final fragment color
|
||||
finalColor = vec4(texelColor.rgb*(ambient + diffuse + specular), texelColor.a);
|
||||
}
|
|
@ -1,23 +1,23 @@
|
|||
#version 330
|
||||
|
||||
// Vertex input data
|
||||
// Input vertex attributes
|
||||
in vec3 vertexPosition;
|
||||
in vec2 vertexTexCoord;
|
||||
in vec3 vertexNormal;
|
||||
|
||||
// Projection and model data
|
||||
// Input uniform values
|
||||
uniform mat4 mvpMatrix;
|
||||
|
||||
uniform mat4 modelMatrix;
|
||||
//uniform mat4 viewMatrix; // Not used
|
||||
|
||||
// Attributes to fragment shader
|
||||
// Output vertex attributes (to fragment shader)
|
||||
out vec2 fragTexCoord;
|
||||
out vec3 fragNormal;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
uniform mat4 modelMatrix;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Send texture coord to fragment shader
|
||||
// Send vertex attributes to fragment shader
|
||||
fragTexCoord = vertexTexCoord;
|
||||
|
||||
// Calculate view vector normal from model
|
|
@ -1,27 +1,32 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
const float renderWidth = 1280.0;
|
||||
const float renderHeight = 720.0;
|
||||
const float renderWidth = 800.0; // HARDCODED for example!
|
||||
const float renderHeight = 480.0; // Use uniforms instead...
|
||||
|
||||
float radius = 250.0;
|
||||
float angle = 0.8;
|
||||
|
||||
uniform vec2 center = vec2(200.0, 200.0);
|
||||
|
||||
void main (void)
|
||||
void main()
|
||||
{
|
||||
vec2 texSize = vec2(renderWidth, renderHeight);
|
||||
vec2 tc = fragTexCoord*texSize;
|
||||
tc -= center;
|
||||
|
||||
float dist = length(tc);
|
||||
|
||||
if (dist < radius)
|
||||
|
@ -37,5 +42,5 @@ void main (void)
|
|||
tc += center;
|
||||
vec3 color = texture(texture0, tc/texSize).rgb;
|
||||
|
||||
fragColor = vec4(color, 1.0);;
|
||||
finalColor = vec4(color, 1.0);;
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#version 330
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 base = texture2D(texture0, fragTexCoord)*fragTintColor;
|
||||
|
||||
// Convert to grayscale using NTSC conversion weights
|
||||
float gray = dot(base.rgb, vec3(0.299, 0.587, 0.114));
|
||||
|
||||
fragColor = vec4(gray, gray, gray, fragTintColor.a);
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
#version 330
|
||||
|
||||
// Vertex shader input data
|
||||
in vec2 fragTexCoord;
|
||||
in vec3 fragNormal;
|
||||
|
||||
// Diffuse data
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Light attributes
|
||||
uniform vec3 light_ambientColor = vec3(0.6, 0.3, 0.0);
|
||||
uniform vec3 light_diffuseColor = vec3(1.0, 0.5, 0.0);
|
||||
uniform vec3 light_specularColor = vec3(0.0, 1.0, 0.0);
|
||||
uniform float light_intensity = 1.0;
|
||||
uniform float light_specIntensity = 1.0;
|
||||
|
||||
// Material attributes
|
||||
uniform vec3 mat_ambientColor = vec3(1.0, 1.0, 1.0);
|
||||
uniform vec3 mat_specularColor = vec3(1.0, 1.0, 1.0);
|
||||
uniform float mat_glossiness = 50.0;
|
||||
|
||||
// World attributes
|
||||
uniform vec3 lightPos;
|
||||
uniform vec3 cameraPos;
|
||||
|
||||
// Fragment shader output data
|
||||
out vec4 fragColor;
|
||||
|
||||
vec3 AmbientLighting()
|
||||
{
|
||||
return (mat_ambientColor*light_ambientColor);
|
||||
}
|
||||
|
||||
vec3 DiffuseLighting(in vec3 N, in vec3 L)
|
||||
{
|
||||
// Lambertian reflection calculation
|
||||
float diffuse = clamp(dot(N, L), 0, 1);
|
||||
|
||||
return (fragTintColor.xyz*light_diffuseColor*light_intensity*diffuse);
|
||||
}
|
||||
|
||||
vec3 SpecularLighting(in vec3 N, in vec3 L, in vec3 V)
|
||||
{
|
||||
float specular = 0.0;
|
||||
|
||||
// Calculate specular reflection only if the surface is oriented to the light source
|
||||
if (dot(N, L) > 0)
|
||||
{
|
||||
// Calculate half vector
|
||||
vec3 H = normalize(L + V);
|
||||
|
||||
// Calculate specular intensity
|
||||
specular = pow(dot(N, H), 3 + mat_glossiness);
|
||||
}
|
||||
|
||||
return (mat_specularColor*light_specularColor*light_specIntensity*specular);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// Normalize input vectors
|
||||
vec3 L = normalize(lightPos);
|
||||
vec3 V = normalize(cameraPos);
|
||||
vec3 N = normalize(fragNormal);
|
||||
|
||||
vec3 ambient = AmbientLighting();
|
||||
vec3 diffuse = DiffuseLighting(N, L);
|
||||
vec3 specular = SpecularLighting(N, L, V);
|
||||
|
||||
// Get base color from texture
|
||||
vec4 textureColor = texture(texture0, fragTexCoord);
|
||||
vec3 finalColor = textureColor.rgb;
|
||||
|
||||
fragColor = vec4(finalColor * (ambient + diffuse + specular), textureColor.a);
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
#version 330
|
||||
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec4 vertexColor;
|
||||
|
||||
uniform mat4 mvpMatrix;
|
||||
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragTintColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragTintColor = vertexColor;
|
||||
|
||||
gl_Position = mvpMatrix*vec4(vertexPosition, 1.0);
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
#version 330
|
||||
|
||||
uniform sampler2D texture0;
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragTintColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 base = texture2D(texture0, fragTexCoord)*fragTintColor;
|
||||
|
||||
// Convert to grayscale using NTSC conversion weights
|
||||
float gray = dot(base.rgb, vec3(0.299, 0.587, 0.114));
|
||||
|
||||
gl_FragColor = vec4(gray, gray, gray, base.a);
|
||||
}
|
|
@ -41,23 +41,23 @@ int main()
|
|||
// Model initialization
|
||||
Vector3 position = { 0.0f, 0.0f, 0.0f };
|
||||
Model model = LoadModel("resources/model/dwarf.obj");
|
||||
Shader shader = LoadShader("resources/shaders/phong.vs", "resources/shaders/phong.fs");
|
||||
Shader shader = LoadShader("resources/shaders/glsl330/phong.vs", "resources/shaders/glsl330/phong.fs");
|
||||
SetModelShader(&model, shader);
|
||||
|
||||
// Shader locations initialization
|
||||
int lIntensityLoc = GetShaderLocation(shader, "light_intensity");
|
||||
int lAmbientLoc = GetShaderLocation(shader, "light_ambientColor");
|
||||
int lDiffuseLoc = GetShaderLocation(shader, "light_diffuseColor");
|
||||
int lSpecularLoc = GetShaderLocation(shader, "light_specularColor");
|
||||
int lSpecIntensityLoc = GetShaderLocation(shader, "light_specIntensity");
|
||||
int lIntensityLoc = GetShaderLocation(shader, "lightIntensity");
|
||||
int lAmbientLoc = GetShaderLocation(shader, "lightAmbientColor");
|
||||
int lDiffuseLoc = GetShaderLocation(shader, "lightDiffuseColor");
|
||||
int lSpecularLoc = GetShaderLocation(shader, "lightSpecularColor");
|
||||
int lSpecIntensityLoc = GetShaderLocation(shader, "lightSpecIntensity");
|
||||
|
||||
int mAmbientLoc = GetShaderLocation(shader, "mat_ambientColor");
|
||||
int mSpecularLoc = GetShaderLocation(shader, "mat_specularColor");
|
||||
int mGlossLoc = GetShaderLocation(shader, "mat_glossiness");
|
||||
int mAmbientLoc = GetShaderLocation(shader, "matAmbientColor");
|
||||
int mSpecularLoc = GetShaderLocation(shader, "matSpecularColor");
|
||||
int mGlossLoc = GetShaderLocation(shader, "matGlossiness");
|
||||
|
||||
// Camera and light vectors shader locations
|
||||
int cameraLoc = GetShaderLocation(shader, "cameraPos");
|
||||
int lightLoc = GetShaderLocation(shader, "lightPos");
|
||||
int cameraLoc = GetShaderLocation(shader, "cameraPosition");
|
||||
int lightLoc = GetShaderLocation(shader, "lightPosition");
|
||||
|
||||
// Model and View matrix locations (required for lighting)
|
||||
int modelLoc = GetShaderLocation(shader, "modelMatrix");
|
||||
|
|
|
@ -36,10 +36,10 @@ int main()
|
|||
Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture
|
||||
SetModelTexture(&dwarf, texture); // Bind texture to model
|
||||
|
||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
||||
|
||||
Shader shader = LoadShader("resources/shaders/base.vs",
|
||||
"resources/shaders/swirl.fs"); // Load postpro shader
|
||||
Shader shader = LoadShader("resources/shaders/glsl330/base.vs",
|
||||
"resources/shaders/glsl330/swirl.fs"); // Load postpro shader
|
||||
|
||||
// Get variable (uniform) location on the shader to connect with the program
|
||||
// NOTE: If uniform variable could not be found in the shader, function returns -1
|
||||
|
@ -47,7 +47,8 @@ int main()
|
|||
|
||||
float swirlCenter[2] = { (float)screenWidth/2, (float)screenHeight/2 };
|
||||
|
||||
SetPostproShader(shader); // Set fullscreen postprocessing shader
|
||||
// Create a RenderTexture2D to be used for render to texture
|
||||
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
|
||||
|
||||
// Setup orbital camera
|
||||
SetCameraMode(CAMERA_ORBITAL); // Set an orbital camera mode
|
||||
|
@ -79,13 +80,22 @@ int main()
|
|||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
Begin3dMode(camera);
|
||||
BeginTextureMode(target); // Enable drawing to texture
|
||||
|
||||
DrawModel(dwarf, position, 2.0f, WHITE); // Draw 3d model with texture
|
||||
Begin3dMode(camera);
|
||||
|
||||
DrawGrid(10, 1.0f); // Draw a grid
|
||||
DrawModel(dwarf, position, 2.0f, WHITE); // Draw 3d model with texture
|
||||
|
||||
End3dMode();
|
||||
DrawGrid(10, 1.0f); // Draw a grid
|
||||
|
||||
End3dMode();
|
||||
|
||||
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();
|
||||
|
||||
DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY);
|
||||
|
||||
|
@ -97,11 +107,12 @@ int main()
|
|||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadShader(shader); // Unload shader
|
||||
UnloadTexture(texture); // Unload texture
|
||||
UnloadModel(dwarf); // Unload model
|
||||
UnloadShader(shader); // Unload shader
|
||||
UnloadTexture(texture); // Unload texture
|
||||
UnloadModel(dwarf); // Unload model
|
||||
UnloadRenderTexture(target); // Unload render texture
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -34,11 +34,11 @@ int main()
|
|||
|
||||
Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model
|
||||
Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture
|
||||
Shader shader = LoadShader("resources/shaders/base.vs",
|
||||
"resources/shaders/grayscale.fs"); // Load model shader
|
||||
Shader shader = LoadShader("resources/shaders/glsl330/base.vs",
|
||||
"resources/shaders/glsl330/grayscale.fs"); // Load model shader
|
||||
|
||||
SetModelShader(&dwarf, shader); // Set shader effect to 3d model
|
||||
SetModelTexture(&dwarf, texture); // Bind texture to model
|
||||
dwarf.material.shader = shader; // Set shader effect to 3d model
|
||||
dwarf.material.texDiffuse = texture; // Bind texture to model
|
||||
|
||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
||||
|
||||
|
|
|
@ -38,10 +38,11 @@ int main()
|
|||
|
||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
||||
|
||||
Shader shader = LoadShader("resources/shaders/base.vs",
|
||||
"resources/shaders/bloom.fs"); // Load postpro shader
|
||||
Shader shader = LoadShader("resources/shaders/glsl330/base.vs",
|
||||
"resources/shaders/glsl330/bloom.fs"); // Load postpro shader
|
||||
|
||||
SetPostproShader(shader); // Set fullscreen postprocessing shader
|
||||
// Create a RenderTexture2D to be used for render to texture
|
||||
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
|
||||
|
||||
// Setup orbital camera
|
||||
SetCameraMode(CAMERA_ORBITAL); // Set an orbital camera mode
|
||||
|
@ -65,15 +66,26 @@ int main()
|
|||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
Begin3dMode(camera);
|
||||
BeginTextureMode(target); // Enable drawing to texture
|
||||
|
||||
DrawModel(dwarf, position, 2.0f, WHITE); // Draw 3d model with texture
|
||||
Begin3dMode(camera);
|
||||
|
||||
DrawGrid(10, 1.0f); // Draw a grid
|
||||
DrawModel(dwarf, position, 2.0f, WHITE); // Draw 3d model with texture
|
||||
|
||||
End3dMode();
|
||||
DrawGrid(10, 1.0f); // Draw a grid
|
||||
|
||||
DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, BLACK);
|
||||
End3dMode();
|
||||
|
||||
DrawText("HELLO POSTPROCESSING!", 70, 190, 50, RED);
|
||||
|
||||
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();
|
||||
|
||||
DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, DARKGRAY);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
|
@ -83,11 +95,12 @@ int main()
|
|||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadShader(shader); // Unload shader
|
||||
UnloadTexture(texture); // Unload texture
|
||||
UnloadModel(dwarf); // Unload model
|
||||
UnloadShader(shader); // Unload shader
|
||||
UnloadTexture(texture); // Unload texture
|
||||
UnloadModel(dwarf); // Unload model
|
||||
UnloadRenderTexture(target); // Unload render texture
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -32,10 +32,9 @@ int main()
|
|||
|
||||
Texture2D sonic = LoadTexture("resources/texture_formats/sonic.png");
|
||||
|
||||
// NOTE: This shader is a bit different than model/postprocessing shaders,
|
||||
// it requires the color data for every vertice to use it in every shape or texture independently
|
||||
Shader shader = LoadShader("resources/shaders/shapes_base.vs",
|
||||
"resources/shaders/shapes_grayscale.fs");
|
||||
// NOTE: Using GLSL 330 shader version, on OpenGL ES 2.0 use GLSL 100 shader version
|
||||
Shader shader = LoadShader("resources/shaders/glsl330/base.vs",
|
||||
"resources/shaders/glsl330/grayscale.fs");
|
||||
|
||||
// Shader usage is also different than models/postprocessing, shader is just activated when required
|
||||
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
#version 330
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sum = vec4(0);
|
||||
vec4 tc = vec4(0);
|
||||
|
||||
for (int i = -4; i < 4; i++)
|
||||
{
|
||||
for (int j = -3; j < 3; j++)
|
||||
{
|
||||
sum += texture(texture0, fragTexCoord + vec2(j, i)*0.004) * 0.25;
|
||||
}
|
||||
}
|
||||
|
||||
if (texture(texture0, fragTexCoord).r < 0.3)
|
||||
{
|
||||
tc = sum*sum*0.012 + texture(texture0, fragTexCoord);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (texture(texture0, fragTexCoord).r < 0.5)
|
||||
{
|
||||
tc = sum*sum*0.009 + texture(texture0, fragTexCoord);
|
||||
}
|
||||
else
|
||||
{
|
||||
tc = sum*sum*0.0075 + texture(texture0, fragTexCoord);
|
||||
}
|
||||
}
|
||||
|
||||
fragColor = tc;
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
#version 330
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
const float renderWidth = 1280.0;
|
||||
const float renderHeight = 720.0;
|
||||
|
||||
float offset[3] = float[](0.0, 1.3846153846, 3.2307692308);
|
||||
float weight[3] = float[](0.2270270270, 0.3162162162, 0.0702702703);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 tc = texture(texture0, fragTexCoord).rgb*weight[0];
|
||||
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
tc += texture(texture0, fragTexCoord + vec2(offset[i])/renderWidth, 0.0).rgb*weight[i];
|
||||
tc += texture(texture0, fragTexCoord - vec2(offset[i])/renderWidth, 0.0).rgb*weight[i];
|
||||
}
|
||||
|
||||
fragColor = vec4(tc, 1.0);
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#version 330
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 base = texture(texture0, fragTexCoord)*fragTintColor;
|
||||
|
||||
// Convert to grayscale using NTSC conversion weights
|
||||
float gray = dot(base.rgb, vec3(0.299, 0.587, 0.114));
|
||||
|
||||
fragColor = vec4(gray, gray, gray, fragTintColor.a);
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
#version 330
|
||||
|
||||
// Vertex shader input data
|
||||
in vec2 fragTexCoord;
|
||||
in vec3 fragNormal;
|
||||
|
||||
// Diffuse data
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Light attributes
|
||||
uniform vec3 light_ambientColor = vec3(0.6, 0.3, 0);
|
||||
uniform vec3 light_diffuseColor = vec3(1, 0.5, 0);
|
||||
uniform vec3 light_specularColor = vec3(0, 1, 0);
|
||||
uniform float light_intensity = 1;
|
||||
uniform float light_specIntensity = 1;
|
||||
|
||||
// Material attributes
|
||||
uniform vec3 mat_ambientColor = vec3(1, 1, 1);
|
||||
uniform vec3 mat_specularColor = vec3(1, 1, 1);
|
||||
uniform float mat_glossiness = 50;
|
||||
|
||||
// World attributes
|
||||
uniform vec3 lightPos;
|
||||
uniform vec3 cameraPos;
|
||||
|
||||
// Fragment shader output data
|
||||
out vec4 fragColor;
|
||||
|
||||
vec3 AmbientLighting()
|
||||
{
|
||||
return mat_ambientColor * light_ambientColor;
|
||||
}
|
||||
|
||||
vec3 DiffuseLighting(in vec3 N, in vec3 L)
|
||||
{
|
||||
// Lambertian reflection calculation
|
||||
float diffuse = clamp(dot(N, L), 0, 1);
|
||||
|
||||
return tintColor.xyz * light_diffuseColor * light_intensity * diffuse;
|
||||
}
|
||||
|
||||
vec3 SpecularLighting(in vec3 N, in vec3 L, in vec3 V)
|
||||
{
|
||||
float specular = 0;
|
||||
|
||||
// Calculate specular reflection only if the surface is oriented to the light source
|
||||
if(dot(N, L) > 0)
|
||||
{
|
||||
// Calculate half vector
|
||||
vec3 H = normalize(L + V);
|
||||
|
||||
// Calculate specular intensity
|
||||
specular = pow(dot(N, H), 3 + mat_glossiness);
|
||||
}
|
||||
|
||||
return mat_specularColor * light_specularColor * light_specIntensity * specular;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// Normalize input vectors
|
||||
vec3 L = normalize(lightPos);
|
||||
vec3 V = normalize(cameraPos);
|
||||
vec3 N = normalize(fragNormal);
|
||||
|
||||
vec3 ambient = AmbientLighting();
|
||||
vec3 diffuse = DiffuseLighting(N, L);
|
||||
vec3 specular = SpecularLighting(N, L, V);
|
||||
|
||||
// Get base color from texture
|
||||
vec4 textureColor = texture(texture0, fragTexCoord);
|
||||
vec3 finalColor = textureColor.rgb;
|
||||
|
||||
fragColor = vec4(finalColor * (ambient + diffuse + specular), textureColor.a);
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
#version 330
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
float gamma = 0.6;
|
||||
float numColors = 8.0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 color = texture(texture0, fragTexCoord.xy).rgb;
|
||||
|
||||
color = pow(color, vec3(gamma, gamma, gamma));
|
||||
color = color*numColors;
|
||||
color = floor(color);
|
||||
color = color/numColors;
|
||||
color = pow(color, vec3(1.0/gamma));
|
||||
|
||||
fragColor = vec4(color, 1.0);
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
varying vec2 fragTexCoord;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 base = texture2D(texture0, fragTexCoord)*fragTintColor;
|
||||
|
||||
// Convert to grayscale using NTSC conversion weights
|
||||
float gray = dot(base.rgb, vec3(0.299, 0.587, 0.114));
|
||||
|
||||
gl_FragColor = vec4(gray, gray, gray, fragTintColor.a);
|
||||
}
|
26
shaders/glsl100/base.vs
Normal file
26
shaders/glsl100/base.vs
Normal file
|
@ -0,0 +1,26 @@
|
|||
#version 100
|
||||
|
||||
// Input vertex attributes
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec3 vertexNormal;
|
||||
attribute vec4 vertexColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvpMatrix;
|
||||
|
||||
// Output vertex attributes (to fragment shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
// Send vertex attributes to fragment shader
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragColor = vertexColor;
|
||||
|
||||
// Calculate final vertex position
|
||||
gl_Position = mvpMatrix*vec4(vertexPosition, 1.0);
|
||||
}
|
37
shaders/glsl100/bloom.fs
Normal file
37
shaders/glsl100/bloom.fs
Normal file
|
@ -0,0 +1,37 @@
|
|||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sum = vec4(0);
|
||||
vec4 tc = vec4(0);
|
||||
|
||||
for (int i = -4; i < 4; i++)
|
||||
{
|
||||
for (int j = -3; j < 3; j++)
|
||||
{
|
||||
sum += texture2D(texture0, fragTexCoord + vec2(j, i)*0.004) * 0.25;
|
||||
}
|
||||
}
|
||||
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||
|
||||
// Calculate final fragment color
|
||||
if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor;
|
||||
else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor;
|
||||
else tc = sum*sum*0.0075 + texelColor;
|
||||
|
||||
gl_FragColor = tc;
|
||||
}
|
|
@ -2,7 +2,11 @@
|
|||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
|
@ -16,6 +20,7 @@ float weight[3] = float[]( 0.2270270270, 0.3162162162, 0.0702702703 );
|
|||
|
||||
void main()
|
||||
{
|
||||
// Texel color fetching from texture sampler
|
||||
vec3 tc = texture2D(texture0, fragTexCoord).rgb*weight[0];
|
||||
|
||||
for (int i = 1; i < 3; i++)
|
|
@ -2,8 +2,11 @@
|
|||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
|
@ -2,8 +2,11 @@
|
|||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
|
@ -46,7 +49,7 @@ vec4 PostFX(sampler2D tex, vec2 uv)
|
|||
return c;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
void main()
|
||||
{
|
||||
vec3 tc = PostFX(texture0, fragTexCoord).rgb;
|
||||
|
|
@ -2,8 +2,11 @@
|
|||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
|
@ -2,8 +2,11 @@
|
|||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
25
shaders/glsl100/grayscale.fs
Normal file
25
shaders/glsl100/grayscale.fs
Normal file
|
@ -0,0 +1,25 @@
|
|||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = texture(texture0, fragTexCoord)*fragTintColor*fragColor;
|
||||
|
||||
// Convert texel color to grayscale using NTSC conversion weights
|
||||
float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114));
|
||||
|
||||
// Calculate final fragment color
|
||||
gl_FragColor = vec4(gray, gray, gray, texelColor.a);
|
||||
}
|
|
@ -2,8 +2,11 @@
|
|||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
|
@ -2,8 +2,11 @@
|
|||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
|
@ -2,8 +2,11 @@
|
|||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
|
@ -2,8 +2,11 @@
|
|||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
|
@ -14,7 +17,7 @@ float frequency = 720/3.0;
|
|||
|
||||
uniform float time;
|
||||
|
||||
void main (void)
|
||||
void main()
|
||||
{
|
||||
/*
|
||||
// Scanlines method 1
|
|
@ -2,26 +2,30 @@
|
|||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
const float renderWidth = 1280;
|
||||
const float renderHeight = 720;
|
||||
const float renderWidth = 800.0; // HARDCODED for example!
|
||||
const float renderHeight = 480.0; // Use uniforms instead...
|
||||
|
||||
float radius = 250.0;
|
||||
float angle = 0.8;
|
||||
|
||||
uniform vec2 center = vec2(200, 200);
|
||||
uniform vec2 center = vec2(200.0, 200.0);
|
||||
|
||||
void main (void)
|
||||
void main()
|
||||
{
|
||||
vec2 texSize = vec2(renderWidth, renderHeight);
|
||||
vec2 tc = fragTexCoord*texSize;
|
||||
tc -= center;
|
||||
|
||||
float dist = length(tc);
|
||||
|
||||
if (dist < radius)
|
|
@ -2,8 +2,11 @@
|
|||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
|
@ -11,6 +14,7 @@ uniform vec4 fragTintColor;
|
|||
|
||||
void main()
|
||||
{
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = texture2D(texture0, fragTexCoord);
|
||||
|
||||
// NOTE: Implement here your fragment shader code
|
|
@ -1,18 +1,26 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes
|
||||
in vec3 vertexPosition;
|
||||
in vec2 vertexTexCoord;
|
||||
in vec3 vertexNormal;
|
||||
in vec4 vertexColor;
|
||||
|
||||
out vec2 fragTexCoord;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvpMatrix;
|
||||
|
||||
// Output vertex attributes (to fragment shader)
|
||||
out vec2 fragTexCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
// Send vertex attributes to fragment shader
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragColor = vertexColor;
|
||||
|
||||
// Calculate final vertex position
|
||||
gl_Position = mvpMatrix*vec4(vertexPosition, 1.0);
|
||||
}
|
38
shaders/glsl330/bloom.fs
Normal file
38
shaders/glsl330/bloom.fs
Normal file
|
@ -0,0 +1,38 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sum = vec4(0);
|
||||
vec4 tc = vec4(0);
|
||||
|
||||
for (int i = -4; i < 4; i++)
|
||||
{
|
||||
for (int j = -3; j < 3; j++)
|
||||
{
|
||||
sum += texture(texture0, fragTexCoord + vec2(j, i)*0.004)*0.25;
|
||||
}
|
||||
}
|
||||
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||
|
||||
// Calculate final fragment color
|
||||
if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor;
|
||||
else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor;
|
||||
else tc = sum*sum*0.0075 + texelColor;
|
||||
|
||||
finalColor = tc;
|
||||
}
|
34
shaders/glsl330/blur.fs
Normal file
34
shaders/glsl330/blur.fs
Normal file
|
@ -0,0 +1,34 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
const float renderWidth = 1280.0;
|
||||
const float renderHeight = 720.0;
|
||||
|
||||
float offset[3] = float[](0.0, 1.3846153846, 3.2307692308);
|
||||
float weight[3] = float[](0.2270270270, 0.3162162162, 0.0702702703);
|
||||
|
||||
void main()
|
||||
{
|
||||
// Texel color fetching from texture sampler
|
||||
vec3 texelColor = texture(texture0, fragTexCoord).rgb*weight[0];
|
||||
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
texelColor += texture(texture0, fragTexCoord + vec2(offset[i])/renderWidth, 0.0).rgb*weight[i];
|
||||
texelColor += texture(texture0, fragTexCoord - vec2(offset[i])/renderWidth, 0.0).rgb*weight[i];
|
||||
}
|
||||
|
||||
finalColor = vec4(texelColor, 1.0);
|
||||
}
|
|
@ -1,12 +1,16 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
float hatchOffsetY = 5.0;
|
||||
|
@ -27,18 +31,18 @@ void main()
|
|||
|
||||
if (lum < lumThreshold02)
|
||||
{
|
||||
if (mod(gl_FragCoord .x - gl_FragCoord .y, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0);
|
||||
if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
if (lum < lumThreshold03)
|
||||
{
|
||||
if (mod(gl_FragCoord .x + gl_FragCoord .y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0);
|
||||
if (mod(gl_FragCoord.x + gl_FragCoord.y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
if (lum < lumThreshold04)
|
||||
{
|
||||
if (mod(gl_FragCoord .x - gl_FragCoord .y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0);
|
||||
if (mod(gl_FragCoord.x - gl_FragCoord.y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
fragColor = vec4(tc, 1.0);
|
||||
finalColor = vec4(tc, 1.0);
|
||||
}
|
|
@ -1,12 +1,16 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
const float renderWidth = 1280.0;
|
||||
|
@ -46,9 +50,9 @@ vec4 PostFX(sampler2D tex, vec2 uv)
|
|||
return c;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
void main()
|
||||
{
|
||||
vec3 tc = PostFX(texture0, fragTexCoord).rgb;
|
||||
|
||||
fragColor = vec4(tc, 1.0);
|
||||
finalColor = vec4(tc, 1.0);
|
||||
}
|
27
shaders/glsl330/depth.fs
Normal file
27
shaders/glsl330/depth.fs
Normal file
|
@ -0,0 +1,27 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0; // Depth texture
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
float zNear = 0.01; // camera z near
|
||||
float zFar = 10.0; // camera z far
|
||||
float z = texture(texture0, fragTexCoord).x;
|
||||
|
||||
// Linearize depth value
|
||||
float depth = (2.0*zNear)/(zFar + zNear - z*(zFar - zNear));
|
||||
|
||||
// Calculate final fragment color
|
||||
finalColor = vec4(depth, depth, depth, 1.0f);
|
||||
}
|
26
shaders/glsl330/grayscale.fs
Normal file
26
shaders/glsl330/grayscale.fs
Normal file
|
@ -0,0 +1,26 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = texture(texture0, fragTexCoord)*fragTintColor*fragColor;
|
||||
|
||||
// Convert texel color to grayscale using NTSC conversion weights
|
||||
float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114));
|
||||
|
||||
// Calculate final fragment color
|
||||
finalColor = vec4(gray, gray, gray, texelColor.a);
|
||||
}
|
85
shaders/glsl330/phong.fs
Normal file
85
shaders/glsl330/phong.fs
Normal file
|
@ -0,0 +1,85 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec3 fragNormal;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
// Light uniform values
|
||||
uniform vec3 lightAmbientColor = vec3(0.6, 0.3, 0.0);
|
||||
uniform vec3 lightDiffuseColor = vec3(1.0, 0.5, 0.0);
|
||||
uniform vec3 lightSpecularColor = vec3(0.0, 1.0, 0.0);
|
||||
uniform float lightIntensity = 1.0;
|
||||
uniform float lightSpecIntensity = 1.0;
|
||||
|
||||
// Material uniform values
|
||||
uniform vec3 matAmbientColor = vec3(1.0, 1.0, 1.0);
|
||||
uniform vec3 matSpecularColor = vec3(1.0, 1.0, 1.0);
|
||||
uniform float matGlossiness = 50.0;
|
||||
|
||||
// World uniform values
|
||||
uniform vec3 lightPosition;
|
||||
uniform vec3 cameraPosition;
|
||||
|
||||
// Fragment shader output data
|
||||
out vec4 fragColor;
|
||||
|
||||
// Calculate ambient lighting component
|
||||
vec3 AmbientLighting()
|
||||
{
|
||||
return (matAmbientColor*lightAmbientColor);
|
||||
}
|
||||
|
||||
// Calculate diffuse lighting component
|
||||
vec3 DiffuseLighting(in vec3 N, in vec3 L)
|
||||
{
|
||||
// Lambertian reflection calculation
|
||||
float diffuse = clamp(dot(N, L), 0, 1);
|
||||
|
||||
return (fragTintColor.xyz*lightDiffuseColor*lightIntensity*diffuse);
|
||||
}
|
||||
|
||||
// Calculate specular lighting component
|
||||
vec3 SpecularLighting(in vec3 N, in vec3 L, in vec3 V)
|
||||
{
|
||||
float specular = 0.0;
|
||||
|
||||
// Calculate specular reflection only if the surface is oriented to the light source
|
||||
if (dot(N, L) > 0)
|
||||
{
|
||||
// Calculate half vector
|
||||
vec3 H = normalize(L + V);
|
||||
|
||||
// Calculate specular intensity
|
||||
specular = pow(dot(N, H), 3 + matGlossiness);
|
||||
}
|
||||
|
||||
return (matSpecularColor*lightSpecularColor*lightSpecIntensity*specular);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// Normalize input vectors
|
||||
vec3 L = normalize(lightPosition);
|
||||
vec3 V = normalize(cameraPosition);
|
||||
vec3 N = normalize(fragNormal);
|
||||
|
||||
// Calculate lighting components
|
||||
vec3 ambient = AmbientLighting();
|
||||
vec3 diffuse = DiffuseLighting(N, L);
|
||||
vec3 specular = SpecularLighting(N, L, V);
|
||||
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||
|
||||
// Calculate final fragment color
|
||||
finalColor = vec4(texelColor.rgb*(ambient + diffuse + specular), texelColor.a);
|
||||
}
|
|
@ -1,21 +1,23 @@
|
|||
#version 330
|
||||
|
||||
// Vertex input data
|
||||
// Input vertex attributes
|
||||
in vec3 vertexPosition;
|
||||
in vec2 vertexTexCoord;
|
||||
in vec3 vertexNormal;
|
||||
|
||||
// Projection and model data
|
||||
// Input uniform values
|
||||
uniform mat4 mvpMatrix;
|
||||
uniform mat4 modelMatrix;
|
||||
|
||||
// Attributes to fragment shader
|
||||
// Output vertex attributes (to fragment shader)
|
||||
out vec2 fragTexCoord;
|
||||
out vec3 fragNormal;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
uniform mat4 modelMatrix;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Send texture coord to fragment shader
|
||||
// Send vertex attributes to fragment shader
|
||||
fragTexCoord = vertexTexCoord;
|
||||
|
||||
// Calculate view vector normal from model
|
|
@ -1,12 +1,16 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
const float renderWidth = 1280.0;
|
||||
|
@ -24,5 +28,5 @@ void main()
|
|||
|
||||
vec3 tc = texture(texture0, coord).rgb;
|
||||
|
||||
fragColor = vec4(tc, 1.0);
|
||||
finalColor = vec4(tc, 1.0);
|
||||
}
|
31
shaders/glsl330/posterization.fs
Normal file
31
shaders/glsl330/posterization.fs
Normal file
|
@ -0,0 +1,31 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
float gamma = 0.6;
|
||||
float numColors = 8.0;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Texel color fetching from texture sampler
|
||||
vec3 texelColor = texture(texture0, fragTexCoord.xy).rgb;
|
||||
|
||||
texelColor = pow(texelColor, vec3(gamma, gamma, gamma));
|
||||
texelColor = texelColor*numColors;
|
||||
texelColor = floor(texelColor);
|
||||
texelColor = texelColor/numColors;
|
||||
texelColor = pow(texelColor, vec3(1.0/gamma));
|
||||
|
||||
finalColor = vec4(texelColor, 1.0);
|
||||
}
|
|
@ -1,27 +1,32 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 color = texture(texture0, fragTexCoord).rgb;
|
||||
// Texel color fetching from texture sampler
|
||||
vec3 texelColor = texture(texture0, fragTexCoord).rgb;
|
||||
vec3 colors[3];
|
||||
colors[0] = vec3(0.0, 0.0, 1.0);
|
||||
colors[1] = vec3(1.0, 1.0, 0.0);
|
||||
colors[2] = vec3(1.0, 0.0, 0.0);
|
||||
|
||||
float lum = (color.r + color.g + color.b)/3.0;
|
||||
float lum = (texelColor.r + texelColor.g + texelColor.b)/3.0;
|
||||
|
||||
int ix = (lum < 0.5)? 0:1;
|
||||
|
||||
vec3 tc = mix(colors[ix], colors[ix + 1], (lum - float(ix)*0.5)/0.5);
|
||||
|
||||
fragColor = vec4(tc, 1.0);
|
||||
finalColor = vec4(tc, 1.0);
|
||||
}
|
|
@ -1,12 +1,16 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
float offset = 0.0;
|
||||
|
@ -14,7 +18,7 @@ float frequency = 720.0/3.0;
|
|||
|
||||
uniform float time;
|
||||
|
||||
void main (void)
|
||||
void main()
|
||||
{
|
||||
/*
|
||||
// Scanlines method 1
|
||||
|
@ -35,7 +39,8 @@ void main (void)
|
|||
float globalPos = (fragTexCoord.y + offset) * frequency;
|
||||
float wavePos = cos((fract(globalPos) - 0.5)*3.14);
|
||||
|
||||
vec4 color = texture(texture0, fragTexCoord);
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||
|
||||
fragColor = mix(vec4(0.0, 0.3, 0.0, 0.0), color, wavePos);
|
||||
finalColor = mix(vec4(0.0, 0.3, 0.0, 0.0), texelColor, wavePos);
|
||||
}
|
46
shaders/glsl330/swirl.fs
Normal file
46
shaders/glsl330/swirl.fs
Normal file
|
@ -0,0 +1,46 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
const float renderWidth = 800.0; // HARDCODED for example!
|
||||
const float renderHeight = 480.0; // Use uniforms instead...
|
||||
|
||||
float radius = 250.0;
|
||||
float angle = 0.8;
|
||||
|
||||
uniform vec2 center = vec2(200.0, 200.0);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 texSize = vec2(renderWidth, renderHeight);
|
||||
vec2 tc = fragTexCoord*texSize;
|
||||
tc -= center;
|
||||
|
||||
float dist = length(tc);
|
||||
|
||||
if (dist < radius)
|
||||
{
|
||||
float percent = (radius - dist)/radius;
|
||||
float theta = percent*percent*angle*8.0;
|
||||
float s = sin(theta);
|
||||
float c = cos(theta);
|
||||
|
||||
tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c)));
|
||||
}
|
||||
|
||||
tc += center;
|
||||
vec3 color = texture(texture0, tc/texSize).rgb;
|
||||
|
||||
finalColor = vec4(color, 1.0);;
|
||||
}
|
|
@ -1,19 +1,24 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 fragTintColor;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||
|
||||
// NOTE: Implement here your fragment shader code
|
||||
|
||||
fragColor = texelColor*fragTintColor;
|
||||
finalColor = texelColor*fragTintColor;
|
||||
}
|
28
src/Makefile
28
src/Makefile
|
@ -21,6 +21,8 @@
|
|||
#
|
||||
#**************************************************************************************************
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
# define raylib platform to compile for
|
||||
# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
@ -84,8 +86,6 @@ else
|
|||
# external libraries headers
|
||||
# GLFW3
|
||||
INCLUDES += -I../external/glfw3/include
|
||||
# GLEW
|
||||
INCLUDES += -I../external/glew/include
|
||||
# OpenAL Soft
|
||||
INCLUDES += -I../external/openal_soft/include
|
||||
endif
|
||||
|
@ -99,9 +99,9 @@ else
|
|||
endif
|
||||
|
||||
|
||||
# typing 'make' will invoke the first target entry in the file,
|
||||
# in this case, the 'default' target entry is raylib
|
||||
default: raylib
|
||||
# typing 'make' will invoke the default target entry called 'all',
|
||||
# in this case, the 'default' target entry is basic_game
|
||||
all: raylib
|
||||
|
||||
# compile raylib library
|
||||
raylib: $(OBJS)
|
||||
|
@ -163,21 +163,21 @@ gestures.o: gestures.c
|
|||
# clean everything
|
||||
clean:
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
rm -f *.o libraylib.a
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -f
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
del *.o libraylib.a
|
||||
else
|
||||
rm -f *.o libraylib.a
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
del *.o libraylib.bc
|
||||
else
|
||||
rm -f *.o libraylib.bc
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
rm -f *.o libraylib.a
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.o libraylib.bc
|
||||
endif
|
||||
@echo Cleaning done
|
||||
|
||||
|
|
650
src/audio.c
650
src/audio.c
|
@ -37,6 +37,7 @@
|
|||
|
||||
#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 <stdlib.h> // Declares malloc() and free() for memory management
|
||||
#include <string.h> // Required for strcmp()
|
||||
|
@ -52,37 +53,55 @@
|
|||
//#define STB_VORBIS_HEADER_ONLY
|
||||
#include "stb_vorbis.h" // OGG loading functions
|
||||
|
||||
#define JAR_XM_IMPLEMENTATION
|
||||
#include "jar_xm.h" // For playing .xm files
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
#define MUSIC_STREAM_BUFFERS 2
|
||||
#define MAX_STREAM_BUFFERS 2 // Number of buffers for each alSource
|
||||
#define MAX_MIX_CHANNELS 4 // Number of open AL sources
|
||||
#define MAX_MUSIC_STREAMS 2 // Number of simultanious music sources
|
||||
|
||||
#if defined(PLATFORM_RPI)
|
||||
// NOTE: On RPI should be lower to avoid frame-stalls
|
||||
#define MUSIC_BUFFER_SIZE 4096*2 // PCM data buffer (short) - 16Kb (RPI)
|
||||
#if defined(PLATFORM_RPI) || defined(PLATFORM_ANDROID)
|
||||
// NOTE: On RPI and Android should be lower to avoid frame-stalls
|
||||
#define MUSIC_BUFFER_SIZE_SHORT 4096*2 // PCM data buffer (short) - 16Kb (RPI)
|
||||
#define MUSIC_BUFFER_SIZE_FLOAT 4096 // PCM data buffer (float) - 16Kb (RPI)
|
||||
#else
|
||||
// NOTE: On HTML5 (emscripten) this is allocated on heap, by default it's only 16MB!...just take care...
|
||||
#define MUSIC_BUFFER_SIZE 4096*8 // PCM data buffer (short) - 64Kb
|
||||
#define MUSIC_BUFFER_SIZE_SHORT 4096*8 // PCM data buffer (short) - 64Kb
|
||||
#define MUSIC_BUFFER_SIZE_FLOAT 4096*4 // PCM data buffer (float) - 64Kb
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Used to create custom audio streams that are not bound to a specific file. There can be
|
||||
// no more than 4 concurrent mixchannels in use. This is due to each active mixc being tied to
|
||||
// a dedicated mix channel.
|
||||
typedef struct MixChannel_t {
|
||||
unsigned short sampleRate; // default is 48000
|
||||
unsigned char channels; // 1=mono,2=stereo
|
||||
unsigned char mixChannel; // 0-3 or mixA-mixD, each mix channel can receive up to one dedicated audio stream
|
||||
bool floatingPoint; // if false then the short datatype is used instead
|
||||
bool playing; // false if paused
|
||||
ALenum alFormat; // openAL format specifier
|
||||
ALuint alSource; // openAL source
|
||||
ALuint alBuffer[MAX_STREAM_BUFFERS]; // openAL sample buffer
|
||||
} MixChannel_t;
|
||||
|
||||
// Music type (file streaming from memory)
|
||||
// NOTE: Anything longer than ~10 seconds should be streamed...
|
||||
// NOTE: Anything longer than ~10 seconds should be streamed into a mix channel...
|
||||
typedef struct Music {
|
||||
stb_vorbis *stream;
|
||||
jar_xm_context_t *chipctx; // Stores jar_xm mixc
|
||||
MixChannel_t *mixc; // mix channel
|
||||
|
||||
ALuint buffers[MUSIC_STREAM_BUFFERS];
|
||||
ALuint source;
|
||||
ALenum format;
|
||||
|
||||
int channels;
|
||||
int sampleRate;
|
||||
int totalSamplesLeft;
|
||||
float totalLengthSeconds;
|
||||
bool loop;
|
||||
|
||||
bool chipTune; // True if chiptune is loaded
|
||||
} Music;
|
||||
|
||||
#if defined(AUDIO_STANDALONE)
|
||||
|
@ -92,19 +111,28 @@ typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
|
|||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
static bool musicEnabled = false;
|
||||
static Music currentMusic; // Current music loaded
|
||||
// NOTE: Only one music file playing at a time
|
||||
static MixChannel_t* mixChannelsActive_g[MAX_MIX_CHANNELS]; // What mix channels are currently active
|
||||
static bool musicEnabled_g = false;
|
||||
static Music currentMusic[MAX_MUSIC_STREAMS]; // Current music loaded, up to two can play at the same time
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
static Wave LoadWAV(const char *fileName); // Load WAV file
|
||||
static Wave LoadOGG(char *fileName); // Load OGG file
|
||||
static void UnloadWave(Wave wave); // Unload wave data
|
||||
static Wave LoadWAV(const char *fileName); // Load WAV file
|
||||
static Wave LoadOGG(char *fileName); // Load OGG file
|
||||
static void UnloadWave(Wave wave); // Unload wave data
|
||||
|
||||
static bool BufferMusicStream(ALuint buffer); // Fill music buffers with data
|
||||
static void EmptyMusicStream(void); // Empty music buffers
|
||||
static bool BufferMusicStream(int index, int numBuffers); // Fill music buffers with data
|
||||
static void EmptyMusicStream(int index); // Empty music buffers
|
||||
|
||||
|
||||
static MixChannel_t* InitMixChannel(unsigned short sampleRate, unsigned char mixChannel, unsigned char channels, bool floatingPoint); // For streaming into mix channels.
|
||||
static void CloseMixChannel(MixChannel_t* mixc); // Frees mix channel
|
||||
static int BufferMixChannel(MixChannel_t* mixc, void *data, int numberElements); // Pushes more audio data into mixc mix channel, if NULL is passed it pauses
|
||||
static int FillAlBufferWithSilence(MixChannel_t *mixc, ALuint buffer); // Fill buffer with zeros, returns number processed
|
||||
static void ResampleShortToFloat(short *shorts, float *floats, unsigned short len); // Pass two arrays of the same legnth in
|
||||
static void ResampleByteToFloat(char *chars, float *floats, unsigned short len); // Pass two arrays of same length in
|
||||
static int IsMusicStreamReadyForBuffering(int index); // Checks if music buffer is ready to be refilled
|
||||
|
||||
#if defined(AUDIO_STANDALONE)
|
||||
const char *GetExtension(const char *fileName); // Get the extension for a filename
|
||||
|
@ -115,7 +143,7 @@ void TraceLog(int msgType, const char *text, ...); // Outputs a trace log messa
|
|||
// Module Functions Definition - Audio Device initialization and Closing
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Initialize audio device and context
|
||||
// Initialize audio device and mixc
|
||||
void InitAudioDevice(void)
|
||||
{
|
||||
// Open and initialize a device with default settings
|
||||
|
@ -131,7 +159,7 @@ void InitAudioDevice(void)
|
|||
|
||||
alcCloseDevice(device);
|
||||
|
||||
TraceLog(ERROR, "Could not setup audio context");
|
||||
TraceLog(ERROR, "Could not setup mix channel");
|
||||
}
|
||||
|
||||
TraceLog(INFO, "Audio device and context initialized successfully: %s", alcGetString(device, ALC_DEVICE_SPECIFIER));
|
||||
|
@ -142,15 +170,19 @@ void InitAudioDevice(void)
|
|||
alListener3f(AL_ORIENTATION, 0, 0, -1);
|
||||
}
|
||||
|
||||
// Close the audio device for the current context, and destroys the context
|
||||
// Close the audio device for all contexts
|
||||
void CloseAudioDevice(void)
|
||||
{
|
||||
StopMusicStream(); // Stop music streaming and close current stream
|
||||
for(int index=0; index<MAX_MUSIC_STREAMS; index++)
|
||||
{
|
||||
if(currentMusic[index].mixc) StopMusicStream(index); // Stop music streaming and close current stream
|
||||
}
|
||||
|
||||
|
||||
ALCdevice *device;
|
||||
ALCcontext *context = alcGetCurrentContext();
|
||||
|
||||
if (context == NULL) TraceLog(WARNING, "Could not get current audio context for closing");
|
||||
if (context == NULL) TraceLog(WARNING, "Could not get current mix channel for closing");
|
||||
|
||||
device = alcGetContextsDevice(context);
|
||||
|
||||
|
@ -159,6 +191,229 @@ void CloseAudioDevice(void)
|
|||
alcCloseDevice(device);
|
||||
}
|
||||
|
||||
// True if call to InitAudioDevice() was successful and CloseAudioDevice() has not been called yet
|
||||
bool IsAudioDeviceReady(void)
|
||||
{
|
||||
ALCcontext *context = alcGetCurrentContext();
|
||||
if (context == NULL) return false;
|
||||
else{
|
||||
ALCdevice *device = alcGetContextsDevice(context);
|
||||
if (device == NULL) return false;
|
||||
else return true;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition - Custom audio output
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// For streaming into mix channels.
|
||||
// The mixChannel is what audio muxing channel you want to operate on, 0-3 are the ones available. Each mix channel can only be used one at a time.
|
||||
// exmple usage is InitMixChannel(48000, 0, 2, true); // mixchannel 1, 48khz, stereo, floating point
|
||||
static MixChannel_t* InitMixChannel(unsigned short sampleRate, unsigned char mixChannel, unsigned char channels, bool floatingPoint)
|
||||
{
|
||||
if(mixChannel >= MAX_MIX_CHANNELS) return NULL;
|
||||
if(!IsAudioDeviceReady()) InitAudioDevice();
|
||||
|
||||
if(!mixChannelsActive_g[mixChannel]){
|
||||
MixChannel_t *mixc = (MixChannel_t*)malloc(sizeof(MixChannel_t));
|
||||
mixc->sampleRate = sampleRate;
|
||||
mixc->channels = channels;
|
||||
mixc->mixChannel = mixChannel;
|
||||
mixc->floatingPoint = floatingPoint;
|
||||
mixChannelsActive_g[mixChannel] = mixc;
|
||||
|
||||
// setup openAL format
|
||||
if(channels == 1)
|
||||
{
|
||||
if(floatingPoint)
|
||||
mixc->alFormat = AL_FORMAT_MONO_FLOAT32;
|
||||
else
|
||||
mixc->alFormat = AL_FORMAT_MONO16;
|
||||
}
|
||||
else if(channels == 2)
|
||||
{
|
||||
if(floatingPoint)
|
||||
mixc->alFormat = AL_FORMAT_STEREO_FLOAT32;
|
||||
else
|
||||
mixc->alFormat = AL_FORMAT_STEREO16;
|
||||
}
|
||||
|
||||
// Create an audio source
|
||||
alGenSources(1, &mixc->alSource);
|
||||
alSourcef(mixc->alSource, AL_PITCH, 1);
|
||||
alSourcef(mixc->alSource, AL_GAIN, 1);
|
||||
alSource3f(mixc->alSource, AL_POSITION, 0, 0, 0);
|
||||
alSource3f(mixc->alSource, AL_VELOCITY, 0, 0, 0);
|
||||
|
||||
// Create Buffer
|
||||
alGenBuffers(MAX_STREAM_BUFFERS, mixc->alBuffer);
|
||||
|
||||
//fill buffers
|
||||
int x;
|
||||
for(x=0;x<MAX_STREAM_BUFFERS;x++)
|
||||
FillAlBufferWithSilence(mixc, mixc->alBuffer[x]);
|
||||
|
||||
alSourceQueueBuffers(mixc->alSource, MAX_STREAM_BUFFERS, mixc->alBuffer);
|
||||
mixc->playing = true;
|
||||
alSourcePlay(mixc->alSource);
|
||||
|
||||
return mixc;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Frees buffer in mix channel
|
||||
static void CloseMixChannel(MixChannel_t* mixc)
|
||||
{
|
||||
if(mixc){
|
||||
alSourceStop(mixc->alSource);
|
||||
mixc->playing = false;
|
||||
|
||||
//flush out all queued buffers
|
||||
ALuint buffer = 0;
|
||||
int queued = 0;
|
||||
alGetSourcei(mixc->alSource, AL_BUFFERS_QUEUED, &queued);
|
||||
while (queued > 0)
|
||||
{
|
||||
alSourceUnqueueBuffers(mixc->alSource, 1, &buffer);
|
||||
queued--;
|
||||
}
|
||||
|
||||
//delete source and buffers
|
||||
alDeleteSources(1, &mixc->alSource);
|
||||
alDeleteBuffers(MAX_STREAM_BUFFERS, mixc->alBuffer);
|
||||
mixChannelsActive_g[mixc->mixChannel] = NULL;
|
||||
free(mixc);
|
||||
mixc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Pushes more audio data into mixc mix channel, only one buffer per call
|
||||
// Call "BufferMixChannel(mixc, NULL, 0)" if you want to pause the audio.
|
||||
// @Returns number of samples that where processed.
|
||||
static int BufferMixChannel(MixChannel_t* mixc, void *data, int numberElements)
|
||||
{
|
||||
if(!mixc || mixChannelsActive_g[mixc->mixChannel] != mixc) return 0; // when there is two channels there must be an even number of samples
|
||||
|
||||
if (!data || !numberElements)
|
||||
{ // pauses audio until data is given
|
||||
if(mixc->playing){
|
||||
alSourcePause(mixc->alSource);
|
||||
mixc->playing = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if(!mixc->playing)
|
||||
{ // restart audio otherwise
|
||||
alSourcePlay(mixc->alSource);
|
||||
mixc->playing = true;
|
||||
}
|
||||
|
||||
|
||||
ALuint buffer = 0;
|
||||
|
||||
alSourceUnqueueBuffers(mixc->alSource, 1, &buffer);
|
||||
if(!buffer) return 0;
|
||||
if(mixc->floatingPoint) // process float buffers
|
||||
{
|
||||
float *ptr = (float*)data;
|
||||
alBufferData(buffer, mixc->alFormat, ptr, numberElements*sizeof(float), mixc->sampleRate);
|
||||
}
|
||||
else // process short buffers
|
||||
{
|
||||
short *ptr = (short*)data;
|
||||
alBufferData(buffer, mixc->alFormat, ptr, numberElements*sizeof(short), mixc->sampleRate);
|
||||
}
|
||||
alSourceQueueBuffers(mixc->alSource, 1, &buffer);
|
||||
|
||||
return numberElements;
|
||||
}
|
||||
|
||||
// fill buffer with zeros, returns number processed
|
||||
static int FillAlBufferWithSilence(MixChannel_t *mixc, ALuint buffer)
|
||||
{
|
||||
if(mixc->floatingPoint){
|
||||
float pcm[MUSIC_BUFFER_SIZE_FLOAT] = {0.f};
|
||||
alBufferData(buffer, mixc->alFormat, pcm, MUSIC_BUFFER_SIZE_FLOAT*sizeof(float), mixc->sampleRate);
|
||||
return MUSIC_BUFFER_SIZE_FLOAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
short pcm[MUSIC_BUFFER_SIZE_SHORT] = {0};
|
||||
alBufferData(buffer, mixc->alFormat, pcm, MUSIC_BUFFER_SIZE_SHORT*sizeof(short), mixc->sampleRate);
|
||||
return MUSIC_BUFFER_SIZE_SHORT;
|
||||
}
|
||||
}
|
||||
|
||||
// example usage:
|
||||
// short sh[3] = {1,2,3};float fl[3];
|
||||
// ResampleShortToFloat(sh,fl,3);
|
||||
static void ResampleShortToFloat(short *shorts, float *floats, unsigned short len)
|
||||
{
|
||||
int x;
|
||||
for(x=0;x<len;x++)
|
||||
{
|
||||
if(shorts[x] < 0)
|
||||
floats[x] = (float)shorts[x] / 32766.f;
|
||||
else
|
||||
floats[x] = (float)shorts[x] / 32767.f;
|
||||
}
|
||||
}
|
||||
|
||||
// example usage:
|
||||
// char ch[3] = {1,2,3};float fl[3];
|
||||
// ResampleByteToFloat(ch,fl,3);
|
||||
static void ResampleByteToFloat(char *chars, float *floats, unsigned short len)
|
||||
{
|
||||
int x;
|
||||
for(x=0;x<len;x++)
|
||||
{
|
||||
if(chars[x] < 0)
|
||||
floats[x] = (float)chars[x] / 127.f;
|
||||
else
|
||||
floats[x] = (float)chars[x] / 128.f;
|
||||
}
|
||||
}
|
||||
|
||||
// used to output raw audio streams, returns negative numbers on error
|
||||
// if floating point is false the data size is 16bit short, otherwise it is float 32bit
|
||||
RawAudioContext InitRawAudioContext(int sampleRate, int channels, bool floatingPoint)
|
||||
{
|
||||
int mixIndex;
|
||||
for(mixIndex = 0; mixIndex < MAX_MIX_CHANNELS; mixIndex++) // find empty mix channel slot
|
||||
{
|
||||
if(mixChannelsActive_g[mixIndex] == NULL) break;
|
||||
else if(mixIndex = MAX_MIX_CHANNELS - 1) return -1; // error
|
||||
}
|
||||
|
||||
if(InitMixChannel(sampleRate, mixIndex, channels, floatingPoint))
|
||||
return mixIndex;
|
||||
else
|
||||
return -2; // error
|
||||
}
|
||||
|
||||
void CloseRawAudioContext(RawAudioContext ctx)
|
||||
{
|
||||
if(mixChannelsActive_g[ctx])
|
||||
CloseMixChannel(mixChannelsActive_g[ctx]);
|
||||
}
|
||||
|
||||
int BufferRawAudioContext(RawAudioContext ctx, void *data, int numberElements)
|
||||
{
|
||||
int numBuffered = 0;
|
||||
if(ctx >= 0)
|
||||
{
|
||||
MixChannel_t* mixc = mixChannelsActive_g[ctx];
|
||||
numBuffered = BufferMixChannel(mixc, data, numberElements);
|
||||
}
|
||||
return numBuffered;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition - Sounds loading and playing (.WAV)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -479,7 +734,7 @@ void StopSound(Sound sound)
|
|||
}
|
||||
|
||||
// Check if a sound is playing
|
||||
bool SoundIsPlaying(Sound sound)
|
||||
bool IsSoundPlaying(Sound sound)
|
||||
{
|
||||
bool playing = false;
|
||||
ALint state;
|
||||
|
@ -507,145 +762,217 @@ void SetSoundPitch(Sound sound, float pitch)
|
|||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Start music playing (open stream)
|
||||
void PlayMusicStream(char *fileName)
|
||||
// returns 0 on success
|
||||
int PlayMusicStream(int musicIndex, char *fileName)
|
||||
{
|
||||
int mixIndex;
|
||||
|
||||
if(currentMusic[musicIndex].stream || currentMusic[musicIndex].chipctx) return 1; // error
|
||||
|
||||
for(mixIndex = 0; mixIndex < MAX_MIX_CHANNELS; mixIndex++) // find empty mix channel slot
|
||||
{
|
||||
if(mixChannelsActive_g[mixIndex] == NULL) break;
|
||||
else if(mixIndex = MAX_MIX_CHANNELS - 1) return 2; // error
|
||||
}
|
||||
|
||||
if (strcmp(GetExtension(fileName),"ogg") == 0)
|
||||
{
|
||||
// Stop current music, clean buffers, unload current stream
|
||||
StopMusicStream();
|
||||
|
||||
// Open audio stream
|
||||
currentMusic.stream = stb_vorbis_open_filename(fileName, NULL, NULL);
|
||||
currentMusic[musicIndex].stream = stb_vorbis_open_filename(fileName, NULL, NULL);
|
||||
|
||||
if (currentMusic.stream == NULL)
|
||||
if (currentMusic[musicIndex].stream == NULL)
|
||||
{
|
||||
TraceLog(WARNING, "[%s] OGG audio file could not be opened", fileName);
|
||||
return 3; // error
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get file info
|
||||
stb_vorbis_info info = stb_vorbis_get_info(currentMusic.stream);
|
||||
|
||||
currentMusic.channels = info.channels;
|
||||
currentMusic.sampleRate = info.sample_rate;
|
||||
stb_vorbis_info info = stb_vorbis_get_info(currentMusic[musicIndex].stream);
|
||||
|
||||
TraceLog(INFO, "[%s] Ogg sample rate: %i", fileName, info.sample_rate);
|
||||
TraceLog(INFO, "[%s] Ogg channels: %i", fileName, info.channels);
|
||||
TraceLog(DEBUG, "[%s] Temp memory required: %i", fileName, info.temp_memory_required);
|
||||
|
||||
if (info.channels == 2) currentMusic.format = AL_FORMAT_STEREO16;
|
||||
else currentMusic.format = AL_FORMAT_MONO16;
|
||||
currentMusic[musicIndex].loop = true; // We loop by default
|
||||
musicEnabled_g = true;
|
||||
|
||||
currentMusic.loop = true; // We loop by default
|
||||
musicEnabled = true;
|
||||
|
||||
// Create an audio source
|
||||
alGenSources(1, ¤tMusic.source); // Generate pointer to audio source
|
||||
currentMusic[musicIndex].totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic[musicIndex].stream) * info.channels;
|
||||
currentMusic[musicIndex].totalLengthSeconds = stb_vorbis_stream_length_in_seconds(currentMusic[musicIndex].stream);
|
||||
|
||||
alSourcef(currentMusic.source, AL_PITCH, 1);
|
||||
alSourcef(currentMusic.source, AL_GAIN, 1);
|
||||
alSource3f(currentMusic.source, AL_POSITION, 0, 0, 0);
|
||||
alSource3f(currentMusic.source, AL_VELOCITY, 0, 0, 0);
|
||||
//alSourcei(currentMusic.source, AL_LOOPING, AL_TRUE); // ERROR: Buffers do not queue!
|
||||
|
||||
// Generate two OpenAL buffers
|
||||
alGenBuffers(2, currentMusic.buffers);
|
||||
|
||||
// Fill buffers with music...
|
||||
BufferMusicStream(currentMusic.buffers[0]);
|
||||
BufferMusicStream(currentMusic.buffers[1]);
|
||||
|
||||
// Queue buffers and start playing
|
||||
alSourceQueueBuffers(currentMusic.source, 2, currentMusic.buffers);
|
||||
alSourcePlay(currentMusic.source);
|
||||
|
||||
// NOTE: Regularly, we must check if a buffer has been processed and refill it: UpdateMusicStream()
|
||||
|
||||
currentMusic.totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels;
|
||||
if (info.channels == 2){
|
||||
currentMusic[musicIndex].mixc = InitMixChannel(info.sample_rate, mixIndex, 2, false);
|
||||
currentMusic[musicIndex].mixc->playing = true;
|
||||
}
|
||||
else{
|
||||
currentMusic[musicIndex].mixc = InitMixChannel(info.sample_rate, mixIndex, 1, false);
|
||||
currentMusic[musicIndex].mixc->playing = true;
|
||||
}
|
||||
if(!currentMusic[musicIndex].mixc) return 4; // error
|
||||
}
|
||||
}
|
||||
else TraceLog(WARNING, "[%s] Music extension not recognized, it can't be loaded", fileName);
|
||||
else if (strcmp(GetExtension(fileName),"xm") == 0)
|
||||
{
|
||||
// only stereo is supported for xm
|
||||
if(!jar_xm_create_context_from_file(¤tMusic[musicIndex].chipctx, 48000, fileName))
|
||||
{
|
||||
currentMusic[musicIndex].chipTune = true;
|
||||
currentMusic[musicIndex].loop = true;
|
||||
jar_xm_set_max_loop_count(currentMusic[musicIndex].chipctx, 0); // infinite number of loops
|
||||
currentMusic[musicIndex].totalSamplesLeft = jar_xm_get_remaining_samples(currentMusic[musicIndex].chipctx);
|
||||
currentMusic[musicIndex].totalLengthSeconds = ((float)currentMusic[musicIndex].totalSamplesLeft) / 48000.f;
|
||||
musicEnabled_g = true;
|
||||
|
||||
TraceLog(INFO, "[%s] XM number of samples: %i", fileName, currentMusic[musicIndex].totalSamplesLeft);
|
||||
TraceLog(INFO, "[%s] XM track length: %11.6f sec", fileName, currentMusic[musicIndex].totalLengthSeconds);
|
||||
|
||||
currentMusic[musicIndex].mixc = InitMixChannel(48000, mixIndex, 2, false);
|
||||
if(!currentMusic[musicIndex].mixc) return 5; // error
|
||||
currentMusic[musicIndex].mixc->playing = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceLog(WARNING, "[%s] XM file could not be opened", fileName);
|
||||
return 6; // error
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceLog(WARNING, "[%s] Music extension not recognized, it can't be loaded", fileName);
|
||||
return 7; // error
|
||||
}
|
||||
return 0; // normal return
|
||||
}
|
||||
|
||||
// Stop music playing (close stream)
|
||||
void StopMusicStream(void)
|
||||
// Stop music playing for individual music index of currentMusic array (close stream)
|
||||
void StopMusicStream(int index)
|
||||
{
|
||||
if (musicEnabled)
|
||||
if (index < MAX_MUSIC_STREAMS && currentMusic[index].mixc)
|
||||
{
|
||||
alSourceStop(currentMusic.source);
|
||||
CloseMixChannel(currentMusic[index].mixc);
|
||||
|
||||
EmptyMusicStream(); // Empty music buffers
|
||||
if (currentMusic[index].chipTune)
|
||||
{
|
||||
jar_xm_free_context(currentMusic[index].chipctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
stb_vorbis_close(currentMusic[index].stream);
|
||||
}
|
||||
|
||||
alDeleteSources(1, ¤tMusic.source);
|
||||
alDeleteBuffers(2, currentMusic.buffers);
|
||||
|
||||
stb_vorbis_close(currentMusic.stream);
|
||||
if(!getMusicStreamCount()) musicEnabled_g = false;
|
||||
if(currentMusic[index].stream || currentMusic[index].chipctx)
|
||||
{
|
||||
currentMusic[index].stream = NULL;
|
||||
currentMusic[index].chipctx = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
musicEnabled = false;
|
||||
//get number of music channels active at this time, this does not mean they are playing
|
||||
int getMusicStreamCount(void)
|
||||
{
|
||||
int musicCount = 0;
|
||||
for(int musicIndex = 0; musicIndex < MAX_MUSIC_STREAMS; musicIndex++) // find empty music slot
|
||||
if(currentMusic[musicIndex].stream != NULL || currentMusic[musicIndex].chipTune) musicCount++;
|
||||
|
||||
return musicCount;
|
||||
}
|
||||
|
||||
// Pause music playing
|
||||
void PauseMusicStream(void)
|
||||
void PauseMusicStream(int index)
|
||||
{
|
||||
// Pause music stream if music available!
|
||||
if (musicEnabled)
|
||||
if (index < MAX_MUSIC_STREAMS && currentMusic[index].mixc && musicEnabled_g)
|
||||
{
|
||||
TraceLog(INFO, "Pausing music stream");
|
||||
alSourcePause(currentMusic.source);
|
||||
musicEnabled = false;
|
||||
alSourcePause(currentMusic[index].mixc->alSource);
|
||||
currentMusic[index].mixc->playing = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Resume music playing
|
||||
void ResumeMusicStream(void)
|
||||
void ResumeMusicStream(int index)
|
||||
{
|
||||
// Resume music playing... if music available!
|
||||
ALenum state;
|
||||
alGetSourcei(currentMusic.source, AL_SOURCE_STATE, &state);
|
||||
|
||||
if (state == AL_PAUSED)
|
||||
{
|
||||
TraceLog(INFO, "Resuming music stream");
|
||||
alSourcePlay(currentMusic.source);
|
||||
musicEnabled = true;
|
||||
if(index < MAX_MUSIC_STREAMS && currentMusic[index].mixc){
|
||||
alGetSourcei(currentMusic[index].mixc->alSource, AL_SOURCE_STATE, &state);
|
||||
if (state == AL_PAUSED)
|
||||
{
|
||||
TraceLog(INFO, "Resuming music stream");
|
||||
alSourcePlay(currentMusic[index].mixc->alSource);
|
||||
currentMusic[index].mixc->playing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if music is playing
|
||||
bool MusicIsPlaying(void)
|
||||
// Check if any music is playing
|
||||
bool IsMusicPlaying(int index)
|
||||
{
|
||||
bool playing = false;
|
||||
ALint state;
|
||||
|
||||
alGetSourcei(currentMusic.source, AL_SOURCE_STATE, &state);
|
||||
if (state == AL_PLAYING) playing = true;
|
||||
if(index < MAX_MUSIC_STREAMS && currentMusic[index].mixc){
|
||||
alGetSourcei(currentMusic[index].mixc->alSource, AL_SOURCE_STATE, &state);
|
||||
if (state == AL_PLAYING) playing = true;
|
||||
}
|
||||
|
||||
return playing;
|
||||
}
|
||||
|
||||
// Set volume for music
|
||||
void SetMusicVolume(float volume)
|
||||
void SetMusicVolume(int index, float volume)
|
||||
{
|
||||
alSourcef(currentMusic.source, AL_GAIN, volume);
|
||||
if(index < MAX_MUSIC_STREAMS && currentMusic[index].mixc){
|
||||
alSourcef(currentMusic[index].mixc->alSource, AL_GAIN, volume);
|
||||
}
|
||||
}
|
||||
|
||||
void SetMusicPitch(int index, float pitch)
|
||||
{
|
||||
if(index < MAX_MUSIC_STREAMS && currentMusic[index].mixc){
|
||||
alSourcef(currentMusic[index].mixc->alSource, AL_PITCH, pitch);
|
||||
}
|
||||
}
|
||||
|
||||
// Get current music time length (in seconds)
|
||||
float GetMusicTimeLength(void)
|
||||
float GetMusicTimeLength(int index)
|
||||
{
|
||||
float totalSeconds = stb_vorbis_stream_length_in_seconds(currentMusic.stream);
|
||||
float totalSeconds;
|
||||
if (currentMusic[index].chipTune)
|
||||
{
|
||||
totalSeconds = currentMusic[index].totalLengthSeconds;
|
||||
}
|
||||
else
|
||||
{
|
||||
totalSeconds = stb_vorbis_stream_length_in_seconds(currentMusic[index].stream);
|
||||
}
|
||||
|
||||
return totalSeconds;
|
||||
}
|
||||
|
||||
// Get current music time played (in seconds)
|
||||
float GetMusicTimePlayed(void)
|
||||
float GetMusicTimePlayed(int index)
|
||||
{
|
||||
int totalSamples = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels;
|
||||
float secondsPlayed;
|
||||
if(index < MAX_MUSIC_STREAMS && currentMusic[index].mixc)
|
||||
{
|
||||
if (currentMusic[index].chipTune)
|
||||
{
|
||||
uint64_t samples;
|
||||
jar_xm_get_position(currentMusic[index].chipctx, NULL, NULL, NULL, &samples);
|
||||
secondsPlayed = (float)samples / (48000 * currentMusic[index].mixc->channels); // Not sure if this is the correct value
|
||||
}
|
||||
else
|
||||
{
|
||||
int totalSamples = stb_vorbis_stream_length_in_samples(currentMusic[index].stream) * currentMusic[index].mixc->channels;
|
||||
int samplesPlayed = totalSamples - currentMusic[index].totalSamplesLeft;
|
||||
secondsPlayed = (float)samplesPlayed / (currentMusic[index].mixc->sampleRate * currentMusic[index].mixc->channels);
|
||||
}
|
||||
}
|
||||
|
||||
int samplesPlayed = totalSamples - currentMusic.totalSamplesLeft;
|
||||
|
||||
float secondsPlayed = (float)samplesPlayed / (currentMusic.sampleRate * currentMusic.channels);
|
||||
|
||||
return secondsPlayed;
|
||||
}
|
||||
|
@ -655,103 +982,118 @@ float GetMusicTimePlayed(void)
|
|||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Fill music buffers with new data from music stream
|
||||
static bool BufferMusicStream(ALuint buffer)
|
||||
static bool BufferMusicStream(int index, int numBuffers)
|
||||
{
|
||||
short pcm[MUSIC_BUFFER_SIZE];
|
||||
|
||||
int size = 0; // Total size of data steamed (in bytes)
|
||||
int streamedBytes = 0; // Bytes of data obtained in one samples get
|
||||
short pcm[MUSIC_BUFFER_SIZE_SHORT];
|
||||
float pcmf[MUSIC_BUFFER_SIZE_FLOAT];
|
||||
|
||||
int size = 0; // Total size of data steamed in L+R samples for xm floats, individual L or R for ogg shorts
|
||||
bool active = true; // We can get more data from stream (not finished)
|
||||
|
||||
if (musicEnabled)
|
||||
if (currentMusic[index].chipTune) // There is no end of stream for xmfiles, once the end is reached zeros are generated for non looped chiptunes.
|
||||
{
|
||||
while (size < MUSIC_BUFFER_SIZE)
|
||||
if(currentMusic[index].totalSamplesLeft >= MUSIC_BUFFER_SIZE_SHORT)
|
||||
size = MUSIC_BUFFER_SIZE_SHORT / 2;
|
||||
else
|
||||
size = currentMusic[index].totalSamplesLeft / 2;
|
||||
|
||||
for(int x=0; x<numBuffers; x++)
|
||||
{
|
||||
streamedBytes = stb_vorbis_get_samples_short_interleaved(currentMusic.stream, currentMusic.channels, pcm + size, MUSIC_BUFFER_SIZE - size);
|
||||
|
||||
if (streamedBytes > 0) size += (streamedBytes*currentMusic.channels);
|
||||
else break;
|
||||
jar_xm_generate_samples_16bit(currentMusic[index].chipctx, pcm, size); // reads 2*readlen shorts and moves them to buffer+size memory location
|
||||
BufferMixChannel(currentMusic[index].mixc, pcm, size * 2);
|
||||
currentMusic[index].totalSamplesLeft -= size * 2;
|
||||
if(currentMusic[index].totalSamplesLeft <= 0)
|
||||
{
|
||||
active = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//TraceLog(DEBUG, "Streaming music data to buffer. Bytes streamed: %i", size);
|
||||
}
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
alBufferData(buffer, currentMusic.format, pcm, size*sizeof(short), currentMusic.sampleRate);
|
||||
|
||||
currentMusic.totalSamplesLeft -= size;
|
||||
}
|
||||
else
|
||||
{
|
||||
active = false;
|
||||
TraceLog(WARNING, "No more data obtained from stream");
|
||||
if(currentMusic[index].totalSamplesLeft >= MUSIC_BUFFER_SIZE_SHORT)
|
||||
size = MUSIC_BUFFER_SIZE_SHORT;
|
||||
else
|
||||
size = currentMusic[index].totalSamplesLeft;
|
||||
|
||||
for(int x=0; x<numBuffers; x++)
|
||||
{
|
||||
int streamedBytes = stb_vorbis_get_samples_short_interleaved(currentMusic[index].stream, currentMusic[index].mixc->channels, pcm, size);
|
||||
BufferMixChannel(currentMusic[index].mixc, pcm, streamedBytes * currentMusic[index].mixc->channels);
|
||||
currentMusic[index].totalSamplesLeft -= streamedBytes * currentMusic[index].mixc->channels;
|
||||
if(currentMusic[index].totalSamplesLeft <= 0)
|
||||
{
|
||||
active = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return active;
|
||||
}
|
||||
|
||||
// Empty music buffers
|
||||
static void EmptyMusicStream(void)
|
||||
static void EmptyMusicStream(int index)
|
||||
{
|
||||
ALuint buffer = 0;
|
||||
int queued = 0;
|
||||
|
||||
alGetSourcei(currentMusic.source, AL_BUFFERS_QUEUED, &queued);
|
||||
alGetSourcei(currentMusic[index].mixc->alSource, AL_BUFFERS_QUEUED, &queued);
|
||||
|
||||
while (queued > 0)
|
||||
{
|
||||
alSourceUnqueueBuffers(currentMusic.source, 1, &buffer);
|
||||
alSourceUnqueueBuffers(currentMusic[index].mixc->alSource, 1, &buffer);
|
||||
|
||||
queued--;
|
||||
}
|
||||
}
|
||||
|
||||
// Update (re-fill) music buffers if data already processed
|
||||
void UpdateMusicStream(void)
|
||||
//determine if a music stream is ready to be written to
|
||||
static int IsMusicStreamReadyForBuffering(int index)
|
||||
{
|
||||
ALuint buffer = 0;
|
||||
ALint processed = 0;
|
||||
alGetSourcei(currentMusic[index].mixc->alSource, AL_BUFFERS_PROCESSED, &processed);
|
||||
return processed;
|
||||
}
|
||||
|
||||
// Update (re-fill) music buffers if data already processed
|
||||
void UpdateMusicStream(int index)
|
||||
{
|
||||
ALenum state;
|
||||
bool active = true;
|
||||
int numBuffers = IsMusicStreamReadyForBuffering(index);
|
||||
|
||||
if (musicEnabled)
|
||||
if (currentMusic[index].mixc->playing && index < MAX_MUSIC_STREAMS && musicEnabled_g && currentMusic[index].mixc && numBuffers)
|
||||
{
|
||||
// Get the number of already processed buffers (if any)
|
||||
alGetSourcei(currentMusic.source, AL_BUFFERS_PROCESSED, &processed);
|
||||
active = BufferMusicStream(index, numBuffers);
|
||||
|
||||
while (processed > 0)
|
||||
if (!active && currentMusic[index].loop)
|
||||
{
|
||||
// Recover processed buffer for refill
|
||||
alSourceUnqueueBuffers(currentMusic.source, 1, &buffer);
|
||||
|
||||
// Refill buffer
|
||||
active = BufferMusicStream(buffer);
|
||||
|
||||
// If no more data to stream, restart music (if loop)
|
||||
if ((!active) && (currentMusic.loop))
|
||||
if (currentMusic[index].chipTune)
|
||||
{
|
||||
stb_vorbis_seek_start(currentMusic.stream);
|
||||
currentMusic.totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic.stream)*currentMusic.channels;
|
||||
|
||||
active = BufferMusicStream(buffer);
|
||||
currentMusic[index].totalSamplesLeft = currentMusic[index].totalLengthSeconds * 48000;
|
||||
}
|
||||
|
||||
// Add refilled buffer to queue again... don't let the music stop!
|
||||
alSourceQueueBuffers(currentMusic.source, 1, &buffer);
|
||||
|
||||
if (alGetError() != AL_NO_ERROR) TraceLog(WARNING, "Ogg playing, error buffering data...");
|
||||
|
||||
processed--;
|
||||
else
|
||||
{
|
||||
stb_vorbis_seek_start(currentMusic[index].stream);
|
||||
currentMusic[index].totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic[index].stream) * currentMusic[index].mixc->channels;
|
||||
}
|
||||
active = true;
|
||||
}
|
||||
|
||||
ALenum state;
|
||||
alGetSourcei(currentMusic.source, AL_SOURCE_STATE, &state);
|
||||
|
||||
if ((state != AL_PLAYING) && active) alSourcePlay(currentMusic.source);
|
||||
if (alGetError() != AL_NO_ERROR) TraceLog(WARNING, "Error buffering data...");
|
||||
|
||||
alGetSourcei(currentMusic[index].mixc->alSource, AL_SOURCE_STATE, &state);
|
||||
|
||||
if (state != AL_PLAYING && active) alSourcePlay(currentMusic[index].mixc->alSource);
|
||||
|
||||
if (!active) StopMusicStream(index);
|
||||
|
||||
if (!active) StopMusicStream();
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Load WAV file into Wave structure
|
||||
|
|
36
src/audio.h
36
src/audio.h
|
@ -41,7 +41,9 @@
|
|||
//----------------------------------------------------------------------------------
|
||||
#ifndef __cplusplus
|
||||
// Boolean type
|
||||
typedef enum { false, true } bool;
|
||||
#ifndef true
|
||||
typedef enum { false, true } bool;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Sound source type
|
||||
|
@ -59,6 +61,8 @@ typedef struct Wave {
|
|||
short channels;
|
||||
} Wave;
|
||||
|
||||
typedef int RawAudioContext;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
|
@ -73,6 +77,7 @@ extern "C" { // Prevents name mangling of functions
|
|||
//----------------------------------------------------------------------------------
|
||||
void InitAudioDevice(void); // Initialize audio device and context
|
||||
void CloseAudioDevice(void); // Close the audio device and context (and music stream)
|
||||
bool IsAudioDeviceReady(void); // True if call to InitAudioDevice() was successful and CloseAudioDevice() has not been called yet
|
||||
|
||||
Sound LoadSound(char *fileName); // Load sound to memory
|
||||
Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
|
||||
|
@ -81,19 +86,28 @@ void UnloadSound(Sound sound); // Unload sound
|
|||
void PlaySound(Sound sound); // Play a sound
|
||||
void PauseSound(Sound sound); // Pause a sound
|
||||
void StopSound(Sound sound); // Stop playing a sound
|
||||
bool SoundIsPlaying(Sound sound); // Check if a sound is currently playing
|
||||
bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing
|
||||
void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
|
||||
void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
|
||||
|
||||
void PlayMusicStream(char *fileName); // Start music playing (open stream)
|
||||
void UpdateMusicStream(void); // Updates buffers for music streaming
|
||||
void StopMusicStream(void); // Stop music playing (close stream)
|
||||
void PauseMusicStream(void); // Pause music playing
|
||||
void ResumeMusicStream(void); // Resume playing paused music
|
||||
bool MusicIsPlaying(void); // Check if music is playing
|
||||
void SetMusicVolume(float volume); // Set volume for music (1.0 is max level)
|
||||
float GetMusicTimeLength(void); // Get current music time length (in seconds)
|
||||
float GetMusicTimePlayed(void); // Get current music time played (in seconds)
|
||||
int PlayMusicStream(int musicIndex, char *fileName); // Start music playing (open stream)
|
||||
void UpdateMusicStream(int index); // Updates buffers for music streaming
|
||||
void StopMusicStream(int index); // Stop music playing (close stream)
|
||||
void PauseMusicStream(int index); // Pause music playing
|
||||
void ResumeMusicStream(int index); // Resume playing paused music
|
||||
bool IsMusicPlaying(int index); // Check if music is playing
|
||||
void SetMusicVolume(int index, float volume); // Set volume for music (1.0 is max level)
|
||||
float GetMusicTimeLength(int index); // Get music time length (in seconds)
|
||||
float GetMusicTimePlayed(int index); // Get current music time played (in seconds)
|
||||
int getMusicStreamCount(void);
|
||||
void SetMusicPitch(int index, float pitch);
|
||||
|
||||
// used to output raw audio streams, returns negative numbers on error
|
||||
// if floating point is false the data size is 16bit short, otherwise it is float 32bit
|
||||
RawAudioContext InitRawAudioContext(int sampleRate, int channels, bool floatingPoint);
|
||||
|
||||
void CloseRawAudioContext(RawAudioContext ctx);
|
||||
int BufferRawAudioContext(RawAudioContext ctx, void *data, int numberElements); // returns number of elements buffered
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
989
src/core.c
989
src/core.c
File diff suppressed because it is too large
Load diff
|
@ -7,6 +7,23 @@
|
|||
* This header uses:
|
||||
* #define EASINGS_STATIC_INLINE // Inlines all functions code, so it runs faster.
|
||||
* // This requires lots of memory on system.
|
||||
* How to use:
|
||||
* The four inputs t,b,c,d are defined as follows:
|
||||
* t = current time in milliseconds
|
||||
* b = starting position in only one dimension [X || Y || Z] your choice
|
||||
* c = the total change in value of b that needs to occur
|
||||
* d = total time it should take to complete
|
||||
*
|
||||
* Example:
|
||||
* float speed = 1.f;
|
||||
* float currentTime = 0.f;
|
||||
* float currentPos[2] = {0,0};
|
||||
* float finalPos[2] = {1,1};
|
||||
* float startPosition[2] = currentPos;//x,y positions
|
||||
* while(currentPos[0] < finalPos[0])
|
||||
* currentPos[0] = EaseSineIn(currentTime, startPosition[0], startPosition[0]-finalPos[0], speed);
|
||||
* currentPos[1] = EaseSineIn(currentTime, startPosition[1], startPosition[1]-finalPos[0], speed);
|
||||
* currentTime += diffTime();
|
||||
*
|
||||
* A port of Robert Penner's easing equations to C (http://robertpenner.com/easing/)
|
||||
*
|
||||
|
|
|
@ -292,14 +292,14 @@ void UpdateGestures(void)
|
|||
}
|
||||
|
||||
// Check if a gesture have been detected
|
||||
bool IsGestureDetected(void)
|
||||
bool IsGestureDetected(int gesture)
|
||||
{
|
||||
if ((enabledGestures & currentGesture) != GESTURE_NONE) return true;
|
||||
if ((enabledGestures & currentGesture) == gesture) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
// Check gesture type
|
||||
int GetGestureType(void)
|
||||
int GetGestureDetected(void)
|
||||
{
|
||||
// Get current gesture only if enabled
|
||||
return (enabledGestures & currentGesture);
|
||||
|
|
|
@ -92,8 +92,8 @@ extern "C" { // Prevents name mangling of functions
|
|||
//----------------------------------------------------------------------------------
|
||||
void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures
|
||||
void UpdateGestures(void); // Update gestures detected (must be called every frame)
|
||||
bool IsGestureDetected(void); // Check if a gesture have been detected
|
||||
int GetGestureType(void); // Get latest detected gesture
|
||||
bool IsGestureDetected(int gesture); // Check if a gesture have been detected
|
||||
int GetGestureDetected(void); // Get latest detected gesture
|
||||
void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags
|
||||
int GetTouchPointsCount(void); // Get touch points count
|
||||
|
||||
|
|
2666
src/jar_xm.h
Normal file
2666
src/jar_xm.h
Normal file
File diff suppressed because it is too large
Load diff
436
src/models.c
436
src/models.c
|
@ -55,7 +55,9 @@ extern unsigned int whiteTexture;
|
|||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
static Mesh LoadOBJ(const char *fileName);
|
||||
static Mesh LoadOBJ(const char *fileName); // Load OBJ mesh data
|
||||
static Material LoadMTL(const char *fileName); // Load MTL material data
|
||||
|
||||
static Mesh GenMeshHeightmap(Image image, Vector3 size);
|
||||
static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);
|
||||
|
||||
|
@ -542,38 +544,118 @@ void DrawGizmo(Vector3 position)
|
|||
Model LoadModel(const char *fileName)
|
||||
{
|
||||
Model model = { 0 };
|
||||
Mesh mesh = { 0 };
|
||||
|
||||
// NOTE: Initialize default data for model in case loading fails, maybe a cube?
|
||||
// TODO: Initialize default data for model in case loading fails, maybe a cube?
|
||||
|
||||
if (strcmp(GetExtension(fileName),"obj") == 0) 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);
|
||||
|
||||
// NOTE: At this point we have all vertex, texcoord, normal data for the model in mesh struct
|
||||
|
||||
if (mesh.vertexCount == 0) TraceLog(WARNING, "Model could not be loaded");
|
||||
if (model.mesh.vertexCount == 0) TraceLog(WARNING, "Model could not be loaded");
|
||||
else
|
||||
{
|
||||
// NOTE: model properties (transform, texture, shader) are initialized inside rlglLoadModel()
|
||||
model = rlglLoadModel(mesh); // Upload vertex data to GPU
|
||||
rlglLoadMesh(&model.mesh, false); // Upload vertex data to GPU (static model)
|
||||
|
||||
// NOTE: Now that vertex data is uploaded to GPU VRAM, we can free arrays from CPU RAM
|
||||
// We don't need CPU vertex data on OpenGL 3.3 or ES2... for static meshes...
|
||||
// ...but we could keep CPU vertex data in case we need to update the mesh
|
||||
model.transform = MatrixIdentity();
|
||||
model.material = LoadDefaultMaterial();
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
// Load a 3d model (from vertex data)
|
||||
Model LoadModelEx(Mesh data)
|
||||
Model LoadModelEx(Mesh data, bool dynamic)
|
||||
{
|
||||
Model model;
|
||||
Model model = { 0 };
|
||||
|
||||
// NOTE: model properties (transform, texture, shader) are initialized inside rlglLoadModel()
|
||||
model = rlglLoadModel(data); // Upload vertex data to GPU
|
||||
model.mesh = data;
|
||||
|
||||
// NOTE: Vertex data is managed externally, must be deallocated manually
|
||||
rlglLoadMesh(&model.mesh, dynamic); // Upload vertex data to GPU
|
||||
|
||||
model.transform = MatrixIdentity();
|
||||
model.material = LoadDefaultMaterial();
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
// Load a 3d model from rRES file (raylib Resource)
|
||||
Model LoadModelFromRES(const char *rresName, int resId)
|
||||
{
|
||||
Model model = { 0 };
|
||||
bool found = false;
|
||||
|
||||
char id[4]; // rRES file identifier
|
||||
unsigned char version; // rRES file version and subversion
|
||||
char useless; // rRES header reserved data
|
||||
short numRes;
|
||||
|
||||
ResInfoHeader infoHeader;
|
||||
|
||||
FILE *rresFile = fopen(rresName, "rb");
|
||||
|
||||
if (rresFile == NULL)
|
||||
{
|
||||
TraceLog(WARNING, "[%s] rRES raylib resource file could not be opened", rresName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read rres file (basic file check - id)
|
||||
fread(&id[0], sizeof(char), 1, rresFile);
|
||||
fread(&id[1], sizeof(char), 1, rresFile);
|
||||
fread(&id[2], sizeof(char), 1, rresFile);
|
||||
fread(&id[3], sizeof(char), 1, rresFile);
|
||||
fread(&version, sizeof(char), 1, rresFile);
|
||||
fread(&useless, sizeof(char), 1, rresFile);
|
||||
|
||||
if ((id[0] != 'r') && (id[1] != 'R') && (id[2] != 'E') &&(id[3] != 'S'))
|
||||
{
|
||||
TraceLog(WARNING, "[%s] This is not a valid raylib resource file", rresName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read number of resources embedded
|
||||
fread(&numRes, sizeof(short), 1, rresFile);
|
||||
|
||||
for (int i = 0; i < numRes; i++)
|
||||
{
|
||||
fread(&infoHeader, sizeof(ResInfoHeader), 1, rresFile);
|
||||
|
||||
if (infoHeader.id == resId)
|
||||
{
|
||||
found = true;
|
||||
|
||||
// Check data is of valid MODEL type
|
||||
if (infoHeader.type == 8)
|
||||
{
|
||||
// TODO: Load model data
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceLog(WARNING, "[%s] Required resource do not seem to be a valid MODEL resource", rresName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Depending on type, skip the right amount of parameters
|
||||
switch (infoHeader.type)
|
||||
{
|
||||
case 0: fseek(rresFile, 6, SEEK_CUR); break; // IMAGE: Jump 6 bytes of parameters
|
||||
case 1: fseek(rresFile, 6, SEEK_CUR); break; // SOUND: Jump 6 bytes of parameters
|
||||
case 2: fseek(rresFile, 5, SEEK_CUR); break; // MODEL: Jump 5 bytes of parameters (TODO: Review)
|
||||
case 3: break; // TEXT: No parameters
|
||||
case 4: break; // RAW: No parameters
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Jump DATA to read next infoHeader
|
||||
fseek(rresFile, infoHeader.size, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(rresFile);
|
||||
}
|
||||
|
||||
if (!found) TraceLog(WARNING, "[%s] Required resource id [%i] could not be found in the raylib resource file", rresName, resId);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
@ -582,8 +664,14 @@ Model LoadModelEx(Mesh data)
|
|||
// NOTE: model map size is defined in generic units
|
||||
Model LoadHeightmap(Image heightmap, Vector3 size)
|
||||
{
|
||||
Mesh mesh = GenMeshHeightmap(heightmap, size);
|
||||
Model model = rlglLoadModel(mesh);
|
||||
Model model = { 0 };
|
||||
|
||||
model.mesh = GenMeshHeightmap(heightmap, size);
|
||||
|
||||
rlglLoadMesh(&model.mesh, false); // Upload vertex data to GPU (static model)
|
||||
|
||||
model.transform = MatrixIdentity();
|
||||
model.material = LoadDefaultMaterial();
|
||||
|
||||
return model;
|
||||
}
|
||||
|
@ -591,34 +679,76 @@ Model LoadHeightmap(Image heightmap, Vector3 size)
|
|||
// Load a map image as a 3d model (cubes based)
|
||||
Model LoadCubicmap(Image cubicmap)
|
||||
{
|
||||
Mesh mesh = GenMeshCubicmap(cubicmap, (Vector3){ 1.0, 1.0, 1.5f });
|
||||
Model model = rlglLoadModel(mesh);
|
||||
Model model = { 0 };
|
||||
|
||||
model.mesh = GenMeshCubicmap(cubicmap, (Vector3){ 1.0, 1.0, 1.5f });
|
||||
|
||||
rlglLoadMesh(&model.mesh, false); // Upload vertex data to GPU (static model)
|
||||
|
||||
model.transform = MatrixIdentity();
|
||||
model.material = LoadDefaultMaterial();
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
// Unload 3d model from memory
|
||||
// Unload 3d model from memory (mesh and material)
|
||||
void UnloadModel(Model model)
|
||||
{
|
||||
// Unload mesh data
|
||||
free(model.mesh.vertices);
|
||||
free(model.mesh.texcoords);
|
||||
free(model.mesh.normals);
|
||||
free(model.mesh.colors);
|
||||
//if (model.mesh.texcoords2 != NULL) free(model.mesh.texcoords2); // Not used
|
||||
//if (model.mesh.tangents != NULL) free(model.mesh.tangents); // Not used
|
||||
rlglUnloadMesh(&model.mesh);
|
||||
|
||||
rlDeleteBuffers(model.mesh.vboId[0]); // vertex
|
||||
rlDeleteBuffers(model.mesh.vboId[1]); // texcoords
|
||||
rlDeleteBuffers(model.mesh.vboId[2]); // normals
|
||||
//rlDeleteBuffers(model.mesh.vboId[3]); // texcoords2 (NOT USED)
|
||||
//rlDeleteBuffers(model.mesh.vboId[4]); // tangents (NOT USED)
|
||||
//rlDeleteBuffers(model.mesh.vboId[5]); // colors (NOT USED)
|
||||
UnloadMaterial(model.material);
|
||||
|
||||
rlDeleteVertexArrays(model.mesh.vaoId);
|
||||
TraceLog(INFO, "Unloaded model data from RAM and VRAM");
|
||||
}
|
||||
|
||||
if (model.mesh.vaoId > 0) TraceLog(INFO, "[VAO ID %i] Unloaded model data from VRAM (GPU)", model.mesh.vaoId);
|
||||
else TraceLog(INFO, "[VBO ID %i][VBO ID %i][VBO ID %i] Unloaded model data from VRAM (GPU)", model.mesh.vboId[0], model.mesh.vboId[1], model.mesh.vboId[2]);
|
||||
// Load material data (from file)
|
||||
Material LoadMaterial(const char *fileName)
|
||||
{
|
||||
Material material = { 0 };
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Load default material (uses default models shader)
|
||||
Material LoadDefaultMaterial(void)
|
||||
{
|
||||
Material material = { 0 };
|
||||
|
||||
material.shader = GetDefaultShader();
|
||||
material.texDiffuse = GetDefaultTexture(); // White texture (1x1 pixel)
|
||||
//material.texNormal; // NOTE: By default, not set
|
||||
//material.texSpecular; // NOTE: By default, not set
|
||||
|
||||
material.colDiffuse = WHITE; // Diffuse color
|
||||
material.colAmbient = WHITE; // Ambient color
|
||||
material.colSpecular = WHITE; // Specular color
|
||||
|
||||
material.glossiness = 100.0f; // Glossiness level
|
||||
material.normalDepth = 1.0f; // Normal map depth
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
// Load standard material (uses standard models shader)
|
||||
// NOTE: Standard shader supports multiple maps and lights
|
||||
Material LoadStandardMaterial(void)
|
||||
{
|
||||
Material material = LoadDefaultMaterial();
|
||||
|
||||
//material.shader = GetStandardShader();
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
// Unload material from memory
|
||||
void UnloadMaterial(Material material)
|
||||
{
|
||||
rlDeleteTextures(material.texDiffuse.id);
|
||||
rlDeleteTextures(material.texNormal.id);
|
||||
rlDeleteTextures(material.texSpecular.id);
|
||||
}
|
||||
|
||||
// Link a texture to a model
|
||||
|
@ -628,11 +758,12 @@ void SetModelTexture(Model *model, Texture2D texture)
|
|||
else model->material.texDiffuse = texture;
|
||||
}
|
||||
|
||||
// Generate a mesh from heightmap
|
||||
static Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
|
||||
{
|
||||
#define GRAY_VALUE(c) ((c.r+c.g+c.b)/3)
|
||||
|
||||
Mesh mesh;
|
||||
Mesh mesh = { 0 };
|
||||
|
||||
int mapX = heightmap.width;
|
||||
int mapZ = heightmap.height;
|
||||
|
@ -647,7 +778,7 @@ static Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
|
|||
mesh.vertices = (float *)malloc(mesh.vertexCount*3*sizeof(float));
|
||||
mesh.normals = (float *)malloc(mesh.vertexCount*3*sizeof(float));
|
||||
mesh.texcoords = (float *)malloc(mesh.vertexCount*2*sizeof(float));
|
||||
mesh.colors = (unsigned char *)malloc(mesh.vertexCount*4*sizeof(unsigned char)); // Not used...
|
||||
mesh.colors = NULL;
|
||||
|
||||
int vCounter = 0; // Used to count vertices float by float
|
||||
int tcCounter = 0; // Used to count texcoords float by float
|
||||
|
@ -730,16 +861,12 @@ static Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
|
|||
|
||||
free(pixels);
|
||||
|
||||
// Fill color data
|
||||
// NOTE: Not used any more... just one plain color defined at DrawModel()
|
||||
for (int i = 0; i < (4*mesh.vertexCount); i++) mesh.colors[i] = 255;
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
|
||||
{
|
||||
Mesh mesh;
|
||||
Mesh mesh = { 0 };
|
||||
|
||||
Color *cubicmapPixels = GetImageData(cubicmap);
|
||||
|
||||
|
@ -1048,11 +1175,7 @@ static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
|
|||
mesh.vertices = (float *)malloc(mesh.vertexCount*3*sizeof(float));
|
||||
mesh.normals = (float *)malloc(mesh.vertexCount*3*sizeof(float));
|
||||
mesh.texcoords = (float *)malloc(mesh.vertexCount*2*sizeof(float));
|
||||
mesh.colors = (unsigned char *)malloc(mesh.vertexCount*4*sizeof(unsigned char)); // Not used...
|
||||
|
||||
// Fill color data
|
||||
// NOTE: Not used any more... just one plain color defined at DrawModel()
|
||||
for (int i = 0; i < (4*mesh.vertexCount); i++) mesh.colors[i] = 255;
|
||||
mesh.colors = NULL;
|
||||
|
||||
int fCounter = 0;
|
||||
|
||||
|
@ -1107,24 +1230,39 @@ void DrawModel(Model model, Vector3 position, float scale, Color tint)
|
|||
// Draw a model with extended parameters
|
||||
void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint)
|
||||
{
|
||||
// NOTE: Rotation must be provided in degrees, it's converted to radians inside rlglDrawModel()
|
||||
rlglDrawModel(model, position, rotationAxis, rotationAngle, scale, tint, false);
|
||||
// Calculate transformation matrix from function parameters
|
||||
// Get transform matrix (rotation -> scale -> translation)
|
||||
Matrix matRotation = MatrixRotate(rotationAxis, rotationAngle*DEG2RAD);
|
||||
Matrix matScale = MatrixScale(scale.x, scale.y, scale.z);
|
||||
Matrix matTranslation = MatrixTranslate(position.x, position.y, position.z);
|
||||
|
||||
// Combine model transformation matrix (model.transform) with matrix generated by function parameters (matTransform)
|
||||
//Matrix matModel = MatrixMultiply(model.transform, matTransform); // Transform to world-space coordinates
|
||||
|
||||
model.transform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation);
|
||||
model.material.colDiffuse = tint;
|
||||
|
||||
rlglDrawMesh(model.mesh, model.material, model.transform);
|
||||
}
|
||||
|
||||
// Draw a model wires (with texture if set)
|
||||
void DrawModelWires(Model model, Vector3 position, float scale, Color color)
|
||||
void DrawModelWires(Model model, Vector3 position, float scale, Color tint)
|
||||
{
|
||||
Vector3 vScale = { scale, scale, scale };
|
||||
Vector3 rotationAxis = { 0.0f, 0.0f, 0.0f };
|
||||
rlEnableWireMode();
|
||||
|
||||
rlglDrawModel(model, position, rotationAxis, 0.0f, vScale, color, true);
|
||||
DrawModel(model, position, scale, tint);
|
||||
|
||||
rlDisableWireMode();
|
||||
}
|
||||
|
||||
// Draw a model wires (with texture if set) with extended parameters
|
||||
void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint)
|
||||
{
|
||||
// NOTE: Rotation must be provided in degrees, it's converted to radians inside rlglDrawModel()
|
||||
rlglDrawModel(model, position, rotationAxis, rotationAngle, scale, tint, true);
|
||||
rlEnableWireMode();
|
||||
|
||||
DrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint);
|
||||
|
||||
rlDisableWireMode();
|
||||
}
|
||||
|
||||
// Draw a billboard
|
||||
|
@ -1329,13 +1467,19 @@ bool CheckCollisionRayBox(Ray ray, BoundingBox box)
|
|||
BoundingBox CalculateBoundingBox(Mesh mesh)
|
||||
{
|
||||
// Get min and max vertex to construct bounds (AABB)
|
||||
Vector3 minVertex = (Vector3){ mesh.vertices[0], mesh.vertices[1], mesh.vertices[2] };
|
||||
Vector3 maxVertex = (Vector3){ mesh.vertices[0], mesh.vertices[1], mesh.vertices[2] };
|
||||
Vector3 minVertex = { 0 };
|
||||
Vector3 maxVertex = { 0 };
|
||||
|
||||
for (int i = 1; i < mesh.vertexCount; i++)
|
||||
if (mesh.vertices != NULL)
|
||||
{
|
||||
minVertex = VectorMin(minVertex, (Vector3){ mesh.vertices[i*3], mesh.vertices[i*3 + 1], mesh.vertices[i*3 + 2] });
|
||||
maxVertex = VectorMax(maxVertex, (Vector3){ mesh.vertices[i*3], mesh.vertices[i*3 + 1], mesh.vertices[i*3 + 2] });
|
||||
minVertex = (Vector3){ mesh.vertices[0], mesh.vertices[1], mesh.vertices[2] };
|
||||
maxVertex = (Vector3){ mesh.vertices[0], mesh.vertices[1], mesh.vertices[2] };
|
||||
|
||||
for (int i = 1; i < mesh.vertexCount; i++)
|
||||
{
|
||||
minVertex = VectorMin(minVertex, (Vector3){ mesh.vertices[i*3], mesh.vertices[i*3 + 1], mesh.vertices[i*3 + 2] });
|
||||
maxVertex = VectorMax(maxVertex, (Vector3){ mesh.vertices[i*3], mesh.vertices[i*3 + 1], mesh.vertices[i*3 + 2] });
|
||||
}
|
||||
}
|
||||
|
||||
// Create the bounding box
|
||||
|
@ -1736,7 +1880,7 @@ static Mesh LoadOBJ(const char *fileName)
|
|||
mesh.vertices = (float *)malloc(mesh.vertexCount*3*sizeof(float));
|
||||
mesh.texcoords = (float *)malloc(mesh.vertexCount*2*sizeof(float));
|
||||
mesh.normals = (float *)malloc(mesh.vertexCount*3*sizeof(float));
|
||||
mesh.colors = (unsigned char *)malloc(mesh.vertexCount*4*sizeof(unsigned char));
|
||||
mesh.colors = NULL;
|
||||
|
||||
int vCounter = 0; // Used to count vertices float by float
|
||||
int tcCounter = 0; // Used to count texcoords float by float
|
||||
|
@ -1836,10 +1980,6 @@ static Mesh LoadOBJ(const char *fileName)
|
|||
// Security check, just in case no normals or no texcoords defined in OBJ
|
||||
if (numTexCoords == 0) for (int i = 0; i < (2*mesh.vertexCount); i++) mesh.texcoords[i] = 0.0f;
|
||||
|
||||
// NOTE: We set all vertex colors to white
|
||||
// NOTE: Not used any more... just one plain color defined at DrawModel()
|
||||
for (int i = 0; i < (4*mesh.vertexCount); i++) mesh.colors[i] = 255;
|
||||
|
||||
// Now we can free temp mid* arrays
|
||||
free(midVertices);
|
||||
free(midNormals);
|
||||
|
@ -1850,3 +1990,163 @@ static Mesh LoadOBJ(const char *fileName)
|
|||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
// Load MTL material data (specs: http://paulbourke.net/dataformats/mtl/)
|
||||
// NOTE: Texture map parameters are not supported
|
||||
static Material LoadMTL(const char *fileName)
|
||||
{
|
||||
#define MAX_BUFFER_SIZE 128
|
||||
|
||||
Material material = { 0 }; // LoadDefaultMaterial();
|
||||
|
||||
char buffer[MAX_BUFFER_SIZE];
|
||||
Vector3 color = { 1.0f, 1.0f, 1.0f };
|
||||
char *mapFileName = NULL;
|
||||
|
||||
FILE *mtlFile;
|
||||
|
||||
mtlFile = fopen(fileName, "rt");
|
||||
|
||||
if (mtlFile == NULL)
|
||||
{
|
||||
TraceLog(WARNING, "[%s] MTL file could not be opened", fileName);
|
||||
return material;
|
||||
}
|
||||
|
||||
while(!feof(mtlFile))
|
||||
{
|
||||
fgets(buffer, MAX_BUFFER_SIZE, mtlFile);
|
||||
|
||||
switch (buffer[0])
|
||||
{
|
||||
case 'n': // newmtl string Material name. Begins a new material description.
|
||||
{
|
||||
// TODO: Support multiple materials in a single .mtl
|
||||
sscanf(buffer, "newmtl %s", mapFileName);
|
||||
|
||||
TraceLog(INFO, "[%s] Loading material...", mapFileName);
|
||||
}
|
||||
case 'i': // illum int Illumination model
|
||||
{
|
||||
// illum = 1 if specular disabled
|
||||
// illum = 2 if specular enabled (lambertian model)
|
||||
// ...
|
||||
}
|
||||
case 'K': // Ka, Kd, Ks, Ke
|
||||
{
|
||||
switch (buffer[1])
|
||||
{
|
||||
case 'a': // Ka float float float Ambient color (RGB)
|
||||
{
|
||||
sscanf(buffer, "Ka %f %f %f", &color.x, &color.y, &color.z);
|
||||
material.colAmbient.r = (unsigned char)(color.x*255);
|
||||
material.colAmbient.g = (unsigned char)(color.y*255);
|
||||
material.colAmbient.b = (unsigned char)(color.z*255);
|
||||
} break;
|
||||
case 'd': // Kd float float float Diffuse color (RGB)
|
||||
{
|
||||
sscanf(buffer, "Kd %f %f %f", &color.x, &color.y, &color.z);
|
||||
material.colDiffuse.r = (unsigned char)(color.x*255);
|
||||
material.colDiffuse.g = (unsigned char)(color.y*255);
|
||||
material.colDiffuse.b = (unsigned char)(color.z*255);
|
||||
} break;
|
||||
case 's': // Ks float float float Specular color (RGB)
|
||||
{
|
||||
sscanf(buffer, "Ks %f %f %f", &color.x, &color.y, &color.z);
|
||||
material.colSpecular.r = (unsigned char)(color.x*255);
|
||||
material.colSpecular.g = (unsigned char)(color.y*255);
|
||||
material.colSpecular.b = (unsigned char)(color.z*255);
|
||||
} break;
|
||||
case 'e': // Ke float float float Emmisive color (RGB)
|
||||
{
|
||||
// TODO: Support Ke ?
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
} break;
|
||||
case 'N': // Ns, Ni
|
||||
{
|
||||
if (buffer[1] == 's') // Ns int Shininess (specular exponent). Ranges from 0 to 1000.
|
||||
{
|
||||
sscanf(buffer, "Ns %i", &material.glossiness);
|
||||
}
|
||||
else if (buffer[1] == 'i') // Ni int Refraction index.
|
||||
{
|
||||
// Not supported...
|
||||
}
|
||||
} break;
|
||||
case 'm': // map_Kd, map_Ks, map_Ka, map_Bump, map_d
|
||||
{
|
||||
switch (buffer[4])
|
||||
{
|
||||
case 'K': // Color texture maps
|
||||
{
|
||||
if (buffer[5] == 'd') // map_Kd string Diffuse color texture map.
|
||||
{
|
||||
sscanf(buffer, "map_Kd %s", mapFileName);
|
||||
if (mapFileName != NULL) material.texDiffuse = LoadTexture(mapFileName);
|
||||
}
|
||||
else if (buffer[5] == 's') // map_Ks string Specular color texture map.
|
||||
{
|
||||
sscanf(buffer, "map_Ks %s", mapFileName);
|
||||
if (mapFileName != NULL) material.texSpecular = LoadTexture(mapFileName);
|
||||
}
|
||||
else if (buffer[5] == 'a') // map_Ka string Ambient color texture map.
|
||||
{
|
||||
// Not supported...
|
||||
}
|
||||
} break;
|
||||
case 'B': // map_Bump string Bump texture map.
|
||||
{
|
||||
sscanf(buffer, "map_Bump %s", mapFileName);
|
||||
if (mapFileName != NULL) material.texNormal = LoadTexture(mapFileName);
|
||||
} break;
|
||||
case 'b': // map_bump string Bump texture map.
|
||||
{
|
||||
sscanf(buffer, "map_bump %s", mapFileName);
|
||||
if (mapFileName != NULL) material.texNormal = LoadTexture(mapFileName);
|
||||
} break;
|
||||
case 'd': // map_d string Opacity texture map.
|
||||
{
|
||||
// Not supported...
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
} break;
|
||||
case 'd': // d, disp
|
||||
{
|
||||
if (buffer[1] == ' ') // d float Dissolve factor. d is inverse of Tr
|
||||
{
|
||||
float alpha = 1.0f;
|
||||
sscanf(buffer, "d %f", &alpha);
|
||||
material.colDiffuse.a = (unsigned char)(alpha*255);
|
||||
}
|
||||
else if (buffer[1] == 'i') // disp string Displacement map
|
||||
{
|
||||
// Not supported...
|
||||
}
|
||||
} break;
|
||||
case 'b': // bump string Bump texture map
|
||||
{
|
||||
sscanf(buffer, "bump %s", mapFileName);
|
||||
if (mapFileName != NULL) material.texNormal = LoadTexture(mapFileName);
|
||||
} break;
|
||||
case 'T': // Tr float Transparency Tr (alpha). Tr is inverse of d
|
||||
{
|
||||
float ialpha = 0.0f;
|
||||
sscanf(buffer, "Tr %f", &ialpha);
|
||||
material.colDiffuse.a = (unsigned char)((1.0f - ialpha)*255);
|
||||
|
||||
} break;
|
||||
case 'r': // refl string Reflection texture map
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(mtlFile);
|
||||
|
||||
// NOTE: At this point we have all material data
|
||||
TraceLog(INFO, "[%s] Material loaded successfully", fileName);
|
||||
|
||||
return material;
|
||||
}
|
||||
|
|
12
src/physac.c
12
src/physac.c
|
@ -49,7 +49,7 @@
|
|||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
static PhysicObject *physicObjects[MAX_PHYSIC_OBJECTS]; // Physic objects pool
|
||||
static PhysicObject physicObjects[MAX_PHYSIC_OBJECTS]; // Physic objects pool
|
||||
static int physicObjectsCount; // Counts current enabled physic objects
|
||||
static Vector2 gravityForce; // Gravity force
|
||||
|
||||
|
@ -463,10 +463,10 @@ void ClosePhysics()
|
|||
}
|
||||
|
||||
// Create a new physic object dinamically, initialize it and add to pool
|
||||
PhysicObject *CreatePhysicObject(Vector2 position, float rotation, Vector2 scale)
|
||||
PhysicObject CreatePhysicObject(Vector2 position, float rotation, Vector2 scale)
|
||||
{
|
||||
// Allocate dynamic memory
|
||||
PhysicObject *obj = (PhysicObject *)malloc(sizeof(PhysicObject));
|
||||
PhysicObject obj = (PhysicObject)malloc(sizeof(PhysicObjectData));
|
||||
|
||||
// Initialize physic object values with generic values
|
||||
obj->id = physicObjectsCount;
|
||||
|
@ -498,7 +498,7 @@ PhysicObject *CreatePhysicObject(Vector2 position, float rotation, Vector2 scale
|
|||
}
|
||||
|
||||
// Destroy a specific physic object and take it out of the list
|
||||
void DestroyPhysicObject(PhysicObject *pObj)
|
||||
void DestroyPhysicObject(PhysicObject pObj)
|
||||
{
|
||||
// Free dynamic memory allocation
|
||||
free(physicObjects[pObj->id]);
|
||||
|
@ -520,7 +520,7 @@ void DestroyPhysicObject(PhysicObject *pObj)
|
|||
}
|
||||
|
||||
// Apply directional force to a physic object
|
||||
void ApplyForce(PhysicObject *pObj, Vector2 force)
|
||||
void ApplyForce(PhysicObject pObj, Vector2 force)
|
||||
{
|
||||
if (pObj->rigidbody.enabled)
|
||||
{
|
||||
|
@ -571,7 +571,7 @@ Rectangle TransformToRectangle(Transform transform)
|
|||
}
|
||||
|
||||
// Draw physic object information at screen position
|
||||
void DrawPhysicObjectInfo(PhysicObject *pObj, Vector2 position, int fontSize)
|
||||
void DrawPhysicObjectInfo(PhysicObject pObj, Vector2 position, int fontSize)
|
||||
{
|
||||
// Draw physic object ID
|
||||
DrawText(FormatText("PhysicObject ID: %i - Enabled: %i", pObj->id, pObj->enabled), position.x, position.y, fontSize, BLACK);
|
||||
|
|
12
src/physac.h
12
src/physac.h
|
@ -66,13 +66,13 @@ typedef struct Collider {
|
|||
int radius; // Used for COLLIDER_CIRCLE
|
||||
} Collider;
|
||||
|
||||
typedef struct PhysicObject {
|
||||
typedef struct PhysicObjectData {
|
||||
unsigned int id;
|
||||
Transform transform;
|
||||
Rigidbody rigidbody;
|
||||
Collider collider;
|
||||
bool enabled;
|
||||
} PhysicObject;
|
||||
} PhysicObjectData, *PhysicObject;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
|
@ -85,14 +85,14 @@ void InitPhysics(Vector2 gravity);
|
|||
void UpdatePhysics(); // Update physic objects, calculating physic behaviours and collisions detection
|
||||
void ClosePhysics(); // Unitialize all physic objects and empty the objects pool
|
||||
|
||||
PhysicObject *CreatePhysicObject(Vector2 position, float rotation, Vector2 scale); // Create a new physic object dinamically, initialize it and add to pool
|
||||
void DestroyPhysicObject(PhysicObject *pObj); // Destroy a specific physic object and take it out of the list
|
||||
PhysicObject CreatePhysicObject(Vector2 position, float rotation, Vector2 scale); // Create a new physic object dinamically, initialize it and add to pool
|
||||
void DestroyPhysicObject(PhysicObject pObj); // Destroy a specific physic object and take it out of the list
|
||||
|
||||
void ApplyForce(PhysicObject *pObj, Vector2 force); // Apply directional force to a physic object
|
||||
void ApplyForce(PhysicObject pObj, Vector2 force); // Apply directional force to a physic object
|
||||
void ApplyForceAtPosition(Vector2 position, float force, float radius); // Apply radial force to all physic objects in range
|
||||
|
||||
Rectangle TransformToRectangle(Transform transform); // Convert Transform data type to Rectangle (position and scale)
|
||||
void DrawPhysicObjectInfo(PhysicObject *pObj, Vector2 position, int fontSize); // Draw physic object information at screen position
|
||||
void DrawPhysicObjectInfo(PhysicObject pObj, Vector2 position, int fontSize); // Draw physic object information at screen position
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
228
src/raylib.h
228
src/raylib.h
|
@ -1,6 +1,6 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raylib 1.4.0 (www.raylib.com)
|
||||
* raylib 1.5.0 (www.raylib.com)
|
||||
*
|
||||
* A simple and easy-to-use library to learn videogames programming
|
||||
*
|
||||
|
@ -261,7 +261,9 @@
|
|||
//----------------------------------------------------------------------------------
|
||||
#ifndef __cplusplus
|
||||
// Boolean type
|
||||
typedef enum { false, true } bool;
|
||||
#ifndef true
|
||||
typedef enum { false, true } bool;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// byte type
|
||||
|
@ -324,6 +326,13 @@ typedef struct Texture2D {
|
|||
int format; // Data format (TextureFormat)
|
||||
} Texture2D;
|
||||
|
||||
// RenderTexture2D type, for texture rendering
|
||||
typedef struct RenderTexture2D {
|
||||
unsigned int id; // Render texture (fbo) id
|
||||
Texture2D texture; // Color buffer attachment texture
|
||||
Texture2D depth; // Depth buffer attachment texture
|
||||
} RenderTexture2D;
|
||||
|
||||
// SpriteFont type, includes texture and charSet array data
|
||||
typedef struct SpriteFont {
|
||||
Texture2D texture; // Font texture
|
||||
|
@ -345,8 +354,8 @@ typedef struct Camera {
|
|||
|
||||
// Camera2D type, defines a 2d camera
|
||||
typedef struct Camera2D {
|
||||
Vector2 position; // Camera position
|
||||
Vector2 origin; // Camera origin (for rotation and zoom)
|
||||
Vector2 offset; // Camera offset (displacement from target)
|
||||
Vector2 target; // Camera target (rotation and zoom origin)
|
||||
float rotation; // Camera rotation in degrees
|
||||
float zoom; // Camera zoom (scaling), should be 1.0f by default
|
||||
} Camera2D;
|
||||
|
@ -359,34 +368,39 @@ typedef struct BoundingBox {
|
|||
|
||||
// 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)
|
||||
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[6]; // OpenGL Vertex Buffer Objects id (6 types of vertex data)
|
||||
unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
|
||||
} Mesh;
|
||||
|
||||
// Shader type (generic shader)
|
||||
typedef struct Shader {
|
||||
unsigned int id; // Shader program id
|
||||
unsigned int id; // Shader program id
|
||||
|
||||
// Variable attributes
|
||||
int vertexLoc; // Vertex attribute location point (vertex shader)
|
||||
int texcoordLoc; // Texcoord attribute location point (vertex shader)
|
||||
int normalLoc; // Normal attribute location point (vertex shader)
|
||||
int colorLoc; // Color attibute location point (vertex shader)
|
||||
// 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)
|
||||
|
||||
// Uniforms
|
||||
// Uniform locations
|
||||
int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
|
||||
int tintColorLoc; // Color uniform location point (fragment shader)
|
||||
|
||||
// Texture map locations
|
||||
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)
|
||||
|
@ -408,14 +422,38 @@ typedef struct Material {
|
|||
float normalDepth; // Normal map depth
|
||||
} Material;
|
||||
|
||||
// 3d Model type
|
||||
// TODO: Replace shader/testure by material
|
||||
// Model type
|
||||
typedef struct Model {
|
||||
Mesh mesh;
|
||||
Matrix transform;
|
||||
Material material;
|
||||
Mesh mesh; // Vertex data buffers (RAM and VRAM)
|
||||
Matrix transform; // Local transform matrix
|
||||
Material material; // Shader and textures data
|
||||
} Model;
|
||||
|
||||
// Light type
|
||||
// TODO: Review contained data to support different light types and features
|
||||
typedef struct LightData {
|
||||
int id;
|
||||
int type; // LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
|
||||
bool enabled;
|
||||
|
||||
Vector3 position;
|
||||
Vector3 direction; // Used on LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction)
|
||||
float attenuation; // Lost of light intensity with distance (use radius?)
|
||||
|
||||
Color diffuse; // Use Vector3 diffuse (including intensities)?
|
||||
float intensity;
|
||||
|
||||
Color specular;
|
||||
//float specFactor; // Specular intensity ?
|
||||
|
||||
//Color ambient; // Required?
|
||||
|
||||
float coneAngle; // SpotLight
|
||||
} LightData, *Light;
|
||||
|
||||
// Light types
|
||||
typedef enum { LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT } LightType;
|
||||
|
||||
// Ray type (useful for raycast)
|
||||
typedef struct Ray {
|
||||
Vector3 position;
|
||||
|
@ -432,11 +470,13 @@ typedef struct Sound {
|
|||
typedef struct Wave {
|
||||
void *data; // Buffer data pointer
|
||||
unsigned int dataSize; // Data size in bytes
|
||||
unsigned int sampleRate;
|
||||
short bitsPerSample;
|
||||
unsigned int sampleRate; // Samples per second to be played
|
||||
short bitsPerSample; // Sample size in bits
|
||||
short channels;
|
||||
} Wave;
|
||||
|
||||
typedef int RawAudioContext;
|
||||
|
||||
// Texture formats
|
||||
// NOTE: Support depends on OpenGL version and platform
|
||||
typedef enum {
|
||||
|
@ -484,7 +524,7 @@ typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction;
|
|||
|
||||
// Gesture events
|
||||
// NOTE: MAX_TOUCH_POINTS fixed to 2
|
||||
typedef struct {
|
||||
typedef struct GestureEvent {
|
||||
int touchAction;
|
||||
int pointCount;
|
||||
int pointerId[MAX_TOUCH_POINTS];
|
||||
|
@ -520,13 +560,13 @@ typedef struct Collider {
|
|||
int radius; // Used for COLLIDER_CIRCLE
|
||||
} Collider;
|
||||
|
||||
typedef struct PhysicObject {
|
||||
typedef struct PhysicObjectData {
|
||||
unsigned int id;
|
||||
Transform transform;
|
||||
Rigidbody rigidbody;
|
||||
Collider collider;
|
||||
bool enabled;
|
||||
} PhysicObject;
|
||||
} PhysicObjectData, *PhysicObject;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
|
@ -550,24 +590,28 @@ void CloseWindow(void); // Close Window and
|
|||
bool WindowShouldClose(void); // Detect if KEY_ESCAPE pressed or Close icon pressed
|
||||
bool IsWindowMinimized(void); // Detect if window has been minimized (or lost focus)
|
||||
void ToggleFullscreen(void); // Fullscreen toggle (only PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
void SetCustomCursor(const char *cursorImage); // Set a custom cursor icon/image
|
||||
void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
|
||||
#endif
|
||||
int GetScreenWidth(void); // Get current screen width
|
||||
int GetScreenHeight(void); // Get current screen height
|
||||
|
||||
void ShowCursor(void); // Shows cursor
|
||||
void HideCursor(void); // Hides cursor
|
||||
bool IsCursorHidden(void); // Returns true if cursor is not visible
|
||||
void EnableCursor(void); // Enables cursor
|
||||
void DisableCursor(void); // Disables cursor
|
||||
|
||||
void ClearBackground(Color color); // Sets Background Color
|
||||
void BeginDrawing(void); // Setup drawing canvas to start drawing
|
||||
void BeginDrawingEx(Camera2D camera); // Setup drawing canvas with 2d camera
|
||||
void BeginDrawingPro(int blendMode, Shader shader, Matrix transform); // Setup drawing canvas with pro parameters
|
||||
void EndDrawing(void); // End canvas drawing and Swap Buffers (Double Buffering)
|
||||
|
||||
void Begin2dMode(Camera2D camera); // Initialize 2D mode with custom camera
|
||||
void End2dMode(void); // Ends 2D mode custom camera usage
|
||||
void Begin3dMode(Camera camera); // Initializes 3D mode for drawing (Camera setup)
|
||||
void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode
|
||||
void BeginTextureMode(RenderTexture2D target); // Initializes render texture for drawing
|
||||
void EndTextureMode(void); // Ends drawing to render texture
|
||||
|
||||
Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position
|
||||
Vector2 WorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position
|
||||
Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position
|
||||
Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix)
|
||||
|
||||
void SetTargetFPS(int fps); // Set target FPS (maximum)
|
||||
|
@ -602,6 +646,15 @@ bool IsKeyDown(int key); // Detect if a key is be
|
|||
bool IsKeyReleased(int key); // Detect if a key has been released once
|
||||
bool IsKeyUp(int key); // Detect if a key is NOT being pressed
|
||||
int GetKeyPressed(void); // Get latest key pressed
|
||||
void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
|
||||
|
||||
bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
|
||||
float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis
|
||||
bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once
|
||||
bool IsGamepadButtonDown(int gamepad, int button); // Detect if a gamepad button is being pressed
|
||||
bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button has been released once
|
||||
bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad button is NOT being pressed
|
||||
#endif
|
||||
|
||||
bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once
|
||||
bool IsMouseButtonDown(int button); // Detect if a mouse button is being pressed
|
||||
|
@ -613,20 +666,6 @@ Vector2 GetMousePosition(void); // Returns mouse positio
|
|||
void SetMousePosition(Vector2 position); // Set mouse position XY
|
||||
int GetMouseWheelMove(void); // Returns mouse wheel movement Y
|
||||
|
||||
void ShowCursor(void); // Shows cursor
|
||||
void HideCursor(void); // Hides cursor
|
||||
void EnableCursor(void); // Enables cursor
|
||||
void DisableCursor(void); // Disables cursor
|
||||
bool IsCursorHidden(void); // Returns true if cursor is not visible
|
||||
|
||||
bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
|
||||
float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis
|
||||
bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once
|
||||
bool IsGamepadButtonDown(int gamepad, int button); // Detect if a gamepad button is being pressed
|
||||
bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button has been released once
|
||||
bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad button is NOT being pressed
|
||||
#endif
|
||||
|
||||
int GetTouchX(void); // Returns touch position X for touch point 0 (relative to screen size)
|
||||
int GetTouchY(void); // Returns touch position Y for touch point 0 (relative to screen size)
|
||||
Vector2 GetTouchPosition(int index); // Returns touch position XY for a touch point index (relative to screen size)
|
||||
|
@ -641,9 +680,9 @@ bool IsButtonReleased(int button); // Detect if an android
|
|||
// Gestures and Touch Handling Functions (Module: gestures)
|
||||
//------------------------------------------------------------------------------------
|
||||
void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures
|
||||
void UpdateGestures(void); // Update gestures detected (must be called every frame)
|
||||
bool IsGestureDetected(void); // Check if a gesture have been detected
|
||||
int GetGestureType(void); // Get latest detected gesture
|
||||
void UpdateGestures(void); // Update gestures detected (called automatically in PollInputEvents())
|
||||
bool IsGestureDetected(int gesture); // Check if a gesture have been detected
|
||||
int GetGestureDetected(void); // Get latest detected gesture
|
||||
void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags
|
||||
int GetTouchPointsCount(void); // Get touch points count
|
||||
|
||||
|
@ -714,8 +753,10 @@ Texture2D LoadTexture(const char *fileName);
|
|||
Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory
|
||||
Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
|
||||
Texture2D LoadTextureFromImage(Image image); // Load a texture from image data
|
||||
RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering
|
||||
void UnloadImage(Image image); // Unload image from CPU memory (RAM)
|
||||
void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
|
||||
void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory
|
||||
Color *GetImageData(Image image); // Get pixel data from image as a Color struct array
|
||||
Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image
|
||||
void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
|
||||
|
@ -785,17 +826,21 @@ void DrawGizmo(Vector3 position);
|
|||
//------------------------------------------------------------------------------------
|
||||
// Model 3d Loading and Drawing Functions (Module: models)
|
||||
//------------------------------------------------------------------------------------
|
||||
Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
|
||||
Model LoadModelEx(Mesh data); // Load a 3d model (from mesh data)
|
||||
//Model LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource)
|
||||
Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model
|
||||
Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
|
||||
void UnloadModel(Model model); // Unload 3d model from memory
|
||||
void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model
|
||||
Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
|
||||
Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data)
|
||||
Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d model from rRES file (raylib Resource)
|
||||
Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model
|
||||
Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
|
||||
void UnloadModel(Model model); // Unload 3d model from memory
|
||||
void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model
|
||||
|
||||
Material LoadMaterial(const char *fileName); // Load material data (from file)
|
||||
Material LoadDefaultMaterial(void); // Load default material (uses default models shader)
|
||||
void UnloadMaterial(Material material); // Unload material textures from VRAM
|
||||
|
||||
void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
|
||||
void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
|
||||
void DrawModelWires(Model model, Vector3 position, float scale, Color color); // Draw a model wires (with texture if set)
|
||||
void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
|
||||
void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
|
||||
void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
|
||||
|
||||
|
@ -816,25 +861,22 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p
|
|||
// 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 shaders strings and return program id
|
||||
void UnloadShader(Shader shader); // Unload a custom shader from memory
|
||||
void SetPostproShader(Shader shader); // Set fullscreen postproduction shader
|
||||
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
|
||||
bool IsPosproShaderEnabled(void); // Check if postprocessing shader is enabled
|
||||
void SetCustomShader(Shader shader); // Set custom shader to be used in batch draw
|
||||
Shader GetDefaultShader(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 SetShaderMapDiffuse(Shader *shader, Texture2D texture); // Default diffuse shader map texture assignment
|
||||
//void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D texture); // Normal map texture shader assignment
|
||||
//void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture); // Specular map texture shader assignment
|
||||
//void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textureUnit); // TODO: Generic shader map assignment
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Physics System Functions (Module: physac)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -842,20 +884,21 @@ void InitPhysics(Vector2 gravity);
|
|||
void UpdatePhysics(); // Update physic objects, calculating physic behaviours and collisions detection
|
||||
void ClosePhysics(); // Unitialize all physic objects and empty the objects pool
|
||||
|
||||
PhysicObject *CreatePhysicObject(Vector2 position, float rotation, Vector2 scale); // Create a new physic object dinamically, initialize it and add to pool
|
||||
void DestroyPhysicObject(PhysicObject *pObj); // Destroy a specific physic object and take it out of the list
|
||||
PhysicObject CreatePhysicObject(Vector2 position, float rotation, Vector2 scale); // Create a new physic object dinamically, initialize it and add to pool
|
||||
void DestroyPhysicObject(PhysicObject pObj); // Destroy a specific physic object and take it out of the list
|
||||
|
||||
void ApplyForce(PhysicObject *pObj, Vector2 force); // Apply directional force to a physic object
|
||||
void ApplyForce(PhysicObject pObj, Vector2 force); // Apply directional force to a physic object
|
||||
void ApplyForceAtPosition(Vector2 position, float force, float radius); // Apply radial force to all physic objects in range
|
||||
|
||||
Rectangle TransformToRectangle(Transform transform); // Convert Transform data type to Rectangle (position and scale)
|
||||
void DrawPhysicObjectInfo(PhysicObject *pObj, Vector2 position, int fontSize); // Draw physic object information at screen position
|
||||
void DrawPhysicObjectInfo(PhysicObject pObj, Vector2 position, int fontSize); // Draw physic object information at screen position
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Audio Loading and Playing Functions (Module: audio)
|
||||
//------------------------------------------------------------------------------------
|
||||
void InitAudioDevice(void); // Initialize audio device and context
|
||||
void CloseAudioDevice(void); // Close the audio device and context (and music stream)
|
||||
bool IsAudioDeviceReady(void); // True if call to InitAudioDevice() was successful and CloseAudioDevice() has not been called yet
|
||||
|
||||
Sound LoadSound(char *fileName); // Load sound to memory
|
||||
Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
|
||||
|
@ -864,19 +907,28 @@ void UnloadSound(Sound sound); // Unload sound
|
|||
void PlaySound(Sound sound); // Play a sound
|
||||
void PauseSound(Sound sound); // Pause a sound
|
||||
void StopSound(Sound sound); // Stop playing a sound
|
||||
bool SoundIsPlaying(Sound sound); // Check if a sound is currently playing
|
||||
bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing
|
||||
void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
|
||||
void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
|
||||
|
||||
void PlayMusicStream(char *fileName); // Start music playing (open stream)
|
||||
void UpdateMusicStream(void); // Updates buffers for music streaming
|
||||
void StopMusicStream(void); // Stop music playing (close stream)
|
||||
void PauseMusicStream(void); // Pause music playing
|
||||
void ResumeMusicStream(void); // Resume playing paused music
|
||||
bool MusicIsPlaying(void); // Check if music is playing
|
||||
void SetMusicVolume(float volume); // Set volume for music (1.0 is max level)
|
||||
float GetMusicTimeLength(void); // Get current music time length (in seconds)
|
||||
float GetMusicTimePlayed(void); // Get current music time played (in seconds)
|
||||
int PlayMusicStream(int musicIndex, char *fileName); // Start music playing (open stream)
|
||||
void UpdateMusicStream(int index); // Updates buffers for music streaming
|
||||
void StopMusicStream(int index); // Stop music playing (close stream)
|
||||
void PauseMusicStream(int index); // Pause music playing
|
||||
void ResumeMusicStream(int index); // Resume playing paused music
|
||||
bool IsMusicPlaying(int index); // Check if music is playing
|
||||
void SetMusicVolume(int index, float volume); // Set volume for music (1.0 is max level)
|
||||
float GetMusicTimeLength(int index); // Get current music time length (in seconds)
|
||||
float GetMusicTimePlayed(int index); // Get current music time played (in seconds)
|
||||
int getMusicStreamCount(void);
|
||||
void SetMusicPitch(int index, float pitch);
|
||||
|
||||
// used to output raw audio streams, returns negative numbers on error
|
||||
// if floating point is false the data size is 16bit short, otherwise it is float 32bit
|
||||
RawAudioContext InitRawAudioContext(int sampleRate, int channels, bool floatingPoint);
|
||||
|
||||
void CloseRawAudioContext(RawAudioContext ctx);
|
||||
int BufferRawAudioContext(RawAudioContext ctx, void *data, int numberElements); // returns number of elements buffered
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
2315
src/rlgl.c
2315
src/rlgl.c
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue