26 Commits
1.0.4 ... 1.1.1

Author SHA1 Message Date
Ray
222995c32e Upload new game: Dr. Turtle & Mr. Gamera 2014-07-25 10:50:51 +02:00
raysan5
56a7979750 Corrected bugs...
Set default raylib to use OpenGL 1.1 (compatibility issues on ATI cards)
2014-07-23 19:50:06 +02:00
raysan5
ecb3c47704 Corrected bug with drawing order
We have three vertex buffers: lines, triangles and quads for textures.
Drawing in a desired order could become a nighmare... noww it seems it
works prety well...
2014-07-23 01:25:33 +02:00
raysan5
0b03431c95 Update to version 1.1.1
Check CHANGELOG for a detailed list of changes
2014-07-23 00:06:24 +02:00
raysan5
5e2e9aa23e Corrected bug with DrawModel() 2014-07-08 10:33:04 +02:00
raysan5
aff8d151a4 Corrected DrawSphereWires() function 2014-06-15 00:50:09 +02:00
raysan5
8e186e840c Updated some comments 2014-06-09 16:33:53 +02:00
raysan5
a42f8328b2 Renamed raylib icon file 2014-05-10 11:39:51 +02:00
raysan5
370479f7c5 Updated GLFW3 to 3.0.4
Added additional files in case somebody wants to use the DLL library
version
2014-05-10 11:37:40 +02:00
raysan5
7a6c22bc25 Renamed GLEW dinamic linkage lib 2014-05-02 20:04:09 +02:00
Ray
8ead7ad4cf Update README.md 2014-04-22 21:09:56 +02:00
raysan5
f76a00adc1 Code used to test some features (and resources) 2014-04-19 16:54:48 +02:00
raysan5
1c8874e6d5 Added raylib 1.1 library binaries
OpenGL 3.3+ compiled binaries
2014-04-19 16:53:52 +02:00
raysan5
f06a15ac8b raylib 1.1
View CHANGELOG for a detailed list of changes
2014-04-19 16:36:49 +02:00
Ray
650a8f7f15 Merge pull request #2 from raysan5/testing
Integrate raylib 1.1 changes into master
2014-04-19 14:21:22 +02:00
raysan5
e6b82cb111 Lots of changes, most of them under testing-review
Added a Tracing/Log system
Added OGG stream music support (DOESN'T WORK)
Added Compressed textures support
* This update is probably very buggy...
2014-04-09 20:25:26 +02:00
raysan5
c04f37d0f5 Adapt multiple functions to rlgl
Nearly a complete rework of Models module
Some teaks on multiple functions
2014-04-04 20:11:57 +02:00
raysan5
79cf87d91d Adding GLEW lib 2014-04-04 20:06:55 +02:00
raysan5
96f520ff6d Road to raylib 1.1 - Testing rlgl 2014-03-25 12:40:35 +01:00
raysan5
1c8dce429e Updated 2014-03-16 21:05:04 +01:00
raysan5
a68818e320 Update to version 1.0.6
Check CHANGELOG for the list of changes in this release!
2014-03-16 20:59:02 +01:00
raysan5
0a71a92eeb Text formatting 2014-03-16 20:27:58 +01:00
raysan5
4127638f92 Deleted for a better replace... soon... 2014-03-16 19:20:00 +01:00
raysan5
451568e5a9 The future of raylib!
Mapping of OpenGL 1.1 immediate mode functions to OpenGL 3.2+ (and
OpenGL ES 2.0) programmable pipeline
2014-03-02 16:06:01 +01:00
raysan5
174cd86d08 3D useful maths
Some useful functions to work with Vector3, Matrix and Quaternions
2014-03-02 16:03:25 +01:00
raysan5
43b13d623b Update to version 1.0.5
Check CHANGELOG for changes
2014-01-28 21:21:29 +01:00
94 changed files with 36280 additions and 2024 deletions

View File

@@ -1,11 +1,86 @@
changelog
---------
Current Release: raylib 1.0.4 (January 2014)
Current Release: raylib 1.1.1 (22 July 2014)
NOTE: Only versions marked as 'Release' are available on release folder, updates are only available as source.
NOTE: Current Release includes all previous updates.
-----------------------------------------------
Release: raylib 1.1.1 (22 July 2014)
-----------------------------------------------
[core] ShowLogo() - To enable raylib logo animation at startup
[core] Corrected bug with window resizing
[rlgl] Redefined colors arrays to use byte instead of float
[rlgl] Removed double buffer system (no performance improvement)
[rlgl] rlglDraw() - Reorganized buffers drawing order
[rlgl] Corrected bug on screen resizing
[shapes] DrawRectangle() - Use QUADS instead of TRIANGLES
[models] DrawSphereWires() - Corrected some issues
[models] LoadOBJ() - Redesigned to support multiple meshes
[models] LoadCubesMap() - Loading a map as cubes (by pixel color)
[textures] Added security check if file doesn't exist
[text] Corrected bug on SpriteFont loading
[examples] Corrected some 3d examples
[test] Added cubesmap loading test
-----------------------------------------------
Release: raylib 1.1.0 (19 April 2014)
-----------------------------------------------
NOTE:
This version supposed a complete internal redesign of the library to support OpenGL 3.3+ and OpenGL ES 2.0.
New module [rlgl] has been added to 'translate' immediate mode style functions (i.e. rlVertex3f()) to GL 1.1, 3.3+ or ES2.
Another new module [raymath] has also been added with lot of useful 3D math vector-matrix-quaternion functions.
[rlgl] New module, abstracts OpenGL rendering (multiple versions support)
[raymath] New module, useful 3D math vector-matrix-quaternion functions
[core] Adapt all OpenGL code (initialization, drawing) to use [rlgl]
[shapes] Rewrite all shapes drawing functions to use [rlgl]
[textures] Adapt texture GPU loading to use [rlgl]
[textures] Added support for DDS images (compressed and uncompressed)
[textures] CreateTexture() - Redesigned to add mipmap automatic generation
[textures] DrawTexturePro() - Redesigned and corrected bugs
[models] Rewrite all 3d-shapes drawing functions to use [rlgl]
[models] Adapt model loading and drawing to use [rlgl]
[models] Model struct updated to include texture id
[models] SetModelTexture() - Added, link a texture to a model
[models] DrawModelEx() - Redesigned with extended parameters
[audio] Added music streaming support (OGG files)
[audio] Added support for OGG files as Sound
[audio] PlayMusicStream() - Added, open a new music stream and play it
[audio] StopMusicStream() - Added, stop music stream playing and close stream
[audio] PauseMusicStream() - Added, pause music stream playing
[audio] MusicIsPlaying() - Added, to check if music is playing
[audio] SetMusicVolume() - Added, set volume for music
[audio] GetMusicTimeLength() - Added, get current music time length (in seconds)
[audio] GetMusicTimePlayed() - Added, get current music time played (in seconds)
[utils] Added log tracing functionality - TraceLog(), TraceLogOpen(), TraceLogClose()
[*] Log tracing messages all around the code
-----------------------------------------------
Release: raylib 1.0.6 (16 March 2014)
-----------------------------------------------
[core] Removed unused lighting-system code
[core] Removed SetPerspective() function, calculated directly
[core] Unload and reload default font on fullscreen toggle
[core] Corrected bug gamepad buttons checking if no gamepad available
[texture] DrawTextureV() - Added, to draw using Vector2 for position
[texture] LoadTexture() - Redesigned, now uses LoadImage() + CreateTexture()
[text] FormatText() - Corrected memory leak bug
[models] Added Matrix struct and related functions
[models] DrawBillboard() - Reviewed, now it works!
[models] DrawBillboardRec() - Reviewed, now it works!
[tests] Added folder with multiple tests for new functions
-----------------------------------------------
Update: raylib 1.0.5 (28 January 2014)
-----------------------------------------------
[audio] LoadSound() - Corrected a bug, WAV file was not closed!
[core] GetMouseWheelMove() - Added, check mouse wheel Y movement
[texture] CreateTexture2D() renamed to CreateTexture()
[models] LoadHeightmap() - Added, Heightmap can be loaded as a Model
[tool] rREM updated, now supports (partially) drag and drop of files
-----------------------------------------------
Release: raylib 1.0.4 (23 January 2014)
-----------------------------------------------

View File

@@ -10,7 +10,7 @@ The following help is highly appreciated:
- Translators / Localizators - Can you translate raylib to another language?
- Documentation / Tutorials / Example writters - Can you write some tutorial / example?
- Web Development - Can you help with the web? Can you setup a forum?
- Porting to Linux and OSX - Can you compile and test raylib on another OS?
- Porting to Linux, OSX... - Can you compile and test raylib on another OS?
- Testers of current features and multiple systems - Can you find some bug on raylib?
If you can not help on any of the above points but you still want to contribute in some way... please, consider helping

View File

@@ -28,11 +28,30 @@ like no transparencies support or no hardware acceleration.
So, I decided to create my own lib, hardware accelerated, clear function names, quite organized, well structured,
plain C coding and, the most important, primarily intended to LEARN videogames programming.
I've coded quite a lot in C# and XNA and I really love it (in fact, my students learn C# with XNA after C),
I've coded quite a lot in C# and XNA and I really love it (in fact, my students learn C# after C),
so, I decided to use C# language notation and XNA naming conventions. That way, students can jump from
raylib to XNA (or MonoGame) extremely easily.
raylib to XNA, MonoGame or similar libs extremely easily.
raylib started as a weekend project and after three months of hard work, here it is the first version.
raylib started as a weekend project and after three months of hard work, first version was published.
Enjoy it.
notes on raylib 1.1
-------------------
On April 2014, after 6 month of first raylib release, raylib 1.1 has been released. This new version presents a
complete internal redesign of the library to support OpenGL 1.1, OpenGL 3.3+ and OpenGL ES 2.0.
A new module named [rlgl] (https://github.com/raysan5/raylib/blob/master/src/rlgl.h) has been added to the library. This new module translate raylib-OpenGL-style
immediate mode functions (i.e. rlVertex3f(), rlBegin(), ...) to different versions of OpenGL (1.1, 3.3+, ES2), selectable by one define.
[rlgl] (https://github.com/raysan5/raylib/blob/master/src/rlgl.h) also comes with a second new module named [raymath] (https://github.com/raysan5/raylib/blob/master/src/raymath.h), which includes
a bunch of useful functions for 3d-math with vectors, matrices and quaternions.
Some other big changes of this new version have been the support for OGG files loading and stream playing, and the
support of DDS texture files (compressed and uncompressed) along with mipmaps support.
Lots of code changes and lot of testing have concluded in this amazing new raylib 1.1.
Enjoy it.
@@ -41,11 +60,14 @@ features
* Written in plain C code (C99)
* Uses C# PascalCase/camelCase notation
* Hardware accelerated using OpenGL 1.1
* Transparencies support (RGBA Colors)
* Custom color palette for better use on white background
* Basic 3D Support (camera, basic models, OBJ models, etc)
* Powerful Text module with SpriteFonts support
* Hardware accelerated with OpenGL (1.1, 3.3+ or ES2)
* Unique OpenGL abstraction layer [rlgl]
* Powerful fonts module with SpriteFonts support
* Multiple textures support, including DDS and mipmaps generation
* Basic 3d support for Shapes, Models, Heightmaps and Billboards
* Powerful math module for Vector and Matrix operations [raymath]
* Audio loading and playing with streaming support
* Custom color palette for fancy visuals on raywhite background
raylib uses on its core module the outstanding [GLFW3] (http://www.glfw.org/) library. The best option by far I found for
window/context and input management (clean, focused, great license, well documented, modern, ...).
@@ -66,6 +88,8 @@ I believe those are the best tools to train spartan-programmers.
Someone could argue about debugging. raylib is a library intended for learning and I think C it's a clear enough language
to allow writing small-mid size programs with a printf-based debugging. All raylib examples have also been written this way.
Since raylib v1.1, you can download a windows Installer package for easy installation and configuration. Check [raylib Webpage](http://www.raylib.com/)
building
--------
@@ -75,19 +99,30 @@ raylib could be build with the following command lines (Using GCC compiler):
gcc -c core.c -std=c99 -Wall
gcc -c shapes.c -std=c99 -Wall
gcc -c textures.c -std=c99 -Wall
gcc -c stb_image.c -std=c99 -Wall
gcc -c text.c -std=c99 -Wall
gcc -c models.c -std=c99 -Wall
gcc -c vector3.c -std=c99 -Wall
gcc -c raymath.c -std=c99 -Wall
gcc -c rlgl.c -std=c99 -Wall
gcc -c audio.c -std=c99 -Wall
gcc -c utils.c -std=c99 -Wall
ar rcs raylib.a core.o shapes.o textures.o stb_image.o text.o models.o vector3.o utils.o audio.o
gcc -c stb_image.c -std=c99 -Wall
gcc -c stb_vorbis.c -std=c99 -Wall
To compile examples, make sure raylib.h is placed in include path and libraries raylib (libraylib.a) and glfw3 (libglfw3.a)
are placed in the libraries path. It's also recommended to link with file icon.o for fancy raylib icon usage.
ar rcs libraylib.a core.o shapes.o textures.o stb_image.o text.o models.o raymath.o rlgl.o utils.o stb_vorbis.o audio.o
To compile examples, make sure raylib.h is placed in the include path and the following libraries are placed in the libraries path:
libraylib.a - raylib
libglfw3.a - GLFW3 (static version)
libglew32.a - GLEW, OpenGL extension loading, only required if using OpenGL 3.3+ or ES2
libopenal32.a - OpenAL, audio device management
It's also recommended to link with file icon.o for fancy raylib icon usage. Linking command:
cd raylib/examples
gcc -o test_code.exe test_code.c icon.o -lraylib -lglfw3 -lopengl32 -lgdi32 -std=c99 -Wl,--subsystem,windows
gcc -o test_code.exe test_code.c icon.o -lraylib -lglfw3 -lglew32 -lopenal32 -lopengl32 -lgdi32 -std=c99 -Wl,--subsystem,windows
If you have any doubt, [let me know][raysan5].
contact
-------
@@ -107,6 +142,7 @@ The following people have contributed in some way to make raylib project a reali
- [Zopokx](https://github.com/Zopokx)
- [Elendow](http://www.elendow.com)
- Victor Dual
- Marc Palau
[raysan5]: mailto:raysan@raysanweb.com "Ramon Santamaria - Ray San"

View File

@@ -1,21 +1,21 @@
roadmap
-------
First version of raylib is quite complete and functional but there is still a lot of things I would like to improve.
Current version of raylib is quite complete and functional but there is still a lot of things I would like to improve.
Here it is a list of features I would like to add and functions to improve.
Around the source code there are some TODO points with pending revisions/bugs and here it is a list of features I would like to add.
raylib v1.x
- Review Billboard Drawing functions
- Review Heightmap Loading and Drawing functions - Load Heightmap directly as a Model
- Lighting support (only 3d mode) - CreateLight()
- [DONE] Review Billboard Drawing functions
- [DONE] Review Heightmap Loading and Drawing functions - Load Heightmap directly as a Model
- Lighting support (only 3d mode)
- [DONE] Simple Collision Detection functions
- Default scene Camera controls (zoom, pan, rotate)
- Basic Procedural Texture / Image generation (Gradient, Checked, Spot, Noise, Cellular)
- Software mipmapping generation and POT conversion (custom implementation)
- Comments / Functions translation (?)
- Basic Procedural Image Generation (Gradient, Checked, Spot, Noise, Cellular)
- [DONE] Software mipmapping generation and POT conversion (custom implementation)
- TTF fonts support
Any feature missing? Do you have a request? [Let me know!][raysan5]

View File

@@ -11,12 +11,6 @@
#include "raylib.h"
// Useful function for fade-ins and fade-outs
Color Fade(Color col, float alpha)
{
return (Color){col.r, col.g, col.b, col.a*alpha};
}
int main()
{
// Initialization

View File

@@ -47,7 +47,7 @@ int main()
DrawCubeWires((Vector3){-4, 0, -2}, 3, 6, 2, MAROON);
DrawSphere((Vector3){-1, 0, -2}, 1, GREEN);
DrawSphereWires((Vector3){1, 0, 2}, 2, LIME);
DrawSphereWires((Vector3){1, 0, 2}, 2, 16, 16, LIME);
DrawCylinder((Vector3){4, 0, -2}, 1, 2, 3, 4, SKYBLUE);
DrawCylinderWires((Vector3){4, 0, -2}, 1, 2, 3, 4, DARKBLUE);

View File

@@ -29,6 +29,7 @@ int main()
Texture2D texture = LoadTexture("resources/catwhite.png");
Model cat = LoadModel("resources/cat.obj");
SetModelTexture(&cat, texture); // Link texture to model
//--------------------------------------------------------------------------------------
// Main game loop
@@ -36,10 +37,10 @@ int main()
{
// Update
//----------------------------------------------------------------------------------
if (IsKeyPressed(KEY_LEFT)) position.x -= 0.2;
if (IsKeyPressed(KEY_RIGHT)) position.x += 0.2;
if (IsKeyPressed(KEY_UP)) position.z -= 0.2;
if (IsKeyPressed(KEY_DOWN)) position.z += 0.2;
if (IsKeyDown(KEY_LEFT)) position.x -= 0.2;
if (IsKeyDown(KEY_RIGHT)) position.x += 0.2;
if (IsKeyDown(KEY_UP)) position.z -= 0.2;
if (IsKeyDown(KEY_DOWN)) position.z += 0.2;
//----------------------------------------------------------------------------------
// Draw
@@ -50,11 +51,11 @@ int main()
Begin3dMode(camera);
DrawModelEx(cat, texture, position, 0.1f, WHITE); // Draw 3d model with texture
DrawModel(cat, position, 0.1f, WHITE); // Draw 3d model with texture
DrawGrid(10.0, 1.0); // Draw a grid
DrawGizmo(position, false);
DrawGizmo(position);
End3dMode();

73
external/glew/LICENSE.txt vendored Normal file
View File

@@ -0,0 +1,73 @@
The OpenGL Extension Wrangler Library
Copyright (C) 2002-2007, Milan Ikits <milan ikits[]ieee org>
Copyright (C) 2002-2007, Marcelo E. Magallon <mmagallo[]debian org>
Copyright (C) 2002, Lev Povalahev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name of the author may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
Mesa 3-D graphics library
Version: 7.0
Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Copyright (c) 2007 The Khronos Group Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and/or associated documentation files (the
"Materials"), to deal in the Materials without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Materials, and to
permit persons to whom the Materials are furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Materials.
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.

BIN
external/glew/glew32.dll vendored Normal file

Binary file not shown.

18062
external/glew/include/GL/glew.h vendored Normal file

File diff suppressed because it is too large Load Diff

1669
external/glew/include/GL/glxew.h vendored Normal file

File diff suppressed because it is too large Load Diff

1421
external/glew/include/GL/wglew.h vendored Normal file

File diff suppressed because it is too large Load Diff

BIN
external/glew/lib/libglew32.a vendored Normal file

Binary file not shown.

BIN
external/glew/lib/libglew32dll.a vendored Normal file

Binary file not shown.

BIN
external/glfw3/glfw3.dll vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,180 @@
/*************************************************************************
* GLFW 3.0 - www.glfw.org
* A library for OpenGL, window and input
*------------------------------------------------------------------------
* Copyright (c) 2002-2006 Marcus Geelnard
* Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
*
* 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 _glfw3_native_h_
#define _glfw3_native_h_
#ifdef __cplusplus
extern "C" {
#endif
/*************************************************************************
* Doxygen documentation
*************************************************************************/
/*! @defgroup native Native access
*
* **By using the native API, you assert that you know what you're doing and
* how to fix problems caused by using it. If you don't, you shouldn't be
* using it.**
*
* Before the inclusion of @ref glfw3native.h, you must define exactly one
* window API macro and exactly one context API macro. Failure to do this
* will cause a compile-time error.
*
* The available window API macros are:
* * `GLFW_EXPOSE_NATIVE_WIN32`
* * `GLFW_EXPOSE_NATIVE_COCOA`
* * `GLFW_EXPOSE_NATIVE_X11`
*
* The available context API macros are:
* * `GLFW_EXPOSE_NATIVE_WGL`
* * `GLFW_EXPOSE_NATIVE_NSGL`
* * `GLFW_EXPOSE_NATIVE_GLX`
* * `GLFW_EXPOSE_NATIVE_EGL`
*
* These macros select which of the native access functions that are declared
* and which platform-specific headers to include. It is then up your (by
* definition platform-specific) code to handle which of these should be
* defined.
*/
/*************************************************************************
* System headers and types
*************************************************************************/
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
#include <windows.h>
#elif defined(GLFW_EXPOSE_NATIVE_COCOA)
#if defined(__OBJC__)
#import <Cocoa/Cocoa.h>
#else
typedef void* id;
#endif
#elif defined(GLFW_EXPOSE_NATIVE_X11)
#include <X11/Xlib.h>
#else
#error "No window API specified"
#endif
#if defined(GLFW_EXPOSE_NATIVE_WGL)
/* WGL is declared by windows.h */
#elif defined(GLFW_EXPOSE_NATIVE_NSGL)
/* NSGL is declared by Cocoa.h */
#elif defined(GLFW_EXPOSE_NATIVE_GLX)
#include <GL/glx.h>
#elif defined(GLFW_EXPOSE_NATIVE_EGL)
#include <EGL/egl.h>
#else
#error "No context API specified"
#endif
/*************************************************************************
* Functions
*************************************************************************/
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
/*! @brief Returns the `HWND` of the specified window.
* @return The `HWND` of the specified window.
* @ingroup native
*/
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_WGL)
/*! @brief Returns the `HGLRC` of the specified window.
* @return The `HGLRC` of the specified window.
* @ingroup native
*/
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
/*! @brief Returns the `NSWindow` of the specified window.
* @return The `NSWindow` of the specified window.
* @ingroup native
*/
GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
/*! @brief Returns the `NSOpenGLContext` of the specified window.
* @return The `NSOpenGLContext` of the specified window.
* @ingroup native
*/
GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_X11)
/*! @brief Returns the `Display` used by GLFW.
* @return The `Display` used by GLFW.
* @ingroup native
*/
GLFWAPI Display* glfwGetX11Display(void);
/*! @brief Returns the `Window` of the specified window.
* @return The `Window` of the specified window.
* @ingroup native
*/
GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_GLX)
/*! @brief Returns the `GLXContext` of the specified window.
* @return The `GLXContext` of the specified window.
* @ingroup native
*/
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
/*! @brief Returns the `EGLDisplay` used by GLFW.
* @return The `EGLDisplay` used by GLFW.
* @ingroup native
*/
GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
/*! @brief Returns the `EGLContext` of the specified window.
* @return The `EGLContext` of the specified window.
* @ingroup native
*/
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
/*! @brief Returns the `EGLSurface` of the specified window.
* @return The `EGLSurface` of the specified window.
* @ingroup native
*/
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
#endif
#ifdef __cplusplus
}
#endif
#endif /* _glfw3_native_h_ */

Binary file not shown.

BIN
external/glfw3/lib/libglfw3dll.a vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,126 @@
/*******************************************************************************************
*
* raylib game - Dr. Turtle & Mr. Gamera
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This game has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
#define MAX_ENEMIES 10
typedef enum { TITLE, GAMEPLAY, ENDING } GameScreen;
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 1280;
const int screenHeight = 720;
// Init window
InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
// Define current screen
GameScreen currentScreen = TITLE;
SetTargetFPS(60); // Setup game frames per second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// Game screens management
switch (currentScreen)
{
case TITLE:
{
// Press enter to change to gameplay screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
}
} break;
case GAMEPLAY:
{
// Press enter to change to ending screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = ENDING;
}
} break;
case ENDING:
{
// Press enter to change to title screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = TITLE;
}
} break;
default: break;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
switch (currentScreen)
{
case TITLE:
{
// Draw title screen
DrawRectangle(0, 0, screenWidth, screenHeight, GREEN);
DrawText("TITLE SCREEN", 20, 20, 40, DARKGREEN);
} break;
case GAMEPLAY:
{
// Draw gameplay screen
DrawRectangle(0, 0, screenWidth, screenHeight, RED);
DrawText("GAMEPLAY SCREEN", 20, 20, 40, MAROON);
} break;
case ENDING:
{
// Draw ending screen
DrawRectangle(0, 0, screenWidth, screenHeight, BLUE);
DrawText("ENDING SCREEN", 20, 20, 40, DARKBLUE);
} break;
default: break;
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@@ -0,0 +1,163 @@
/*******************************************************************************************
*
* raylib game - Dr. Turtle & Mr. Gamera
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This game has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
#define MAX_ENEMIES 10
typedef enum { TITLE, GAMEPLAY, ENDING } GameScreen;
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 1280;
const int screenHeight = 720;
// Init window
InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
// Load game resources: textures
Texture2D sky = LoadTexture("resources/sky.png");
Texture2D mountains = LoadTexture("resources/mountains.png");
Texture2D sea = LoadTexture("resources/sea.png");
// Define scrolling variables
int backScrolling = 0;
int seaScrolling = 0;
// Define current screen
GameScreen currentScreen = TITLE;
SetTargetFPS(60); // Setup game frames per second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// Game screens management
switch (currentScreen)
{
case TITLE:
{
// Sea scrolling
seaScrolling -= 2;
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Press enter to change to gameplay screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
}
} break;
case GAMEPLAY:
{
// Background scrolling logic
backScrolling--;
if (backScrolling <= -screenWidth) backScrolling = 0;
// Sea scrolling logic
seaScrolling -= 8;
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Press enter to change to ending screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = ENDING;
}
} break;
case ENDING:
{
// Press enter to change to title screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = TITLE;
}
} break;
default: break;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw background (common to all screens)
DrawTexture(sky, 0, 0, WHITE);
DrawTexture(mountains, backScrolling, 0, WHITE);
DrawTexture(mountains, screenWidth + backScrolling, 0, WHITE);
DrawTexture(sea, seaScrolling, 0, BLUE);
DrawTexture(sea, screenWidth + seaScrolling, 0, BLUE);
switch (currentScreen)
{
case TITLE:
{
// Draw title screen
DrawText("PRESS ENTER", 450, 420, 40, BLACK);
} break;
case GAMEPLAY:
{
// Draw gameplay screen
DrawText("GAMEPLAY SCREEN", 20, 20, 40, MAROON);
} break;
case ENDING:
{
// Draw ending screen
// Draw a transparent black rectangle that covers all screen
DrawRectangle(0, 0, screenWidth, screenHeight, Fade(BLACK, 0.4f));
DrawText("ENDING SCREEN", 20, 20, 40, DARKBLUE);
} break;
default: break;
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// Unload textures
UnloadTexture(sky);
UnloadTexture(mountains);
UnloadTexture(sea);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@@ -0,0 +1,212 @@
/*******************************************************************************************
*
* raylib game - Dr. Turtle & Mr. Gamera
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This game has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
#define MAX_ENEMIES 10
typedef enum { TITLE, GAMEPLAY, ENDING } GameScreen;
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 1280;
const int screenHeight = 720;
// Init window
InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
// Load game resources: textures
Texture2D sky = LoadTexture("resources/sky.png");
Texture2D mountains = LoadTexture("resources/mountains.png");
Texture2D sea = LoadTexture("resources/sea.png");
Texture2D title = LoadTexture("resources/title.png");
Texture2D turtle = LoadTexture("resources/turtle.png");
Texture2D gamera = LoadTexture("resources/gamera.png");
// Define scrolling variables
int backScrolling = 0;
int seaScrolling = 0;
// Define current screen
GameScreen currentScreen = TITLE;
// Define player variables
int playerRail = 1;
Rectangle playerBounds = { 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
bool gameraMode = false;
// Define additional game variables
int framesCounter = 0;
SetTargetFPS(60); // Setup game frames per second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
framesCounter++;
// Game screens management
switch (currentScreen)
{
case TITLE:
{
// Sea scrolling
seaScrolling -= 2;
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Press enter to change to gameplay screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
framesCounter = 0;
}
} break;
case GAMEPLAY:
{
// Background scrolling logic
backScrolling--;
if (backScrolling <= -screenWidth) backScrolling = 0;
// Sea scrolling logic
seaScrolling -= 8;
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Player movement logic
if (IsKeyPressed(KEY_DOWN)) playerRail++;
else if (IsKeyPressed(KEY_UP)) playerRail--;
// Check player not out of rails
if (playerRail > 4) playerRail = 4;
else if (playerRail < 0) playerRail = 0;
// Update player bounds
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
if (IsKeyPressed(KEY_SPACE)) gameraMode = !gameraMode;
if (IsKeyPressed(KEY_ENTER)) currentScreen = ENDING;
} break;
case ENDING:
{
// Press enter to play again
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
// Reset player
playerRail = 1;
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
gameraMode = false;
framesCounter = 0;
}
} break;
default: break;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw background (common to all screens)
DrawTexture(sky, 0, 0, WHITE);
DrawTexture(mountains, backScrolling, 0, WHITE);
DrawTexture(mountains, screenWidth + backScrolling, 0, WHITE);
if (!gameraMode)
{
DrawTexture(sea, seaScrolling, 0, BLUE);
DrawTexture(sea, screenWidth + seaScrolling, 0, BLUE);
}
else
{
DrawTexture(sea, seaScrolling, 0, RED);
DrawTexture(sea, screenWidth + seaScrolling, 0, RED);
}
switch (currentScreen)
{
case TITLE:
{
// Draw title
//DrawTexture(title, screenWidth/2 - title.width/2, screenHeight/2 - title.height/2 - 80, WHITE);
DrawRectangle(380, 140, 500, 300, GRAY);
// Draw blinking text
if ((framesCounter/30) % 2) DrawText("PRESS ENTER", 480, 480, 40, BLACK);
} break;
case GAMEPLAY:
{
// Draw player
//if (!gameraMode) DrawTexture(turtle, playerBounds.x - 14, playerBounds.y - 14, WHITE);
//else DrawTexture(gamera, playerBounds.x - 64, playerBounds.y - 64, WHITE);
// Draw player bounding box
if (!gameraMode) DrawRectangleRec(playerBounds, GREEN);
else DrawRectangleRec(playerBounds, ORANGE);
} break;
case ENDING:
{
// Draw a transparent black rectangle that covers all screen
DrawRectangle(0, 0, screenWidth, screenHeight, Fade(BLACK, 0.4f));
DrawText("GAME OVER", 300, 200, 100, MAROON);
// Draw blinking text
if ((framesCounter/30) % 2) DrawText("PRESS ENTER to REPLAY", 400, 420, 30, LIGHTGRAY);
} break;
default: break;
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// Unload textures
UnloadTexture(sky);
UnloadTexture(mountains);
UnloadTexture(sea);
UnloadTexture(title);
UnloadTexture(turtle);
UnloadTexture(gamera);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@@ -0,0 +1,393 @@
/*******************************************************************************************
*
* raylib game - Dr. Turtle & Mr. Gamera
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This game has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
#define MAX_ENEMIES 10
typedef enum { TITLE, GAMEPLAY, ENDING } GameScreen;
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 1280;
const int screenHeight = 720;
// Init window
InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
// Load game resources: textures
Texture2D sky = LoadTexture("resources/sky.png");
Texture2D mountains = LoadTexture("resources/mountains.png");
Texture2D sea = LoadTexture("resources/sea.png");
Texture2D title = LoadTexture("resources/title.png");
Texture2D turtle = LoadTexture("resources/turtle.png");
Texture2D gamera = LoadTexture("resources/gamera.png");
Texture2D shark = LoadTexture("resources/shark.png");
Texture2D orca = LoadTexture("resources/orca.png");
Texture2D swhale = LoadTexture("resources/swhale.png");
Texture2D fish = LoadTexture("resources/fish.png");
// Define scrolling variables
int backScrolling = 0;
int seaScrolling = 0;
// Define current screen
GameScreen currentScreen = TITLE;
// Define player variables
int playerRail = 1;
Rectangle playerBounds = { 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
bool gameraMode = false;
// Define enemies variables
Rectangle enemyBounds[MAX_ENEMIES];
int enemyRail[MAX_ENEMIES];
int enemyType[MAX_ENEMIES];
bool enemyActive[MAX_ENEMIES];
float enemySpeed = 10;
// Init enemies variables
for (int i = 0; i < MAX_ENEMIES; i++)
{
// Define enemy type (all same probability)
enemyType[i] = GetRandomValue(0, 3);
// Define enemy rail
enemyRail[i] = GetRandomValue(0, 4);
// Define enemy bounding box
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
enemyActive[i] = false;
}
// Define additional game variables
int foodBar = 0;
int framesCounter = 0;
SetTargetFPS(60); // Setup game frames per second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
framesCounter++;
// Game screens management
switch (currentScreen)
{
case TITLE:
{
// Sea scrolling
seaScrolling -= 2;
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Press enter to change to gameplay screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
framesCounter = 0;
}
} break;
case GAMEPLAY:
{
// Background scrolling logic
backScrolling--;
if (backScrolling <= -screenWidth) backScrolling = 0;
// Sea scrolling logic
seaScrolling -= (enemySpeed - 2);
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Player movement logic
if (IsKeyPressed(KEY_DOWN)) playerRail++;
else if (IsKeyPressed(KEY_UP)) playerRail--;
// Check player not out of rails
if (playerRail > 4) playerRail = 4;
else if (playerRail < 0) playerRail = 0;
// Update player bounds
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
// Enemies activation logic (every 40 frames)
if (framesCounter > 40)
{
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i] == false)
{
enemyActive[i] = true;
i = MAX_ENEMIES;
}
}
framesCounter = 0;
}
// Enemies logic
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
enemyBounds[i].x -= enemySpeed;
}
// Check enemies out of screen
if (enemyBounds[i].x <= 0 - 128)
{
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
enemyActive[i] = false;
}
}
// Enemies speed increase every frame
if (!gameraMode) enemySpeed += 0.005;
// Check collision player vs enemies
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
if (CheckCollisionRecs(playerBounds, enemyBounds[i]))
{
if (enemyType[i] < 3) // Bad enemies
{
if (gameraMode)
{
foodBar += 15;
// After enemy deactivation, reset enemy parameters to be reused
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
enemyActive[i] = false;
}
else
{
// Player die logic
currentScreen = ENDING;
framesCounter = 0;
}
}
else // Sweet fish
{
enemyActive[i] = false;
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
if (!gameraMode) foodBar += 80;
else foodBar += 25;
if (foodBar == 400)
{
gameraMode = true;
}
}
}
}
}
// Gamera mode logic
if (gameraMode)
{
foodBar--;
if (foodBar <= 0)
{
gameraMode = false;
enemySpeed -= 2;
if (enemySpeed < 10) enemySpeed = 10;
}
}
} break;
case ENDING:
{
// Press enter to play again
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
// Reset player
playerRail = 1;
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
gameraMode = false;
// Reset enemies data
for (int i = 0; i < MAX_ENEMIES; i++)
{
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
enemyActive[i] = false;
}
enemySpeed = 10;
// Reset game variables
foodBar = 0;
framesCounter = 0;
}
} break;
default: break;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw background (common to all screens)
DrawTexture(sky, 0, 0, WHITE);
DrawTexture(mountains, backScrolling, 0, WHITE);
DrawTexture(mountains, screenWidth + backScrolling, 0, WHITE);
if (!gameraMode)
{
DrawTexture(sea, seaScrolling, 0, BLUE);
DrawTexture(sea, screenWidth + seaScrolling, 0, BLUE);
}
else
{
DrawTexture(sea, seaScrolling, 0, RED);
DrawTexture(sea, screenWidth + seaScrolling, 0, RED);
}
switch (currentScreen)
{
case TITLE:
{
// Draw title
DrawTexture(title, screenWidth/2 - title.width/2, screenHeight/2 - title.height/2 - 80, WHITE);
// Draw blinking text
if ((framesCounter/30) % 2) DrawText("PRESS ENTER", 480, 480, 40, BLACK);
} break;
case GAMEPLAY:
{
// Draw water lines
for (int i = 0; i < 5; i++) DrawRectangle(0, i*120 + 120, screenWidth, 110, Fade(SKYBLUE, 0.1f));
// Draw player
if (!gameraMode) DrawTexture(turtle, playerBounds.x - 14, playerBounds.y - 14, WHITE);
else DrawTexture(gamera, playerBounds.x - 64, playerBounds.y - 64, WHITE);
// Draw player bounding box
//if (!gameraMode) DrawRectangleRec(playerBounds, Fade(GREEN, 0.4f));
//else DrawRectangleRec(playerBounds, Fade(ORANGE, 0.4f));
// Draw enemies
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
// Draw enemies
/*
switch(enemyType[i])
{
case 0: DrawTexture(shark, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 1: DrawTexture(orca, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 2: DrawTexture(swhale, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 3: DrawTexture(fish, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
default: break;
}
*/
// Draw enemies bounding boxes
switch(enemyType[i])
{
case 0: DrawRectangleRec(enemyBounds[i], RED); break;
case 1: DrawRectangleRec(enemyBounds[i], RED); break;
case 2: DrawRectangleRec(enemyBounds[i], RED); break;
case 3: DrawRectangleRec(enemyBounds[i], GREEN); break;
default: break;
}
}
}
// Draw gameplay interface
// Draw food bar
DrawRectangle(20, 20, 400, 40, Fade(GRAY, 0.4f));
DrawRectangle(20, 20, foodBar, 40, ORANGE);
DrawRectangleLines(20, 20, 400, 40, BLACK);
if (gameraMode)
{
DrawText("GAMERA MODE", 60, 22, 40, GRAY);
}
} break;
case ENDING:
{
// Draw a transparent black rectangle that covers all screen
DrawRectangle(0, 0, screenWidth, screenHeight, Fade(BLACK, 0.4f));
DrawText("GAME OVER", 300, 200, 100, MAROON);
// Draw blinking text
if ((framesCounter/30) % 2) DrawText("PRESS ENTER to REPLAY", 400, 420, 30, LIGHTGRAY);
} break;
default: break;
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// Unload textures
UnloadTexture(sky);
UnloadTexture(mountains);
UnloadTexture(sea);
UnloadTexture(title);
UnloadTexture(turtle);
UnloadTexture(gamera);
UnloadTexture(shark);
UnloadTexture(orca);
UnloadTexture(swhale);
UnloadTexture(fish);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@@ -0,0 +1,447 @@
/*******************************************************************************************
*
* raylib game - Dr. Turtle & Mr. Gamera
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This game has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
#define MAX_ENEMIES 10
typedef enum { TITLE, GAMEPLAY, ENDING } GameScreen;
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 1280;
const int screenHeight = 720;
// Init window
InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
// Load game resources: textures
Texture2D sky = LoadTexture("resources/sky.png");
Texture2D mountains = LoadTexture("resources/mountains.png");
Texture2D sea = LoadTexture("resources/sea.png");
Texture2D title = LoadTexture("resources/title.png");
Texture2D turtle = LoadTexture("resources/turtle.png");
Texture2D gamera = LoadTexture("resources/gamera.png");
Texture2D shark = LoadTexture("resources/shark.png");
Texture2D orca = LoadTexture("resources/orca.png");
Texture2D swhale = LoadTexture("resources/swhale.png");
Texture2D fish = LoadTexture("resources/fish.png");
Texture2D gframe = LoadTexture("resources/gframe.png");
// Load game resources: fonts
SpriteFont font = LoadSpriteFont("resources/komika.png");
// Define scrolling variables
int backScrolling = 0;
int seaScrolling = 0;
// Define current screen
GameScreen currentScreen = TITLE;
// Define player variables
int playerRail = 1;
Rectangle playerBounds = { 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
bool gameraMode = false;
// Define enemies variables
Rectangle enemyBounds[MAX_ENEMIES];
int enemyRail[MAX_ENEMIES];
int enemyType[MAX_ENEMIES];
bool enemyActive[MAX_ENEMIES];
float enemySpeed = 10;
// Init enemies variables
for (int i = 0; i < MAX_ENEMIES; i++)
{
// Define enemy type (all same probability)
//enemyType[i] = GetRandomValue(0, 3);
// Probability system for enemies type
int enemyProb = GetRandomValue(0, 100);
if (enemyProb < 30) enemyType[i] = 0;
else if (enemyProb < 60) enemyType[i] = 1;
else if (enemyProb < 90) enemyType[i] = 2;
else enemyType[i] = 3;
// Define enemy rail
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
enemyActive[i] = false;
}
// Define additional game variables
int score = 0;
float distance = 0.0f;
int hiscore = 0;
float hidistance = 0.0f;
int foodBar = 0;
int framesCounter = 0;
SetTargetFPS(60); // Setup game frames per second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
framesCounter++;
// Game screens management
switch (currentScreen)
{
case TITLE:
{
// Sea scrolling
seaScrolling -= 2;
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Press enter to change to gameplay screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
framesCounter = 0;
}
} break;
case GAMEPLAY:
{
// Background scrolling logic
backScrolling--;
if (backScrolling <= -screenWidth) backScrolling = 0;
// Sea scrolling logic
seaScrolling -= (enemySpeed - 2);
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Player movement logic
if (IsKeyPressed(KEY_DOWN)) playerRail++;
else if (IsKeyPressed(KEY_UP)) playerRail--;
// Check player not out of rails
if (playerRail > 4) playerRail = 4;
else if (playerRail < 0) playerRail = 0;
// Update player bounds
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
// Enemies activation logic (every 40 frames)
if (framesCounter > 40)
{
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i] == false)
{
enemyActive[i] = true;
i = MAX_ENEMIES;
}
}
framesCounter = 0;
}
// Enemies logic
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
enemyBounds[i].x -= enemySpeed;
}
// Check enemies out of screen
if (enemyBounds[i].x <= 0 - 128)
{
enemyActive[i] = false;
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
}
}
if (!gameraMode) enemySpeed += 0.005;
// Check collision player vs enemies
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
if (CheckCollisionRecs(playerBounds, enemyBounds[i]))
{
if (enemyType[i] < 3) // Bad enemies
{
if (gameraMode)
{
if (enemyType[i] == 0) score += 50;
else if (enemyType[i] == 1) score += 150;
else if (enemyType[i] == 2) score += 300;
foodBar += 15;
enemyActive[i] = false;
// After enemy deactivation, reset enemy parameters to be reused
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
// Make sure not two consecutive enemies in the same row
if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
}
else
{
// Player die logic
currentScreen = ENDING;
framesCounter = 0;
// Save hiscore and hidistance for next game
if (score > hiscore) hiscore = score;
if (distance > hidistance) hidistance = distance;
}
}
else // Sweet fish
{
enemyActive[i] = false;
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
// Make sure not two consecutive enemies in the same row
if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
if (!gameraMode) foodBar += 80;
else foodBar += 25;
score += 10;
if (foodBar == 400)
{
gameraMode = true;
}
}
}
}
}
// Gamera mode logic
if (gameraMode)
{
foodBar--;
if (foodBar <= 0)
{
gameraMode = false;
enemySpeed -= 2;
if (enemySpeed < 10) enemySpeed = 10;
}
}
// Update distance counter
distance += 0.5f;
} break;
case ENDING:
{
// Press enter to play again
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
// Reset player
playerRail = 1;
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
gameraMode = false;
// Reset enemies data
for (int i = 0; i < MAX_ENEMIES; i++)
{
int enemyProb = GetRandomValue(0, 100);
if (enemyProb < 30) enemyType[i] = 0;
else if (enemyProb < 60) enemyType[i] = 1;
else if (enemyProb < 90) enemyType[i] = 2;
else enemyType[i] = 3;
//enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
enemyActive[i] = false;
}
enemySpeed = 10;
// Reset game variables
score = 0;
distance = 0.0;
foodBar = 0;
framesCounter = 0;
}
} break;
default: break;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw background (common to all screens)
DrawTexture(sky, 0, 0, WHITE);
DrawTexture(mountains, backScrolling, 0, WHITE);
DrawTexture(mountains, screenWidth + backScrolling, 0, WHITE);
if (!gameraMode)
{
DrawTexture(sea, seaScrolling, 0, (Color){ 16, 189, 227, 255});
DrawTexture(sea, screenWidth + seaScrolling, 0, (Color){ 16, 189, 227, 255});
}
else
{
DrawTexture(sea, seaScrolling, 0, (Color){ 255, 113, 66, 255});
DrawTexture(sea, screenWidth + seaScrolling, 0, (Color){ 255, 113, 66, 255});
}
switch (currentScreen)
{
case TITLE:
{
// Draw title
DrawTexture(title, screenWidth/2 - title.width/2, screenHeight/2 - title.height/2 - 80, WHITE);
// Draw blinking text
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER", (Vector2){ screenWidth/2 - 150, 480 }, GetFontBaseSize(font), 0, WHITE);
} break;
case GAMEPLAY:
{
// Draw water lines
for (int i = 0; i < 5; i++) DrawRectangle(0, i*120 + 120, screenWidth, 110, Fade(SKYBLUE, 0.1f));
// Draw player
if (!gameraMode) DrawTexture(turtle, playerBounds.x - 14, playerBounds.y - 14, WHITE);
else DrawTexture(gamera, playerBounds.x - 64, playerBounds.y - 64, WHITE);
// Draw player bounding box
//if (!gameraMode) DrawRectangleRec(playerBounds, Fade(GREEN, 0.4f));
//else DrawRectangleRec(playerBounds, Fade(ORANGE, 0.4f));
// Draw enemies
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
// Draw enemies
switch(enemyType[i])
{
case 0: DrawTexture(shark, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 1: DrawTexture(orca, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 2: DrawTexture(swhale, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 3: DrawTexture(fish, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
default: break;
}
// Draw enemies bounding boxes
/*
switch(enemyType[i])
{
case 0: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
case 1: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
case 2: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
case 3: DrawRectangleRec(enemyBounds[i], Fade(GREEN, 0.5f)); break;
default: break;
}
*/
}
}
// Draw gameplay interface
DrawRectangle(20, 20, 400, 40, Fade(GRAY, 0.4f));
DrawRectangle(20, 20, foodBar, 40, ORANGE);
DrawRectangleLines(20, 20, 400, 40, BLACK);
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ screenWidth - 300, 20 }, GetFontBaseSize(font), -2, ORANGE);
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 550, 20 }, GetFontBaseSize(font), -2, ORANGE);
if (gameraMode)
{
DrawText("GAMERA MODE", 60, 22, 40, GRAY);
DrawTexture(gframe, 0, 0, Fade(WHITE, 0.5f));
}
} break;
case ENDING:
{
// Draw a transparent black rectangle that covers all screen
DrawRectangle(0, 0, screenWidth, screenHeight, Fade(BLACK, 0.4f));
DrawTextEx(font, "GAME OVER", (Vector2){ 300, 160 }, GetFontBaseSize(font)*3, -2, MAROON);
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ 680, 350 }, GetFontBaseSize(font), -2, GOLD);
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 290, 350 }, GetFontBaseSize(font), -2, GOLD);
DrawTextEx(font, FormatText("HISCORE: %04i", hiscore), (Vector2){ 665, 400 }, GetFontBaseSize(font), -2, ORANGE);
DrawTextEx(font, FormatText("HIDISTANCE: %04i", (int)hidistance), (Vector2){ 270, 400 }, GetFontBaseSize(font), -2, ORANGE);
// Draw blinking text
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER to REPLAY", (Vector2){ screenWidth/2 - 250, 520 }, GetFontBaseSize(font), -2, LIGHTGRAY);
} break;
default: break;
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// Unload textures
UnloadTexture(sky);
UnloadTexture(mountains);
UnloadTexture(sea);
UnloadTexture(gframe);
UnloadTexture(title);
UnloadTexture(turtle);
UnloadTexture(shark);
UnloadTexture(orca);
UnloadTexture(swhale);
UnloadTexture(fish);
UnloadTexture(gamera);
// Unload font texture
UnloadSpriteFont(font);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@@ -0,0 +1,468 @@
/*******************************************************************************************
*
* raylib game - Dr. Turtle & Mr. Gamera
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This game has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
#define MAX_ENEMIES 10
typedef enum { TITLE, GAMEPLAY, ENDING } GameScreen;
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 1280;
const int screenHeight = 720;
// Init window
InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
// Initialize audio device
InitAudioDevice();
// Load game resources: textures
Texture2D sky = LoadTexture("resources/sky.png");
Texture2D mountains = LoadTexture("resources/mountains.png");
Texture2D sea = LoadTexture("resources/sea.png");
Texture2D title = LoadTexture("resources/title.png");
Texture2D turtle = LoadTexture("resources/turtle.png");
Texture2D shark = LoadTexture("resources/shark.png");
Texture2D orca = LoadTexture("resources/orca.png");
Texture2D swhale = LoadTexture("resources/swhale.png");
Texture2D fish = LoadTexture("resources/fish.png");
Texture2D gamera = LoadTexture("resources/gamera.png");
Texture2D gframe = LoadTexture("resources/gframe.png");
// Load game resources: fonts
SpriteFont font = LoadSpriteFont("resources/komika.png");
// Load game resources: sounds
Sound eat = LoadSound("resources/eat.wav");
Sound die = LoadSound("resources/die.wav");
Sound growl = LoadSound("resources/gamera.wav");
// Start playing streaming music
PlayMusicStream("resources/speeding.ogg");
// Define scrolling variables
int backScrolling = 0;
int seaScrolling = 0;
// Define current screen
GameScreen currentScreen = TITLE;
// Define player variables
int playerRail = 1;
Rectangle playerBounds = { 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
bool gameraMode = false;
// Define enemies variables
Rectangle enemyBounds[MAX_ENEMIES];
int enemyRail[MAX_ENEMIES];
int enemyType[MAX_ENEMIES];
bool enemyActive[MAX_ENEMIES];
float enemySpeed = 10;
// Init enemies variables
for (int i = 0; i < MAX_ENEMIES; i++)
{
// Define enemy type (all same probability)
//enemyType[i] = GetRandomValue(0, 3);
// Probability system for enemies type
int enemyProb = GetRandomValue(0, 100);
if (enemyProb < 30) enemyType[i] = 0;
else if (enemyProb < 60) enemyType[i] = 1;
else if (enemyProb < 90) enemyType[i] = 2;
else enemyType[i] = 3;
// Define enemy rail
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
enemyActive[i] = false;
}
// Define additional game variables
int score = 0;
float distance = 0.0f;
int hiscore = 0;
float hidistance = 0.0f;
int foodBar = 0;
int framesCounter = 0;
SetTargetFPS(60); // Setup game frames per second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
framesCounter++;
// Game screens management
switch (currentScreen)
{
case TITLE:
{
// Sea scrolling
seaScrolling -= 2;
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Press enter to change to gameplay screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
framesCounter = 0;
}
} break;
case GAMEPLAY:
{
// Background scrolling logic
backScrolling--;
if (backScrolling <= -screenWidth) backScrolling = 0;
// Sea scrolling logic
seaScrolling -= (enemySpeed - 2);
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Player movement logic
if (IsKeyPressed(KEY_DOWN)) playerRail++;
else if (IsKeyPressed(KEY_UP)) playerRail--;
// Check player not out of rails
if (playerRail > 4) playerRail = 4;
else if (playerRail < 0) playerRail = 0;
// Update player bounds
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
// Enemies activation logic (every 40 frames)
if (framesCounter > 40)
{
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i] == false)
{
enemyActive[i] = true;
i = MAX_ENEMIES;
}
}
framesCounter = 0;
}
// Enemies logic
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
enemyBounds[i].x -= enemySpeed;
}
// Check enemies out of screen
if (enemyBounds[i].x <= 0 - 128)
{
enemyActive[i] = false;
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
}
}
if (!gameraMode) enemySpeed += 0.005;
// Check collision player vs enemies
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
if (CheckCollisionRecs(playerBounds, enemyBounds[i]))
{
if (enemyType[i] < 3) // Bad enemies
{
if (gameraMode)
{
if (enemyType[i] == 0) score += 50;
else if (enemyType[i] == 1) score += 150;
else if (enemyType[i] == 2) score += 300;
foodBar += 15;
enemyActive[i] = false;
// After enemy deactivation, reset enemy parameters to be reused
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
PlaySound(eat);
}
else
{
// Player die logic
PlaySound(die);
currentScreen = ENDING;
framesCounter = 0;
// Save hiscore and hidistance for next game
if (score > hiscore) hiscore = score;
if (distance > hidistance) hidistance = distance;
}
}
else // Sweet fish
{
enemyActive[i] = false;
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
if (!gameraMode) foodBar += 80;
else foodBar += 25;
score += 10;
if (foodBar == 400)
{
gameraMode = true;
PlaySound(growl);
}
PlaySound(eat);
}
}
}
}
// Gamera mode logic
if (gameraMode)
{
foodBar--;
if (foodBar <= 0)
{
gameraMode = false;
enemySpeed -= 2;
if (enemySpeed < 10) enemySpeed = 10;
}
}
// Update distance counter
distance += 0.5f;
} break;
case ENDING:
{
// Press enter to play again
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
// Reset player
playerRail = 1;
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
// Reset enemies data
for (int i = 0; i < MAX_ENEMIES; i++)
{
int enemyProb = GetRandomValue(0, 100);
if (enemyProb < 30) enemyType[i] = 0;
else if (enemyProb < 60) enemyType[i] = 1;
else if (enemyProb < 90) enemyType[i] = 2;
else enemyType[i] = 3;
//enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
enemyActive[i] = false;
}
enemySpeed = 10;
// Reset game variables
score = 0;
distance = 0.0;
foodBar = 0;
gameraMode = false;
framesCounter = 0;
}
} break;
default: break;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw background (common to all screens)
DrawTexture(sky, 0, 0, WHITE);
DrawTexture(mountains, backScrolling, 0, WHITE);
DrawTexture(mountains, screenWidth + backScrolling, 0, WHITE);
if (!gameraMode)
{
DrawTexture(sea, seaScrolling, 0, (Color){ 16, 189, 227, 255});
DrawTexture(sea, screenWidth + seaScrolling, 0, (Color){ 16, 189, 227, 255});
}
else
{
DrawTexture(sea, seaScrolling, 0, (Color){ 255, 113, 66, 255});
DrawTexture(sea, screenWidth + seaScrolling, 0, (Color){ 255, 113, 66, 255});
}
switch (currentScreen)
{
case TITLE:
{
// Draw title
DrawTexture(title, screenWidth/2 - title.width/2, screenHeight/2 - title.height/2 - 80, WHITE);
// Draw blinking text
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER", (Vector2){ screenWidth/2 - 150, 480 }, GetFontBaseSize(font), 0, WHITE);
} break;
case GAMEPLAY:
{
// Draw water lines
for (int i = 0; i < 5; i++) DrawRectangle(0, i*120 + 120, screenWidth, 110, Fade(SKYBLUE, 0.1f));
// Draw player
if (!gameraMode) DrawTexture(turtle, playerBounds.x - 14, playerBounds.y - 14, WHITE);
else DrawTexture(gamera, playerBounds.x - 64, playerBounds.y - 64, WHITE);
// Draw player bounding box
//if (!gameraMode) DrawRectangleRec(playerBounds, Fade(GREEN, 0.4f));
//else DrawRectangleRec(playerBounds, Fade(ORANGE, 0.4f));
// Draw enemies
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
// Draw enemies
switch(enemyType[i])
{
case 0: DrawTexture(shark, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 1: DrawTexture(orca, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 2: DrawTexture(swhale, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 3: DrawTexture(fish, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
default: break;
}
// Draw enemies bounding boxes
/*
switch(enemyType[i])
{
case 0: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
case 1: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
case 2: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
case 3: DrawRectangleRec(enemyBounds[i], Fade(GREEN, 0.5f)); break;
default: break;
}
*/
}
}
// Draw gameplay interface
DrawRectangle(20, 20, 400, 40, Fade(GRAY, 0.4f));
DrawRectangle(20, 20, foodBar, 40, ORANGE);
DrawRectangleLines(20, 20, 400, 40, BLACK);
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ screenWidth - 300, 20 }, GetFontBaseSize(font), -2, ORANGE);
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 550, 20 }, GetFontBaseSize(font), -2, ORANGE);
if (gameraMode)
{
DrawText("GAMERA MODE", 60, 22, 40, GRAY);
DrawTexture(gframe, 0, 0, Fade(WHITE, 0.5f));
}
} break;
case ENDING:
{
// Draw a transparent black rectangle that covers all screen
DrawRectangle(0, 0, screenWidth, screenHeight, Fade(BLACK, 0.4f));
DrawTextEx(font, "GAME OVER", (Vector2){ 300, 160 }, GetFontBaseSize(font)*3, -2, MAROON);
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ 680, 350 }, GetFontBaseSize(font), -2, GOLD);
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 290, 350 }, GetFontBaseSize(font), -2, GOLD);
DrawTextEx(font, FormatText("HISCORE: %04i", hiscore), (Vector2){ 665, 400 }, GetFontBaseSize(font), -2, ORANGE);
DrawTextEx(font, FormatText("HIDISTANCE: %04i", (int)hidistance), (Vector2){ 270, 400 }, GetFontBaseSize(font), -2, ORANGE);
// Draw blinking text
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER to REPLAY", (Vector2){ screenWidth/2 - 250, 520 }, GetFontBaseSize(font), -2, LIGHTGRAY);
} break;
default: break;
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// Unload textures
UnloadTexture(sky);
UnloadTexture(mountains);
UnloadTexture(sea);
UnloadTexture(gframe);
UnloadTexture(title);
UnloadTexture(turtle);
UnloadTexture(shark);
UnloadTexture(orca);
UnloadTexture(swhale);
UnloadTexture(fish);
UnloadTexture(gamera);
// Unload font texture
UnloadSpriteFont(font);
// Unload sounds
UnloadSound(eat);
UnloadSound(die);
UnloadSound(growl);
StopMusicStream(); // Stop music
CloseAudioDevice(); // Close audio device
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@@ -0,0 +1,491 @@
/*******************************************************************************************
*
* raylib game - Dr. Turtle & Mr. Gamera
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This game has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
#define MAX_ENEMIES 10
typedef enum { TITLE, GAMEPLAY, ENDING } GameScreen;
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 1280;
const int screenHeight = 720;
// Init window
ShowLogo();
InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
// Initialize audio device
InitAudioDevice();
// Load game resources: textures
Texture2D sky = LoadTexture("resources/sky.png");
Texture2D mountains = LoadTexture("resources/mountains.png");
Texture2D sea = LoadTexture("resources/sea.png");
Texture2D title = LoadTexture("resources/title.png");
Texture2D turtle = LoadTexture("resources/turtle.png");
Texture2D gamera = LoadTexture("resources/gamera.png");
Texture2D shark = LoadTexture("resources/shark.png");
Texture2D orca = LoadTexture("resources/orca.png");
Texture2D swhale = LoadTexture("resources/swhale.png");
Texture2D fish = LoadTexture("resources/fish.png");
Texture2D gframe = LoadTexture("resources/gframe.png");
// Load game resources: fonts
SpriteFont font = LoadSpriteFont("resources/komika.png");
// Load game resources: sounds
Sound eat = LoadSound("resources/eat.wav");
Sound die = LoadSound("resources/die.wav");
Sound growl = LoadSound("resources/gamera.wav");
// Start playing streaming music
PlayMusicStream("resources/speeding.ogg");
// Define scrolling variables
int backScrolling = 0;
int seaScrolling = 0;
// Define current screen
GameScreen currentScreen = TITLE;
// Define player variables
int playerRail = 1;
Rectangle playerBounds = { 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
bool gameraMode = false;
// Define enemies variables
Rectangle enemyBounds[MAX_ENEMIES];
int enemyRail[MAX_ENEMIES];
int enemyType[MAX_ENEMIES];
bool enemyActive[MAX_ENEMIES];
float enemySpeed = 10;
// Init enemies variables
for (int i = 0; i < MAX_ENEMIES; i++)
{
// Define enemy type (all same probability)
//enemyType[i] = GetRandomValue(0, 3);
// Probability system for enemies type
int enemyProb = GetRandomValue(0, 100);
if (enemyProb < 30) enemyType[i] = 0;
else if (enemyProb < 60) enemyType[i] = 1;
else if (enemyProb < 90) enemyType[i] = 2;
else enemyType[i] = 3;
// define enemy rail
enemyRail[i] = GetRandomValue(0, 4);
// Make sure not two consecutive enemies in the same row
if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
enemyActive[i] = false;
}
// Define additional game variables
int score = 0;
float distance = 0.0f;
int hiscore = 0;
float hidistance = 0.0f;
int foodBar = 0;
int framesCounter = 0;
unsigned char blue = 200;
float timeCounter = 0;
SetTargetFPS(60); // Setup game frames per second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
framesCounter++;
// Sea color tint effect
blue = 210 + 25 * sin(timeCounter);
timeCounter += 0.01;
// Game screens management
switch (currentScreen)
{
case TITLE:
{
// Sea scrolling
seaScrolling -= 2;
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Press enter to change to gameplay screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
framesCounter = 0;
}
} break;
case GAMEPLAY:
{
// Background scrolling logic
backScrolling--;
if (backScrolling <= -screenWidth) backScrolling = 0;
// Sea scrolling logic
seaScrolling -= (enemySpeed - 2);
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Player movement logic
if (IsKeyPressed(KEY_DOWN)) playerRail++;
else if (IsKeyPressed(KEY_UP)) playerRail--;
// Check player not out of rails
if (playerRail > 4) playerRail = 4;
else if (playerRail < 0) playerRail = 0;
// Update player bounds
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
// Enemies activation logic (every 40 frames)
if (framesCounter > 40)
{
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i] == false)
{
enemyActive[i] = true;
i = MAX_ENEMIES;
}
}
framesCounter = 0;
}
// Enemies logic
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
enemyBounds[i].x -= enemySpeed;
}
// Check enemies out of screen
if (enemyBounds[i].x <= 0 - 128)
{
enemyActive[i] = false;
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
// Make sure not two consecutive enemies in the same row
if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
}
}
if (!gameraMode) enemySpeed += 0.005;
// Check collision player vs enemies
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
if (CheckCollisionRecs(playerBounds, enemyBounds[i]))
{
if (enemyType[i] < 3) // Bad enemies
{
if (gameraMode)
{
if (enemyType[i] == 0) score += 50;
else if (enemyType[i] == 1) score += 150;
else if (enemyType[i] == 2) score += 300;
foodBar += 15;
enemyActive[i] = false;
// After enemy deactivation, reset enemy parameters to be reused
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
// Make sure not two consecutive enemies in the same row
if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
PlaySound(eat);
}
else
{
// Player die logic
PlaySound(die);
currentScreen = ENDING;
framesCounter = 0;
// Save hiscore and hidistance for next game
if (score > hiscore) hiscore = score;
if (distance > hidistance) hidistance = distance;
}
}
else // Sweet fish
{
enemyActive[i] = false;
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
// Make sure not two consecutive enemies in the same row
if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
if (!gameraMode) foodBar += 80;
else foodBar += 25;
score += 10;
if (foodBar == 400)
{
gameraMode = true;
PlaySound(growl);
}
PlaySound(eat);
}
}
}
}
// Gamera mode logic
if (gameraMode)
{
foodBar--;
if (foodBar <= 0)
{
gameraMode = false;
enemySpeed -= 2;
if (enemySpeed < 10) enemySpeed = 10;
}
}
// Update distance counter
distance += 0.5f;
} break;
case ENDING:
{
// Press enter to play again
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
// Reset player
playerRail = 1;
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
gameraMode = false;
// Reset enemies data
for (int i = 0; i < MAX_ENEMIES; i++)
{
int enemyProb = GetRandomValue(0, 100);
if (enemyProb < 30) enemyType[i] = 0;
else if (enemyProb < 60) enemyType[i] = 1;
else if (enemyProb < 90) enemyType[i] = 2;
else enemyType[i] = 3;
//enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
// Make sure not two consecutive enemies in the same row
if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
enemyActive[i] = false;
}
enemySpeed = 10;
// Reset game variables
score = 0;
distance = 0.0;
foodBar = 0;
framesCounter = 0;
}
} break;
default: break;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw background (common to all screens)
DrawTexture(sky, 0, 0, WHITE);
DrawTexture(mountains, backScrolling, 0, WHITE);
DrawTexture(mountains, screenWidth + backScrolling, 0, WHITE);
if (!gameraMode)
{
DrawTexture(sea, seaScrolling, 0, (Color){ 16, 189, blue, 255});
DrawTexture(sea, screenWidth + seaScrolling, 0, (Color){ 16, 189, blue, 255});
}
else
{
DrawTexture(sea, seaScrolling, 0, (Color){ 255, 113, 66, 255});
DrawTexture(sea, screenWidth + seaScrolling, 0, (Color){ 255, 113, 66, 255});
}
switch (currentScreen)
{
case TITLE:
{
// Draw title
DrawTexture(title, screenWidth/2 - title.width/2, screenHeight/2 - title.height/2 - 80, WHITE);
// Draw blinking text
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER", (Vector2){ screenWidth/2 - 150, 480 }, GetFontBaseSize(font), 0, WHITE);
} break;
case GAMEPLAY:
{
// Draw water lines
for (int i = 0; i < 5; i++) DrawRectangle(0, i*120 + 120, screenWidth, 110, Fade(SKYBLUE, 0.1f));
// Draw player
if (!gameraMode) DrawTexture(turtle, playerBounds.x - 14, playerBounds.y - 14, WHITE);
else DrawTexture(gamera, playerBounds.x - 64, playerBounds.y - 64, WHITE);
// Draw player bounding box
//if (!gameraMode) DrawRectangleRec(playerBounds, Fade(GREEN, 0.4f));
//else DrawRectangleRec(playerBounds, Fade(ORANGE, 0.4f));
// Draw enemies
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
// Draw enemies
switch(enemyType[i])
{
case 0: DrawTexture(shark, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 1: DrawTexture(orca, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 2: DrawTexture(swhale, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 3: DrawTexture(fish, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
default: break;
}
// Draw enemies bounding boxes
/*
switch(enemyType[i])
{
case 0: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
case 1: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
case 2: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
case 3: DrawRectangleRec(enemyBounds[i], Fade(GREEN, 0.5f)); break;
default: break;
}
*/
}
}
// Draw gameplay interface
DrawRectangle(20, 20, 400, 40, Fade(GRAY, 0.4f));
DrawRectangle(20, 20, foodBar, 40, ORANGE);
DrawRectangleLines(20, 20, 400, 40, BLACK);
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ screenWidth - 300, 20 }, GetFontBaseSize(font), -2, ORANGE);
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 550, 20 }, GetFontBaseSize(font), -2, ORANGE);
if (gameraMode)
{
DrawText("GAMERA MODE", 60, 22, 40, GRAY);
DrawTexture(gframe, 0, 0, Fade(WHITE, 0.5f));
}
} break;
case ENDING:
{
// Draw a transparent black rectangle that covers all screen
DrawRectangle(0, 0, screenWidth, screenHeight, Fade(BLACK, 0.4f));
DrawTextEx(font, "GAME OVER", (Vector2){ 300, 160 }, GetFontBaseSize(font)*3, -2, MAROON);
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ 680, 350 }, GetFontBaseSize(font), -2, GOLD);
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 290, 350 }, GetFontBaseSize(font), -2, GOLD);
DrawTextEx(font, FormatText("HISCORE: %04i", hiscore), (Vector2){ 665, 400 }, GetFontBaseSize(font), -2, ORANGE);
DrawTextEx(font, FormatText("HIDISTANCE: %04i", (int)hidistance), (Vector2){ 270, 400 }, GetFontBaseSize(font), -2, ORANGE);
// Draw blinking text
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER to REPLAY", (Vector2){ screenWidth/2 - 250, 520 }, GetFontBaseSize(font), -2, LIGHTGRAY);
} break;
default: break;
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// Unload textures
UnloadTexture(sky);
UnloadTexture(mountains);
UnloadTexture(sea);
UnloadTexture(gframe);
UnloadTexture(title);
UnloadTexture(turtle);
UnloadTexture(shark);
UnloadTexture(orca);
UnloadTexture(swhale);
UnloadTexture(fish);
UnloadTexture(gamera);
// Unload font texture
UnloadSpriteFont(font);
// Unload sounds
UnloadSound(eat);
UnloadSound(die);
UnloadSound(growl);
StopMusicStream(); // Stop music
CloseAudioDevice(); // Close audio device
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -1,20 +1,26 @@
/*********************************************************************************************
*
* raylib 1.0.4 (www.raylib.com)
* raylib 1.1 (www.raylib.com)
*
* A simple and easy-to-use library to learn videogames programming
*
* Features:
* Library written in plain C code (C99)
* Uses C# PascalCase/camelCase notation
* Hardware accelerated with OpenGL 1.1
* Hardware accelerated with OpenGL (1.1, 3.3+ or ES2)
* Unique OpenGL abstraction layer [rlgl]
* Powerful fonts module with SpriteFonts support
* Basic 3d support for Shapes and Models
* Audio loading and playing
* Multiple textures support, including DDS and mipmaps generation
* Basic 3d support for Shapes, Models, Heightmaps and Billboards
* Powerful math module for Vector and Matrix operations [raymath]
* Audio loading and playing with streaming support
*
* Used external libs:
* GLFW3 (www.glfw.org) for window/context management and input
* GLEW for OpenGL extensions loading (3.3+ and ES2)
* stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC)
* stb_image_write (Sean Barret) for image writting (PNG)
* stb_vorbis (Sean Barret) for ogg audio loading
* OpenAL Soft for audio device/context management
* tinfl for data decompression (DEFLATE algorithm)
*
@@ -23,8 +29,9 @@
* 32bit Textures - All loaded images are converted automatically to RGBA textures
* SpriteFonts - All loaded sprite-font images are converted to RGBA and POT textures
* One custom default font is loaded automatically when InitWindow()
* If using OpenGL 3.3+ or ES2, one default shader is loaded automatically (internally defined)
*
* -- LICENSE (raylib v1.0, November 2013) --
* -- LICENSE (raylib v1.1, April 2014) --
*
* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software:
@@ -65,6 +72,7 @@
#define KEY_SPACE 32
#define KEY_ESCAPE 256
#define KEY_ENTER 257
#define KEY_BACKSPACE 259
#define KEY_RIGHT 262
#define KEY_LEFT 263
#define KEY_DOWN 264
@@ -149,6 +157,19 @@
// Boolean type
typedef enum { false, true } bool;
// Vector2 type
typedef struct Vector2 {
float x;
float y;
} Vector2;
// Vector3 type
typedef struct Vector3 {
float x;
float y;
float z;
} Vector3;
// Color type, RGBA (32bit)
typedef struct Color {
unsigned char r;
@@ -176,12 +197,13 @@ typedef struct Image {
// Texture2D type, bpp always RGBA (32bit)
// NOTE: Data stored in GPU memory
typedef struct Texture2D {
unsigned int glId;
unsigned int id; // OpenGL id
int width;
int height;
} Texture2D;
// SpriteFont one Character (Glyph) data, defined in text module
// Character type (one font glyph)
// NOTE: Defined in module: text
typedef struct Character Character;
// SpriteFont type, includes texture and charSet array data
@@ -191,19 +213,6 @@ typedef struct SpriteFont {
Character *charSet;
} SpriteFont;
// Vector2 type
typedef struct Vector2 {
float x;
float y;
} Vector2;
// Vector3 type
typedef struct Vector3 {
float x;
float y;
float z;
} Vector3;
// Camera type, defines a camera position/orientation in 3d space
typedef struct Camera {
Vector3 position;
@@ -211,15 +220,25 @@ typedef struct Camera {
Vector3 up;
} Camera;
// Basic 3d Model type
// Vertex data definning a mesh
typedef struct VertexData {
int vertexCount;
float *vertices; // 3 components per vertex
float *texcoords; // 2 components per vertex
float *normals; // 3 components per vertex
unsigned char *colors; // 4 components per vertex
} VertexData;
// 3d Model type
// NOTE: If using OpenGL 1.1, loaded in CPU (mesh); if OpenGL 3.3+ loaded in GPU (vaoId)
typedef struct Model {
int numVertices;
Vector3 *vertices;
Vector2 *texcoords;
Vector3 *normals;
VertexData mesh;
unsigned int vaoId;
unsigned int textureId;
//Matrix transform;
} Model;
// Basic Sound source and buffer
// Sound source type
typedef struct Sound {
unsigned int source;
unsigned int buffer;
@@ -263,6 +282,8 @@ int GetHexValue(Color color); // Returns hexadecim
int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0 to 1.0
void ShowLogo(); // Activates raylib logo at startup
//------------------------------------------------------------------------------------
// Input Handling Functions (Module: core)
//------------------------------------------------------------------------------------
@@ -278,6 +299,7 @@ bool IsMouseButtonUp(int button); // Detect if a mouse but
int GetMouseX(); // Returns mouse position X
int GetMouseY(); // Returns mouse position Y
Vector2 GetMousePosition(); // Returns mouse position XY
int GetMouseWheelMove(); // Returns mouse wheel movement Y
bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
Vector2 GetGamepadMovement(int gamepad); // Return axis movement vector for a gamepad
@@ -323,11 +345,12 @@ Image LoadImage(const char *fileName);
Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
Texture2D CreateTexture2D(Image image); // Create a Texture2D from Image data
Texture2D CreateTexture(Image image, bool genMipmaps); // Create a Texture2D from Image data (and generate mipmaps)
void UnloadImage(Image image); // Unload image from CPU memory (RAM)
void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, // Draw a part of a texture defined by a rectangle with 'pro' parameters
@@ -339,6 +362,7 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
SpriteFont GetDefaultFont(); // Get the default SpriteFont
SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
int fontSize, int spacing, Color tint);
@@ -354,15 +378,17 @@ const char *FormatText(const char *text, ...);
void DrawCube(Vector3 position, float width, float height, float lenght, Color color); // Draw cube
void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color); // Draw cube wires
void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float lenght, Color color); // Draw cube textured
void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
void DrawSphereWires(Vector3 centerPos, float radius, Color color); // Draw sphere wires
void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color); // Draw a plane
void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, int slicesZ, Color color); // Draw a plane with divisions
void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
void DrawGizmo(Vector3 position, bool orbits); // Draw gizmo (with or without orbits)
void DrawGizmo(Vector3 position); // Draw simple gizmo
void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale); // Draw gizmo with extended parameters
//DrawTorus(), DrawTeapot() are useless...
//------------------------------------------------------------------------------------
@@ -370,33 +396,41 @@ void DrawGizmo(Vector3 position, bool orbits);
//------------------------------------------------------------------------------------
Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
//Model LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource)
Model LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model
Model LoadCubesmap(Image cubesmap); // Load a map image as a 3d model (cubes based)
void UnloadModel(Model model); // Unload 3d model from memory
void DrawModel(Model model, Vector3 position, float scale, Color color); // Draw a model
void DrawModelEx(Model model, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a textured model
void DrawModelWires(Model model, Vector3 position, float scale, Color color); // Draw a model wires
void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model
// NOTE: The following functions work but are incomplete or require some revision
// DrawHeightmap is extremely inefficient and can impact performance up to 60%
void DrawBillboard(Camera camera, Texture2D texture, Vector3 basePos, float size, Color tint); // REVIEW: Draw a billboard (raylib 1.x)
void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 basePos, float size, Color tint); // REVIEW: Draw a billboard (raylib 1.x)
void DrawHeightmap(Image heightmap, Vector3 centerPos, Vector3 scale, Color color); // REVIEW: Draw heightmap using image map (raylib 1.x)
void DrawHeightmapEx(Image heightmap, Texture2D texture, Vector3 centerPos, Vector3 scale, Color tint); // REVIEW: Draw textured heightmap (raylib 1.x)
void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
void DrawModelEx(Model model, Vector3 position, Vector3 rotation, 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 DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture
void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
//------------------------------------------------------------------------------------
// Audio Loading and Playing Functions (Module: audio)
//------------------------------------------------------------------------------------
void InitAudioDevice(); // Initialize audio device and context
void CloseAudioDevice(); // Close the audio device and context
void CloseAudioDevice(); // Close the audio device and context (and music stream)
Sound LoadSound(char *fileName); // Load sound to memory
Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
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 IsPlaying(Sound sound); // Check if a sound is currently playing
void SetVolume(Sound sound, float volume); // Set volume for a sound (1.0 is base level)
void SetPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
bool SoundIsPlaying(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 StopMusicStream(); // Stop music playing (close stream)
void PauseMusicStream(); // Pause music playing
bool MusicIsPlaying(); // Check if music is playing
void SetMusicVolume(float volume); // Set volume for music (1.0 is max level)
float GetMusicTimeLength(); // Get current music time length (in seconds)
float GetMusicTimePlayed(); // Get current music time played (in seconds)
#ifdef __cplusplus
}

Binary file not shown.

View File

@@ -6,7 +6,7 @@
*
* Uses external lib:
* OpenAL - Audio device management lib
* TODO: stb_vorbis - Ogg audio files loading
* stb_vorbis - Ogg audio files loading
*
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
@@ -32,27 +32,45 @@
#include <AL/al.h> // OpenAL basic header
#include <AL/alc.h> // OpenAL context header (like OpenGL, OpenAL requires a context to work)
#include <stdlib.h> // To use exit() function
#include <stdlib.h> // Declares malloc() and free() for memory management
#include <string.h> // Required for strcmp()
#include <stdio.h> // Used for .WAV loading
#include "utils.h" // rRES data decompression utility function
//#include "stb_vorbis.h" // TODO: OGG loading functions
#include "stb_vorbis.h" // OGG loading functions
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
// Nop...
#define MUSIC_STREAM_BUFFERS 2
#define MUSIC_BUFFER_SIZE 4096*8 //4096*32
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
// Music type (file streaming from memory)
// NOTE: Anything longer than ~10 seconds should be streamed...
typedef struct Music {
stb_vorbis *stream;
ALuint buffers[MUSIC_STREAM_BUFFERS];
ALuint source;
ALenum format;
int channels;
int sampleRate;
int totalSamplesLeft;
bool loop;
} Music;
// Wave file data
typedef struct Wave {
unsigned char *data; // Buffer data pointer
void *data; // Buffer data pointer
unsigned int dataSize; // Data size in bytes
unsigned int sampleRate;
unsigned int dataSize;
short bitsPerSample;
short channels;
} Wave;
@@ -60,17 +78,23 @@ typedef struct Wave {
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
// Nop...
bool musicEnabled = false;
static Music currentMusic; // Current music loaded
// NOTE: Only one music file playing at a time
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
static Wave LoadWAV(char *fileName);
static void UnloadWAV(Wave wave);
//static Ogg LoadOGG(char *fileName);
static Wave LoadWAV(const char *fileName);
static Wave LoadOGG(char *fileName);
static void UnloadWave(Wave wave);
static bool BufferMusicStream(ALuint buffer); // Fill music buffers with data
static void EmptyMusicStream(); // Empty music buffers
extern void UpdateMusicStream(); // Updates buffers (refill) for music streaming
//----------------------------------------------------------------------------------
// Module Functions Definition - Window and OpenGL Context Functions
// Module Functions Definition - Audio Device initialization and Closing
//----------------------------------------------------------------------------------
// Initialize audio device and context
@@ -79,11 +103,7 @@ void InitAudioDevice()
// Open and initialize a device with default settings
ALCdevice *device = alcOpenDevice(NULL);
if(!device)
{
fprintf(stderr, "Could not open a device!\n");
exit(1);
}
if(!device) TraceLog(ERROR, "Could not open audio device");
ALCcontext *context = alcCreateContext(device, NULL);
@@ -93,11 +113,10 @@ void InitAudioDevice()
alcCloseDevice(device);
fprintf(stderr, "Could not set a context!\n");
exit(1);
TraceLog(ERROR, "Could not setup audio context");
}
printf("Opened \"%s\"\n", alcGetString(device, ALC_DEVICE_SPECIFIER));
TraceLog(INFO, "Audio device and context initialized successfully: %s\n", alcGetString(device, ALC_DEVICE_SPECIFIER));
// Listener definition (just for 2D)
alListener3f(AL_POSITION, 0, 0, 0);
@@ -108,10 +127,12 @@ void InitAudioDevice()
// Close the audio device for the current context, and destroys the context
void CloseAudioDevice()
{
StopMusicStream(); // Stop music streaming and close current stream
ALCdevice *device;
ALCcontext *context = alcGetCurrentContext();
if (context == NULL) return;
if (context == NULL) TraceLog(WARNING, "Could not get current audio context for closing");
device = alcGetContextsDevice(context);
@@ -120,18 +141,28 @@ void CloseAudioDevice()
alcCloseDevice(device);
}
//----------------------------------------------------------------------------------
// Module Functions Definition - Sounds loading and playing (.WAV)
//----------------------------------------------------------------------------------
// Load sound to memory
Sound LoadSound(char *fileName)
{
Sound sound;
Wave wave;
// NOTE: The entire file is loaded to memory to play it all at once (no-streaming)
// WAV file loading
// NOTE: Buffer space is allocated inside LoadWAV, Wave must be freed
Wave wave = LoadWAV(fileName);
// Audio file loading
// NOTE: Buffer space is allocated inside function, Wave must be freed
ALenum format;
if (strcmp(GetExtension(fileName),"wav") == 0) wave = LoadWAV(fileName);
else if (strcmp(GetExtension(fileName),"ogg") == 0) wave = LoadOGG(fileName);
else TraceLog(WARNING, "[%s] Sound extension not recognized, it can't be loaded", fileName);
if (wave.data != NULL)
{
ALenum format = 0;
// The OpenAL format is worked out by looking at the number of channels and the bits per sample
if (wave.channels == 1)
{
@@ -144,7 +175,6 @@ Sound LoadSound(char *fileName)
else if (wave.bitsPerSample == 16) format = AL_FORMAT_STEREO16;
}
// Create an audio source
ALuint source;
alGenSources(1, &source); // Generate pointer to audio source
@@ -161,21 +191,20 @@ Sound LoadSound(char *fileName)
alGenBuffers(1, &buffer); // Generate pointer to buffer
// Upload sound data to buffer
alBufferData(buffer, format, (void*)wave.data, wave.dataSize, wave.sampleRate);
alBufferData(buffer, format, wave.data, wave.dataSize, wave.sampleRate);
// Attach sound buffer to source
alSourcei(source, AL_BUFFER, buffer);
// Unallocate WAV data
UnloadWAV(wave);
UnloadWave(wave);
printf("Sample rate: %i\n", wave.sampleRate);
printf("Channels: %i\n", wave.channels);
printf("Audio file loaded...!\n");
TraceLog(INFO, "[%s] Sound file loaded successfully", fileName);
TraceLog(INFO, "[%s] Sample rate: %i - Channels: %i", fileName, wave.sampleRate, wave.channels);
sound.source = source;
sound.buffer = buffer;
}
return sound;
}
@@ -196,8 +225,9 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
FILE *rresFile = fopen(rresName, "rb");
if (!rresFile) printf("Error opening raylib Resource file\n");
if (!rresFile) TraceLog(WARNING, "[%s] Could not open raylib resource file", rresName);
else
{
// Read rres file (basic file check - id)
fread(&id[0], sizeof(char), 1, rresFile);
fread(&id[1], sizeof(char), 1, rresFile);
@@ -208,10 +238,10 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
if ((id[0] != 'r') && (id[1] != 'R') && (id[2] != 'E') &&(id[3] != 'S'))
{
printf("This is not a valid raylib Resource file!\n");
exit(1);
TraceLog(WARNING, "[%s] This is not a valid raylib resource file", rresName);
}
else
{
// Read number of resources embedded
fread(&numRes, sizeof(short), 1, rresFile);
@@ -239,10 +269,6 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
fread(&channels, 1, 1, rresFile); // Channels (1 - mono, 2 - stereo)
fread(&reserved, 1, 1, rresFile); // <reserved>
printf("Sample rate: %i\n", (int)sampleRate);
printf("Bits per sample: %i\n", (int)bps);
printf("Channels: %i\n", (int)channels);
wave.sampleRate = sampleRate;
wave.dataSize = infoHeader.srcSize;
wave.bitsPerSample = bps;
@@ -257,7 +283,7 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
free(data);
// Convert wave to Sound (OpenAL)
ALenum format;
ALenum format = 0;
// The OpenAL format is worked out by looking at the number of channels and the bits per sample
if (wave.channels == 1)
@@ -294,18 +320,16 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
alSourcei(source, AL_BUFFER, buffer);
// Unallocate WAV data
UnloadWAV(wave);
UnloadWave(wave);
printf("Audio file loaded...!\n");
TraceLog(INFO, "[%s] Sound loaded successfully from resource, sample rate: %i", rresName, (int)sampleRate);
sound.source = source;
sound.buffer = buffer;
}
else
{
printf("Required resource do not seem to be a valid IMAGE resource\n");
exit(2);
TraceLog(WARNING, "[%s] Required resource do not seem to be a valid SOUND resource", rresName);
}
}
else
@@ -325,10 +349,12 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
fseek(rresFile, infoHeader.size, SEEK_CUR);
}
}
}
fclose(rresFile);
}
if (!found) printf("Required resource id could not be found in the raylib Resource file!\n");
if (!found) TraceLog(WARNING, "[%s] Required resource id [%i] could not be found in the raylib resource file", rresName, resId);
return sound;
}
@@ -345,7 +371,7 @@ void PlaySound(Sound sound)
{
alSourcePlay(sound.source); // Play the sound
printf("Playing sound!\n");
//TraceLog(INFO, "Playing sound");
// Find the current position of the sound being played
// NOTE: Only work when the entire file is in a single buffer
@@ -361,22 +387,6 @@ void PlaySound(Sound sound)
//alGetSourcef(sound.source, AL_SEC_OFFSET, &result); // AL_SAMPLE_OFFSET
}
// Play a sound with extended options
// TODO: This function should be reviewed...
void PlaySoundEx(Sound sound, float timePosition, bool loop)
{
// TODO: Review
// Change the current position (e.g. skip some part of the sound)
// NOTE: Only work when the entire file is in a single buffer
//alSourcei(sound.source, AL_BYTE_OFFSET, int(position * sampleRate));
alSourcePlay(sound.source); // Play the sound
if (loop) alSourcei(sound.source, AL_LOOPING, AL_TRUE);
else alSourcei(sound.source, AL_LOOPING, AL_FALSE);
}
// Pause a sound
void PauseSound(Sound sound)
{
@@ -390,7 +400,7 @@ void StopSound(Sound sound)
}
// Check if a sound is playing
bool IsPlaying(Sound sound)
bool SoundIsPlaying(Sound sound)
{
bool playing = false;
ALint state;
@@ -402,19 +412,249 @@ bool IsPlaying(Sound sound)
}
// Set volume for a sound
void SetVolume(Sound sound, float volume)
void SetSoundVolume(Sound sound, float volume)
{
alSourcef(sound.source, AL_GAIN, volume);
}
// Set pitch for a sound
void SetPitch(Sound sound, float pitch)
void SetSoundPitch(Sound sound, float pitch)
{
alSourcef(sound.source, AL_PITCH, pitch);
}
//----------------------------------------------------------------------------------
// Module Functions Definition - Music loading and stream playing (.OGG)
//----------------------------------------------------------------------------------
// Start music playing (open stream)
void PlayMusicStream(char *fileName)
{
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);
if (currentMusic.stream == NULL) TraceLog(WARNING, "[%s] Could not open ogg audio file", fileName);
else
{
// Get file info
stb_vorbis_info info = stb_vorbis_get_info(currentMusic.stream);
currentMusic.channels = info.channels;
currentMusic.sampleRate = info.sample_rate;
TraceLog(INFO, "[%s] Ogg sample rate: %i", fileName, info.sample_rate);
TraceLog(INFO, "[%s] Ogg channels: %i", fileName, info.channels);
TraceLog(INFO, "[%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.loop = true; // We loop by default
musicEnabled = true;
// Create an audio source
alGenSources(1, &currentMusic.source); // Generate pointer to audio source
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: MusicStreamUpdate()
currentMusic.totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels;
}
}
else TraceLog(WARNING, "[%s] Music extension not recognized, it can't be loaded", fileName);
}
// Stop music playing (close stream)
void StopMusicStream()
{
if (musicEnabled)
{
alSourceStop(currentMusic.source);
EmptyMusicStream(); // Empty music buffers
alDeleteSources(1, &currentMusic.source);
alDeleteBuffers(2, currentMusic.buffers);
stb_vorbis_close(currentMusic.stream);
}
musicEnabled = false;
}
// Pause music playing
void PauseMusicStream()
{
// TODO: Record music is paused or check if music available!
alSourcePause(currentMusic.source);
}
// Check if music is playing
bool MusicIsPlaying()
{
ALenum state;
alGetSourcei(currentMusic.source, AL_SOURCE_STATE, &state);
return (state == AL_PLAYING);
}
// Set volume for music
void SetMusicVolume(float volume)
{
alSourcef(currentMusic.source, AL_GAIN, volume);
}
// Get current music time length (in seconds)
float GetMusicTimeLength()
{
float totalSeconds = stb_vorbis_stream_length_in_seconds(currentMusic.stream);
return totalSeconds;
}
// Get current music time played (in seconds)
float GetMusicTimePlayed()
{
int totalSamples = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels;
int samplesPlayed = totalSamples - currentMusic.totalSamplesLeft;
float secondsPlayed = (float)samplesPlayed / (currentMusic.sampleRate * currentMusic.channels);
return secondsPlayed;
}
//----------------------------------------------------------------------------------
// Module specific Functions Definition
//----------------------------------------------------------------------------------
// Fill music buffers with new data from music stream
static bool BufferMusicStream(ALuint buffer)
{
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
bool active = true; // We can get more data from stream (not finished)
if (musicEnabled)
{
while (size < MUSIC_BUFFER_SIZE)
{
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;
}
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");
}
return active;
}
// Empty music buffers
static void EmptyMusicStream()
{
ALuint buffer = 0;
int queued = 0;
alGetSourcei(currentMusic.source, AL_BUFFERS_QUEUED, &queued);
while(queued > 0)
{
alSourceUnqueueBuffers(currentMusic.source, 1, &buffer);
queued--;
}
}
// Update (re-fill) music buffers if data already processed
extern void UpdateMusicStream()
{
ALuint buffer = 0;
ALint processed = 0;
bool active = true;
if (musicEnabled)
{
// Get the number of already processed buffers (if any)
alGetSourcei(currentMusic.source, AL_BUFFERS_PROCESSED, &processed);
while (processed > 0)
{
// 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.loop)
{
stb_vorbis_seek_start(currentMusic.stream);
currentMusic.totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels;
active = BufferMusicStream(buffer);
}
}
// 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--;
}
ALenum state;
alGetSourcei(currentMusic.source, AL_SOURCE_STATE, &state);
if ((state != AL_PLAYING) && active) alSourcePlay(currentMusic.source);
if (!active) StopMusicStream();
}
}
// Load WAV file into Wave structure
static Wave LoadWAV(char *fileName)
static Wave LoadWAV(const char *fileName)
{
// Basic WAV headers structs
typedef struct {
@@ -450,48 +690,46 @@ static Wave LoadWAV(char *fileName)
if (!wavFile)
{
printf("Could not open WAV file.\n");
exit(1);
TraceLog(WARNING, "[%s] Could not open WAV file", fileName);
}
else
{
// Read in the first chunk into the struct
fread(&riffHeader, sizeof(RiffHeader), 1, wavFile);
// Check for RIFF and WAVE tags
if ((riffHeader.chunkID[0] != 'R' ||
riffHeader.chunkID[1] != 'I' ||
riffHeader.chunkID[2] != 'F' ||
riffHeader.chunkID[3] != 'F') ||
(riffHeader.format[0] != 'W' ||
riffHeader.format[1] != 'A' ||
riffHeader.format[2] != 'V' ||
riffHeader.format[3] != 'E'))
printf("Invalid RIFF or WAVE Header");
if (((riffHeader.chunkID[0] != 'R') || (riffHeader.chunkID[1] != 'I') || (riffHeader.chunkID[2] != 'F') || (riffHeader.chunkID[3] != 'F')) ||
((riffHeader.format[0] != 'W') || (riffHeader.format[1] != 'A') || (riffHeader.format[2] != 'V') || (riffHeader.format[3] != 'E')))
{
TraceLog(WARNING, "[%s] Invalid RIFF or WAVE Header", fileName);
}
else
{
// Read in the 2nd chunk for the wave info
fread(&waveFormat, sizeof(WaveFormat), 1, wavFile);
// Check for fmt tag
if (waveFormat.subChunkID[0] != 'f' ||
waveFormat.subChunkID[1] != 'm' ||
waveFormat.subChunkID[2] != 't' ||
waveFormat.subChunkID[3] != ' ')
printf("Invalid Wave Format");
if ((waveFormat.subChunkID[0] != 'f') || (waveFormat.subChunkID[1] != 'm') ||
(waveFormat.subChunkID[2] != 't') || (waveFormat.subChunkID[3] != ' '))
{
TraceLog(WARNING, "[%s] Invalid Wave format", fileName);
}
else
{
// Check for extra parameters;
if (waveFormat.subChunkSize > 16)
fseek(wavFile, sizeof(short), SEEK_CUR);
if (waveFormat.subChunkSize > 16) fseek(wavFile, sizeof(short), SEEK_CUR);
// Read in the the last byte of data before the sound file
fread(&waveData, sizeof(WaveData), 1, wavFile);
// Check for data tag
if (waveData.subChunkID[0] != 'd' ||
waveData.subChunkID[1] != 'a' ||
waveData.subChunkID[2] != 't' ||
waveData.subChunkID[3] != 'a')
printf("Invalid data header");
if ((waveData.subChunkID[0] != 'd') || (waveData.subChunkID[1] != 'a') ||
(waveData.subChunkID[2] != 't') || (waveData.subChunkID[3] != 'a'))
{
TraceLog(WARNING, "[%s] Invalid data header", fileName);
}
else
{
// Allocate memory for data
wave.data = (unsigned char *)malloc(sizeof(unsigned char) * waveData.subChunkSize);
@@ -504,15 +742,62 @@ static Wave LoadWAV(char *fileName)
wave.channels = waveFormat.numChannels;
wave.bitsPerSample = waveFormat.bitsPerSample;
TraceLog(INFO, "[%s] Wave file loaded successfully", fileName);
}
}
}
fclose(wavFile);
}
return wave;
}
// Unload WAV file data
static void UnloadWAV(Wave wave)
// Load OGG file into Wave structure
static Wave LoadOGG(char *fileName)
{
Wave wave;
stb_vorbis *oggFile = stb_vorbis_open_filename(fileName, NULL, NULL);
stb_vorbis_info info = stb_vorbis_get_info(oggFile);
wave.sampleRate = info.sample_rate;
wave.bitsPerSample = 16;
wave.channels = info.channels;
TraceLog(DEBUG, "[%s] Ogg sample rate: %i", fileName, info.sample_rate);
TraceLog(DEBUG, "[%s] Ogg channels: %i", fileName, info.channels);
int totalSamplesLength = (stb_vorbis_stream_length_in_samples(oggFile) * info.channels);
wave.dataSize = totalSamplesLength*sizeof(short); // Size must be in bytes
TraceLog(DEBUG, "[%s] Samples length: %i", fileName, totalSamplesLength);
float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile);
TraceLog(DEBUG, "[%s] Total seconds: %f", fileName, totalSeconds);
if (totalSeconds > 10) TraceLog(WARNING, "[%s] Ogg audio lenght is larger than 10 seconds (%f), that's a big file in memory, consider music streaming", fileName, totalSeconds);
int totalSamples = totalSeconds*info.sample_rate*info.channels;
TraceLog(DEBUG, "[%s] Total samples calculated: %i", fileName, totalSamples);
//short *data
wave.data = malloc(sizeof(short)*totalSamplesLength);
int samplesObtained = stb_vorbis_get_samples_short_interleaved(oggFile, info.channels, wave.data, totalSamplesLength);
TraceLog(DEBUG, "[%s] Samples obtained: %i", fileName, samplesObtained);
stb_vorbis_close(oggFile);
return wave;
}
// Unload Wave data
static void UnloadWave(Wave wave)
{
free(wave.data);
}
// TODO: Ogg data loading
//static Ogg LoadOGG(char *fileName) { }

View File

@@ -28,15 +28,19 @@
#include "raylib.h"
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
#include <GLFW/glfw3.h> // GLFW3 lib: Windows, OpenGL context and Input management
//#include <GL/gl.h> // OpenGL functions (GLFW3 already includes gl.h)
#include <stdio.h> // Standard input / output lib
#include <stdlib.h> // Declares malloc() and free() for memory management, rand()
#include <time.h> // Useful to initialize random seed
#include <math.h> // Math related functions, tan() on SetPerspective
#include "vector3.h" // Basic Vector3 functions
#include <math.h> // Math related functions, tan() used to set perspective
//#include "vector3.h" // Basic Vector3 functions, not required any more, replaced by raymath
#include "utils.h" // WritePNG() function
#include "raymath.h" // Required for data type Matrix and Matrix functions
//#define GLFW_DLL // Using GLFW DLL on Windows -> No, we use static version!
//----------------------------------------------------------------------------------
@@ -47,7 +51,7 @@
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef Color pixel;
// ...
//----------------------------------------------------------------------------------
// Global Variables Definition
@@ -62,7 +66,7 @@ static double targetTime = 0; // Desired time for one frame, if 0
static int windowWidth, windowHeight; // Required to switch between windowed/fullscren mode (F11)
static const char *windowTitle; // Required to switch between windowed/fullscren mode (F11)
static int exitKey = GLFW_KEY_ESCAPE;
static int exitKey = GLFW_KEY_ESCAPE; // Default exit key (ESC)
static bool customCursor = false; // Tracks if custom cursor has been set
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
@@ -77,23 +81,31 @@ static char currentMouseState[3] = { 0 }; // Required to check if mouse btn pr
static char previousGamepadState[32] = {0}; // Required to check if gamepad btn pressed/released once
static char currentGamepadState[32] = {0}; // Required to check if gamepad btn pressed/released once
static int previousMouseWheelY = 0; // Required to track mouse wheel variation
static int currentMouseWheelY = 0; // Required to track mouse wheel variation
static Color background = { 0, 0, 0, 0 }; // Screen background color
static bool showLogo = false;
//----------------------------------------------------------------------------------
// Other Modules Functions Declaration (required by core)
//----------------------------------------------------------------------------------
extern void LoadDefaultFont(); // [Module: text] Loads default font on InitWindow()
extern void UnloadDefaultFont(); // [Module: text] Unloads default font from GPU memory
extern void UpdateMusicStream(); // [Module: audio] Updates buffers for music streaming
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
static void InitGraphicsDevice(); // Initialize Graphics Device (OpenGL stuff)
static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed
static void ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); // GLFW3 Srolling Callback, runs on mouse wheel
static void CursorEnterCallback(GLFWwindow* window, int enter); // GLFW3 Cursor Enter Callback, cursor enters client area
static void WindowSizeCallback(GLFWwindow* window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
static void CameraLookAt(Vector3 position, Vector3 target, Vector3 up); // Setup camera view (updates MODELVIEW matrix)
static void SetPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); // Setup view projection (updates PROJECTION matrix)
static void TakeScreenshot(); // Takes a bitmap (BMP) screenshot and saves it in the same folder as executable
static void TakeScreenshot(); // Takes a screenshot and saves it in the same folder as executable
static void LogoAnimation(); // Plays raylib logo appearing animation
//----------------------------------------------------------------------------------
// Module Functions Definition - Window and OpenGL Context Functions
@@ -110,12 +122,20 @@ void InitWindowEx(int width, int height, const char* title, bool resizable, cons
{
glfwSetErrorCallback(ErrorCallback);
if (!glfwInit()) exit(1);
if (!glfwInit()) TraceLog(ERROR, "Failed to initialize GLFW");
//glfwDefaultWindowHints() // Set default windows hints
//glfwWindowHint(GLFW_SAMPLES, 4); // If called before windows creation, enables multisampling x4 (MSAA), default is 0
if (!resizable) glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable
#ifdef USE_OPENGL_33
//glfwWindowHint(GLFW_SAMPLES, 4); // Enables multisampling x4 (MSAA), default is 0
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE);
#endif
window = glfwCreateWindow(width, height, title, NULL, NULL);
windowWidth = width;
@@ -125,7 +145,7 @@ void InitWindowEx(int width, int height, const char* title, bool resizable, cons
if (!window)
{
glfwTerminate();
exit(1);
TraceLog(ERROR, "Failed to initialize Window");
}
glfwSetWindowSizeCallback(window, WindowSizeCallback);
@@ -133,25 +153,40 @@ void InitWindowEx(int width, int height, const char* title, bool resizable, cons
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, KeyCallback);
glfwSetScrollCallback(window, ScrollCallback);
glfwSwapInterval(0); // Disables GPU v-sync (if set), so frames are not limited to screen refresh rate (60Hz -> 60 FPS)
// If not set, swap interval uses GPU v-sync configuration
// Framerate can be setup using SetTargetFPS()
InitGraphicsDevice();
//------------------------------------------------------
#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2)
rlglInit(); // Init rlgl
#endif
//------------------------------------------------------
int fbWidth, fbHeight;
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
//------------------------------------------------------
rlglInitGraphicsDevice(fbWidth, fbHeight);
//------------------------------------------------------
previousTime = glfwGetTime();
LoadDefaultFont();
LoadDefaultFont(); // NOTE: External function (defined in module: text)
if (cursorImage != NULL)
{
// Load image as texture
cursor = LoadTexture(cursorImage);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
customCursor = true;
}
if (cursorImage != NULL) SetCustomCursor(cursorImage);
srand(time(NULL)); // Initialize random seed
ClearBackground(RAYWHITE); // Default background color for raylib games :P
// raylib logo appearing animation
if (showLogo)
{
SetTargetFPS(60);
LogoAnimation();
}
}
// Close Window and Terminate Context
@@ -159,6 +194,12 @@ void CloseWindow()
{
UnloadDefaultFont();
//------------------------------------------------------
#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2)
rlglClose(); // De-init rlgl
#endif
//------------------------------------------------------
glfwDestroyWindow(window);
glfwTerminate();
}
@@ -194,35 +235,51 @@ void ToggleFullscreen()
{
fullscreen = !fullscreen; // Toggle fullscreen flag
UnloadDefaultFont();
glfwDestroyWindow(window); // Destroy the current window (we will recreate it!)
// TODO: WARNING! All loaded resources are lost, we loose Context!
// NOTE: Window aspect ratio is always windowWidth / windowHeight
if (fullscreen) window = glfwCreateWindow(windowWidth, windowHeight, windowTitle, glfwGetPrimaryMonitor(), NULL); // Fullscreen mode
if (fullscreen)
{
// TODO: Get desktop window size and adapt aspect-ratio (?)
//const GLFWvidmode *mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
//windowWidth = mode->width;
//windowHeight = mode->height;
window = glfwCreateWindow(windowWidth, windowHeight, windowTitle, glfwGetPrimaryMonitor(), NULL); // Fullscreen mode
}
else window = glfwCreateWindow(windowWidth, windowHeight, windowTitle, NULL, NULL);
if (!window)
{
glfwTerminate();
exit(1);
TraceLog(ERROR, "Failed to initialize Window when switching fullscreen mode");
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, KeyCallback);
InitGraphicsDevice();
int fbWidth, fbHeight;
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
rlglInitGraphicsDevice(fbWidth, fbHeight);
LoadDefaultFont();
}
}
// Sets Background Color
void ClearBackground(Color color)
{
// Color values clamp to 0.0f(0) and 1.0f(255)
float r = (float)color.r / 255;
float g = (float)color.g / 255;
float b = (float)color.b / 255;
float a = (float)color.a / 255;
if ((color.r != background.r) || (color.g != background.g) || (color.b != background.b) || (color.a != background.a))
{
rlClearColor(color.r, color.g, color.b, color.a);
glClearColor(r, g, b, a);
background = color;
}
}
// Setup drawing canvas to start drawing
@@ -232,11 +289,14 @@ void BeginDrawing()
updateTime = currentTime - previousTime;
previousTime = currentTime;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear used buffers, Depth Buffer is used for 3D
rlClearScreenBuffers();
glLoadIdentity(); // Reset current matrix (MODELVIEW)
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
glTranslatef(0.375, 0.375, 0); // HACK to have 2D pixel-perfect drawing on OpenGL
//#ifdef USE_OPENGL_11
// rlTranslatef(0.375, 0.375, 0); // HACK to have 2D pixel-perfect drawing on OpenGL
// NOTE: Not required with OpenGL 3.3+
//#endif
}
// End canvas drawing and Swap Buffers (Double Buffering)
@@ -244,9 +304,17 @@ void EndDrawing()
{
if (customCursor && cursorOnScreen) DrawTexture(cursor, GetMouseX(), GetMouseY(), WHITE);
//------------------------------------------------------
#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2)
rlglDraw(); // Draw Buffers
#endif
//------------------------------------------------------
glfwSwapBuffers(window); // Swap back and front buffers
glfwPollEvents(); // Register keyboard/mouse events
UpdateMusicStream(); // NOTE: Function checks if music is enabled
currentTime = glfwGetTime();
drawTime = currentTime - previousTime;
previousTime = currentTime;
@@ -268,33 +336,48 @@ void EndDrawing()
// Initializes 3D mode for drawing (Camera setup)
void Begin3dMode(Camera camera)
{
//glEnable(GL_LIGHTING); // TODO: Setup proper lighting system (raylib 1.x)
//------------------------------------------------------
#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2)
rlglDraw(); // Draw Buffers
#endif
//------------------------------------------------------
glMatrixMode(GL_PROJECTION); // Switch to projection matrix
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
glPushMatrix(); // Save previous matrix, which contains the settings for the 2d ortho projection
glLoadIdentity(); // Reset current matrix (PROJECTION)
rlPushMatrix(); // Save previous matrix, which contains the settings for the 2d ortho projection
rlLoadIdentity(); // Reset current matrix (PROJECTION)
SetPerspective(45.0f, (GLfloat)windowWidth/(GLfloat)windowHeight, 0.1f, 100.0f); // Setup perspective projection
// Setup perspective projection
float aspect = (GLfloat)windowWidth/(GLfloat)windowHeight;
double top = 0.1f*tan(45.0f*PI / 360.0);
double right = top*aspect;
glMatrixMode(GL_MODELVIEW); // Switch back to modelview matrix
glLoadIdentity(); // Reset current matrix (MODELVIEW)
rlFrustum(-right, right, -top, top, 0.1f, 100.0f);
CameraLookAt(camera.position, camera.target, camera.up); // Setup Camera view
rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
// Setup Camera view
Matrix matLookAt = MatrixLookAt(camera.position, camera.target, camera.up);
rlMultMatrixf(GetMatrixVector(matLookAt)); // Multiply MODELVIEW matrix by view matrix (camera)
}
// Ends 3D mode and returns to default 2D orthographic mode
void End3dMode()
{
glMatrixMode(GL_PROJECTION); // Switch to projection matrix
glPopMatrix(); // Restore previous matrix (PROJECTION) from matrix stack
//------------------------------------------------------
#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2)
rlglDraw(); // Draw Buffers
#endif
//------------------------------------------------------
glMatrixMode(GL_MODELVIEW); // Get back to modelview matrix
glLoadIdentity(); // Reset current matrix (MODELVIEW)
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
rlPopMatrix(); // Restore previous matrix (PROJECTION) from matrix stack
glTranslatef(0.375, 0.375, 0); // HACK to ensure pixel-perfect drawing on OpenGL (after exiting 3D mode)
rlMatrixMode(RL_MODELVIEW); // Get back to modelview matrix
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
//glDisable(GL_LIGHTING); // TODO: Setup proper lighting system (raylib 1.x)
//rlTranslatef(0.375, 0.375, 0); // HACK to ensure pixel-perfect drawing on OpenGL (after exiting 3D mode)
}
// Set target FPS for the game
@@ -302,7 +385,7 @@ void SetTargetFPS(int fps)
{
targetTime = 1 / (float)fps;
printf("TargetTime per Frame: %f seconds\n", (float)targetTime);
TraceLog(INFO, "Target time per frame: %02.03f milliseconds", (float)targetTime*1000);
}
// Returns current FPS
@@ -363,6 +446,12 @@ Color Fade(Color color, float alpha)
return (Color){color.r, color.g, color.b, color.a*alpha};
}
// Activates raylib logo at startup
void ShowLogo()
{
showLogo = true;
}
//----------------------------------------------------------------------------------
// Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions
//----------------------------------------------------------------------------------
@@ -370,18 +459,18 @@ Color Fade(Color color, float alpha)
// Detect if a key has been pressed once
bool IsKeyPressed(int key)
{
bool ret = false;
bool pressed = false;
currentKeyState[key] = IsKeyDown(key);
if (currentKeyState[key] != previousKeyState[key])
{
if (currentKeyState[key]) ret = true;
if (currentKeyState[key]) pressed = true;
previousKeyState[key] = currentKeyState[key];
}
else ret = false;
else pressed = false;
return ret;
return pressed;
}
// Detect if a key is being pressed (key held down)
@@ -394,18 +483,18 @@ bool IsKeyDown(int key)
// Detect if a key has been released once
bool IsKeyReleased(int key)
{
bool ret = false;
bool released = false;
currentKeyState[key] = IsKeyUp(key);
if (currentKeyState[key] != previousKeyState[key])
{
if (currentKeyState[key]) ret = true;
if (currentKeyState[key]) released = true;
previousKeyState[key] = currentKeyState[key];
}
else ret = false;
else released = false;
return ret;
return released;
}
// Detect if a key is NOT being pressed (key not held down)
@@ -418,18 +507,18 @@ bool IsKeyUp(int key)
// Detect if a mouse button has been pressed once
bool IsMouseButtonPressed(int button)
{
bool ret = false;
bool pressed = false;
currentMouseState[button] = IsMouseButtonDown(button);
if (currentMouseState[button] != previousMouseState[button])
{
if (currentMouseState[button]) ret = true;
if (currentMouseState[button]) pressed = true;
previousMouseState[button] = currentMouseState[button];
}
else ret = false;
else pressed = false;
return ret;
return pressed;
}
// Detect if a mouse button is being pressed
@@ -442,18 +531,18 @@ bool IsMouseButtonDown(int button)
// Detect if a mouse button has been released once
bool IsMouseButtonReleased(int button)
{
bool ret = false;
bool released = false;
currentMouseState[button] = IsMouseButtonUp(button);
if (currentMouseState[button] != previousMouseState[button])
{
if (currentMouseState[button]) ret = true;
if (currentMouseState[button]) released = true;
previousMouseState[button] = currentMouseState[button];
}
else ret = false;
else released = false;
return ret;
return released;
}
// Detect if a mouse button is NOT being pressed
@@ -498,6 +587,16 @@ Vector2 GetMousePosition()
return position;
}
// Returns mouse wheel movement Y
int GetMouseWheelMove()
{
previousMouseWheelY = currentMouseWheelY;
currentMouseWheelY = 0;
return previousMouseWheelY;
}
// Detect if a gamepad is available
bool IsGamepadAvailable(int gamepad)
{
@@ -532,18 +631,18 @@ Vector2 GetGamepadMovement(int gamepad)
// Detect if a gamepad button is being pressed
bool IsGamepadButtonPressed(int gamepad, int button)
{
bool ret = false;
bool pressed = false;
currentGamepadState[button] = IsGamepadButtonDown(gamepad, button);
if (currentGamepadState[button] != previousGamepadState[button])
{
if (currentGamepadState[button]) ret = true;
if (currentGamepadState[button]) pressed = true;
previousGamepadState[button] = currentGamepadState[button];
}
else ret = false;
else pressed = false;
return ret;
return pressed;
}
bool IsGamepadButtonDown(int gamepad, int button)
@@ -553,7 +652,7 @@ bool IsGamepadButtonDown(int gamepad, int button)
buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
if (buttons[button] == GLFW_PRESS)
if ((buttons != NULL) && (buttons[button] == GLFW_PRESS))
{
return true;
}
@@ -563,18 +662,18 @@ bool IsGamepadButtonDown(int gamepad, int button)
// Detect if a gamepad button is NOT being pressed
bool IsGamepadButtonReleased(int gamepad, int button)
{
bool ret = false;
bool released = false;
currentGamepadState[button] = IsGamepadButtonUp(gamepad, button);
if (currentGamepadState[button] != previousGamepadState[button])
{
if (currentGamepadState[button]) ret = true;
if (currentGamepadState[button]) released = true;
previousGamepadState[button] = currentGamepadState[button];
}
else ret = false;
else released = false;
return ret;
return released;
}
bool IsGamepadButtonUp(int gamepad, int button)
@@ -584,7 +683,7 @@ bool IsGamepadButtonUp(int gamepad, int button)
buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
if (buttons[button] == GLFW_RELEASE)
if ((buttons != NULL) && (buttons[button] == GLFW_RELEASE))
{
return true;
}
@@ -598,8 +697,13 @@ bool IsGamepadButtonUp(int gamepad, int button)
// GLFW3 Error Callback, runs on GLFW3 error
static void ErrorCallback(int error, const char *description)
{
printf(description);
//fprintf(stderr, description);
TraceLog(WARNING, "[GLFW3 Error] Code: %i Decription: %s", error, description);
}
// GLFW3 Srolling Callback, runs on mouse wheel
static void ScrollCallback(GLFWwindow* window, double xoffset, double yoffset)
{
currentMouseWheelY = (int)yoffset;
}
// GLFW3 Keyboard Callback, runs on key pressed
@@ -629,113 +733,19 @@ static void CursorEnterCallback(GLFWwindow* window, int enter)
// GLFW3 WindowSize Callback, runs when window is resized
static void WindowSizeCallback(GLFWwindow* window, int width, int height)
{
InitGraphicsDevice(); // If window is resized, graphics device is re-initialized
// NOTE: Aspect ratio does not change, so, image can be deformed
}
// Initialize Graphics Device (OpenGL stuff)
static void InitGraphicsDevice()
{
int fbWidth, fbHeight;
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
glViewport(0, 0, fbWidth, fbHeight); // Set viewport width and height
// If window is resized, graphics device is re-initialized (but only ortho mode)
rlglInitGraphicsDevice(fbWidth, fbHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear used buffers, depth buffer is used for 3D
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Set background color (black)
glClearDepth(1.0f); // Clear depth buffer
// Window size must be updated to be used on 3D mode to get new aspect ratio (Begin3dMode())
windowWidth = fbWidth;
windowHeight = fbHeight;
glEnable(GL_DEPTH_TEST); // Enables depth testing (required for 3D)
glDepthFunc(GL_LEQUAL); // Type of depth testing to apply
glEnable(GL_BLEND); // Enable color blending (required to work with transparencies)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Color blending function (how colors are mixed)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Improve quality of color and texture coordinate interpolation (Deprecated in OGL 3.0)
// Other options: GL_FASTEST, GL_DONT_CARE (default)
glMatrixMode(GL_PROJECTION); // Switch to PROJECTION matrix
glLoadIdentity(); // Reset current matrix (PROJECTION)
glOrtho(0, fbWidth, fbHeight, 0, 0, 1); // Config orthographic mode: top-left corner --> (0,0)
glMatrixMode(GL_MODELVIEW); // Switch back to MODELVIEW matrix
glLoadIdentity(); // Reset current matrix (MODELVIEW)
glDisable(GL_LIGHTING); // Lighting Disabled...
// TODO: Create an efficient Lighting System with proper functions (raylib 1.x)
/*
glEnable(GL_COLOR_MATERIAL); // Enable materials, causes some glMaterial atributes to track the current color (glColor)...
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // Material types and where to apply them
// NOTE: ONLY works with lighting; defines how light interacts with material
glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmbient); // Define ambient light color property
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDiffuse); // Define diffuse light color property
glLightfv(GL_LIGHT1, GL_POSITION, lightPosition); // Define light position
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1); // Enable light one (8 lights available at the same time)
*/
// TODO: Review all shapes/models are drawn CCW and enable backface culling
//glEnable(GL_CULL_FACE); // Enable backface culling (Disabled by default)
//glCullFace(GL_BACK); // Cull the Back face (default)
//glFrontFace(GL_CCW); // Front face are defined counter clockwise (default)
glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation)
// Possible options: GL_SMOOTH (Color interpolation) or GL_FLAT (no interpolation)
}
// Setup camera view (updates MODELVIEW matrix)
static void CameraLookAt(Vector3 position, Vector3 target, Vector3 up)
{
float rotMatrix[16]; // Matrix to store camera rotation
Vector3 rotX, rotY, rotZ; // Vectors to calculate camera rotations X, Y, Z (Euler)
// Construct rotation matrix from vectors
rotZ = VectorSubtract(position, target);
VectorNormalize(&rotZ);
rotY = up; // Y rotation vector
rotX = VectorCrossProduct(rotY, rotZ); // X rotation vector = Y cross Z
rotY = VectorCrossProduct(rotZ, rotX); // Recompute Y rotation = Z cross X
VectorNormalize(&rotX); // X rotation vector normalization
VectorNormalize(&rotY); // Y rotation vector normalization
rotMatrix[0] = rotX.x;
rotMatrix[1] = rotY.x;
rotMatrix[2] = rotZ.x;
rotMatrix[3] = 0.0f;
rotMatrix[4] = rotX.y;
rotMatrix[5] = rotY.y;
rotMatrix[6] = rotZ.y;
rotMatrix[7] = 0.0f;
rotMatrix[8] = rotX.z;
rotMatrix[9] = rotY.z;
rotMatrix[10] = rotZ.z;
rotMatrix[11] = 0.0f;
rotMatrix[12] = 0.0f;
rotMatrix[13] = 0.0f;
rotMatrix[14] = 0.0f;
rotMatrix[15] = 1.0f;
glMultMatrixf(rotMatrix); // Multiply MODELVIEW matrix by rotation matrix
glTranslatef(-position.x, -position.y, -position.z); // Translate eye to position
}
// Setup view projection (updates PROJECTION matrix)
static void SetPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
{
double xmin, xmax, ymin, ymax;
ymax = zNear * tan(fovy * PI / 360.0);
ymin = -ymax;
xmin = ymin * aspect;
xmax = ymax * aspect;
glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
// Background must be also re-cleared
rlClearColor(background.r, background.g, background.b, background.a);
}
// Takes a bitmap (BMP) screenshot and saves it in the same folder as executable
@@ -744,38 +754,138 @@ static void TakeScreenshot()
static int shotNum = 0; // Screenshot number, increments every screenshot take during program execution
char buffer[20]; // Buffer to store file name
int fbWidth, fbHeight;
unsigned char *imgData; // Pixel image data array
int fbWidth, fbHeight; // Frame buffer width and height
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
imgData = (unsigned char *)malloc(fbWidth * fbHeight * sizeof(unsigned char) * 4);
// NOTE: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer
glReadPixels(0, 0, fbWidth, fbHeight, GL_RGBA, GL_UNSIGNED_BYTE, imgData);
// TODO: Flip image vertically!
unsigned char *imgDataFlip = (unsigned char *)malloc(fbWidth * fbHeight * sizeof(unsigned char) * 4);
for (int y = fbHeight-1; y >= 0; y--)
{
for (int x = 0; x < (fbWidth*4); x++)
{
imgDataFlip[x + (fbHeight - y - 1)*fbWidth*4] = imgData[x + (y*fbWidth*4)];
}
}
free(imgData);
unsigned char *imgData = rlglReadScreenPixels(fbWidth, fbHeight);
sprintf(buffer, "screenshot%03i.png", shotNum);
// NOTE: BMP directly stores data flipped vertically
//WriteBitmap(buffer, imgDataPixel, fbWidth, fbHeight); // Writes pixel data array into a bitmap (BMP) file
WritePNG(buffer, imgDataFlip, fbWidth, fbHeight);
WritePNG(buffer, imgData, fbWidth, fbHeight);
free(imgDataFlip);
free(imgData);
shotNum++;
TraceLog(INFO, "[%s] Screenshot taken!", buffer);
}
static void LogoAnimation()
{
int logoPositionX = windowWidth/2 - 128;
int logoPositionY = windowHeight/2 - 128;
int framesCounter = 0;
int lettersCount = 0;
int topSideRecWidth = 16;
int leftSideRecHeight = 16;
int bottomSideRecWidth = 16;
int rightSideRecHeight = 16;
char raylib[8] = " "; // raylib text array, max 8 letters
int state = 0; // Tracking animation states (State Machine)
float alpha = 1.0; // Useful for fading
while (!WindowShouldClose() && (state != 4)) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
if (state == 0) // State 0: Small box blinking
{
framesCounter++;
if (framesCounter == 84)
{
state = 1;
framesCounter = 0; // Reset counter... will be used later...
}
}
else if (state == 1) // State 1: Top and left bars growing
{
topSideRecWidth += 4;
leftSideRecHeight += 4;
if (topSideRecWidth == 256) state = 2;
}
else if (state == 2) // State 2: Bottom and right bars growing
{
bottomSideRecWidth += 4;
rightSideRecHeight += 4;
if (bottomSideRecWidth == 256) state = 3;
}
else if (state == 3) // State 3: Letters appearing (one by one)
{
framesCounter++;
if (framesCounter/12) // Every 12 frames, one more letter!
{
lettersCount++;
framesCounter = 0;
}
switch (lettersCount)
{
case 1: raylib[0] = 'r'; break;
case 2: raylib[1] = 'a'; break;
case 3: raylib[2] = 'y'; break;
case 4: raylib[3] = 'l'; break;
case 5: raylib[4] = 'i'; break;
case 6: raylib[5] = 'b'; break;
default: break;
}
if (lettersCount >= 10) // When all letters have appeared, just fade out everything
{
alpha -= 0.02;
if (alpha <= 0)
{
alpha = 0;
state = 4;
}
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
if (state == 0)
{
if ((framesCounter/12)%2) DrawRectangle(logoPositionX, logoPositionY, 16, 16, BLACK);
}
else if (state == 1)
{
DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK);
DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK);
}
else if (state == 2)
{
DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK);
DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK);
DrawRectangle(logoPositionX + 240, logoPositionY, 16, rightSideRecHeight, BLACK);
DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, BLACK);
}
else if (state == 3)
{
DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, Fade(BLACK, alpha));
DrawRectangle(logoPositionX, logoPositionY + 16, 16, leftSideRecHeight - 32, Fade(BLACK, alpha));
DrawRectangle(logoPositionX + 240, logoPositionY + 16, 16, rightSideRecHeight - 32, Fade(BLACK, alpha));
DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, Fade(BLACK, alpha));
DrawRectangle(windowWidth/2 - 112, windowHeight/2 - 112, 224, 224, Fade(RAYWHITE, alpha));
DrawText(raylib, windowWidth/2 - 44, windowHeight/2 + 48, 50, Fade(BLACK, alpha));
}
EndDrawing();
//----------------------------------------------------------------------------------
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +1,26 @@
/*********************************************************************************************
*
* raylib 1.0.4 (www.raylib.com)
* raylib 1.1 (www.raylib.com)
*
* A simple and easy-to-use library to learn videogames programming
*
* Features:
* Library written in plain C code (C99)
* Uses C# PascalCase/camelCase notation
* Hardware accelerated with OpenGL 1.1
* Hardware accelerated with OpenGL (1.1, 3.3+ or ES2)
* Unique OpenGL abstraction layer [rlgl]
* Powerful fonts module with SpriteFonts support
* Basic 3d support for Shapes and Models
* Audio loading and playing
* Multiple textures support, including DDS and mipmaps generation
* Basic 3d support for Shapes, Models, Heightmaps and Billboards
* Powerful math module for Vector and Matrix operations [raymath]
* Audio loading and playing with streaming support
*
* Used external libs:
* GLFW3 (www.glfw.org) for window/context management and input
* GLEW for OpenGL extensions loading (3.3+ and ES2)
* stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC)
* stb_image_write (Sean Barret) for image writting (PNG)
* stb_vorbis (Sean Barret) for ogg audio loading
* OpenAL Soft for audio device/context management
* tinfl for data decompression (DEFLATE algorithm)
*
@@ -23,8 +29,9 @@
* 32bit Textures - All loaded images are converted automatically to RGBA textures
* SpriteFonts - All loaded sprite-font images are converted to RGBA and POT textures
* One custom default font is loaded automatically when InitWindow()
* If using OpenGL 3.3+ or ES2, one default shader is loaded automatically (internally defined)
*
* -- LICENSE (raylib v1.0, November 2013) --
* -- LICENSE (raylib v1.1, April 2014) --
*
* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software:
@@ -65,6 +72,7 @@
#define KEY_SPACE 32
#define KEY_ESCAPE 256
#define KEY_ENTER 257
#define KEY_BACKSPACE 259
#define KEY_RIGHT 262
#define KEY_LEFT 263
#define KEY_DOWN 264
@@ -149,6 +157,19 @@
// Boolean type
typedef enum { false, true } bool;
// Vector2 type
typedef struct Vector2 {
float x;
float y;
} Vector2;
// Vector3 type
typedef struct Vector3 {
float x;
float y;
float z;
} Vector3;
// Color type, RGBA (32bit)
typedef struct Color {
unsigned char r;
@@ -176,12 +197,13 @@ typedef struct Image {
// Texture2D type, bpp always RGBA (32bit)
// NOTE: Data stored in GPU memory
typedef struct Texture2D {
unsigned int glId;
unsigned int id; // OpenGL id
int width;
int height;
} Texture2D;
// SpriteFont one Character (Glyph) data, defined in text module
// Character type (one font glyph)
// NOTE: Defined in module: text
typedef struct Character Character;
// SpriteFont type, includes texture and charSet array data
@@ -191,19 +213,6 @@ typedef struct SpriteFont {
Character *charSet;
} SpriteFont;
// Vector2 type
typedef struct Vector2 {
float x;
float y;
} Vector2;
// Vector3 type
typedef struct Vector3 {
float x;
float y;
float z;
} Vector3;
// Camera type, defines a camera position/orientation in 3d space
typedef struct Camera {
Vector3 position;
@@ -211,15 +220,25 @@ typedef struct Camera {
Vector3 up;
} Camera;
// Basic 3d Model type
// Vertex data definning a mesh
typedef struct VertexData {
int vertexCount;
float *vertices; // 3 components per vertex
float *texcoords; // 2 components per vertex
float *normals; // 3 components per vertex
unsigned char *colors; // 4 components per vertex
} VertexData;
// 3d Model type
// NOTE: If using OpenGL 1.1, loaded in CPU (mesh); if OpenGL 3.3+ loaded in GPU (vaoId)
typedef struct Model {
int numVertices;
Vector3 *vertices;
Vector2 *texcoords;
Vector3 *normals;
VertexData mesh;
unsigned int vaoId;
unsigned int textureId;
//Matrix transform;
} Model;
// Basic Sound source and buffer
// Sound source type
typedef struct Sound {
unsigned int source;
unsigned int buffer;
@@ -263,6 +282,8 @@ int GetHexValue(Color color); // Returns hexadecim
int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0 to 1.0
void ShowLogo(); // Activates raylib logo at startup
//------------------------------------------------------------------------------------
// Input Handling Functions (Module: core)
//------------------------------------------------------------------------------------
@@ -278,6 +299,7 @@ bool IsMouseButtonUp(int button); // Detect if a mouse but
int GetMouseX(); // Returns mouse position X
int GetMouseY(); // Returns mouse position Y
Vector2 GetMousePosition(); // Returns mouse position XY
int GetMouseWheelMove(); // Returns mouse wheel movement Y
bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
Vector2 GetGamepadMovement(int gamepad); // Return axis movement vector for a gamepad
@@ -323,11 +345,12 @@ Image LoadImage(const char *fileName);
Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
Texture2D CreateTexture2D(Image image); // Create a Texture2D from Image data
Texture2D CreateTexture(Image image, bool genMipmaps); // Create a Texture2D from Image data (and generate mipmaps)
void UnloadImage(Image image); // Unload image from CPU memory (RAM)
void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, // Draw a part of a texture defined by a rectangle with 'pro' parameters
@@ -339,6 +362,7 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
SpriteFont GetDefaultFont(); // Get the default SpriteFont
SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
int fontSize, int spacing, Color tint);
@@ -354,15 +378,17 @@ const char *FormatText(const char *text, ...);
void DrawCube(Vector3 position, float width, float height, float lenght, Color color); // Draw cube
void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color); // Draw cube wires
void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float lenght, Color color); // Draw cube textured
void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
void DrawSphereWires(Vector3 centerPos, float radius, Color color); // Draw sphere wires
void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color); // Draw a plane
void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, int slicesZ, Color color); // Draw a plane with divisions
void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
void DrawGizmo(Vector3 position, bool orbits); // Draw gizmo (with or without orbits)
void DrawGizmo(Vector3 position); // Draw simple gizmo
void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale); // Draw gizmo with extended parameters
//DrawTorus(), DrawTeapot() are useless...
//------------------------------------------------------------------------------------
@@ -370,33 +396,41 @@ void DrawGizmo(Vector3 position, bool orbits);
//------------------------------------------------------------------------------------
Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
//Model LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource)
Model LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model
Model LoadCubesmap(Image cubesmap); // Load a map image as a 3d model (cubes based)
void UnloadModel(Model model); // Unload 3d model from memory
void DrawModel(Model model, Vector3 position, float scale, Color color); // Draw a model
void DrawModelEx(Model model, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a textured model
void DrawModelWires(Model model, Vector3 position, float scale, Color color); // Draw a model wires
void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model
// NOTE: The following functions work but are incomplete or require some revision
// DrawHeightmap is extremely inefficient and can impact performance up to 60%
void DrawBillboard(Camera camera, Texture2D texture, Vector3 basePos, float size, Color tint); // REVIEW: Draw a billboard (raylib 1.x)
void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 basePos, float size, Color tint); // REVIEW: Draw a billboard (raylib 1.x)
void DrawHeightmap(Image heightmap, Vector3 centerPos, Vector3 scale, Color color); // REVIEW: Draw heightmap using image map (raylib 1.x)
void DrawHeightmapEx(Image heightmap, Texture2D texture, Vector3 centerPos, Vector3 scale, Color tint); // REVIEW: Draw textured heightmap (raylib 1.x)
void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
void DrawModelEx(Model model, Vector3 position, Vector3 rotation, 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 DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture
void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
//------------------------------------------------------------------------------------
// Audio Loading and Playing Functions (Module: audio)
//------------------------------------------------------------------------------------
void InitAudioDevice(); // Initialize audio device and context
void CloseAudioDevice(); // Close the audio device and context
void CloseAudioDevice(); // Close the audio device and context (and music stream)
Sound LoadSound(char *fileName); // Load sound to memory
Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
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 IsPlaying(Sound sound); // Check if a sound is currently playing
void SetVolume(Sound sound, float volume); // Set volume for a sound (1.0 is base level)
void SetPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
bool SoundIsPlaying(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 StopMusicStream(); // Stop music playing (close stream)
void PauseMusicStream(); // Pause music playing
bool MusicIsPlaying(); // Check if music is playing
void SetMusicVolume(float volume); // Set volume for music (1.0 is max level)
float GetMusicTimeLength(); // Get current music time length (in seconds)
float GetMusicTimePlayed(); // Get current music time played (in seconds)
#ifdef __cplusplus
}

1054
src/raymath.c Normal file

File diff suppressed because it is too large Load Diff

142
src/raymath.h Normal file
View File

@@ -0,0 +1,142 @@
/*********************************************************************************************
*
* raymath
*
* Some useful functions to work with Vector3, Matrix and Quaternions
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
* 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 RAYMATH_H
#define RAYMATH_H
//#define RAYMATH_STANDALONE // NOTE: To use raymath as standalone lib, just uncomment this line
#ifndef RAYMATH_STANDALONE
#include "raylib.h" // Required for typedef: Vector3
#endif
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
#ifndef PI
#define PI 3.14159265358979323846
#endif
#define DEG2RAD (PI / 180.0)
#define RAD2DEG (180.0 / PI)
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
#ifdef RAYMATH_STANDALONE
// Vector3 type
typedef struct Vector3 {
float x;
float y;
float z;
} Vector3;
#endif
// Matrix type (OpenGL style 4x4 - right handed)
typedef struct Matrix {
float m0, m4, m8, m12;
float m1, m5, m9, m13;
float m2, m6, m10, m14;
float m3, m7, m11, m15;
} Matrix;
// Quaternion type
typedef struct Quaternion {
float x;
float y;
float z;
float w;
} Quaternion;
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
//------------------------------------------------------------------------------------
// Functions Declaration to work with Vector3
//------------------------------------------------------------------------------------
Vector3 VectorAdd(Vector3 v1, Vector3 v2); // Add two vectors
Vector3 VectorSubtract(Vector3 v1, Vector3 v2); // Substract two vectors
Vector3 VectorCrossProduct(Vector3 v1, Vector3 v2); // Calculate two vectors cross product
Vector3 VectorPerpendicular(Vector3 v); // Calculate one vector perpendicular vector
float VectorDotProduct(Vector3 v1, Vector3 v2); // Calculate two vectors dot product
float VectorLength(const Vector3 v); // Calculate vector lenght
void VectorScale(Vector3 *v, float scale); // Scale provided vector
void VectorNegate(Vector3 *v); // Negate provided vector (invert direction)
void VectorNormalize(Vector3 *v); // Normalize provided vector
float VectorDistance(Vector3 v1, Vector3 v2); // Calculate distance between two points
Vector3 VectorLerp(Vector3 v1, Vector3 v2, float amount); // Calculate linear interpolation between two vectors
Vector3 VectorReflect(Vector3 vector, Vector3 normal); // Calculate reflected vector to normal
void VectorTransform(Vector3 *v, Matrix mat); // Transforms a Vector3 with a given Matrix
Vector3 VectorZero(); // Return a Vector3 init to zero
//------------------------------------------------------------------------------------
// Functions Declaration to work with Matrix
//------------------------------------------------------------------------------------
float *GetMatrixVector(Matrix mat); // Returns an OpenGL-ready vector (glMultMatrixf)
float MatrixDeterminant(Matrix mat); // Compute matrix determinant
float MatrixTrace(Matrix mat); // Returns the trace of the matrix (sum of the values along the diagonal)
void MatrixTranspose(Matrix *mat); // Transposes provided matrix
void MatrixInvert(Matrix *mat); // Invert provided matrix
void MatrixNormalize(Matrix *mat); // Normalize provided matrix
Matrix MatrixIdentity(); // Returns identity matrix
Matrix MatrixAdd(Matrix left, Matrix right); // Add two matrices
Matrix MatrixSubstract(Matrix left, Matrix right); // Substract two matrices (left - right)
Matrix MatrixTranslate(float x, float y, float z); // Returns translation matrix
Matrix MatrixRotate(float angleX, float angleY, float angleZ); // Returns rotation matrix
Matrix MatrixRotateAroundAxis(Vector3 axis, float angle); // Returns rotation matrix for an angle around an specified axis
Matrix MatrixRotateAroundAxis2(Vector3 axis, float angle); // Returns rotation matrix for an angle around an specified axis (test another implemntation)
Matrix MatrixFromQuaternion(Quaternion q); // Returns rotation matrix for a given quaternion
Matrix MatrixRotateX(float angle); // Returns x-rotation matrix (angle in radians)
Matrix MatrixRotateY(float angle); // Returns y-rotation matrix (angle in radians)
Matrix MatrixRotateZ(float angle); // Returns z-rotation matrix (angle in radians)
Matrix MatrixScale(float x, float y, float z); // Returns scaling matrix
Matrix MatrixTransform(Vector3 translation, Vector3 rotation, Vector3 scale); // Returns transformation matrix for a given translation, rotation and scale
Matrix MatrixMultiply(Matrix left, Matrix right); // Returns two matrix multiplication
Matrix MatrixFrustum(double left, double right, double bottom, double top, double near, double far); // Returns perspective projection matrix
Matrix MatrixPerspective(double fovy, double aspect, double near, double far); // Returns perspective projection matrix
Matrix MatrixOrtho(double left, double right, double bottom, double top, double near, double far); // Returns orthographic projection matrix
Matrix MatrixLookAt(Vector3 position, Vector3 target, Vector3 up); // Returns camera look-at matrix (view matrix)
void PrintMatrix(Matrix m); // Print matrix utility
//------------------------------------------------------------------------------------
// Functions Declaration to work with Quaternions
//------------------------------------------------------------------------------------
float QuaternionLength(Quaternion quat); // Calculates the length of a quaternion
void QuaternionNormalize(Quaternion *q); // Normalize provided quaternion
Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2); // Calculate two quaternion multiplication
Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float slerp); // Calculates spherical linear interpolation between two quaternions
Quaternion QuaternionFromMatrix(Matrix matrix); // Returns a quaternion from a given rotation matrix
Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle); // Returns rotation quaternion for an angle around an axis
Matrix QuaternionToMatrix(Quaternion q); // Calculates the matrix from the given quaternion
void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle); // Returns the axis and the angle for a given quaternion
#ifdef __cplusplus
}
#endif
#endif // RAYMATH_H

1765
src/rlgl.c Normal file

File diff suppressed because it is too large Load Diff

148
src/rlgl.h Normal file
View File

@@ -0,0 +1,148 @@
/*********************************************************************************************
*
* 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 - Same behaviour as OpenGL 3.3+ (NOT TESTED)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
* 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: Model
#include "utils.h" // Required for function TraceLog()
#endif
#include "raymath.h" // Required for data type Matrix and Matrix functions
// Select desired OpenGL version
//#define USE_OPENGL_11
//#define USE_OPENGL_33
//#define USE_OPENGL_ES2
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
#define MAX_LINES_BATCH 8192 // NOTE: Be careful with limits!
#define MAX_TRIANGLES_BATCH 4096 // NOTE: Be careful with limits!
#define MAX_QUADS_BATCH 8192 // NOTE: Be careful with limits!
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef unsigned char byte;
typedef enum { RL_PROJECTION, RL_MODELVIEW, RL_TEXTURE } MatrixMode;
typedef enum { RL_LINES, RL_TRIANGLES, RL_QUADS } DrawMode;
#ifdef RLGL_STANDALONE
typedef struct {
int vertexCount;
float *vertices; // 3 components per vertex
float *texcoords; // 2 components per vertex
float *normals; // 3 components per vertex
unsigned char *colors;
} VertexData;
typedef struct Model {
VertexData mesh;
unsigned int vaoId;
unsigned int textureId;
//Matrix transform;
} Model;
#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(); // Push the current matrix to stack
void rlPopMatrix(); // Pop lattest inserted matrix from stack
void rlLoadIdentity(); // 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(); // 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(); // Disable texture usage
void rlDeleteTextures(unsigned int id); // Delete OpenGL texture from GPU
void rlDeleteVertexArrays(unsigned int id); // Unload vertex data from GPU memory
void rlClearColor(byte r, byte g, byte b, byte a); // Clear color buffer with color
void rlClearScreenBuffers(); // Clear used screen buffers (color and depth)
//------------------------------------------------------------------------------------
// Functions Declaration - rlgl functionality
//------------------------------------------------------------------------------------
#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2)
void rlglInit(); // Initialize rlgl (shaders, VAO, VBO...)
void rlglClose(); // De-init rlgl
void rlglDraw(); // Draw VAOs
unsigned int rlglLoadModel(VertexData mesh);
unsigned int rlglLoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int format);
#endif
void rlglDrawModel(Model model, Vector3 position, Vector3 rotation, Vector3 scale, Color color, bool wires);
void rlglInitGraphicsDevice(int fbWidth, int fbHeight); // Initialize Graphics Device (OpenGL stuff)
unsigned int rlglLoadTexture(unsigned char *data, int width, int height, bool genMipmaps); // Load in GPU OpenGL texture
byte *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2)
void PrintProjectionMatrix(); // DEBUG: Print projection matrix
void PrintModelviewMatrix(); // DEBUG: Print modelview matrix
#endif
#ifdef __cplusplus
}
#endif
#endif // RLGL_H

View File

@@ -25,11 +25,17 @@
#include "raylib.h"
#include <GL/gl.h> // OpenGL functions
#include <stdlib.h> // Required for abs() function
#include <math.h> // Math related functions, sin() and cos() used on DrawCircle*
// sqrt() and pow() and abs() used on CheckCollision*
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
// Security check in case no USE_OPENGL_* defined
#if !defined(USE_OPENGL_11) && !defined(USE_OPENGL_33) && !defined(USE_OPENGL_ES2)
#define USE_OPENGL_11
#endif
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
@@ -57,141 +63,102 @@
// Draw a pixel
void DrawPixel(int posX, int posY, Color color)
{
glBegin(GL_POINTS);
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2i(posX, posY);
glEnd();
// NOTE: Alternative method to draw a pixel (point)
/*
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); // Deprecated on OGL 3.0
glPointSize(1.0f);
glPoint((float)posX, (float)posY, 0.0f);
*/
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(posX, posY);
rlVertex2i(posX + 1, posY + 1);
rlEnd();
}
// Draw a pixel (Vector version)
void DrawPixelV(Vector2 position, Color color)
{
glBegin(GL_POINTS);
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2f(position.x, position.y);
glEnd();
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(position.x, position.y);
rlVertex2i(position.x + 1, position.y + 1);
rlEnd();
}
// Draw a line
void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color)
{
glBegin(GL_LINES);
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2i(startPosX, startPosY);
glVertex2i(endPosX, endPosY);
glEnd();
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(startPosX, startPosY);
rlVertex2i(endPosX, endPosY);
rlEnd();
}
// Draw a line (Vector version)
void DrawLineV(Vector2 startPos, Vector2 endPos, Color color)
{
glBegin(GL_LINES);
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2f(startPos.x, startPos.y);
glVertex2f(endPos.x, endPos.y);
glEnd();
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(startPos.x, startPos.y);
rlVertex2f(endPos.x, endPos.y);
rlEnd();
}
// Draw a color-filled circle
// TODO: Review, on some GPUs is drawn with a weird transparency (GL_POLYGON_SMOOTH issue?)
void DrawCircle(int centerX, int centerY, float radius, Color color)
{
glEnable(GL_POLYGON_SMOOTH);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); // Deprecated on OGL 3.0
DrawPoly((Vector2){centerX, centerY}, 360, radius, 0, color);
glDisable(GL_POLYGON_SMOOTH);
// NOTE: Alternative method to draw a circle (point)
/*
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); // Deprecated on OGL 3.0
glPointSize(radius);
glPoint((float)centerX, (float)centerY, 0.0f);
*/
}
// Draw a gradient-filled circle
// NOTE: Gradient goes from center (color1) to border (color2)
void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2)
{
glBegin(GL_TRIANGLE_FAN);
glColor4ub(color1.r, color1.g, color1.b, color1.a);
glVertex2i(centerX, centerY);
glColor4ub(color2.r, color2.g, color2.b, color2.a);
for (int i=0; i <= 360; i++) //i++ --> Step = 1.0 pixels
rlBegin(RL_TRIANGLES);
for (int i=0; i < 360; i += 2)
{
glVertex2f(centerX + sin(DEG2RAD*i) * radius, centerY + cos(DEG2RAD*i) * radius);
rlColor4ub(color1.r, color1.g, color1.b, color1.a);
rlVertex2i(centerX, centerY);
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
rlVertex2f(centerX + sin(DEG2RAD*i) * radius, centerY + cos(DEG2RAD*i) * radius);
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
rlVertex2f(centerX + sin(DEG2RAD*(i+2)) * radius, centerY + cos(DEG2RAD*(i+2)) * radius);
}
glEnd();
rlEnd();
}
// Draw a color-filled circle (Vector version)
void DrawCircleV(Vector2 center, float radius, Color color)
{
glEnable(GL_POLYGON_SMOOTH);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
glBegin(GL_TRIANGLE_FAN);
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2f(center.x, center.y);
for (int i=0; i <= 360; i++) //i++ --> Step = 1.0 pixels
rlBegin(RL_TRIANGLES);
for (int i=0; i < 360; i += 2)
{
glVertex2f(center.x + sin(DEG2RAD*i) * radius, center.y + cos(DEG2RAD*i) * radius);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(center.x, center.y);
rlVertex2f(center.x + sin(DEG2RAD*i) * radius, center.y + cos(DEG2RAD*i) * radius);
rlVertex2f(center.x + sin(DEG2RAD*(i+2)) * radius, center.y + cos(DEG2RAD*(i+2)) * radius);
}
glEnd();
glDisable(GL_POLYGON_SMOOTH);
rlEnd();
}
// Draw circle outline
void DrawCircleLines(int centerX, int centerY, float radius, Color color)
{
glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
glBegin(GL_LINE_LOOP);
glColor4ub(color.r, color.g, color.b, color.a);
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
// NOTE: Circle outline is drawn pixel by pixel every degree (0 to 360)
for (int i=0; i < 360; i++)
{
glVertex2f(centerX + sin(DEG2RAD*i) * radius, centerY + cos(DEG2RAD*i) * radius);
rlVertex2f(centerX + sin(DEG2RAD*i) * radius, centerY + cos(DEG2RAD*i) * radius);
rlVertex2f(centerX + sin(DEG2RAD*(i+1)) * radius, centerY + cos(DEG2RAD*(i+1)) * radius);
}
glEnd();
// NOTE: Alternative method to draw circle outline
/*
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
DrawCircle(centerX, centerY, radius, color);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
*/
glDisable(GL_LINE_SMOOTH);
rlEnd();
}
// Draw a color-filled rectangle
void DrawRectangle(int posX, int posY, int width, int height, Color color)
{
glBegin(GL_QUADS);
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2i(posX, posY);
glVertex2i(posX + width, posY);
glVertex2i(posX + width, posY + height);
glVertex2i(posX, posY + height);
glEnd();
Vector2 position = { (float)posX, (float)posY };
Vector2 size = { (float)width, (float)height };
DrawRectangleV(position, size, color);
}
// Draw a color-filled rectangle
@@ -204,73 +171,102 @@ void DrawRectangleRec(Rectangle rec, Color color)
// NOTE: Gradient goes from bottom (color1) to top (color2)
void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2)
{
glBegin(GL_QUADS);
glColor4ub(color1.r, color1.g, color1.b, color1.a);
glVertex2i(posX, posY);
glVertex2i(posX + width, posY);
glColor4ub(color2.r, color2.g, color2.b, color2.a);
glVertex2i(posX + width, posY + height);
glVertex2i(posX, posY + height);
glEnd();
rlBegin(RL_TRIANGLES);
rlColor4ub(color1.r, color1.g, color1.b, color1.a); rlVertex2i(posX, posY);
rlColor4ub(color2.r, color2.g, color2.b, color2.a); rlVertex2i(posX, posY + height);
rlColor4ub(color2.r, color2.g, color2.b, color2.a); rlVertex2i(posX + width, posY + height);
rlColor4ub(color1.r, color1.g, color1.b, color1.a); rlVertex2i(posX, posY);
rlColor4ub(color2.r, color2.g, color2.b, color2.a); rlVertex2i(posX + width, posY + height);
rlColor4ub(color1.r, color1.g, color1.b, color1.a); rlVertex2i(posX + width, posY);
rlEnd();
}
// Draw a color-filled rectangle (Vector version)
void DrawRectangleV(Vector2 position, Vector2 size, Color color)
{
glBegin(GL_QUADS);
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2i(position.x, position.y);
glVertex2i(position.x + size.x, position.y);
glVertex2i(position.x + size.x, position.y + size.y);
glVertex2i(position.x, position.y + size.y);
glEnd();
#ifdef USE_OPENGL_11
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();
#endif
#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2)
// NOTE: This shape uses QUADS to avoid drawing order issues (view rlglDraw)
rlEnableTexture(1); // Default white texture
rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a);
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
rlTexCoord2f(0.0f, 0.0f);
rlVertex2f(position.x, position.y);
rlTexCoord2f(0.0f, 1.0f);
rlVertex2f(position.x, position.y + size.y);
rlTexCoord2f(1.0f, 1.0f);
rlVertex2f(position.x + size.x, position.y + size.y);
rlTexCoord2f(1.0f, 0.0f);
rlVertex2f(position.x + size.x, position.y);
rlEnd();
rlDisableTexture();
#endif
}
// Draw rectangle outline
void DrawRectangleLines(int posX, int posY, int width, int height, Color color)
{
//glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
//glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(posX + 1, posY + 1);
rlVertex2i(posX + width, posY + 1);
// NOTE: Lines are rasterized using the "Diamond Exit" rule so, it's nearly impossible to obtain a pixel-perfect engine
// NOTE: Recommended trying to avoid using lines, at least >1.0f pixel lines with anti-aliasing (glLineWidth function)
rlVertex2i(posX + width, posY + 1);
rlVertex2i(posX + width, posY + height);
glBegin(GL_LINE_LOOP);
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2i(posX, posY);
glVertex2i(posX + width - 1, posY);
glVertex2i(posX + width - 1, posY + height - 1);
glVertex2i(posX, posY + height - 1);
glEnd();
rlVertex2i(posX + width, posY + height);
rlVertex2i(posX + 1, posY + height);
// NOTE: Alternative method to draw rectangle outline
/*
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
DrawRectangle(posX, posY, width - 1, height - 1, color);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
*/
//glDisable(GL_LINE_SMOOTH);
rlVertex2i(posX + 1, posY + height);
rlVertex2i(posX + 1, posY + 1);
rlEnd();
}
// Draw a triangle
void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
{
glBegin(GL_TRIANGLES);
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2f(v1.x, v1.y);
glVertex2f(v2.x, v2.y);
glVertex2f(v3.x, v3.y);
glEnd();
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(v1.x, v1.y);
rlVertex2f(v2.x, v2.y);
rlVertex2f(v3.x, v3.y);
rlEnd();
}
void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
{
glBegin(GL_LINE_LOOP);
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2f(v1.x, v1.y);
glVertex2f(v2.x, v2.y);
glVertex2f(v3.x, v3.y);
glEnd();
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(v1.x, v1.y);
rlVertex2f(v2.x, v2.y);
rlVertex2f(v2.x, v2.y);
rlVertex2f(v3.x, v3.y);
rlVertex2f(v3.x, v3.y);
rlVertex2f(v1.x, v1.y);
rlEnd();
}
// Draw a regular polygon of n sides (Vector version)
@@ -278,20 +274,21 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col
{
if (sides < 3) sides = 3;
glPushMatrix();
glTranslatef(center.x, center.y, 0);
glRotatef(rotation, 0, 0, 1);
rlPushMatrix();
rlTranslatef(center.x, center.y, 0.0);
rlRotatef(rotation, 0, 0, 1);
glBegin(GL_TRIANGLE_FAN);
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2f(0, 0);
for (int i=0; i <= sides; i++)
rlBegin(RL_TRIANGLES);
for (int i=0; i < 360; i += 360/sides)
{
glVertex2f(radius*cos(i*2*PI/sides), radius*sin(i*2*PI/sides));
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(0, 0);
rlVertex2f(sin(DEG2RAD*i) * radius, cos(DEG2RAD*i) * radius);
rlVertex2f(sin(DEG2RAD*(i+360/sides)) * radius, cos(DEG2RAD*(i+360/sides)) * radius);
}
glEnd();
glPopMatrix();
rlEnd();
rlPopMatrix();
}
// Draw a closed polygon defined by points
@@ -300,19 +297,16 @@ void DrawPolyEx(Vector2 *points, int numPoints, Color color)
{
if (numPoints >= 3)
{
glEnable(GL_POLYGON_SMOOTH);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
glBegin(GL_POLYGON);
glColor4ub(color.r, color.g, color.b, color.a);
for (int i = 0; i < numPoints; i++)
for (int i = 0; i < numPoints - 2; i++)
{
glVertex2f(points[i].x, points[i].y);
rlVertex2f(points[i].x, points[i].y);
rlVertex2f(points[i+1].x, points[i+1].y);
rlVertex2f(points[i+2].x, points[i+2].y);
}
glEnd();
glDisable(GL_POLYGON_SMOOTH);
rlEnd();
}
}
@@ -322,22 +316,22 @@ void DrawPolyExLines(Vector2 *points, int numPoints, Color color)
{
if (numPoints >= 2)
{
//glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
//glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
glBegin(GL_LINE_LOOP);
glColor4ub(color.r, color.g, color.b, color.a);
for (int i = 0; i < numPoints; i++)
for (int i = 0; i < numPoints - 1; i++)
{
glVertex2f(points[i].x, points[i].y);
rlVertex2f(points[i].x, points[i].y);
rlVertex2f(points[i+1].x, points[i+1].y);
}
glEnd();
//glDisable(GL_LINE_SMOOTH);
rlEnd();
}
}
//----------------------------------------------------------------------------------
// Module Functions Definition - Collision Detection functions
//----------------------------------------------------------------------------------
// Check if point is inside rectangle
bool CheckCollisionPointRec(Vector2 point, Rectangle rec)
{

14
src/simple150.frag Normal file
View File

@@ -0,0 +1,14 @@
#version 150
uniform sampler2D texture0;
in vec2 fragTexCoord;
in vec4 fragColor;
out vec4 pixelColor;
void main()
{
// Output pixel color
pixelColor = texture(texture0, fragTexCoord) * fragColor;
}

21
src/simple150.vert Normal file
View File

@@ -0,0 +1,21 @@
#version 150
uniform mat4 projectionMatrix;
uniform mat4 modelviewMatrix;
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in vec4 vertexColor;
out vec2 fragTexCoord;
out vec4 fragColor;
void main()
{
// Pass some variables to the fragment shader
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;
// Apply all matrix transformations to vertex
gl_Position = projectionMatrix * modelviewMatrix * vec4(vertexPosition, 1.0);
}

514
src/stb_image_write.h Normal file
View File

@@ -0,0 +1,514 @@
/* stbiw-0.92 - public domain - http://nothings.org/stb/stb_image_write.h
writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010
no warranty implied; use at your own risk
Before #including,
#define STB_IMAGE_WRITE_IMPLEMENTATION
in the file that you want to have the implementation.
ABOUT:
This header file is a library for writing images to C stdio. It could be
adapted to write to memory or a general streaming interface; let me know.
The PNG output is not optimal; it is 20-50% larger than the file
written by a decent optimizing implementation. This library is designed
for source code compactness and simplicitly, not optimal image file size
or run-time performance.
USAGE:
There are three functions, one for each image file format:
int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
Each function returns 0 on failure and non-0 on success.
The functions create an image file defined by the parameters. The image
is a rectangle of pixels stored from left-to-right, top-to-bottom.
Each pixel contains 'comp' channels of data stored interleaved with 8-bits
per channel, in the following order: 1=L, 2=LA, 3=RGB, 4=RGBA. (L is
luminance, i.e. monochrome "color", i.e. grey value.) The rectangle is
'w' pixels wide and 'h' pixels tall. The *data pointer points to the
first byte of the top-left-most pixel. For PNG, "stride_in_bytes" is
the distance in bytes from the first byte of a row of pixels to the
first byte of the next row of pixels. Other file formats assume the
first byte of the each row of pixels begins immediately after the last
byte of the previous row.
PNG creates output files with the same number of components as the input.
The BMP and TGA formats expand Y to RGB in the file format. BMP does not
output alpha.
PNG supports writing rectangles of data even when the bytes storing rows of
data are not consecutive in memory (e.g. sub-rectangles of a larger image),
by supplying the stride between the beginning of adjacent rows. The other
formats do not. (Thus you cannot write an in-memory BMP through the BMP
writer, both because it is in BGR order and because it may have padding
at the end of the line.)
*/
#ifndef INCLUDE_STB_IMAGE_WRITE_H
#define INCLUDE_STB_IMAGE_WRITE_H
#ifdef __cplusplus
extern "C" {
#endif
extern int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
extern int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
extern int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
#ifdef __cplusplus
}
#endif
#endif//INCLUDE_STB_IMAGE_WRITE_H
#ifdef STB_IMAGE_WRITE_IMPLEMENTATION
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
typedef unsigned int stbiw_uint32;
typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
static void writefv(FILE *f, const char *fmt, va_list v)
{
while (*fmt) {
switch (*fmt++) {
case ' ': break;
case '1': { unsigned char x = (unsigned char) va_arg(v, int); fputc(x,f); break; }
case '2': { int x = va_arg(v,int); unsigned char b[2];
b[0] = (unsigned char) x; b[1] = (unsigned char) (x>>8);
fwrite(b,2,1,f); break; }
case '4': { stbiw_uint32 x = va_arg(v,int); unsigned char b[4];
b[0]=(unsigned char)x; b[1]=(unsigned char)(x>>8);
b[2]=(unsigned char)(x>>16); b[3]=(unsigned char)(x>>24);
fwrite(b,4,1,f); break; }
default:
assert(0);
return;
}
}
}
static void write3(FILE *f, unsigned char a, unsigned char b, unsigned char c)
{
unsigned char arr[3];
arr[0] = a, arr[1] = b, arr[2] = c;
fwrite(arr, 3, 1, f);
}
static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad)
{
unsigned char bg[3] = { 255, 0, 255}, px[3];
stbiw_uint32 zero = 0;
int i,j,k, j_end;
if (y <= 0)
return;
if (vdir < 0)
j_end = -1, j = y-1;
else
j_end = y, j = 0;
for (; j != j_end; j += vdir) {
for (i=0; i < x; ++i) {
unsigned char *d = (unsigned char *) data + (j*x+i)*comp;
if (write_alpha < 0)
fwrite(&d[comp-1], 1, 1, f);
switch (comp) {
case 1:
case 2: write3(f, d[0],d[0],d[0]);
break;
case 4:
if (!write_alpha) {
// composite against pink background
for (k=0; k < 3; ++k)
px[k] = bg[k] + ((d[k] - bg[k]) * d[3])/255;
write3(f, px[1-rgb_dir],px[1],px[1+rgb_dir]);
break;
}
/* FALLTHROUGH */
case 3:
write3(f, d[1-rgb_dir],d[1],d[1+rgb_dir]);
break;
}
if (write_alpha > 0)
fwrite(&d[comp-1], 1, 1, f);
}
fwrite(&zero,scanline_pad,1,f);
}
}
static int outfile(char const *filename, int rgb_dir, int vdir, int x, int y, int comp, void *data, int alpha, int pad, const char *fmt, ...)
{
FILE *f;
if (y < 0 || x < 0) return 0;
f = fopen(filename, "wb");
if (f) {
va_list v;
va_start(v, fmt);
writefv(f, fmt, v);
va_end(v);
write_pixels(f,rgb_dir,vdir,x,y,comp,data,alpha,pad);
fclose(f);
}
return f != NULL;
}
int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
{
int pad = (-x*3) & 3;
return outfile(filename,-1,-1,x,y,comp,(void *) data,0,pad,
"11 4 22 4" "4 44 22 444444",
'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
}
int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
{
int has_alpha = !(comp & 1);
return outfile(filename, -1,-1, x, y, comp, (void *) data, has_alpha, 0,
"111 221 2222 11", 0,0,2, 0,0,0, 0,0,x,y, 24+8*has_alpha, 8*has_alpha);
}
// stretchy buffer; stbi__sbpush() == vector<>::push_back() -- stbi__sbcount() == vector<>::size()
#define stbi__sbraw(a) ((int *) (a) - 2)
#define stbi__sbm(a) stbi__sbraw(a)[0]
#define stbi__sbn(a) stbi__sbraw(a)[1]
#define stbi__sbneedgrow(a,n) ((a)==0 || stbi__sbn(a)+n >= stbi__sbm(a))
#define stbi__sbmaybegrow(a,n) (stbi__sbneedgrow(a,(n)) ? stbi__sbgrow(a,n) : 0)
#define stbi__sbgrow(a,n) stbi__sbgrowf((void **) &(a), (n), sizeof(*(a)))
#define stbi__sbpush(a, v) (stbi__sbmaybegrow(a,1), (a)[stbi__sbn(a)++] = (v))
#define stbi__sbcount(a) ((a) ? stbi__sbn(a) : 0)
#define stbi__sbfree(a) ((a) ? free(stbi__sbraw(a)),0 : 0)
static void *stbi__sbgrowf(void **arr, int increment, int itemsize)
{
int m = *arr ? 2*stbi__sbm(*arr)+increment : increment+1;
void *p = realloc(*arr ? stbi__sbraw(*arr) : 0, itemsize * m + sizeof(int)*2);
assert(p);
if (p) {
if (!*arr) ((int *) p)[1] = 0;
*arr = (void *) ((int *) p + 2);
stbi__sbm(*arr) = m;
}
return *arr;
}
static unsigned char *stbi__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount)
{
while (*bitcount >= 8) {
stbi__sbpush(data, (unsigned char) *bitbuffer);
*bitbuffer >>= 8;
*bitcount -= 8;
}
return data;
}
static int stbi__zlib_bitrev(int code, int codebits)
{
int res=0;
while (codebits--) {
res = (res << 1) | (code & 1);
code >>= 1;
}
return res;
}
static unsigned int stbi__zlib_countm(unsigned char *a, unsigned char *b, int limit)
{
int i;
for (i=0; i < limit && i < 258; ++i)
if (a[i] != b[i]) break;
return i;
}
static unsigned int stbi__zhash(unsigned char *data)
{
stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
return hash;
}
#define stbi__zlib_flush() (out = stbi__zlib_flushf(out, &bitbuf, &bitcount))
#define stbi__zlib_add(code,codebits) \
(bitbuf |= (code) << bitcount, bitcount += (codebits), stbi__zlib_flush())
#define stbi__zlib_huffa(b,c) stbi__zlib_add(stbi__zlib_bitrev(b,c),c)
// default huffman tables
#define stbi__zlib_huff1(n) stbi__zlib_huffa(0x30 + (n), 8)
#define stbi__zlib_huff2(n) stbi__zlib_huffa(0x190 + (n)-144, 9)
#define stbi__zlib_huff3(n) stbi__zlib_huffa(0 + (n)-256,7)
#define stbi__zlib_huff4(n) stbi__zlib_huffa(0xc0 + (n)-280,8)
#define stbi__zlib_huff(n) ((n) <= 143 ? stbi__zlib_huff1(n) : (n) <= 255 ? stbi__zlib_huff2(n) : (n) <= 279 ? stbi__zlib_huff3(n) : stbi__zlib_huff4(n))
#define stbi__zlib_huffb(n) ((n) <= 143 ? stbi__zlib_huff1(n) : stbi__zlib_huff2(n))
#define stbi__ZHASH 16384
unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
{
static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 };
static unsigned char lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 };
static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 };
static unsigned char disteb[] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 };
unsigned int bitbuf=0;
int i,j, bitcount=0;
unsigned char *out = NULL;
unsigned char **hash_table[stbi__ZHASH]; // 64KB on the stack!
if (quality < 5) quality = 5;
stbi__sbpush(out, 0x78); // DEFLATE 32K window
stbi__sbpush(out, 0x5e); // FLEVEL = 1
stbi__zlib_add(1,1); // BFINAL = 1
stbi__zlib_add(1,2); // BTYPE = 1 -- fixed huffman
for (i=0; i < stbi__ZHASH; ++i)
hash_table[i] = NULL;
i=0;
while (i < data_len-3) {
// hash next 3 bytes of data to be compressed
int h = stbi__zhash(data+i)&(stbi__ZHASH-1), best=3;
unsigned char *bestloc = 0;
unsigned char **hlist = hash_table[h];
int n = stbi__sbcount(hlist);
for (j=0; j < n; ++j) {
if (hlist[j]-data > i-32768) { // if entry lies within window
int d = stbi__zlib_countm(hlist[j], data+i, data_len-i);
if (d >= best) best=d,bestloc=hlist[j];
}
}
// when hash table entry is too long, delete half the entries
if (hash_table[h] && stbi__sbn(hash_table[h]) == 2*quality) {
memcpy(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality);
stbi__sbn(hash_table[h]) = quality;
}
stbi__sbpush(hash_table[h],data+i);
if (bestloc) {
// "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal
h = stbi__zhash(data+i+1)&(stbi__ZHASH-1);
hlist = hash_table[h];
n = stbi__sbcount(hlist);
for (j=0; j < n; ++j) {
if (hlist[j]-data > i-32767) {
int e = stbi__zlib_countm(hlist[j], data+i+1, data_len-i-1);
if (e > best) { // if next match is better, bail on current match
bestloc = NULL;
break;
}
}
}
}
if (bestloc) {
int d = data+i - bestloc; // distance back
assert(d <= 32767 && best <= 258);
for (j=0; best > lengthc[j+1]-1; ++j);
stbi__zlib_huff(j+257);
if (lengtheb[j]) stbi__zlib_add(best - lengthc[j], lengtheb[j]);
for (j=0; d > distc[j+1]-1; ++j);
stbi__zlib_add(stbi__zlib_bitrev(j,5),5);
if (disteb[j]) stbi__zlib_add(d - distc[j], disteb[j]);
i += best;
} else {
stbi__zlib_huffb(data[i]);
++i;
}
}
// write out final bytes
for (;i < data_len; ++i)
stbi__zlib_huffb(data[i]);
stbi__zlib_huff(256); // end of block
// pad with 0 bits to byte boundary
while (bitcount)
stbi__zlib_add(0,1);
for (i=0; i < stbi__ZHASH; ++i)
(void) stbi__sbfree(hash_table[i]);
{
// compute adler32 on input
unsigned int i=0, s1=1, s2=0, blocklen = data_len % 5552;
int j=0;
while (j < data_len) {
for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1;
s1 %= 65521, s2 %= 65521;
j += blocklen;
blocklen = 5552;
}
stbi__sbpush(out, (unsigned char) (s2 >> 8));
stbi__sbpush(out, (unsigned char) s2);
stbi__sbpush(out, (unsigned char) (s1 >> 8));
stbi__sbpush(out, (unsigned char) s1);
}
*out_len = stbi__sbn(out);
// make returned pointer freeable
memmove(stbi__sbraw(out), out, *out_len);
return (unsigned char *) stbi__sbraw(out);
}
unsigned int stbi__crc32(unsigned char *buffer, int len)
{
static unsigned int crc_table[256];
unsigned int crc = ~0u;
int i,j;
if (crc_table[1] == 0)
for(i=0; i < 256; i++)
for (crc_table[i]=i, j=0; j < 8; ++j)
crc_table[i] = (crc_table[i] >> 1) ^ (crc_table[i] & 1 ? 0xedb88320 : 0);
for (i=0; i < len; ++i)
crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
return ~crc;
}
#define stbi__wpng4(o,a,b,c,d) ((o)[0]=(unsigned char)(a),(o)[1]=(unsigned char)(b),(o)[2]=(unsigned char)(c),(o)[3]=(unsigned char)(d),(o)+=4)
#define stbi__wp32(data,v) stbi__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
#define stbi__wptag(data,s) stbi__wpng4(data, s[0],s[1],s[2],s[3])
static void stbi__wpcrc(unsigned char **data, int len)
{
unsigned int crc = stbi__crc32(*data - len - 4, len+4);
stbi__wp32(*data, crc);
}
static unsigned char stbi__paeth(int a, int b, int c)
{
int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c);
if (pa <= pb && pa <= pc) return (unsigned char) a;
if (pb <= pc) return (unsigned char) b;
return (unsigned char) c;
}
unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
{
int ctype[5] = { -1, 0, 4, 2, 6 };
unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
unsigned char *out,*o, *filt, *zlib;
signed char *line_buffer;
int i,j,k,p,zlen;
if (stride_bytes == 0)
stride_bytes = x * n;
filt = (unsigned char *) malloc((x*n+1) * y); if (!filt) return 0;
line_buffer = (signed char *) malloc(x * n); if (!line_buffer) { free(filt); return 0; }
for (j=0; j < y; ++j) {
static int mapping[] = { 0,1,2,3,4 };
static int firstmap[] = { 0,1,0,5,6 };
int *mymap = j ? mapping : firstmap;
int best = 0, bestval = 0x7fffffff;
for (p=0; p < 2; ++p) {
for (k= p?best:0; k < 5; ++k) {
int type = mymap[k],est=0;
unsigned char *z = pixels + stride_bytes*j;
for (i=0; i < n; ++i)
switch (type) {
case 0: line_buffer[i] = z[i]; break;
case 1: line_buffer[i] = z[i]; break;
case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break;
case 4: line_buffer[i] = (signed char) (z[i] - stbi__paeth(0,z[i-stride_bytes],0)); break;
case 5: line_buffer[i] = z[i]; break;
case 6: line_buffer[i] = z[i]; break;
}
for (i=n; i < x*n; ++i) {
switch (type) {
case 0: line_buffer[i] = z[i]; break;
case 1: line_buffer[i] = z[i] - z[i-n]; break;
case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break;
case 4: line_buffer[i] = z[i] - stbi__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
case 6: line_buffer[i] = z[i] - stbi__paeth(z[i-n], 0,0); break;
}
}
if (p) break;
for (i=0; i < x*n; ++i)
est += abs((signed char) line_buffer[i]);
if (est < bestval) { bestval = est; best = k; }
}
}
// when we get here, best contains the filter type, and line_buffer contains the data
filt[j*(x*n+1)] = (unsigned char) best;
memcpy(filt+j*(x*n+1)+1, line_buffer, x*n);
}
free(line_buffer);
zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory
free(filt);
if (!zlib) return 0;
// each tag requires 12 bytes of overhead
out = (unsigned char *) malloc(8 + 12+13 + 12+zlen + 12);
if (!out) return 0;
*out_len = 8 + 12+13 + 12+zlen + 12;
o=out;
memcpy(o,sig,8); o+= 8;
stbi__wp32(o, 13); // header length
stbi__wptag(o, "IHDR");
stbi__wp32(o, x);
stbi__wp32(o, y);
*o++ = 8;
*o++ = (unsigned char) ctype[n];
*o++ = 0;
*o++ = 0;
*o++ = 0;
stbi__wpcrc(&o,13);
stbi__wp32(o, zlen);
stbi__wptag(o, "IDAT");
memcpy(o, zlib, zlen); o += zlen; free(zlib);
stbi__wpcrc(&o, zlen);
stbi__wp32(o,0);
stbi__wptag(o, "IEND");
stbi__wpcrc(&o,0);
assert(o == out + *out_len);
return out;
}
int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes)
{
FILE *f;
int len;
unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
if (!png) return 0;
f = fopen(filename, "wb");
if (!f) { free(png); return 0; }
fwrite(png, 1, len, f);
fclose(f);
free(png);
return 1;
}
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
/* Revision history
0.92 (2010-08-01)
casts to unsigned char to fix warnings
0.91 (2010-07-17)
first public release
0.90 first internal release
*/

View File

@@ -11,6 +11,7 @@
// Get the latest version and other information at:
// http://nothings.org/stb_vorbis/
// Todo:
//
// - seeking (note you can seek yourself using the pushdata API)
@@ -25,6 +26,9 @@
//
// All of these limitations may be removed in future versions.
#include "stb_vorbis.h"
#ifndef STB_VORBIS_HEADER_ONLY
// global configuration settings (e.g. set these in the project/makefile),

View File

@@ -11,6 +11,7 @@
// Get the latest version and other information at:
// http://nothings.org/stb_vorbis/
// Todo:
//
// - seeking (note you can seek yourself using the pushdata API)
@@ -25,12 +26,6 @@
//
// All of these limitations may be removed in future versions.
//////////////////////////////////////////////////////////////////////////////
//
// HEADER BEGINS HERE
//
#ifndef STB_VORBIS_INCLUDE_STB_VORBIS_H
#define STB_VORBIS_INCLUDE_STB_VORBIS_H

View File

@@ -28,17 +28,21 @@
#include "raylib.h"
#include <GL/gl.h> // OpenGL functions
#include <stdlib.h> // Declares malloc() and free() for memory management
#include <string.h> // String management functions (just strlen() is used)
#include <stdarg.h> // Used for functions with variable number of parameters (FormatText())
#include "stb_image.h" // Used to read image data (multiple formats support)
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
#include "utils.h" // Required for function GetExtendion()
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
#define FIRST_CHAR 32
#define FONT_FIRST_CHAR 32
#define MAX_FONTCHARS 128
#define MAX_FORMATTEXT_LENGTH 50
#define BIT_CHECK(a,b) ((a) & (1<<(b)))
@@ -48,13 +52,13 @@
typedef unsigned char byte;
// SpriteFont one Character (Glyph) data
struct Character {
typedef struct Character {
int value; //char value = ' '; (int)value = 32;
int x;
int y;
int w;
int h;
};
} Character;
//----------------------------------------------------------------------------------
// Global variables
@@ -62,6 +66,11 @@ struct Character {
static SpriteFont defaultFont; // Default font provided by raylib
// NOTE: defaultFont is loaded on InitWindow and disposed on CloseWindow [module: core]
//----------------------------------------------------------------------------------
// Other Modules Functions Declaration (required by text)
//----------------------------------------------------------------------------------
//...
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
@@ -69,7 +78,6 @@ static bool PixelIsMagenta(Color p); // Check if a pixel is magen
static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Character **charSet); // Parse image pixel data to obtain character set measures
static int GetNextPOT(int num); // Calculate next power-of-two value for a given value
static SpriteFont LoadRBMF(const char *fileName); // Load a rBMF font file (raylib BitMap Font)
static const char *GetExtension(const char *fileName);
//----------------------------------------------------------------------------------
// Module Functions Definition
@@ -77,8 +85,10 @@ static const char *GetExtension(const char *fileName);
extern void LoadDefaultFont()
{
defaultFont.numChars = 96; // We know our default font has 94 chars
defaultFont.texture.width = 128; // We know our default font texture is 128 pixels width
defaultFont.texture.height = 64; // We know our default font texture is 64 pixels height
Image image;
image.width = 128; // We know our default font image is 128 pixels width
image.height = 64; // We know our default font image is 64 pixels height
// Default font is directly defined here (data generated from a sprite font image)
// This way, we reconstruct SpriteFont without creating large global variables
@@ -114,6 +124,29 @@ extern void LoadDefaultFont()
7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 5, 6, 5, 7, 6, 6, 6, 6, 6, 6, 7, 6, 7, 7, 6, 6, 6, 2, 7, 2, 3, 5,
2, 5, 5, 5, 5, 5, 4, 5, 5, 1, 2, 5, 2, 5, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 3, 1, 3, 4, 4 };
// Re-construct image from defaultFontData and generate OpenGL texture
//----------------------------------------------------------------------
image.pixels = (Color *)malloc(image.width * image.height * sizeof(Color));
for (int i = 0; i < image.width * image.height; i++) image.pixels[i] = BLANK; // Initialize array
int counter = 0; // Font data elements counter
// Fill imgData with defaultFontData (convert from bit to pixel!)
for (int i = 0; i < image.width * image.height; i += 32)
{
for (int j = 31; j >= 0; j--)
{
if (BIT_CHECK(defaultFontData[counter], j)) image.pixels[i+j] = WHITE;
}
counter++;
if (counter > 256) counter = 0; // Security check...
}
defaultFont.texture = CreateTexture(image, false); // Convert loaded image to OpenGL texture
UnloadImage(image);
// Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, numChars
//------------------------------------------------------------------------------
@@ -125,7 +158,7 @@ extern void LoadDefaultFont()
for (int i = 0; i < defaultFont.numChars; i++)
{
defaultFont.charSet[i].value = FIRST_CHAR + i;
defaultFont.charSet[i].value = FONT_FIRST_CHAR + i; // First char is 32
defaultFont.charSet[i].x = currentPosX;
defaultFont.charSet[i].y = charsDivisor + currentLine * (charsHeight + charsDivisor);
defaultFont.charSet[i].w = charsWidth[i];
@@ -145,52 +178,12 @@ extern void LoadDefaultFont()
else currentPosX = testPosX;
}
// Re-construct image from defaultFontData and generate OpenGL texture
//----------------------------------------------------------------------
Color *imgDataPixel = (Color *)malloc(defaultFont.texture.width * defaultFont.texture.height * sizeof(Color));
for (int i = 0; i < defaultFont.texture.width * defaultFont.texture.height; i++) imgDataPixel[i] = BLANK; // Initialize array
int counter = 0; // Font data elements counter
// Fill imgData with defaultFontData (convert from bit to pixel!)
for (int i = 0; i < defaultFont.texture.width * defaultFont.texture.height; i += 32)
{
for (int j = 31; j >= 0; j--)
{
if (BIT_CHECK(defaultFontData[counter], j)) imgDataPixel[i+j] = WHITE;
}
counter++;
if (counter > 256) counter = 0; // Security check...
}
// Convert loaded data to OpenGL texture
//----------------------------------------
GLuint id;
glGenTextures(1, &id); // Generate pointer to the texture
glBindTexture(GL_TEXTURE_2D, id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); // Set texture to clamp on x-axis
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); // Set texture to clamp on y-axis
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, defaultFont.texture.width, defaultFont.texture.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgDataPixel);
// NOTE: Not using mipmappings (texture for 2D drawing)
// At this point we have the image converted to texture and uploaded to GPU
free(imgDataPixel); // Now we can free loaded data from RAM memory
defaultFont.texture.glId = id;
TraceLog(INFO, "Default font loaded successfully");
}
extern void UnloadDefaultFont()
{
glDeleteTextures(1, &defaultFont.texture.glId);
rlDeleteTextures(defaultFont.texture.id);
free(defaultFont.charSet);
}
@@ -205,6 +198,8 @@ SpriteFont LoadSpriteFont(const char* fileName)
{
SpriteFont spriteFont;
Image image;
// Check file extension
if (strcmp(GetExtension(fileName),"rbmf") == 0) spriteFont = LoadRBMF(fileName);
else
@@ -235,12 +230,14 @@ SpriteFont LoadSpriteFont(const char* fileName)
// At this point we have a pixel array with all the data...
TraceLog(INFO, "[%s] SpriteFont image loaded: %i x %i", fileName, imgWidth, imgHeight);
// Process bitmap Font pixel data to get measures (Character array)
// spriteFont.charSet data is filled inside the function and memory is allocated!
int numChars = ParseImageData(imgDataPixel, imgWidth, imgHeight, &spriteFont.charSet);
fprintf(stderr, "SpriteFont data parsed correctly!\n");
fprintf(stderr, "SpriteFont num chars: %i\n", numChars);
TraceLog(INFO, "[%s] SpriteFont data parsed correctly", fileName);
TraceLog(INFO, "[%s] SpriteFont num chars detected: %i", fileName, numChars);
spriteFont.numChars = numChars;
@@ -264,29 +261,17 @@ SpriteFont LoadSpriteFont(const char* fileName)
}
}
fprintf(stderr, "SpriteFont texture converted to POT: %i %i\n", potWidth, potHeight);
TraceLog(WARNING, "SpriteFont texture converted to POT: %ix%i", potWidth, potHeight);
}
free(imgDataPixel);
// Convert loaded data to OpenGL texture
//----------------------------------------
GLuint id;
glGenTextures(1, &id); // Generate pointer to the texture
image.pixels = imgDataPixelPOT;
image.width = potWidth;
image.height = potHeight;
glBindTexture(GL_TEXTURE_2D, id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, potWidth, potHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgDataPixelPOT);
// NOTE: Not using mipmappings (texture for 2D drawing)
// At this point we have the image converted to texture and uploaded to GPU
free(imgDataPixelPOT); // Now we can free loaded data from RAM memory
spriteFont.texture.glId = id;
spriteFont.texture.width = potWidth;
spriteFont.texture.height = potHeight;
spriteFont.texture = CreateTexture(image, false); // Convert loaded image to OpenGL texture
UnloadImage(image);
}
return spriteFont;
@@ -295,7 +280,7 @@ SpriteFont LoadSpriteFont(const char* fileName)
// Unload SpriteFont from GPU memory
void UnloadSpriteFont(SpriteFont spriteFont)
{
glDeleteTextures(1, &spriteFont.texture.glId);
rlDeleteTextures(spriteFont.texture.id);
free(spriteFont.charSet);
}
@@ -329,48 +314,45 @@ void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int f
if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
else scaleFactor = (float)fontSize / spriteFont.charSet[0].h;
glDisable(GL_LIGHTING); // When drawing text, disable LIGHTING
glEnable(GL_TEXTURE_2D);
rlEnableTexture(spriteFont.texture.id);
glBindTexture(GL_TEXTURE_2D, spriteFont.texture.glId);
glPushMatrix();
// Optimized to use one draw call per string
glBegin(GL_QUADS);
rlBegin(RL_QUADS);
for(int i = 0; i < length; i++)
{
c = spriteFont.charSet[(int)text[i] - FIRST_CHAR];
c = spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR];
glColor4ub(tint.r, tint.g, tint.b, tint.a);
glNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
glTexCoord2f((float)c.x / spriteFont.texture.width, (float)c.y / spriteFont.texture.height); glVertex2f(positionX, position.y);
glTexCoord2f((float)c.x / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height); glVertex2f(positionX, position.y + (c.h) * scaleFactor);
glTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height); glVertex2f(positionX + (c.w) * scaleFactor, position.y + (c.h) * scaleFactor);
glTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)c.y / spriteFont.texture.height); glVertex2f(positionX + (c.w) * scaleFactor, position.y);
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
positionX += ((spriteFont.charSet[(int)text[i] - FIRST_CHAR].w) * scaleFactor + spacing);
rlTexCoord2f((float)c.x / spriteFont.texture.width, (float)c.y / spriteFont.texture.height);
rlVertex2f(positionX, position.y);
rlTexCoord2f((float)c.x / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height);
rlVertex2f(positionX, position.y + (c.h) * scaleFactor);
rlTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height);
rlVertex2f(positionX + (c.w) * scaleFactor, position.y + (c.h) * scaleFactor);
rlTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)c.y / spriteFont.texture.height);
rlVertex2f(positionX + (c.w) * scaleFactor, position.y);
positionX += ((spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR].w) * scaleFactor + spacing);
}
glEnd();
rlEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
rlDisableTexture();
}
// Formatting of text with variables to 'embed'
const char *FormatText(const char *text, ...)
{
int length = strlen(text);
char *buffer = malloc(length + 20); // We add 20 extra characters, should be enough... :P
static char buffer[MAX_FORMATTEXT_LENGTH];
va_list args;
va_start(args, text);
vsprintf(buffer, text, args); // NOTE: We use vsprintf() defined in <stdarg.h>
vsprintf(buffer, text, args);
va_end(args);
//strcat(buffer, "\0"); // We add a end-of-string mark at the end (not needed)
return buffer;
}
@@ -393,7 +375,7 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int
for (int i = 0; i < len; i++)
{
textWidth += spriteFont.charSet[(int)text[i] - FIRST_CHAR].w;
textWidth += spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR].w;
}
if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
@@ -425,20 +407,17 @@ void DrawFPS(int posX, int posY)
if (counter < refreshRate)
{
sprintf(buffer, "%2.0f FPS", fps);
DrawText(buffer, posX, posY, 20, LIME);
counter++;
}
else
{
fps = GetFPS();
refreshRate = fps;
sprintf(buffer, "%2.0f FPS", fps);
DrawText(buffer, posX, posY, 20, LIME);
counter = 0;
}
sprintf(buffer, "%2.0f FPS", fps);
DrawText(buffer, posX, posY, 20, LIME);
}
//----------------------------------------------------------------------------------
@@ -491,7 +470,7 @@ static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Char
while((xPosToRead < imgWidth) &&
!PixelIsMagenta((imgDataPixel[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*imgWidth + xPosToRead])))
{
tempCharSet[index].value = FIRST_CHAR + index;
tempCharSet[index].value = FONT_FIRST_CHAR + index;
tempCharSet[index].x = xPosToRead;
tempCharSet[index].y = lineSpacing + lineToRead * (charHeight + lineSpacing);
tempCharSet[index].h = charHeight;
@@ -571,7 +550,7 @@ static SpriteFont LoadRBMF(const char *fileName)
fread(&rbmfHeader, sizeof(rbmfInfoHeader), 1, rbmfFile);
//printf("rBMF info: %i %i %i %i\n", rbmfHeader.imgWidth, rbmfHeader.imgHeight, rbmfHeader.numChars, rbmfHeader.charHeight);
TraceLog(INFO, "[%s] Loading rBMF file, size: %ix%i, numChars: %i, charHeight: %i", fileName, rbmfHeader.imgWidth, rbmfHeader.imgHeight, rbmfHeader.numChars, rbmfHeader.charHeight);
spriteFont.numChars = (int)rbmfHeader.numChars;
@@ -588,8 +567,6 @@ static SpriteFont LoadRBMF(const char *fileName)
for(int i = 0; i < spriteFont.numChars; i++) fread(&rbmfCharWidthData[i], sizeof(unsigned char), 1, rbmfFile);
printf("Just read image data and width data... Starting image reconstruction...");
// Re-construct image from rbmfFileData
//-----------------------------------------
image.pixels = (Color *)malloc(image.width * image.height * sizeof(Color));
@@ -609,13 +586,12 @@ static SpriteFont LoadRBMF(const char *fileName)
counter++;
}
printf("Image reconstructed correctly... now converting it to texture...");
spriteFont.texture = CreateTexture2D(image);
TraceLog(INFO, "[%s] Image reconstructed correctly, now converting it to texture", fileName);
spriteFont.texture = CreateTexture(image, false);
UnloadImage(image); // Unload image data
printf("Starting charSet reconstruction...\n");
TraceLog(INFO, "[%s] Starting charSet reconstruction", fileName);
// Reconstruct charSet using rbmfCharWidthData, rbmfHeader.charHeight, charsDivisor, rbmfHeader.numChars
spriteFont.charSet = (Character *)malloc(spriteFont.numChars * sizeof(Character)); // Allocate space for our character data
@@ -644,11 +620,9 @@ static SpriteFont LoadRBMF(const char *fileName)
spriteFont.charSet[i].y = charsDivisor + currentLine * (rbmfHeader.charHeight + charsDivisor);
}
else currentPosX = testPosX;
//printf("Char %i data: %i %i %i %i\n", spriteFont.charSet[i].value, spriteFont.charSet[i].x, spriteFont.charSet[i].y, spriteFont.charSet[i].w, spriteFont.charSet[i].h);
}
printf("CharSet reconstructed correctly... Data should be ready...\n");
TraceLog(INFO, "[%s] rBMF file loaded correctly as SpriteFont", fileName);
fclose(rbmfFile);
@@ -658,9 +632,12 @@ static SpriteFont LoadRBMF(const char *fileName)
return spriteFont;
}
static const char *GetExtension(const char *fileName)
// Generate a sprite font from TTF data (font size required)
static SpriteFont GenerateFromTTF(const char *fileName, int fontSize)
{
const char *dot = strrchr(fileName, '.');
if(!dot || dot == fileName) return "";
return dot + 1;
SpriteFont font;
// TODO: Load TTF and generate bitmap font and chars data
return font;
}

View File

@@ -28,12 +28,18 @@
#include "raylib.h"
#include <GL/gl.h> // OpenGL functions
#include <stdlib.h> // Declares malloc() and free() for memory management
#include <string.h> // Required for strcmp(), strrchr(), strncmp()
#include "stb_image.h" // Used to read image data (multiple formats support)
#include "utils.h" // rRES data decompression utility function
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
// Security check in case no USE_OPENGL_* defined
#if !defined(USE_OPENGL_11) && !defined(USE_OPENGL_33) && !defined(USE_OPENGL_ES2)
#define USE_OPENGL_11
#endif
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
@@ -44,15 +50,30 @@
//----------------------------------------------------------------------------------
typedef unsigned char byte;
typedef struct {
unsigned char *data; // Image raw data
int width; // Image base width
int height; // Image base height
//int bpp; // bytes per pixel
//int components; // num color components
int mipmaps; // Mipmap levels, 1 by default
int compFormat; // Compressed data format, 0 if no compression
} ImageEx;
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
// It's lonely here...
//----------------------------------------------------------------------------------
// Other Modules Functions Declaration (required by text)
//----------------------------------------------------------------------------------
//...
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
// No private (static) functions in this module (.c file)
static ImageEx LoadDDS(const char *fileName);
//----------------------------------------------------------------------------------
// Module Functions Definition
@@ -63,6 +84,19 @@ Image LoadImage(const char *fileName)
{
Image image;
// Initial values
image.pixels = NULL;
image.width = 0;
image.height = 0;
if ((strcmp(GetExtension(fileName),"png") == 0) ||
(strcmp(GetExtension(fileName),"bmp") == 0) ||
(strcmp(GetExtension(fileName),"tga") == 0) ||
(strcmp(GetExtension(fileName),"jpg") == 0) ||
(strcmp(GetExtension(fileName),"gif") == 0) ||
(strcmp(GetExtension(fileName),"psd") == 0) ||
(strcmp(GetExtension(fileName),"pic") == 0))
{
int imgWidth;
int imgHeight;
int imgBpp;
@@ -71,6 +105,8 @@ Image LoadImage(const char *fileName)
// Force loading to 4 components (RGBA)
byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
if (imgData != NULL)
{
// Convert array to pixel array for working convenience
image.pixels = (Color *)malloc(imgWidth * imgHeight * sizeof(Color));
@@ -90,6 +126,41 @@ Image LoadImage(const char *fileName)
image.width = imgWidth;
image.height = imgHeight;
TraceLog(INFO, "[%s] Image loaded successfully", fileName);
}
else TraceLog(WARNING, "[%s] Image could not be loaded", fileName);
}
else if (strcmp(GetExtension(fileName),"dds") == 0)
{
// NOTE: DDS uncompressed images can also be loaded (discarding mipmaps...)
ImageEx imageDDS = LoadDDS(fileName);
if (imageDDS.compFormat == 0)
{
image.pixels = (Color *)malloc(imageDDS.width * imageDDS.height * sizeof(Color));
image.width = imageDDS.width;
image.height = imageDDS.height;
int pix = 0;
for (int i = 0; i < (image.width * image.height * 4); i += 4)
{
image.pixels[pix].r = imageDDS.data[i];
image.pixels[pix].g = imageDDS.data[i+1];
image.pixels[pix].b = imageDDS.data[i+2];
image.pixels[pix].a = imageDDS.data[i+3];
pix++;
}
free(imageDDS.data);
TraceLog(INFO, "[%s] Image loaded successfully", fileName);
}
else TraceLog(WARNING, "[%s] Compressed image data could not be loaded", fileName);
}
else TraceLog(WARNING, "[%s] Image extension not recognized, it can't be loaded", fileName);
// ALTERNATIVE: We can load pixel data directly into Color struct pixels array,
// to do that struct data alignment should be the right one (4 byte); it is.
//image.pixels = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
@@ -100,7 +171,8 @@ Image LoadImage(const char *fileName)
// Load an image from rRES file (raylib Resource)
Image LoadImageFromRES(const char *rresName, int resId)
{
// NOTE: rresName could be directly a char array with all the data!!! ---> TODO!
// TODO: rresName could be directly a char array with all the data! --> support it! :P
Image image;
bool found = false;
@@ -113,8 +185,9 @@ Image LoadImageFromRES(const char *rresName, int resId)
FILE *rresFile = fopen(rresName, "rb");
if (!rresFile) printf("Error opening raylib Resource file\n");
if (!rresFile) TraceLog(WARNING, "[%s] Could not open raylib resource file", rresName);
else
{
// Read rres file (basic file check - id)
fread(&id[0], sizeof(char), 1, rresFile);
fread(&id[1], sizeof(char), 1, rresFile);
@@ -125,10 +198,10 @@ Image LoadImageFromRES(const char *rresName, int resId)
if ((id[0] != 'r') && (id[1] != 'R') && (id[2] != 'E') &&(id[3] != 'S'))
{
printf("This is not a valid raylib Resource file!\n");
exit(1);
TraceLog(WARNING, "[%s] This is not a valid raylib resource file", rresName);
}
else
{
// Read number of resources embedded
fread(&numRes, sizeof(short), 1, rresFile);
@@ -144,8 +217,8 @@ Image LoadImageFromRES(const char *rresName, int resId)
if (infoHeader.type == 0) // IMAGE data type
{
// TODO: Check data compression type
// NOTE: We suppose compression type 2 (DEFLATE - default)
short imgWidth, imgHeight;
char colorFormat, mipmaps;
@@ -154,9 +227,6 @@ Image LoadImageFromRES(const char *rresName, int resId)
fread(&colorFormat, 1, 1, rresFile); // Image data color format (default: RGBA 32 bit)
fread(&mipmaps, 1, 1, rresFile); // Mipmap images included (default: 0)
printf("Image width: %i\n", (int)imgWidth);
printf("Image height: %i\n", (int)imgHeight);
image.width = (int)imgWidth;
image.height = (int)imgHeight;
@@ -182,11 +252,12 @@ Image LoadImageFromRES(const char *rresName, int resId)
free(imgData);
free(data);
TraceLog(INFO, "[%s] Image loaded successfully from resource, size: %ix%i", rresName, image.width, image.height);
}
else
{
printf("Required resource do not seem to be a valid IMAGE resource\n");
exit(2);
TraceLog(WARNING, "[%s] Required resource do not seem to be a valid IMAGE resource", rresName);
}
}
else
@@ -206,10 +277,12 @@ Image LoadImageFromRES(const char *rresName, int resId)
fseek(rresFile, infoHeader.size, SEEK_CUR);
}
}
}
fclose(rresFile);
}
if (!found) printf("Required resource id could not be found in the raylib Resource file!\n");
if (!found) TraceLog(WARNING, "[%s] Required resource id [%i] could not be found in the raylib resource file", rresName, resId);
return image;
}
@@ -219,36 +292,39 @@ Texture2D LoadTexture(const char *fileName)
{
Texture2D texture;
int imgWidth;
int imgHeight;
int imgBpp;
if (strcmp(GetExtension(fileName),"dds") == 0)
{
ImageEx image = LoadDDS(fileName);
// NOTE: Using stb_image to load images (Supports: BMP, TGA, PNG, JPG, ...)
// Force loading to 4 components (RGBA)
byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
if (image.compFormat == 0)
{
texture.id = rlglLoadTexture(image.data, image.width, image.height, false);
}
else
{
#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2)
texture.id = rlglLoadCompressedTexture(image.data, image.width, image.height, image.mipmaps, image.compFormat);
#endif
}
// Convert loaded data to OpenGL texture
//----------------------------------------
GLuint id;
glGenTextures(1, &id); // Generate Pointer to the Texture
texture.width = image.width;
texture.height = image.height;
glBindTexture(GL_TEXTURE_2D, id);
if (texture.id == 0) TraceLog(WARNING, "[%s] DDS texture could not be loaded", fileName);
else TraceLog(INFO, "[%s] DDS texture loaded successfully", fileName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repead on x-axis
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repead on y-axis
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
free(image.data);
}
else
{
Image image = LoadImage(fileName);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imgWidth, imgHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgData);
// NOTE: Not using mipmappings (texture for 2D drawing)
// At this point we have the image converted to texture and uploaded to GPU
stbi_image_free(imgData); // Now we can free loaded data from RAM memory
texture.glId = id;
texture.width = imgWidth;
texture.height = imgHeight;
if (image.pixels != NULL)
{
texture = CreateTexture(image, false);
UnloadImage(image);
}
}
return texture;
}
@@ -259,54 +335,8 @@ Texture2D LoadTextureFromRES(const char *rresName, int resId)
Texture2D texture;
Image image = LoadImageFromRES(rresName, resId);
texture = CreateTexture2D(image);
return texture;
}
// Load an image as texture (and convert to POT with mipmaps)
Texture2D LoadTextureEx(const char *fileName, bool createPOT, bool mipmaps)
{
Texture2D texture;
// TODO: Load and image and convert to Power-Of-Two
// NOTE: Conversion could be done just adding extra space to image or by scaling image
// NOTE: If scaling image, be careful with scaling algorithm (aproximation, bilinear, bicubic...)
// TODO: Generate all required mipmap levels from image and convert to testure (not that easy)
// NOTE: If using OpenGL 1.1, the only option is doing mipmap generation on CPU side (i.e. gluBuild2DMipmaps)
// NOTE: raylib tries to minimize external dependencies so, we are not using GLU
// NOTE: Re-implement some function similar to gluBuild2DMipmaps (not that easy...)
return texture;
}
// Create a Texture2D from Image data
// NOTE: Image is not unloaded, it should be done manually...
Texture2D CreateTexture2D(Image image)
{
Texture2D texture;
// Convert image data to OpenGL texture
//----------------------------------------
GLuint id;
glGenTextures(1, &id); // Generate Pointer to the Texture
glBindTexture(GL_TEXTURE_2D, id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repead on x-axis
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repead on y-axis
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.width, image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.pixels);
// NOTE: Not using mipmappings (texture for 2D drawing)
// At this point we have the image converted to texture and uploaded to GPU
texture.glId = id;
texture.width = image.width;
texture.height = image.height;
texture = CreateTexture(image, false);
UnloadImage(image);
return texture;
}
@@ -320,113 +350,274 @@ void UnloadImage(Image image)
// Unload texture from GPU memory
void UnloadTexture(Texture2D texture)
{
glDeleteTextures(1, &texture.glId);
rlDeleteTextures(texture.id);
}
// Draw a Texture2D
void DrawTexture(Texture2D texture, int posX, int posY, Color tint)
{
DrawTextureEx(texture, (Vector2){ (float)posX, (float)posY}, 0, 1.0f, tint);
DrawTextureEx(texture, (Vector2){ (float)posX, (float)posY }, 0, 1.0f, tint);
}
// Draw a Texture2D with position defined as Vector2
void DrawTextureV(Texture2D texture, Vector2 position, Color tint)
{
DrawTextureEx(texture, position, 0, 1.0f, tint);
}
// Draw a Texture2D with extended parameters
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint)
{
glEnable(GL_TEXTURE_2D); // Enable textures usage
Rectangle sourceRec = { 0, 0, texture.width, texture.height };
Rectangle destRec = { (int)position.x, (int)position.y, texture.width*scale, texture.height*scale };
Vector2 origin = { 0, 0 };
glBindTexture(GL_TEXTURE_2D, texture.glId);
glPushMatrix();
// NOTE: Rotation is applied before translation and scaling, even being called in inverse order...
// NOTE: Rotation point is upper-left corner
glTranslatef(position.x, position.y, 0);
glScalef(scale, scale, 1.0f);
glRotatef(rotation, 0, 0, 1);
glBegin(GL_QUADS);
glColor4ub(tint.r, tint.g, tint.b, tint.a);
glNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); // Bottom-left corner for texture and quad
glTexCoord2f(1.0f, 0.0f); glVertex2f(texture.width, 0.0f); // Bottom-right corner for texture and quad
glTexCoord2f(1.0f, 1.0f); glVertex2f(texture.width, texture.height); // Top-right corner for texture and quad
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, texture.height); // Top-left corner for texture and quad
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D); // Disable textures usage
DrawTexturePro(texture, sourceRec, destRec, origin, rotation, tint);
}
// Draw a part of a texture (defined by a rectangle)
void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint)
{
glEnable(GL_TEXTURE_2D); // Enable textures usage
Rectangle destRec = { (int)position.x, (int)position.y, sourceRec.width, sourceRec.height };
Vector2 origin = { 0, 0 };
glBindTexture(GL_TEXTURE_2D, texture.glId);
glPushMatrix();
glTranslatef(position.x, position.y, 0);
//glScalef(1.0f, 1.0f, 1.0f);
//glRotatef(rotation, 0, 0, 1);
glBegin(GL_QUADS);
glColor4ub(tint.r, tint.g, tint.b, tint.a);
glNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
// Bottom-left corner for texture and quad
glTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
glVertex2f(0.0f, 0.0f);
// Bottom-right corner for texture and quad
glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
glVertex2f(sourceRec.width, 0.0f);
// Top-right corner for texture and quad
glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
glVertex2f(sourceRec.width, sourceRec.height);
// Top-left corner for texture and quad
glTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
glVertex2f(0.0f, sourceRec.height);
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D); // Disable textures usage
DrawTexturePro(texture, sourceRec, destRec, origin, 0, tint);
}
// Draw a part of a texture (defined by a rectangle) with 'pro' parameters
// TODO: Test this function...
// NOTE: origin is relative to destination rectangle size
void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint)
{
glEnable(GL_TEXTURE_2D); // Enable textures usage
rlEnableTexture(texture.id);
glBindTexture(GL_TEXTURE_2D, texture.glId);
rlPushMatrix();
rlTranslatef(destRec.x, destRec.y, 0);
rlRotatef(rotation, 0, 0, 1);
rlTranslatef(-origin.x, -origin.y, 0);
glPushMatrix();
glTranslatef(-origin.x, -origin.y, 0);
glRotatef(rotation, 0, 0, 1);
glTranslatef(destRec.x + origin.x, destRec.y + origin.y, 0);
glBegin(GL_QUADS);
glColor4ub(tint.r, tint.g, tint.b, tint.a);
glNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
rlBegin(RL_QUADS);
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
// Bottom-left corner for texture and quad
glTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
glVertex2f(0.0f, 0.0f);
rlTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
rlVertex2f(0.0f, 0.0f);
// Bottom-right corner for texture and quad
glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
glVertex2f(destRec.width, 0.0f);
rlTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
rlVertex2f(0.0f, destRec.height);
// Top-right corner for texture and quad
glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
glVertex2f(destRec.width, destRec.height);
rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
rlVertex2f(destRec.width, destRec.height);
// Top-left corner for texture and quad
glTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
glVertex2f(0.0f, destRec.height);
glEnd();
glPopMatrix();
rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
rlVertex2f(destRec.width, 0.0f);
rlEnd();
rlPopMatrix();
glDisable(GL_TEXTURE_2D); // Disable textures usage
rlDisableTexture();
}
// Create a texture from an image
// NOTE: image is not unloaded, iot must be done manually
Texture2D CreateTexture(Image image, bool genMipmaps)
{
Texture2D texture;
// Init texture to default values
texture.id = 0;
texture.width = 0;
texture.height = 0;
if (image.pixels != NULL)
{
unsigned char *imgData = malloc(image.width * image.height * 4);
int j = 0;
for (int i = 0; i < image.width * image.height * 4; i += 4)
{
imgData[i] = image.pixels[j].r;
imgData[i+1] = image.pixels[j].g;
imgData[i+2] = image.pixels[j].b;
imgData[i+3] = image.pixels[j].a;
j++;
}
// NOTE: rlglLoadTexture() can generate mipmaps (POT image required)
texture.id = rlglLoadTexture(imgData, image.width, image.height, genMipmaps);
texture.width = image.width;
texture.height = image.height;
TraceLog(INFO, "[ID %i] Texture created successfully", texture.id);
free(imgData);
}
else TraceLog(WARNING, "Texture could not be created, image data is not valid");
return texture;
}
// Loading DDS image data (compressed or uncompressed)
// NOTE: Compressed data loading not supported on OpenGL 1.1
ImageEx LoadDDS(const char *fileName)
{
#define FOURCC_DXT1 0x31545844 // Equivalent to "DXT1" in ASCII
#define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
#define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII
#ifndef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
#endif
#ifndef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
#endif
#ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
#endif
// DDS Pixel Format
typedef struct {
unsigned int size;
unsigned int flags;
unsigned int fourCC;
unsigned int rgbBitCount;
unsigned int rBitMask;
unsigned int gBitMask;
unsigned int bitMask;
unsigned int aBitMask;
} ddsPixelFormat;
// DDS Header (124 bytes)
typedef struct {
unsigned int size;
unsigned int flags;
unsigned int height;
unsigned int width;
unsigned int pitchOrLinearSize;
unsigned int depth;
unsigned int mipMapCount;
unsigned int reserved1[11];
ddsPixelFormat ddspf;
unsigned int caps;
unsigned int caps2;
unsigned int caps3;
unsigned int caps4;
unsigned int reserved2;
} ddsHeader;
ImageEx image;
ddsHeader header;
FILE *ddsFile = fopen(fileName, "rb");
if (ddsFile == NULL)
{
TraceLog(WARNING, "DDS File could not be opened");
}
else
{
// Verify the type of file
char filecode[4];
fread(filecode, 1, 4, ddsFile);
if (strncmp(filecode, "DDS ", 4) != 0)
{
TraceLog(WARNING, "DDS File does not seem to be valid");
fclose(ddsFile);
}
else
{
// Get the surface descriptor
fread(&header, sizeof(ddsHeader), 1, ddsFile);
TraceLog(DEBUG, "[%s] DDS file header size: %i", fileName, sizeof(ddsHeader));
TraceLog(DEBUG, "[%s] DDS file pixel format size: %i", fileName, header.ddspf.size);
TraceLog(DEBUG, "[%s] DDS file pixel format flags: 0x%x", fileName, header.ddspf.flags);
TraceLog(DEBUG, "[%s] DDS file format: 0x%x", fileName, header.ddspf.fourCC);
image.width = header.width;
image.height = header.height;
image.mipmaps = 1;
image.compFormat = 0;
if (header.ddspf.flags == 0x40 && header.ddspf.rgbBitCount == 24) // DDS_RGB, no compressed
{
image.data = (unsigned char *)malloc(header.width * header.height * 4);
unsigned char *buffer = (unsigned char *)malloc(header.width * header.height * 3);
fread(buffer, image.width*image.height*3, 1, ddsFile);
unsigned char *src = buffer;
unsigned char *dest = image.data;
for(int y = 0; y < image.height; y++)
{
for(int x = 0; x < image.width; x++)
{
*dest++ = *src++;
*dest++ = *src++;
*dest++ = *src++;
*dest++ = 255;
}
}
free(buffer);
}
else if (header.ddspf.flags == 0x41 && header.ddspf.rgbBitCount == 32) // DDS_RGBA, no compressed
{
image.data = (unsigned char *)malloc(header.width * header.height * 4);
fread(image.data, image.width*image.height*4, 1, ddsFile);
image.mipmaps = 1;
image.compFormat = 0;
}
else if ((header.ddspf.flags == 0x04) && (header.ddspf.fourCC > 0))
{
#ifdef USE_OPENGL_11
TraceLog(WARNING, "[%s] DDS image uses compression, not supported by current OpenGL version", fileName);
TraceLog(WARNING, "[%s] DDS compressed files require OpenGL 3.2+ or ES 2.0", fileName);
fclose(ddsFile);
#else
int bufsize;
// Calculate data size, including all mipmaps
if (header.mipMapCount > 1) bufsize = header.pitchOrLinearSize * 2;
else bufsize = header.pitchOrLinearSize;
image.data = (unsigned char*)malloc(bufsize * sizeof(unsigned char));
fread(image.data, 1, bufsize, ddsFile);
// Close file pointer
fclose(ddsFile);
image.mipmaps = header.mipMapCount;
image.compFormat = 0;
switch(header.ddspf.fourCC)
{
case FOURCC_DXT1: image.compFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
case FOURCC_DXT3: image.compFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
case FOURCC_DXT5: image.compFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
default: break;
}
// NOTE: Image num color components not required... for now...
//if (fourCC == FOURCC_DXT1) image.components = 3;
//else image.components = 4;
#endif
}
}
}
return image;
}

View File

@@ -4,8 +4,9 @@
*
* Utils Functions Definitions
*
* Uses external lib:
* Uses external libs:
* tinfl - zlib DEFLATE algorithm decompression lib
* stb_image_write - PNG writting functions
*
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
@@ -29,14 +30,24 @@
#include "utils.h"
#include <stdlib.h> // malloc(), free()
#include <stdio.h> // printf()
#include <stdio.h> // printf(), fprintf()
#include <stdarg.h> // Used for functions with variable number of parameters (TraceLog())
//#include <string.h> // String management functions: strlen(), strrchr(), strcmp()
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h" // Create PNG file
#include "tinfl.c"
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
static FILE *logstream = NULL;
//----------------------------------------------------------------------------------
// Module Functions Definition - Utilities
//----------------------------------------------------------------------------------
// Data decompression function
// NOTE: Allocated data MUST be freed!
unsigned char *DecompressData(const unsigned char *data, unsigned long compSize, int uncompSize)
@@ -50,28 +61,28 @@ unsigned char *DecompressData(const unsigned char *data, unsigned long compSize,
// Check correct memory allocation
if (!pUncomp)
{
printf("Out of memory!\n");
return NULL;
TraceLog(WARNING, "Out of memory while decompressing data");
}
else
{
// Decompress data
tempUncompSize = tinfl_decompress_mem_to_mem(pUncomp, (size_t)uncompSize, data, compSize, 1);
if (tempUncompSize == -1)
{
printf("Decompression failed!\n");
TraceLog(WARNING, "Data decompression failed");
free(pUncomp);
return NULL;
}
if (uncompSize != (int)tempUncompSize)
{
printf("WARNING! Expected uncompressed size do not match! Data may be corrupted!\n");
printf(" -- Expected uncompressed size: %i\n", uncompSize);
printf(" -- Returned uncompressed size: %i\n", tempUncompSize);
TraceLog(WARNING, "Expected uncompressed size do not match, data may be corrupted");
TraceLog(WARNING, " -- Expected uncompressed size: %i", uncompSize);
TraceLog(WARNING, " -- Returned uncompressed size: %i", tempUncompSize);
}
printf("Decompressed from %u bytes to %u bytes\n", (mz_uint32)compSize, (mz_uint32)tempUncompSize);
TraceLog(INFO, "Data decompressed successfully from %u bytes to %u bytes", (mz_uint32)compSize, (mz_uint32)tempUncompSize);
}
return pUncomp;
}
@@ -125,3 +136,70 @@ void WritePNG(const char *fileName, unsigned char *imgData, int width, int heigh
{
stbi_write_png(fileName, width, height, 4, imgData, width*4); // It WORKS!!!
}
// Outputs a trace log message (INFO, ERROR, WARNING)
// NOTE: If a file has been init, output log is written there
void TraceLog(int msgType, const char *text, ...)
{
va_list args;
int traceDebugMsgs = 1;
#ifdef DO_NOT_TRACE_DEBUG_MSGS
traceDebugMsgs = 0;
#endif
// NOTE: If trace log file not set, output redirected to stdout
if (logstream == NULL) logstream = stdout;
switch(msgType)
{
case INFO: fprintf(logstream, "INFO: "); break;
case ERROR: fprintf(logstream, "ERROR: "); break;
case WARNING: fprintf(logstream, "WARNING: "); break;
case DEBUG: if (traceDebugMsgs) fprintf(logstream, "DEBUG: "); break;
default: break;
}
if ((msgType != DEBUG) || ((msgType == DEBUG) && (traceDebugMsgs)))
{
va_start(args, text);
vfprintf(logstream, text, args);
va_end(args);
fprintf(logstream, "\n");
}
if (msgType == ERROR) exit(1); // If ERROR message, exit program
}
// Open a trace log file (if desired)
void TraceLogOpen(const char *logFileName)
{
// stdout redirected to stream file
FILE *logstream = fopen(logFileName, "w");
if (logstream == NULL) TraceLog(WARNING, "Unable to open log file");
}
// Close the trace log file
void TraceLogClose()
{
if (logstream != NULL) fclose(logstream);
}
// Keep track of memory allocated
// NOTE: mallocType defines the type of data allocated
void RecordMalloc(int mallocType, int mallocSize, const char *msg)
{
// TODO: Investigate how to record memory allocation data...
// Maybe creating my own malloc function...
}
// Get the extension for a filename
const char *GetExtension(const char *fileName)
{
const char *dot = strrchr(fileName, '.');
if(!dot || dot == fileName) return "";
return (dot + 1);
}

View File

@@ -4,9 +4,6 @@
*
* Some utility functions: rRES files data decompression
*
* Uses external lib:
* tinfl - zlib DEFLATE algorithm decompression lib
*
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
* This software is provided "as-is", without any express or implied warranty. In no event
@@ -32,12 +29,14 @@
//----------------------------------------------------------------------------------
// Some basic Defines
//----------------------------------------------------------------------------------
//...
#define DO_NOT_TRACE_DEBUG_MSGS // Use this define to avoid DEBUG tracing
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef enum { IMAGE, SOUND, MODEL, TEXT, RAW } DataType;
typedef enum { IMAGE = 0, SOUND, MODEL, TEXT, RAW } DataType;
typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
// One resource info header, every resource includes this header (8 byte)
typedef struct {
@@ -61,9 +60,16 @@ extern "C" { // Prevents name mangling of functions
// Module Functions Declaration
//----------------------------------------------------------------------------------
unsigned char *DecompressData(const unsigned char *data, unsigned long compSize, int uncompSize);
void WriteBitmap(const char *fileName, unsigned char *imgData, int width, int height);
void WritePNG(const char *fileName, unsigned char *imgData, int width, int height);
void TraceLog(int msgType, const char *text, ...); // Outputs a trace log message
void TraceLogOpen(const char *logFileName); // Open a trace log file (if desired)
void TraceLogClose(); // Close the trace log file
const char *GetExtension(const char *fileName);
#ifdef __cplusplus
}
#endif

View File

@@ -1,140 +0,0 @@
/*********************************************************************************************
*
* raylib.vector3
*
* Vector3 Functions Definition
*
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
* 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.
*
**********************************************************************************************/
#include "vector3.h"
#include <math.h>
// Add two vectors
Vector3 VectorAdd(Vector3 v1, Vector3 v2)
{
Vector3 out;
out.x = v1.x + v2.x;
out.y = v1.y + v2.y;
out.z = v1.z + v2.z;
return out;
}
// Substract two vectors
Vector3 VectorSubtract(Vector3 v1, Vector3 v2)
{
Vector3 out;
out.x = v1.x - v2.x;
out.y = v1.y - v2.y;
out.z = v1.z - v2.z;
return out;
}
// Calculate two vectors cross product
Vector3 VectorCrossProduct(Vector3 v1, Vector3 v2)
{
Vector3 cross;
cross.x = v1.y*v2.z - v1.z*v2.y;
cross.y = v1.z*v2.x - v1.x*v2.z;
cross.z = v1.x*v2.y - v1.y*v2.x;
return cross;
}
// Calculate one vector perpendicular vector
Vector3 VectorPerpendicular(Vector3 v)
{
Vector3 out;
float min = fabs(v.x);
Vector3 cardinalAxis = {1.0, 0.0, 0.0};
if (fabs(v.y) < min)
{
min = fabs(v.y);
cardinalAxis = (Vector3){0.0, 1.0, 0.0};
}
if(fabs(v.z) < min)
{
cardinalAxis = (Vector3){0.0, 0.0, 1.0};
}
out = VectorCrossProduct(v, cardinalAxis);
return out;
}
// Calculate two vectors dot product
float VectorDotProduct(Vector3 v1, Vector3 v2)
{
float dot;
dot = v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
return dot;
}
// Calculate vector lenght
float VectorLength(const Vector3 v)
{
float length;
length = sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
return length;
}
// Scale provided vector
void VectorScale(Vector3 *v, float scale)
{
v->x *= scale;
v->y *= scale;
v->z *= scale;
}
// Invert provided vector (direction)
void VectorInverse(Vector3 *v)
{
v->x = -v->x;
v->y = -v->y;
v->z = -v->z;
}
// Normalize provided vector
void VectorNormalize(Vector3 *v)
{
float length, ilength;
length = VectorLength(*v);
if (length == 0) length = 1;
ilength = 1.0/length;
v->x *= ilength;
v->y *= ilength;
v->z *= ilength;
}

View File

@@ -1,57 +0,0 @@
/*********************************************************************************************
*
* raylib.vector3
*
* Some useful functions to work with Vector3
*
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
* 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 VECTOR3_H
#define VECTOR3_H
#include "raylib.h" // Defines Vector3 structure
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
//------------------------------------------------------------------------------------
// Global Variables Definition
//------------------------------------------------------------------------------------
// It's lonely here...
//------------------------------------------------------------------------------------
// Functions Declaration to work with Vector3
//------------------------------------------------------------------------------------
Vector3 VectorAdd(Vector3 v1, Vector3 v2); // Add two vectors
Vector3 VectorSubtract(Vector3 v1, Vector3 v2); // Substract two vectors
Vector3 VectorCrossProduct(Vector3 v1, Vector3 v2); // Calculate two vectors cross product
Vector3 VectorPerpendicular(Vector3 v); // Calculate one vector perpendicular vector
float VectorDotProduct(Vector3 v1, Vector3 v2); // Calculate two vectors dot product
float VectorLength(const Vector3 v); // Calculate vector lenght
void VectorScale(Vector3 *v, float scale); // Scale provided vector
void VectorInverse(Vector3 *v); // Invert provided vector (direction)
void VectorNormalize(Vector3 *v); // Normalize provided vector
#ifdef __cplusplus
}
#endif
#endif // VECTOR3_H

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

4731
tests/resources/cat.obj Normal file

File diff suppressed because it is too large Load Diff

BIN
tests/resources/catsham.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
tests/resources/mouse.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

79
tests/test_3d_models.c Normal file
View File

@@ -0,0 +1,79 @@
/*******************************************************************************************
*
* raylib test - Load and draw a 3d model (OBJ)
*
* This test has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
Vector3 position = { 0.0, 0.0, 0.0 };
// Define the camera to look into our 3d world
Camera camera = {{ 10.0, 8.0, 10.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }};
InitWindow(screenWidth, screenHeight, "raylib test - 3d models in OpenGL 3.3+");
Texture2D texture = LoadTexture("resources/catwhite.png");
Model cat = LoadModel("resources/cat.obj");
SetModelTexture(&cat, texture);
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
if (IsKeyDown(KEY_LEFT)) position.x -= 0.2;
if (IsKeyDown(KEY_RIGHT)) position.x += 0.2;
if (IsKeyDown(KEY_UP)) position.z -= 0.2;
if (IsKeyDown(KEY_DOWN)) position.z += 0.2;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
Begin3dMode(camera);
DrawModel(cat, position, 0.1f, BEIGE); // OK_GL11, OK_GL33
//DrawModelWires(cat, position, 0.1f, RED); // OK_GL11, OK_GL33
DrawGrid(10.0, 1.0); // Draw a grid
DrawGizmo(position);
End3dMode();
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texture); // Unload texture
UnloadModel(cat); // Unload model
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

77
tests/test_billboard.c Normal file
View File

@@ -0,0 +1,77 @@
/*******************************************************************************************
*
* raylib test - Testing DrawBillboard() and DrawBillboardRec()
*
* This test has been created using raylib 1.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
Vector3 position = { 0.0, 0.0, 0.0 };
// Define the camera to look into our 3d world
Camera camera = {{ 10.0, 8.0, 10.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }};
InitWindow(screenWidth, screenHeight, "raylib test - Billboards");
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
Texture2D texture = LoadTexture("resources/raylib_logo.png");
Texture2D lena = LoadTexture("resources/lena.png");
Rectangle eyesRec = { 225, 240, 155, 50 };
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
if (IsKeyDown(KEY_LEFT)) camera.position.x -= 0.2;
if (IsKeyDown(KEY_RIGHT)) camera.position.x += 0.2;
if (IsKeyDown(KEY_UP)) camera.position.y -= 0.2;
if (IsKeyDown(KEY_DOWN)) camera.position.y += 0.2;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
Begin3dMode(camera);
//DrawBillboard(camera, texture, position, 2.0, WHITE);
DrawBillboardRec(camera, lena, eyesRec, position, 4.0, WHITE);
DrawGrid(10.0, 1.0); // Draw a grid
End3dMode();
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texture); // Unload texture
UnloadTexture(lena); // Unload texture
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

83
tests/test_cubesmap.c Normal file
View File

@@ -0,0 +1,83 @@
/*******************************************************************************************
*
* raylib test - Testing Heightmap Loading and Drawing
*
* This test has been created using raylib 1.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "../raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
Vector3 position = { 0.5, 0.0, 0.5 };
// Define the camera to look into our 3d world
Camera camera = {{ 7.0, 6.0, 7.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }};
InitWindow(screenWidth, screenHeight, "raylib test - Heightmap loading and drawing");
Image img = LoadImage("resources/cubesmap.png");
Model map = LoadCubesmap(img);
Texture2D texture = CreateTexture(img, false);
UnloadImage(img);
SetModelTexture(&map, texture);
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
if (IsKeyDown(KEY_UP)) camera.position.y += 0.2f;
else if (IsKeyDown(KEY_DOWN)) camera.position.y -= 0.2f;
if (IsKeyDown(KEY_RIGHT)) camera.position.z += 0.2f;
else if (IsKeyDown(KEY_LEFT)) camera.position.z -= 0.2f;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
Begin3dMode(camera);
//DrawCube(position, 1.0f, 1.0f, 1.0f, RED);
DrawModel(map, position, 1.0f, MAROON);
DrawGrid(10.0, 1.0); // Draw a grid
DrawGizmo(position);
End3dMode();
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texture); // Unload texture
UnloadModel(map); // Unload model
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

62
tests/test_formattext.c Normal file
View File

@@ -0,0 +1,62 @@
/*******************************************************************************************
*
* raylib test - Testing FormatText() function
*
* This test has been created using raylib 1.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
int score = 100020;
int hiscore = 200450;
int lives = 5;
InitWindow(screenWidth, screenHeight, "raylib test - FormatText()");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText(FormatText("Score: %08i", score), 80, 80, 20, RED);
DrawText(FormatText("HiScore: %08i", hiscore), 80, 120, 20, GREEN);
DrawText(FormatText("Lives: %02i", lives), 80, 160, 40, BLUE);
DrawText(FormatText("Elapsed Time: %02.02f ms", GetFrameTime()*1000), 80, 220, 20, BLACK);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

77
tests/test_heightmap.c Normal file
View File

@@ -0,0 +1,77 @@
/*******************************************************************************************
*
* raylib test - Testing Heightmap Loading and Drawing
*
* This test has been created using raylib 1.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
Vector3 position = { 0.0, 0.0, 0.0 };
// Define the camera to look into our 3d world
Camera camera = {{ 12.0, 10.0, 12.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }};
InitWindow(screenWidth, screenHeight, "raylib test - Heightmap loading and drawing");
Image img = LoadImage("resources/heightmap.png");
Model map = LoadHeightmap(img, 4);
Texture2D texture = CreateTexture(img, false);
UnloadImage(img);
SetModelTexture(&map, texture);
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// ...
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
Begin3dMode(camera);
DrawModel(map, position, 0.5f, MAROON);
DrawGrid(10.0, 1.0); // Draw a grid
DrawGizmo(position);
End3dMode();
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texture); // Unload texture
UnloadModel(map); // Unload model
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@@ -0,0 +1,60 @@
/*******************************************************************************************
*
* raylib test - Testing LoadImage() and CreateTexture()
*
* This test has been created using raylib 1.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib test - Image loading");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
Image img = LoadImage("resources/raylib_logo.png");
Texture2D texture = CreateTexture(img, false);
UnloadImage(img);
//---------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2, WHITE);
DrawText("this IS a texture!", 360, 370, 10, GRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texture); // Texture unloading
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

57
tests/test_mouse_wheel.c Normal file
View File

@@ -0,0 +1,57 @@
/*******************************************************************************************
*
* raylib test - Testing GetMouseWheelMove()
*
* This test has been created using raylib 1.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib test - Mouse wheel");
int positionY = 0;
int scrollSpeed = 4; // Scrolling speed in pixels
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
positionY -= (GetMouseWheelMove()*scrollSpeed);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawRectangle(200, positionY, 80, 80, MAROON);
DrawText(FormatText("%i", positionY), 10, 10, 20, GRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

86
tests/test_music_stream.c Normal file
View File

@@ -0,0 +1,86 @@
/*******************************************************************************************
*
* raylib test - Music playing (streaming)
*
* NOTE: This test requires OpenAL32 dll installed (or in the same folder)
*
* This test has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib test - music playing (streaming)");
InitAudioDevice(); // Initialize audio device
PlayMusicStream("resources/audio/deserve_to_be_loved.ogg"); // Load Music file
int framesCounter = 0;
float volume = 1.0;
float timePlayed = 0;
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
framesCounter++;
// Testing music fading
/*
if (framesCounter > 600)
{
volume -= 0.01;
if (volume <= 0)
{
volume = 1.0;
framesCounter = -600;
PlayMusicStream("resources/audio/destiny.ogg");
}
SetMusicVolume(volume);
}
*/
timePlayed = GetMusicTimePlayed() / GetMusicTimeLength() * 100 * 4; // We scale by 4 to fit 400 pixels
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText("MUSIC SHOULD BE PLAYING!", 255, 200, 20, LIGHTGRAY);
DrawRectangle(200, 250, 400, 12, LIGHTGRAY);
DrawRectangle(200, 250, (int)timePlayed, 12, MAROON);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

62
tests/test_random.c Normal file
View File

@@ -0,0 +1,62 @@
/*******************************************************************************************
*
* raylib test - Testing GetRandomValue()
*
* This example has been created using raylib 1.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
int framesCounter = 0;
InitWindow(screenWidth, screenHeight, "raylib test - Random numbers");
int randValue = GetRandomValue(-8,5);
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
framesCounter++;
if ((framesCounter/60)%2)
{
randValue = GetRandomValue(-8,5);
framesCounter = 0;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText(FormatText("%i", randValue), 120, 120, 60, LIGHTGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

60
tests/test_sound_ogg.c Normal file
View File

@@ -0,0 +1,60 @@
/*******************************************************************************************
*
* raylib test - OGG audio loading and playing
*
* NOTE: This test requires OpenAL32 dll installed (or in the same folder)
*
* This test has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib test - ogg audio loading and playing");
InitAudioDevice(); // Initialize audio device
Sound fx = LoadSound("resources/audio/0564.ogg"); // Load audio file
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
if (IsKeyPressed(KEY_SPACE)) PlaySound(fx); // Play the sound!
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText("Press SPACE to PLAY the SOUND!", 240, 200, 20, LIGHTGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadSound(fx); // Unload sound data
CloseAudioDevice(); // Close audio device
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@@ -0,0 +1,59 @@
/*******************************************************************************************
*
* raylib test - Texture loading with mipmaps, mipmaps generation
*
* This test has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib test - texture mipmaps");
Image image = LoadImage("resources/raylib_logo.png");
Texture2D texture = CreateTexture(image, true);
// NOTE: With OpenGL 3.3 mipmaps generation works great (automatic generation)
// NOTE: With OpenGL 1.1 mipmaps generation works great too! (manual generation)
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawTexture(texture, 0, 0, WHITE);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texture); // Texture unloading
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

66
tests/test_texture_pro.c Normal file
View File

@@ -0,0 +1,66 @@
/*******************************************************************************************
*
* raylib test - Texture loading and drawing with pro parameters (rotation, origin, scale...)
*
* This test has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib test - texture pro");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
Texture2D texture = LoadTexture("resources/raylib_logo.png"); // Texture loading
Vector2 position = { 200, 100 };
Rectangle sourceRec = { 128, 128, 128, 128 };
Rectangle destRec = { 128, 128, 128, 128 };
Vector2 origin = { 64, 64 }; // NOTE: origin is relative to destRec size
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
//DrawTextureEx(texture, position, 45, 1, MAROON);
DrawTexturePro(texture, sourceRec, destRec, origin, 45, GREEN);
DrawLine(destRec.x, 0, destRec.x, screenHeight, RED);
DrawLine(0, destRec.y, screenWidth, destRec.y, RED);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texture); // Texture unloading
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

66
tests/test_textures_dds.c Normal file
View File

@@ -0,0 +1,66 @@
/*******************************************************************************************
*
* raylib test - DDS Texture loading and drawing (compressed and uncompressed)
*
* This test has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
********************************************************************************************/
#include "raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib test - DDS texture loading and drawing");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
//Texture2D texture = LoadTexture("resources/raylib_logo.dds"); // Texture loading
//Texture2D texture = LoadTexture("resources/raylib_logo_uncompressed.dds"); // Texture loading
Image image = LoadImage("resources/raylib_logo_uncompressed.dds");
Texture2D texture = CreateTexture(image, false);
// NOTE: With OpenGL 3.3 mipmaps generation works great
SetTargetFPS(60);
//---------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2, WHITE);
DrawText("this IS a texture!", 360, 370, 10, GRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
//UnloadTexture(texture); // Texture unloading
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@@ -8,29 +8,23 @@
*
***********************************************************************************************/
rrem creates a .rres resource with embedded files and a .h header to access embedded data
Usage example:
1) Create 'resources.rres' and 'resources.h' including 3 files:
rrem image01.png image02.jpg sound03.wav
2) In your raylib program, just add at top:
#include "resources.h"
3) When a resource is required, just load it using:
Texture2D mytex = LoadTextureFromRES("resources.rres", RES_image01);
Sound mysound = LoadSoundFromRES("resources.rres", RES_sound03);
Note that you can check resources id names in resources.h file
Have fun! :)

Binary file not shown.