aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile163
-rw-r--r--src/audio.c29
-rw-r--r--src/camera.h65
-rw-r--r--src/core.c75
-rw-r--r--src/models.c4
-rw-r--r--src/raylib.h4
-rw-r--r--src/raymath.h51
-rw-r--r--src/rlgl.c38
-rw-r--r--src/rlgl.h127
-rw-r--r--src/text.c2
-rw-r--r--src/textures.c67
11 files changed, 364 insertions, 261 deletions
diff --git a/src/Makefile b/src/Makefile
index b616b583..f2e09988 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,10 +1,19 @@
#******************************************************************************
#
-# raylib makefile for desktop platforms, Raspberry Pi and HTML5 (emscripten)
+# raylib makefile
#
-# Many Thanks to Emanuele Petriglia for his contribution on GNU/Linux pipeline.
+# Platforms supported:
+# PLATFORM_DESKTOP: Windows (win32/Win64)
+# PLATFORM_DESKTOP: Linux
+# PLATFORM_DESKTOP: OSX (Mac)
+# PLATFORM_ANDROID: Android (ARM or ARM64)
+# PLATFORM_RPI: Raspberry Pi (Raspbian)
+# PLATFORM_WEB: HTML5 (Chrome, Firefox)
#
-# Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+# Many thanks to Milan Nikolic (@gen2brain) for implementing Android platform pipeline.
+# Many thanks to Emanuele Petriglia for his contribution on GNU/Linux pipeline.
+#
+# Copyright (c) 2014-2017 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
@@ -29,7 +38,7 @@
# Please read the wiki to know how to compile raylib, because there are
# different methods.
-.PHONY: all clean install unistall
+.PHONY: all clean install uninstall
# define raylib platform to compile for
# possible platforms: PLATFORM_DESKTOP PLATFORM_ANDROID PLATFORM_RPI PLATFORM_WEB
@@ -38,12 +47,16 @@ PLATFORM ?= PLATFORM_DESKTOP
# define YES if you want shared/dynamic version of library instead of static (default)
SHARED ?= NO
-# define NO to use OpenAL Soft as static library (or shared by default)
-SHARED_OPENAL ?= YES
+# use OpenAL Soft as shared library (.so / .dll)
+# NOTE: If defined NO, static OpenAL Soft library should be provided
+SHARED_OPENAL ?= NO
# on PLATFORM_WEB force OpenAL Soft shared library
ifeq ($(PLATFORM),PLATFORM_WEB)
- SHARED_OPENAL ?= YES
+ SHARED_OPENAL = YES
+endif
+ifeq ($(PLATFORM),PLATFORM_ANDROID)
+ SHARED_OPENAL = YES
endif
# determine if the file has root access (only for installing raylib)
@@ -69,48 +82,67 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
endif
endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ # Emscripten required variables
+ EMSDK_PATH = C:/emsdk
+ EMSCRIPTEN_VERSION = 1.37.9
+ CLANG_VERSION=e1.37.9_64bit
+ PYTHON_VERSION=2.7.5.3_64bit
+ NODE_VERSION=4.1.1_64bit
+ export PATH=$(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
+ EMSCRIPTEN=$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION)
+endif
+
ifeq ($(PLATFORM),PLATFORM_ANDROID)
- # path to Android NDK
+ # Android NDK path
+ # NOTE: Required for standalone toolchain generation
ANDROID_NDK = $(ANDROID_NDK_HOME)
+
+ # Android standalone toolchain path
+ # NOTE: This path is also used if toolchain generation
+ #ANDROID_TOOLCHAIN = $(CURDIR)/toolchain
+ ANDROID_TOOLCHAIN = C:/raylib/android-standalone-toolchain
- # possible Android architectures: ARM ARM64
+ # Android architecture: ARM or ARM64
ANDROID_ARCH ?= ARM
- # define YES to use clang instead of gcc
+ # Android compiler: gcc or clang
+ # NOTE: Define YES to use clang instead of gcc
ANDROID_LLVM ?= NO
-
- # standalone Android toolchain install dir
- ANDROID_TOOLCHAIN = $(CURDIR)/toolchain
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
+ # RPI cross-compiler
CROSS_COMPILE ?= NO
endif
# define raylib graphics api depending on selected platform
-ifeq ($(PLATFORM),PLATFORM_ANDROID)
- GRAPHICS = GRAPHICS_API_OPENGL_ES2
-endif
-ifeq ($(PLATFORM),PLATFORM_RPI)
- # define raylib graphics api to use (on RPI, OpenGL ES 2.0 must be used)
- GRAPHICS = GRAPHICS_API_OPENGL_ES2
-else
- # define raylib graphics api to use (OpenGL 3.3 by default)
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ # by default use OpenGL 3.3 on desktop platforms
GRAPHICS ?= GRAPHICS_API_OPENGL_33
#GRAPHICS = GRAPHICS_API_OPENGL_11 # Uncomment to use OpenGL 1.1
#GRAPHICS = GRAPHICS_API_OPENGL_21 # Uncomment to use OpenGL 2.1
endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ # on RPI OpenGL ES 2.0 must be used
+ GRAPHICS = GRAPHICS_API_OPENGL_ES2
+endif
ifeq ($(PLATFORM),PLATFORM_WEB)
+ # on HTML5 OpenGL ES 2.0 is used, emscripten translates it to WebGL 1.0
+ GRAPHICS = GRAPHICS_API_OPENGL_ES2
+endif
+ifeq ($(PLATFORM),PLATFORM_ANDROID)
+ # by default use OpenGL ES 2.0 on Android
GRAPHICS = GRAPHICS_API_OPENGL_ES2
endif
# NOTE: makefiles targets require tab indentation
-
-# define compiler: gcc for C program, define as g++ for C++
+# NOTE: define compiler: gcc for C program, define as g++ for C++
# default gcc compiler
CC = gcc
+# Android toolchain compiler
ifeq ($(PLATFORM),PLATFORM_ANDROID)
ifeq ($(ANDROID_ARCH),ARM)
ifeq ($(ANDROID_LLVM),YES)
@@ -128,6 +160,7 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID)
endif
endif
+# RPI cross-compiler
ifeq ($(PLATFORM),PLATFORM_RPI)
ifeq ($(CROSS_COMPILE),YES)
# rpi compiler
@@ -135,13 +168,15 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
endif
endif
+# HTML5 emscripten compiler
ifeq ($(PLATFORM),PLATFORM_WEB)
- # emscripten compiler
CC = emcc
endif
+# default archiver program to pack libraries
AR = ar
+# Android archiver
ifeq ($(PLATFORM),PLATFORM_ANDROID)
ifeq ($(ANDROID_ARCH),ARM)
AR = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-ar
@@ -159,29 +194,17 @@ endif
# -std=gnu99 defines C language mode (GNU C from 1999 revision)
# -fgnu89-inline declaring inline functions support (GCC optimized)
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
-# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB
-ifeq ($(PLATFORM),PLATFORM_DESKTOP)
- ifeq ($(PLATFORM_OS),WINDOWS)
- CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline -Wno-missing-braces
- endif
- ifeq ($(PLATFORM_OS),LINUX)
- CFLAGS = -O1 -Wall -std=c99 -D_DEFAULT_SOURCE
- endif
- ifeq ($(PLATFORM_OS),OSX)
- CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline -Wno-missing-braces
- endif
-endif
+# -D_DEFAULT_SOURCE use with -std=c99
+CFLAGS = -O1 -Wall -std=c99 -D_DEFAULT_SOURCE -fgnu89-inline -Wno-missing-braces
+
ifeq ($(PLATFORM),PLATFORM_WEB)
- CFLAGS = -O1 -Wall -std=c99 -D_DEFAULT_SOURCE -s USE_GLFW=3 -s ASSERTIONS=1 --profiling --preload-file resources
+ CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 --profiling --preload-file resources
# -O2 # if used, also set --memory-init-file 0
# --memory-init-file 0 # to avoid an external memory initialization code file (.mem)
# -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
# -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
# -s USE_PTHREADS=1 # multithreading support
endif
-ifeq ($(PLATFORM),PLATFORM_RPI)
- CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline -Wno-missing-braces
-endif
#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
@@ -205,32 +228,32 @@ endif
#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
-# define any directories containing required header files
-ifeq ($(PLATFORM),PLATFORM_ANDROID)
-# STB libraries and others
- INCLUDES = -I. -Iexternal
+# external required libraries (stb and others)
+INCLUDES = -I. -Iexternal
# OpenAL Soft library
- INCLUDES += -Iexternal/openal_soft/include
-# Android includes
- INCLUDES += -I$(ANDROID_TOOLCHAIN)/sysroot/usr/include
- INCLUDES += -I$(ANDROID_NDK)/sources/android/native_app_glue
-else
-# STB libraries and others
- INCLUDES = -I. -Iexternal
-# GLFW3 library
+INCLUDES += -Iexternal/openal_soft/include
+
+# define any directories containing required header files
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ # GLFW3 library
INCLUDES += -Iexternal/glfw3/include
-# OpenAL Soft library
- INCLUDES += -Iexternal/openal_soft/include
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
-# STB libraries and others
- INCLUDES = -I. -Iexternal
-# RPi libraries
+ # RPI requried libraries
INCLUDES += -I/opt/vc/include
INCLUDES += -I/opt/vc/include/interface/vmcs_host/linux
INCLUDES += -I/opt/vc/include/interface/vcos/pthreads
-# OpenAL Soft library
- INCLUDES += -Iexternal/openal_soft/include
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ # GLFW3 library
+ INCLUDES += -Iexternal/glfw3/include
+endif
+ifeq ($(PLATFORM),PLATFORM_ANDROID)
+ # Android required libraries
+ INCLUDES += -I$(ANDROID_TOOLCHAIN)/sysroot/usr/include
+ # Include android_native_app_glue.h
+ INCLUDES += -Iandroid/jni/include
+ #INCLUDES += -I$(ANDROID_NDK)/sources/android/native_app_glue
endif
# define output directory for compiled library
@@ -245,6 +268,12 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
OUTPUT_PATH = ../release/osx
endif
endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ OUTPUT_PATH = ../release/rpi
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ OUTPUT_PATH = ../release/html5
+endif
ifeq ($(PLATFORM),PLATFORM_ANDROID)
ifeq ($(ANDROID_ARCH),ARM)
OUTPUT_PATH = ../release/android/armeabi-v7a
@@ -253,12 +282,6 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID)
OUTPUT_PATH = ../release/android/arm64-v8a
endif
endif
-ifeq ($(PLATFORM),PLATFORM_WEB)
- OUTPUT_PATH = ../release/html5
-endif
-ifeq ($(PLATFORM),PLATFORM_RPI)
- OUTPUT_PATH = ../release/rpi
-endif
# define all object files required with a wildcard
# The wildcard takes all files that finish with ".c", then it replaces the
@@ -268,9 +291,10 @@ OBJS += external/stb_vorbis.o
# typing 'make' will invoke the default target entry called 'all',
# in this case, the 'default' target entry is raylib
-all: toolchain raylib
+all: raylib
-# make standalone Android toolchain
+# generate standalone Android toolchain
+# NOTE: Android toolchain could already be provided
toolchain:
ifeq ($(PLATFORM),PLATFORM_ANDROID)
ifeq ($(ANDROID_ARCH),ARM)
@@ -304,7 +328,7 @@ else
@echo "raylib shared library (libraylib.so) generated!"
endif
else
- # compile raylib static library.
+ # compile raylib static library.
$(AR) rcs $(OUTPUT_PATH)/libraylib.a $(OBJS)
@echo "libraylib.a generated (static library)!"
ifeq ($(SHARED_OPENAL),NO)
@@ -353,6 +377,7 @@ external/stb_vorbis.o: external/stb_vorbis.c external/stb_vorbis.h
utils.o : utils.c utils.h
$(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(SHAREDFLAG)
+
# It installs generated and needed files to compile projects using raylib.
# The installation works manually.
# TODO: add other platforms.
@@ -379,7 +404,7 @@ endif
# it removes raylib dev files installed on the system.
# TODO: see 'install' target.
-unistall :
+uninstall :
ifeq ($(ROOT),root)
ifeq ($(PLATFORM_OS),LINUX)
rm --force /usr/local/include/raylib.h
diff --git a/src/audio.c b/src/audio.c
index d63047a8..39befbbc 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -79,7 +79,7 @@
#include "utils.h" // Required for: fopen() Android mapping
#endif
-#ifdef __APPLE__
+#if defined(__APPLE__)
#include "OpenAL/al.h" // OpenAL basic header
#include "OpenAL/alc.h" // OpenAL context header (like OpenGL, OpenAL requires a context to work)
#else
@@ -570,7 +570,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
// NOTE: Only supported mono <--> stereo
if (wave->channels != channels)
{
- void *data = malloc(wave->sampleCount*channels*wave->sampleSize/8);
+ void *data = malloc(wave->sampleCount*wave->sampleSize/8*channels);
if ((wave->channels == 1) && (channels == 2)) // mono ---> stereo (duplicate mono information)
{
@@ -607,7 +607,7 @@ Wave WaveCopy(Wave wave)
{
Wave newWave = { 0 };
- newWave.data = malloc(wave.sampleCount*wave.channels*wave.sampleSize/8);
+ newWave.data = malloc(wave.sampleCount*wave.sampleSize/8*wave.channels);
if (newWave.data != NULL)
{
@@ -632,7 +632,7 @@ void WaveCrop(Wave *wave, int initSample, int finalSample)
{
int sampleCount = finalSample - initSample;
- void *data = malloc(sampleCount*wave->channels*wave->sampleSize/8);
+ void *data = malloc(sampleCount*wave->sampleSize/8*wave->channels);
memcpy(data, (unsigned char*)wave->data + (initSample*wave->channels*wave->sampleSize/8), sampleCount*wave->channels*wave->sampleSize/8);
@@ -810,7 +810,8 @@ void StopMusicStream(Music music)
for (int i = 0; i < MAX_STREAM_BUFFERS; i++)
{
- alBufferData(music->stream.buffers[i], music->stream.format, pcm, AUDIO_BUFFER_SIZE*music->stream.sampleSize/8*music->stream.channels, music->stream.sampleRate);
+ UpdateAudioStream(music->stream, pcm, AUDIO_BUFFER_SIZE);
+ //alBufferData(music->stream.buffers[i], music->stream.format, pcm, AUDIO_BUFFER_SIZE*music->stream.sampleSize/8*music->stream.channels, music->stream.sampleRate);
}
free(pcm);
@@ -849,11 +850,11 @@ void UpdateMusicStream(Music music)
bool active = true;
// NOTE: Using dynamic allocation because it could require more than 16KB
- void *pcm = calloc(AUDIO_BUFFER_SIZE*music->stream.channels*music->stream.sampleSize/8, 1);
+ void *pcm = calloc(AUDIO_BUFFER_SIZE*music->stream.sampleSize/8*music->stream.channels, 1);
int numBuffersToProcess = processed;
int samplesCount = 0; // Total size of data steamed in L+R samples for xm floats,
- //individual L or R for ogg shorts
+ // individual L or R for ogg shorts
for (int i = 0; i < numBuffersToProcess; i++)
{
@@ -1245,23 +1246,19 @@ static Wave LoadWAV(const char *fileName)
// NOTE: Using stb_vorbis library
static Wave LoadOGG(const char *fileName)
{
- Wave wave;
+ Wave wave = { 0 };
stb_vorbis *oggFile = stb_vorbis_open_filename(fileName, NULL, NULL);
- if (oggFile == NULL)
- {
- TraceLog(WARNING, "[%s] OGG file could not be opened", fileName);
- wave.data = NULL;
- }
+ if (oggFile == NULL) TraceLog(WARNING, "[%s] OGG file could not be opened", fileName);
else
{
stb_vorbis_info info = stb_vorbis_get_info(oggFile);
-
+
wave.sampleRate = info.sample_rate;
wave.sampleSize = 16; // 16 bit per sample (short)
wave.channels = info.channels;
- wave.sampleCount = (int)stb_vorbis_stream_length_in_samples(oggFile);
+ wave.sampleCount = (int)stb_vorbis_stream_length_in_samples(oggFile); // Independent by channel
float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile);
if (totalSeconds > 10) TraceLog(WARNING, "[%s] Ogg audio length is larger than 10 seconds (%f), that's a big file in memory, consider music streaming", fileName, totalSeconds);
@@ -1329,7 +1326,7 @@ void TraceLog(int msgType, const char *text, ...)
va_list args;
int traceDebugMsgs = 0;
-#ifdef DO_NOT_TRACE_DEBUG_MSGS
+#if defined(DO_NOT_TRACE_DEBUG_MSGS)
traceDebugMsgs = 0;
#endif
diff --git a/src/camera.h b/src/camera.h
index e1b00ac2..8067e7bf 100644
--- a/src/camera.h
+++ b/src/camera.h
@@ -181,7 +181,14 @@ void SetCameraMoveControls(int frontKey, int backKey,
// Types and Structures Definition
//----------------------------------------------------------------------------------
// Camera move modes (first person and third person cameras)
-typedef enum { MOVE_FRONT = 0, MOVE_BACK, MOVE_RIGHT, MOVE_LEFT, MOVE_UP, MOVE_DOWN } CameraMove;
+typedef enum {
+ MOVE_FRONT = 0,
+ MOVE_BACK,
+ MOVE_RIGHT,
+ MOVE_LEFT,
+ MOVE_UP,
+ MOVE_DOWN
+} CameraMove;
//----------------------------------------------------------------------------------
// Global Variables Definition
@@ -203,15 +210,14 @@ static int cameraMode = CAMERA_CUSTOM; // Current camera mode
#if defined(CAMERA_STANDALONE)
// NOTE: Camera controls depend on some raylib input functions
// TODO: Set your own input functions (used in UpdateCamera())
-static Vector2 GetMousePosition() { return (Vector2){ 0.0f, 0.0f }; }
-static void SetMousePosition(Vector2 pos) {}
+static void EnableCursor() {} // Unlock cursor
+static void DisableCursor() {} // Lock cursor
+
+static int IsKeyDown(int key) { return 0; }
+
static int IsMouseButtonDown(int button) { return 0;}
static int GetMouseWheelMove() { return 0; }
-static int GetScreenWidth() { return 1280; }
-static int GetScreenHeight() { return 720; }
-static void ShowCursor() {}
-static void HideCursor() {}
-static int IsKeyDown(int key) { return 0; }
+static Vector2 GetMousePosition() { return (Vector2){ 0.0f, 0.0f }; }
#endif
//----------------------------------------------------------------------------------
@@ -242,18 +248,23 @@ void SetCameraMode(Camera camera, int mode)
cameraAngle.y = -asinf(fabsf(dy)/distance.y); // Camera angle in plane XY (0 aligned with X, move positive CW)
// NOTE: Just testing what cameraAngle means
- //cameraAngle.x = 0.0f*DEG2RAD; // Camera angle in plane XZ (0 aligned with Z, move positive CCW)
+ //cameraAngle.x = 0.0f*DEG2RAD; // Camera angle in plane XZ (0 aligned with Z, move positive CCW)
//cameraAngle.y = -60.0f*DEG2RAD; // Camera angle in plane XY (0 aligned with X, move positive CW)
playerEyesPosition = camera.position.y;
+
+ // Lock cursor for first person and third person cameras
+ if ((mode == CAMERA_FIRST_PERSON) ||
+ (mode == CAMERA_THIRD_PERSON)) DisableCursor();
+ else EnableCursor();
cameraMode = mode;
}
// Update camera depending on selected mode
// NOTE: Camera controls depend on some raylib functions:
-// Mouse: GetMousePosition(), SetMousePosition(), IsMouseButtonDown(), GetMouseWheelMove()
-// System: GetScreenWidth(), GetScreenHeight(), ShowCursor(), HideCursor()
+// System: EnableCursor(), DisableCursor()
+// Mouse: IsMouseButtonDown(), GetMousePosition(), GetMouseWheelMove()
// Keys: IsKeyDown()
// TODO: Port to quaternion-based camera
void UpdateCamera(Camera *camera)
@@ -284,36 +295,10 @@ void UpdateCamera(Camera *camera)
if (cameraMode != CAMERA_CUSTOM)
{
- // Get screen size
- int screenWidth = GetScreenWidth();
- int screenHeight = GetScreenHeight();
-
- if ((cameraMode == CAMERA_FIRST_PERSON) ||
- (cameraMode == CAMERA_THIRD_PERSON))
- {
- HideCursor();
-
- if (mousePosition.x < (float)screenHeight/3.0f) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y });
- else if (mousePosition.y < (float)screenHeight/3.0f) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3 });
- else if (mousePosition.x > (screenWidth - (float)screenHeight/3.0f)) SetMousePosition((Vector2){ screenHeight/3, mousePosition.y });
- else if (mousePosition.y > (screenHeight - (float)screenHeight/3.0f)) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3 });
- else
- {
- mousePositionDelta.x = mousePosition.x - previousMousePosition.x;
- mousePositionDelta.y = mousePosition.y - previousMousePosition.y;
- }
- }
- else // CAMERA_FREE, CAMERA_ORBITAL
- {
- ShowCursor();
-
- mousePositionDelta.x = mousePosition.x - previousMousePosition.x;
- mousePositionDelta.y = mousePosition.y - previousMousePosition.y;
- }
+ mousePositionDelta.x = mousePosition.x - previousMousePosition.x;
+ mousePositionDelta.y = mousePosition.y - previousMousePosition.y;
- // NOTE: We GetMousePosition() again because it can be modified by a previous SetMousePosition() call
- // If using directly mousePosition variable we have problems on CAMERA_FIRST_PERSON and CAMERA_THIRD_PERSON
- previousMousePosition = GetMousePosition();
+ previousMousePosition = mousePosition;
}
// Support for multiple automatic camera modes
diff --git a/src/core.c b/src/core.c
index ee069d97..508049c9 100644
--- a/src/core.c
+++ b/src/core.c
@@ -5,11 +5,10 @@
* PLATFORMS SUPPORTED:
* - Windows (win32/Win64)
* - Linux (tested on Ubuntu)
-* - Mac (OSX)
-* - Android (API Level 9 or greater)
+* - OSX (Mac)
+* - Android (ARM or ARM64)
* - Raspberry Pi (Raspbian)
* - HTML5 (Chrome, Firefox)
-* - Oculus Rift CV1
*
* CONFIGURATION:
*
@@ -42,6 +41,9 @@
* #define SUPPORT_MOUSE_GESTURES
* Mouse gestures are directly mapped like touches and processed by gestures system.
*
+* #define SUPPORT_BUSY_WAIT_LOOP
+* Use busy wait loop for timming sync, if not defined, a high-resolution timer is setup and used
+*
* DEPENDENCIES:
* GLFW3 - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX)
* raymath - 3D math functionality (Vector3, Matrix, Quaternion)
@@ -76,6 +78,7 @@
#define SUPPORT_MOUSE_GESTURES
#define SUPPORT_CAMERA_SYSTEM
#define SUPPORT_GESTURES_SYSTEM
+#define SUPPORT_BUSY_WAIT_LOOP
//-------------------------------------------------
#include "raylib.h"
@@ -105,9 +108,9 @@
#include <string.h> // Required for: strrchr(), strcmp()
//#include <errno.h> // Macros for reporting and retrieving error conditions through error codes
-#if defined __linux__ || defined(PLATFORM_WEB)
+#if defined(__linux__) || defined(PLATFORM_WEB)
#include <sys/time.h> // Required for: timespec, nanosleep(), select() - POSIX
-#elif defined __APPLE__
+#elif defined(__APPLE__)
#include <unistd.h> // Required for: usleep()
#endif
@@ -115,13 +118,19 @@
//#define GLFW_INCLUDE_NONE // Disable the standard OpenGL header inclusion on GLFW3
#include <GLFW/glfw3.h> // GLFW3 library: Windows, OpenGL context and Input management
- #ifdef __linux__
+ #if defined(__linux__)
#define GLFW_EXPOSE_NATIVE_X11 // Linux specific definitions for getting
#define GLFW_EXPOSE_NATIVE_GLX // native functions like glfwGetX11Window
#include <GLFW/glfw3native.h> // which are required for hiding mouse
#endif
//#include <GL/gl.h> // OpenGL functions (GLFW3 already includes gl.h)
//#define GLFW_DLL // Using GLFW DLL on Windows -> No, we use static version!
+
+ #if !defined(SUPPORT_BUSY_WAIT_LOOP) && defined(_WIN32)
+ // NOTE: Those functions require linking with winmm library
+ __stdcall unsigned int timeBeginPeriod(unsigned int uPeriod);
+ __stdcall unsigned int timeEndPeriod(unsigned int uPeriod);
+ #endif
#endif
#if defined(PLATFORM_ANDROID)
@@ -277,6 +286,10 @@ static int gamepadAxisCount = 0; // Register number of available game
static Vector2 mousePosition; // Mouse position on screen
+#if defined(PLATFORM_WEB)
+static bool toggleCursorLock = false; // Ask for cursor pointer lock on next click
+#endif
+
#if defined(SUPPORT_GESTURES_SYSTEM)
static Vector2 touchPosition[MAX_TOUCH_POINTS]; // Touch position on screen
#endif
@@ -507,6 +520,10 @@ void CloseWindow(void)
glfwTerminate();
#endif
+#if !defined(SUPPORT_BUSY_WAIT_LOOP) && defined(_WIN32)
+ timeEndPeriod(1); // Restore time period
+#endif
+
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
// Close surface, context and display
if (display != EGL_NO_DISPLAY)
@@ -629,6 +646,15 @@ void SetWindowMonitor(int monitor)
#endif
}
+// Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE)
+void SetWindowMinSize(int width, int height)
+{
+#if defined(PLATFORM_DESKTOP)
+ const GLFWvidmode *mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
+ glfwSetWindowSizeLimits(window, width, height, mode->width, mode->height);
+#endif
+}
+
// Get current screen width
int GetScreenWidth(void)
{
@@ -646,7 +672,7 @@ int GetScreenHeight(void)
void ShowCursor()
{
#if defined(PLATFORM_DESKTOP)
- #ifdef __linux__
+ #if defined(__linux__)
XUndefineCursor(glfwGetX11Display(), glfwGetX11Window(window));
#else
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
@@ -659,7 +685,7 @@ void ShowCursor()
void HideCursor()
{
#if defined(PLATFORM_DESKTOP)
- #ifdef __linux__
+ #if defined(__linux__)
XColor col;
const char nil[] = {0};
@@ -687,6 +713,9 @@ void EnableCursor()
#if defined(PLATFORM_DESKTOP)
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
#endif
+#if defined(PLATFORM_WEB)
+ toggleCursorLock = true;
+#endif
cursorHidden = false;
}
@@ -696,6 +725,9 @@ void DisableCursor()
#if defined(PLATFORM_DESKTOP)
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
#endif
+#if defined(PLATFORM_WEB)
+ toggleCursorLock = true;
+#endif
cursorHidden = true;
}
#endif // !defined(PLATFORM_ANDROID)
@@ -1657,7 +1689,7 @@ static void InitGraphicsDevice(int width, int height)
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint)
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Profiles Hint: Only 3.3 and above!
// Other values: GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_COMPAT_PROFILE
-#ifdef __APPLE__
+#if defined(__APPLE__)
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // OSX Requires
#else
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE); // Fordward Compatibility Hint: Only 3.3 and above!
@@ -1799,12 +1831,13 @@ static void InitGraphicsDevice(int width, int height)
const EGLint framebufferAttribs[] =
{
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Type of context support -> Required on RPI?
- //EGL_SURFACE_TYPE, EGL_WINDOW_BIT, // Don't use it on Android!
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Type of context support -> Required on RPI?
+ //EGL_SURFACE_TYPE, EGL_WINDOW_BIT, // Don't use it on Android!
EGL_RED_SIZE, 8, // RED color bit depth (alternative: 5)
EGL_GREEN_SIZE, 8, // GREEN color bit depth (alternative: 6)
EGL_BLUE_SIZE, 8, // BLUE color bit depth (alternative: 5)
//EGL_ALPHA_SIZE, 8, // ALPHA bit depth
+ //EGL_TRANSPARENT_TYPE, EGL_TRANSPARENT_RGB, // Request transparent framebuffer
EGL_DEPTH_SIZE, 16, // Depth buffer size (Required to use Depth testing!)
//EGL_STENCIL_SIZE, 8, // Stencil buffer size
EGL_SAMPLE_BUFFERS, sampleBuffer, // Activate MSAA
@@ -1942,7 +1975,7 @@ static void InitGraphicsDevice(int width, int height)
// Set viewport parameters
static void SetupViewport(void)
{
-#ifdef __APPLE__
+#if defined(__APPLE__)
// Get framebuffer size of current window
// NOTE: Required to handle HighDPI display correctly on OSX because framebuffer
// is automatically reasized to adapt to new DPI.
@@ -2034,6 +2067,10 @@ static void SetupFramebufferSize(int displayWidth, int displayHeight)
static void InitTimer(void)
{
srand(time(NULL)); // Initialize random seed
+
+#if !defined(SUPPORT_BUSY_WAIT_LOOP) && defined(_WIN32)
+ timeBeginPeriod(1); // Setup high-resolution timer to 1ms (granularity of 1-2 ms)
+#endif
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
struct timespec now;
@@ -2070,7 +2107,6 @@ static double GetTime(void)
// http://stackoverflow.com/questions/43057578/c-programming-win32-games-sleep-taking-longer-than-expected
static void Wait(float ms)
{
-#define SUPPORT_BUSY_WAIT_LOOP
#if defined(SUPPORT_BUSY_WAIT_LOOP)
double prevTime = GetTime();
double nextTime = 0.0;
@@ -2078,9 +2114,9 @@ static void Wait(float ms)
// Busy wait loop
while ((nextTime - prevTime) < ms/1000.0f) nextTime = GetTime();
#else
- #if defined _WIN32
+ #if defined(_WIN32)
Sleep((unsigned int)ms);
- #elif defined __linux__ || defined(PLATFORM_WEB)
+ #elif defined(__linux__) || defined(PLATFORM_WEB)
struct timespec req = { 0 };
time_t sec = (int)(ms/1000.0f);
ms -= (sec*1000);
@@ -2089,7 +2125,7 @@ static void Wait(float ms)
// NOTE: Use nanosleep() on Unix platforms... usleep() it's deprecated.
while (nanosleep(&req, &req) == -1) continue;
- #elif defined __APPLE__
+ #elif defined(__APPLE__)
usleep(ms*1000.0f);
#endif
#endif
@@ -2719,7 +2755,8 @@ static EM_BOOL EmscriptenKeyboardCallback(int eventType, const EmscriptenKeyboar
// Register mouse input events
static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
{
- if (eventType == EMSCRIPTEN_EVENT_CLICK)
+ // Lock mouse pointer when click on screen
+ if ((eventType == EMSCRIPTEN_EVENT_CLICK) && toggleCursorLock)
{
EmscriptenPointerlockChangeEvent plce;
emscripten_get_pointerlock_status(&plce);
@@ -2731,6 +2768,8 @@ static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent
emscripten_get_pointerlock_status(&plce);
//if (plce.isActive) TraceLog(WARNING, "Pointer lock exit did not work!");
}
+
+ toggleCursorLock = false;
}
return 0;
@@ -3251,7 +3290,7 @@ static void *GamepadThread(void *arg)
// Plays raylib logo appearing animation
static void LogoAnimation(void)
{
-#ifndef PLATFORM_WEB
+#if !defined(PLATFORM_WEB)
int logoPositionX = screenWidth/2 - 128;
int logoPositionY = screenHeight/2 - 128;
diff --git a/src/models.c b/src/models.c
index fa6faf16..2459edf1 100644
--- a/src/models.c
+++ b/src/models.c
@@ -1218,11 +1218,13 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
Matrix matRotation = MatrixRotate(rotationAxis, rotationAngle*DEG2RAD);
Matrix matScale = MatrixScale(scale.x, scale.y, scale.z);
Matrix matTranslation = MatrixTranslate(position.x, position.y, position.z);
+
+ Matrix matTransform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation);
// 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.transform = MatrixMultiply(model.transform, matTransform);
model.material.colDiffuse = tint; // TODO: Multiply tint color by diffuse color?
rlglDrawMesh(model.mesh, model.material, model.transform);
diff --git a/src/raylib.h b/src/raylib.h
index 18d442d1..4038215e 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -351,7 +351,7 @@ typedef struct Image {
int format; // Data format (TextureFormat type)
} Image;
-// Texture2D type, bpp always RGBA (32bit)
+// Texture2D type
// NOTE: Data stored in GPU memory
typedef struct Texture2D {
unsigned int id; // OpenGL texture id
@@ -553,6 +553,7 @@ typedef enum {
UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha)
UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha)
UNCOMPRESSED_R8G8B8A8, // 32 bpp
+ UNCOMPRESSED_R32G32B32, // 32 bit per channel (float) - HDR
COMPRESSED_DXT1_RGB, // 4 bpp (no alpha)
COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha)
COMPRESSED_DXT3_RGBA, // 8 bpp
@@ -667,6 +668,7 @@ RLAPI void ToggleFullscreen(void); // Fullscreen
RLAPI void SetWindowIcon(Image image); // Set icon for window (only PLATFORM_DESKTOP)
RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP)
RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window (fullscreen mode)
+RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE)
RLAPI int GetScreenWidth(void); // Get current screen width
RLAPI int GetScreenHeight(void); // Get current screen height
diff --git a/src/raymath.h b/src/raymath.h
index 3bde10fc..1dbebc07 100644
--- a/src/raymath.h
+++ b/src/raymath.h
@@ -189,8 +189,10 @@ RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float slerp); //
RMDEF Quaternion QuaternionFromMatrix(Matrix matrix); // Returns a quaternion for a given rotation matrix
RMDEF Matrix QuaternionToMatrix(Quaternion q); // Returns a matrix for a given quaternion
RMDEF Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle); // Returns rotation quaternion for an angle and axis
-RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle); // Returns the rotation angle and axis for a given quaternion
-RMDEF void QuaternionTransform(Quaternion *q, Matrix mat); // Transform a quaternion given a transformation matrix
+RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle); // Returns the rotation angle and axis for a given quaternion
+RMDEF Quaternion QuaternionFromEuler(float roll, float pitch, float yaw); // Returns he quaternion equivalent to Euler angles
+RMDEF Vector3 QuaternionToEuler(Quaternion q); // Return the Euler angles equivalent to quaternion (roll, pitch, yaw)
+RMDEF void QuaternionTransform(Quaternion *q, Matrix mat); // Transform a quaternion given a transformation matrix
#endif // notdef RAYMATH_EXTERN_INLINE
@@ -1180,6 +1182,51 @@ RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle
*outAngle = resAngle;
}
+// Returns he quaternion equivalent to Euler angles
+RMDEF Quaternion QuaternionFromEuler(float roll, float pitch, float yaw)
+{
+ Quaternion q = { 0 };
+
+ float x0 = cosf(roll*0.5f);
+ float x1 = sinf(roll*0.5f);
+ float y0 = cosf(pitch*0.5f);
+ float y1 = sinf(pitch*0.5f);
+ float z0 = cosf(yaw*0.5f);
+ float z1 = sinf(yaw*0.5f);
+
+ q.x = x1*y0*z0 - x0*y1*z1;
+ q.y = x0*y1*z0 + x1*y0*z1;
+ q.z = x0*y0*z1 - x1*y1*z0;
+ q.w = x0*y0*z0 + x1*y1*z1;
+
+ return q;
+}
+
+// Return the Euler angles equivalent to quaternion (roll, pitch, yaw)
+// NOTE: Angles are returned in a Vector3 struct and in degrees
+RMDEF Vector3 QuaternionToEuler(Quaternion q)
+{
+ Vector3 v = { 0 };
+
+ // roll (x-axis rotation)
+ float x0 = 2.0f*(q.w*q.x + q.y*q.z);
+ float x1 = 1.0f - 2.0f*(q.x*q.x + q.y*q.y);
+ v.x = atan2f(x0, x1)*RAD2DEG;
+
+ // pitch (y-axis rotation)
+ float y0 = 2.0f*(q.w*q.y - q.z*q.x);
+ y0 = y0 > 1.0f ? 1.0f : y0;
+ y0 = y0 < -1.0f ? -1.0f : y0;
+ v.y = asinf(y0)*RAD2DEG;
+
+ // yaw (z-axis rotation)
+ float z0 = 2.0f*(q.w*q.z + q.x*q.y);
+ float z1 = 1.0f - 2.0f*(q.y*q.y + q.z*q.z);
+ v.z = atan2f(z0, z1)*RAD2DEG;
+
+ return v;
+}
+
// Transform a quaternion given a transformation matrix
RMDEF void QuaternionTransform(Quaternion *q, Matrix mat)
{
diff --git a/src/rlgl.c b/src/rlgl.c
index b336571f..323a95b1 100644
--- a/src/rlgl.c
+++ b/src/rlgl.c
@@ -64,15 +64,15 @@
#include <stdio.h> // Required for: fopen(), fclose(), fread()... [Used only on LoadText()]
#include <stdlib.h> // Required for: malloc(), free(), rand()
-#include <string.h> // Required for: strcmp(), strlen(), strtok()
+#include <string.h> // Required for: strcmp(), strlen(), strtok() [Used only in extensions loading]
#include <math.h> // Required for: atan2()
-#ifndef RLGL_STANDALONE
+#if !defined(RLGL_STANDALONE)
#include "raymath.h" // Required for: Vector3 and Matrix functions
#endif
#if defined(GRAPHICS_API_OPENGL_11)
- #ifdef __APPLE__
+ #if defined(__APPLE__)
#include <OpenGL/gl.h> // OpenGL 1.1 library for OSX
#else
#include <GL/gl.h> // OpenGL 1.1 library
@@ -84,7 +84,7 @@
#endif
#if defined(GRAPHICS_API_OPENGL_33)
- #ifdef __APPLE__
+ #if defined(__APPLE__)
#include <OpenGL/gl3.h> // OpenGL 3 library for OSX
#else
#define GLAD_IMPLEMENTATION
@@ -317,7 +317,8 @@ static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays;
// Compressed textures support flags
static bool texCompDXTSupported = false; // DDS texture compression support
-static bool npotSupported = false; // NPOT textures full support
+static bool texNPOTSupported = false; // NPOT textures full support
+static bool texFloatSupported = false; // float textures support (32 bit per channel)
static int blendMode = 0; // Track current blending mode
@@ -1050,7 +1051,7 @@ void rlglInit(int width, int height)
// NOTE: On OpenGL 3.3 VAO and NPOT are supported by default
vaoSupported = true;
- npotSupported = true;
+ texNPOTSupported = true;
// We get a list of available extensions and we check for some of them (compressed textures)
// NOTE: We don't need to check again supported extensions but we do (GLAD already dealt with that)
@@ -1119,7 +1120,10 @@ void rlglInit(int width, int height)
// Check NPOT textures support
// NOTE: Only check on OpenGL ES, OpenGL 3.3 has NPOT textures full support as core feature
- if (strcmp(extList[i], (const char *)"GL_OES_texture_npot") == 0) npotSupported = true;
+ if (strcmp(extList[i], (const char *)"GL_OES_texture_npot") == 0) texNPOTSupported = true;
+
+ // Check texture float support
+ if (strcmp(extList[i], (const char *)"OES_texture_float") == 0) texFloatSupported = true;
#endif
// DDS texture compression support
@@ -1159,7 +1163,7 @@ void rlglInit(int width, int height)
if (vaoSupported) TraceLog(INFO, "[EXTENSION] VAO extension detected, VAO functions initialized successfully");
else TraceLog(WARNING, "[EXTENSION] VAO extension not found, VAO usage not supported");
- if (npotSupported) TraceLog(INFO, "[EXTENSION] NPOT textures extension detected, full NPOT textures supported");
+ if (texNPOTSupported) TraceLog(INFO, "[EXTENSION] NPOT textures extension detected, full NPOT textures supported");
else TraceLog(WARNING, "[EXTENSION] NPOT textures extension not found, limited NPOT support (no-mipmaps, no-repeat)");
#endif
@@ -1286,21 +1290,17 @@ void rlglLoadExtensions(void *loader)
{
#if defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_33)
// NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions)
- #ifndef __APPLE__
+ #if !defined(__APPLE__)
if (!gladLoadGLLoader((GLADloadproc)loader)) TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions");
else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully");
- #endif
-#if defined(GRAPHICS_API_OPENGL_21)
- #ifndef __APPLE__
+ #if defined(GRAPHICS_API_OPENGL_21)
if (GLAD_GL_VERSION_2_1) TraceLog(INFO, "OpenGL 2.1 profile supported");
- #endif
-#elif defined(GRAPHICS_API_OPENGL_33)
- #ifndef __APPLE__
+ #elif defined(GRAPHICS_API_OPENGL_33)
if(GLAD_GL_VERSION_3_3) TraceLog(INFO, "OpenGL 3.3 Core profile supported");
else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported");
+ #endif
#endif
-#endif
// With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans
//if (GLAD_GL_ARB_vertex_array_object) // Use GL_ARB_vertex_array_object
@@ -1425,6 +1425,7 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int format, int
case UNCOMPRESSED_R5G5B5A1: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, (unsigned short *)data); break;
case UNCOMPRESSED_R4G4B4A4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, (unsigned short *)data); break;
case UNCOMPRESSED_R8G8B8A8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
+ case UNCOMPRESSED_R32G32B32: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_FLOAT, (float *)data); break;
case COMPRESSED_DXT1_RGB: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB_S3TC_DXT1_EXT); break;
case COMPRESSED_DXT1_RGBA: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); break;
case COMPRESSED_DXT3_RGBA: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT); break;
@@ -1450,6 +1451,7 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int format, int
case UNCOMPRESSED_R4G4B4A4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, (unsigned short *)data); break;
case UNCOMPRESSED_R8G8B8A8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
#if defined(GRAPHICS_API_OPENGL_ES2)
+ case UNCOMPRESSED_R32G32B32: if (texFloatSupported) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_FLOAT, (float *)data); break; // Requries extension OES_texture_float
case COMPRESSED_DXT1_RGB: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB_S3TC_DXT1_EXT); break;
case COMPRESSED_DXT1_RGBA: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); break;
case COMPRESSED_DXT3_RGBA: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT); break; // NOTE: Not supported by WebGL
@@ -1470,7 +1472,7 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int format, int
// NOTE: glTexParameteri does NOT affect texture uploading, just the way it's used
#if defined(GRAPHICS_API_OPENGL_ES2)
// NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so CLAMP_TO_EDGE must be used
- if (npotSupported)
+ if (texNPOTSupported)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repeat on x-axis
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repeat on y-axis
@@ -1650,7 +1652,7 @@ void rlglGenerateMipmaps(Texture2D *texture)
if (((texture->width > 0) && ((texture->width & (texture->width - 1)) == 0)) &&
((texture->height > 0) && ((texture->height & (texture->height - 1)) == 0))) texIsPOT = true;
- if ((texIsPOT) || (npotSupported))
+ if ((texIsPOT) || (texNPOTSupported))
{
#if defined(GRAPHICS_API_OPENGL_11)
// Compute required mipmaps
diff --git a/src/rlgl.h b/src/rlgl.h
index f3fd6b22..6d6ad516 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -17,7 +17,9 @@
* #define GRAPHICS_API_OPENGL_21
* #define GRAPHICS_API_OPENGL_33
* #define GRAPHICS_API_OPENGL_ES2
-* Use selected OpenGL backend
+* Use selected OpenGL graphics backend, should be supported by platform
+* Those preprocessor defines are only used on rlgl module, if OpenGL version is
+* required by any other module, use rlGetVersion() tocheck it
*
* #define RLGL_STANDALONE
* Use rlgl as standalone library (no raylib dependency)
@@ -35,7 +37,7 @@
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+* Copyright (c) 2014-2017 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.
@@ -57,28 +59,14 @@
#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: Model, Shader, Texture2D
- #include "utils.h" // Required for: TraceLog()
-#endif
-
-#ifdef RLGL_STANDALONE
+#if defined(RLGL_STANDALONE)
#define RAYMATH_STANDALONE
+#else
+ #include "raylib.h" // Required for: Model, Shader, Texture2D, TraceLog()
#endif
#include "raymath.h" // Required for: 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 and RLGL_OCULUS_SUPPORT
-//#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_21) && !defined(GRAPHICS_API_OPENGL_33) && !defined(GRAPHICS_API_OPENGL_ES2)
#define GRAPHICS_API_OPENGL_11
@@ -165,28 +153,23 @@ typedef unsigned char byte;
unsigned char b;
unsigned char a;
} Color;
+
+ // 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;
- // 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;
+ // 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;
// Vertex data definning a mesh
typedef struct Mesh {
@@ -228,23 +211,6 @@ typedef unsigned char byte;
int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2)
} 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; // Standard shader (supports 3 map types: diffuse, normal, specular)
@@ -267,6 +233,38 @@ typedef unsigned char byte;
Vector3 up; // Camera up vector (rotation over its axis)
float fovy; // Camera field-of-view apperture in Y (degrees)
} Camera;
+
+ // TraceLog message types
+ typedef enum {
+ INFO = 0,
+ ERROR,
+ WARNING,
+ DEBUG,
+ OTHER
+ } TraceLogType;
+
+ // 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
+ UNCOMPRESSED_R32G32B32, // 32 bit per channel (float) - HDR
+ 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;
// Texture parameters: filter mode
// NOTE 1: Filtering considers mipmaps if available in the texture
@@ -281,13 +279,18 @@ typedef unsigned char byte;
} TextureFilterMode;
// Texture parameters: wrap mode
- typedef enum { WRAP_REPEAT = 0, WRAP_CLAMP, WRAP_MIRROR } TextureWrapMode;
+ typedef enum {
+ WRAP_REPEAT = 0,
+ WRAP_CLAMP,
+ WRAP_MIRROR
+ } TextureWrapMode;
// Color blending modes (pre-defined)
- typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
-
- // TraceLog message types
- typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
+ typedef enum {
+ BLEND_ALPHA = 0,
+ BLEND_ADDITIVE,
+ BLEND_MULTIPLIED
+ } BlendMode;
// VR Head Mounted Display devices
typedef enum {
diff --git a/src/text.c b/src/text.c
index cba9a7d6..027701de 100644
--- a/src/text.c
+++ b/src/text.c
@@ -443,7 +443,7 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float
index = GetCharIndex(spriteFont, (int)letter + 64);
i++;
}
- else index = GetCharIndex(spriteFont, (int)text[i]);
+ else index = GetCharIndex(spriteFont, (unsigned char)text[i]);
DrawTexturePro(spriteFont.texture, spriteFont.chars[index].rec,
(Rectangle){ position.x + textOffsetX + spriteFont.chars[index].offsetX*scaleFactor,
diff --git a/src/textures.c b/src/textures.c
index 6c56d6c5..115c8fff 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -53,6 +53,7 @@
// Default configuration flags (supported features)
//-------------------------------------------------
#define SUPPORT_FILEFORMAT_PNG
+#define SUPPORT_FILEFORMAT_HDR
#define SUPPORT_IMAGE_MANIPULATION
//-------------------------------------------------
@@ -98,7 +99,7 @@
defined(SUPPORT_FILEFORMAT_JPG) || defined(SUPPORT_FILEFORMAT_PSD) || defined(SUPPORT_FILEFORMAT_GIF) || \
defined(SUPPORT_FILEFORMAT_HDR))
#define STB_IMAGE_IMPLEMENTATION
- #include "external/stb_image.h" // Required for: stbi_load()
+ #include "external/stb_image.h" // Required for: stbi_load_from_file()
// NOTE: Used to read image data (multiple formats support)
#endif
@@ -154,14 +155,7 @@ static Image LoadASTC(const char *fileName); // Load ASTC file
// Load image from file into CPU memory (RAM)
Image LoadImage(const char *fileName)
{
- Image image;
-
- // Initialize image default values
- image.data = NULL;
- image.width = 0;
- image.height = 0;
- image.mipmaps = 0;
- image.format = 0;
+ Image image = { 0 };
if (IsFileExtension(fileName, ".rres"))
{
@@ -212,6 +206,29 @@ Image LoadImage(const char *fileName)
else if (imgBpp == 3) image.format = UNCOMPRESSED_R8G8B8;
else if (imgBpp == 4) image.format = UNCOMPRESSED_R8G8B8A8;
}
+#if defined(SUPPORT_FILEFORMAT_HDR)
+ else if (IsFileExtension(fileName, ".hdr"))
+ {
+ int imgBpp = 0;
+
+ FILE *imFile = fopen(fileName, "rb");
+
+ // Load 32 bit per channel floats data
+ image.data = stbi_loadf_from_file(imFile, &image.width, &image.height, &imgBpp, 0);
+
+ fclose(imFile);
+
+ image.mipmaps = 1;
+
+ if (imgBpp == 3) image.format = UNCOMPRESSED_R32G32B32;
+ else
+ {
+ // TODO: Support different number of channels at 32 bit float
+ TraceLog(WARNING, "[%s] Image fileformat not supported (only 3 channel 32 bit floats)", fileName);
+ UnloadImage(image);
+ }
+ }
+#endif
#if defined(SUPPORT_FILEFORMAT_DDS)
else if (IsFileExtension(fileName, ".dds")) image = LoadDDS(fileName);
#endif
@@ -282,13 +299,7 @@ Image LoadImagePro(void *data, int width, int height, int format)
// Load an image from RAW file data
Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize)
{
- Image image;
-
- image.data = NULL;
- image.width = 0;
- image.height = 0;
- image.mipmaps = 0;
- image.format = 0;
+ Image image = { 0 };
FILE *rawFile = fopen(fileName, "rb");
@@ -311,6 +322,7 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
case UNCOMPRESSED_R5G5B5A1: image.data = (unsigned short *)malloc(size); break; // 16 bpp (1 bit alpha)
case UNCOMPRESSED_R4G4B4A4: image.data = (unsigned short *)malloc(size); break; // 16 bpp (4 bit alpha)
case UNCOMPRESSED_R8G8B8A8: image.data = (unsigned char *)malloc(size*4); size *= 4; break; // 32 bpp
+ case UNCOMPRESSED_R32G32B32: image.data = (float *)malloc(size*12); size *= 12; break; // 4 byte per channel (12 byte)
default: TraceLog(WARNING, "Image format not suported"); break;
}
@@ -342,7 +354,7 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
// Load texture from file into GPU memory (VRAM)
Texture2D LoadTexture(const char *fileName)
{
- Texture2D texture;
+ Texture2D texture = { 0 };
Image image = LoadImage(fileName);
@@ -351,11 +363,7 @@ Texture2D LoadTexture(const char *fileName)
texture = LoadTextureFromImage(image);
UnloadImage(image);
}
- else
- {
- TraceLog(WARNING, "Texture could not be created");
- texture.id = 0;
- }
+ else TraceLog(WARNING, "Texture could not be created");
return texture;
}
@@ -364,14 +372,7 @@ Texture2D LoadTexture(const char *fileName)
// NOTE: image is not unloaded, it must be done manually
Texture2D LoadTextureFromImage(Image image)
{
- Texture2D texture;
-
- // Init texture to default values
- texture.id = 0;
- texture.width = 0;
- texture.height = 0;
- texture.mipmaps = 0;
- texture.format = 0;
+ Texture2D texture = { 0 };
texture.id = rlglLoadTexture(image.data, image.width, image.height, image.format, image.mipmaps);
@@ -510,9 +511,8 @@ Color *GetImageData(Image image)
// NOTE: Compressed texture formats not supported
Image GetTextureData(Texture2D texture)
{
- Image image;
- image.data = NULL;
-
+ Image image = { 0 };
+
if (texture.format < 8)
{
image.data = rlglReadTexturePixels(texture);
@@ -787,6 +787,7 @@ Image ImageCopy(Image image)
case UNCOMPRESSED_R4G4B4A4: byteSize *= 2; break; // 16 bpp (2 bytes)
case UNCOMPRESSED_R8G8B8: byteSize *= 3; break; // 24 bpp (3 bytes)
case UNCOMPRESSED_R8G8B8A8: byteSize *= 4; break; // 32 bpp (4 bytes)
+ case UNCOMPRESSED_R32G32B32: byteSize *= 12; break; // 4 byte per channel (12 bytes)
case COMPRESSED_DXT3_RGBA:
case COMPRESSED_DXT5_RGBA:
case COMPRESSED_ETC2_EAC_RGBA: