mirror of https://github.com/raysan5/raylib
Merged master fixed conflict.
This commit is contained in:
commit
3a9ed0e846
51
CHANGELOG
51
CHANGELOG
|
@ -1,11 +1,60 @@
|
|||
changelog
|
||||
---------
|
||||
|
||||
Current Release: raylib 1.2.2 (31 December 2014)
|
||||
Current Release: raylib 1.3.0 (01 September 2015)
|
||||
|
||||
NOTE: Only versions marked as 'Release' are available in installer, updates are only available as source.
|
||||
NOTE: Current Release includes all previous updates.
|
||||
|
||||
-----------------------------------------------
|
||||
Release: raylib 1.3.0 (01 September 2015)
|
||||
-----------------------------------------------
|
||||
NOTE:
|
||||
This version supposed a big boost for raylib, new modules have been added with lots of features.
|
||||
Most of the modules have been completely reviewed to accomodate to the new features.
|
||||
|
||||
BIG changes:
|
||||
[camera] NEW MODULE: Set of cameras for 3d view: Free, Orbital, 1st person, 3rd person
|
||||
[gestures] NEW MODULE: Gestures system for Android and HTML5 platforms
|
||||
[raygui] NEW MODULE: Set of IMGUI elements for tools development
|
||||
[rlgl] SHADERS: Support for model shaders and postprocessing shaders (multiple functions)
|
||||
[textures] FORMATS: Added support for multiple internal formats, including compressed formats
|
||||
|
||||
smaller changes:
|
||||
[rlgl] Added check for OpenGL supported extensions
|
||||
[rlgl] Added function SetBlenMode() to select some predefined blending modes
|
||||
[core] Added support for drop&drag of external files into running program
|
||||
[core] Added functions ShowCursor(), HideCursor(), IsCursorHidden()
|
||||
[core] Renamed function SetFlags() to SetConfigFlags()
|
||||
[shapes] Simplified some functions to improve performance
|
||||
[textures] Added function LoadImageEx()
|
||||
[textures] Added function LoadImageRaw()
|
||||
[textures] Added function LoadTextureEx()
|
||||
[textures] Simplified function parameters LoadTextureFromImage()
|
||||
[textures] Added function GetImageData()
|
||||
[textures] Added function GetTextureData()
|
||||
[textures] Renamed function ConvertToPOT() to ImageConvertToPOT()
|
||||
[textures] Added function ImageConvertFormat()
|
||||
[textures] Added function GenTextureMipmaps()
|
||||
[text] Added support for Latin-1 Extended characters for default font
|
||||
[models] Review of struct: Model (added shaders support)
|
||||
[models] Added 3d collision functions (sphere vs sphere vs box vs box)
|
||||
[models] Added function DrawCubeTexture()
|
||||
[models] Added function DrawQuad()
|
||||
[models] Added function DrawRay()
|
||||
[models] Simplified funtion DrawPlane()
|
||||
[models] Removed function DrawPlaneEx()
|
||||
[models] Simplified funtion DrawGizmo()
|
||||
[models] Removed function DrawGizmoEx()
|
||||
[models] Added function LoadModelEx()
|
||||
[models] Review of function LoadCubicMap()
|
||||
[models] Added function ResolveCollisionCubicmap()
|
||||
[audio] Decopupled from raylib, now this module can be used as standalone
|
||||
[audio] Added function UpdateMusicStream()
|
||||
[raymath] Complete review of the module
|
||||
[stb] Updated to latest headers versions
|
||||
[*] Lots of tweaks around
|
||||
|
||||
-----------------------------------------------
|
||||
Release: raylib 1.2.2 (31 December 2014)
|
||||
-----------------------------------------------
|
||||
|
|
|
@ -19,7 +19,7 @@ with a small [donation](http://www.raylib.com/helpme.htm) (just some euros...).
|
|||
raylib philosophy
|
||||
------------------
|
||||
|
||||
* raylib is a tool to LEARN videogames programming, every single function in raylib should be a tutorial on itself.
|
||||
* raylib is a tool to LEARN videogames programming, every single function in raylib should be a tutorial on itself (clear code).
|
||||
* raylib is SIMPLE and EASY-TO-USE, I tried to keep it compact with a small set of functions, if a function is too complex or
|
||||
has not a clear usefulness, better not to include it.
|
||||
* raylib is open source and free; educators and institutions can use this tool to TEACH videogames programming completely by free.
|
||||
|
|
342
LICENSE.md
342
LICENSE.md
|
@ -37,3 +37,345 @@ All rBMF fonts provided with raylib are free to use (freeware) and have been des
|
|||
* Mecha - Captain Falcon
|
||||
* PixelPlay - Aleksander Shevchuk
|
||||
* PixAntiqua - Gerhard Großmann
|
||||
|
||||
3d models
|
||||
---------
|
||||
|
||||
dwarf 3d model used in examples is created by Daniel Moreno and licensed as Creative Commons Attribution-NonCommercial 3.0
|
||||
|
||||
Full license provided below:
|
||||
|
||||
Creative Commons Legal Code
|
||||
|
||||
Attribution-NonCommercial 3.0 Unported
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR
|
||||
DAMAGES RESULTING FROM ITS USE.
|
||||
|
||||
License
|
||||
|
||||
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
|
||||
COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
|
||||
COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
|
||||
AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
|
||||
|
||||
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
|
||||
TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY
|
||||
BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS
|
||||
CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
|
||||
CONDITIONS.
|
||||
|
||||
1. Definitions
|
||||
|
||||
a. "Adaptation" means a work based upon the Work, or upon the Work and
|
||||
other pre-existing works, such as a translation, adaptation,
|
||||
derivative work, arrangement of music or other alterations of a
|
||||
literary or artistic work, or phonogram or performance and includes
|
||||
cinematographic adaptations or any other form in which the Work may be
|
||||
recast, transformed, or adapted including in any form recognizably
|
||||
derived from the original, except that a work that constitutes a
|
||||
Collection will not be considered an Adaptation for the purpose of
|
||||
this License. For the avoidance of doubt, where the Work is a musical
|
||||
work, performance or phonogram, the synchronization of the Work in
|
||||
timed-relation with a moving image ("synching") will be considered an
|
||||
Adaptation for the purpose of this License.
|
||||
b. "Collection" means a collection of literary or artistic works, such as
|
||||
encyclopedias and anthologies, or performances, phonograms or
|
||||
broadcasts, or other works or subject matter other than works listed
|
||||
in Section 1(f) below, which, by reason of the selection and
|
||||
arrangement of their contents, constitute intellectual creations, in
|
||||
which the Work is included in its entirety in unmodified form along
|
||||
with one or more other contributions, each constituting separate and
|
||||
independent works in themselves, which together are assembled into a
|
||||
collective whole. A work that constitutes a Collection will not be
|
||||
considered an Adaptation (as defined above) for the purposes of this
|
||||
License.
|
||||
c. "Distribute" means to make available to the public the original and
|
||||
copies of the Work or Adaptation, as appropriate, through sale or
|
||||
other transfer of ownership.
|
||||
d. "Licensor" means the individual, individuals, entity or entities that
|
||||
offer(s) the Work under the terms of this License.
|
||||
e. "Original Author" means, in the case of a literary or artistic work,
|
||||
the individual, individuals, entity or entities who created the Work
|
||||
or if no individual or entity can be identified, the publisher; and in
|
||||
addition (i) in the case of a performance the actors, singers,
|
||||
musicians, dancers, and other persons who act, sing, deliver, declaim,
|
||||
play in, interpret or otherwise perform literary or artistic works or
|
||||
expressions of folklore; (ii) in the case of a phonogram the producer
|
||||
being the person or legal entity who first fixes the sounds of a
|
||||
performance or other sounds; and, (iii) in the case of broadcasts, the
|
||||
organization that transmits the broadcast.
|
||||
f. "Work" means the literary and/or artistic work offered under the terms
|
||||
of this License including without limitation any production in the
|
||||
literary, scientific and artistic domain, whatever may be the mode or
|
||||
form of its expression including digital form, such as a book,
|
||||
pamphlet and other writing; a lecture, address, sermon or other work
|
||||
of the same nature; a dramatic or dramatico-musical work; a
|
||||
choreographic work or entertainment in dumb show; a musical
|
||||
composition with or without words; a cinematographic work to which are
|
||||
assimilated works expressed by a process analogous to cinematography;
|
||||
a work of drawing, painting, architecture, sculpture, engraving or
|
||||
lithography; a photographic work to which are assimilated works
|
||||
expressed by a process analogous to photography; a work of applied
|
||||
art; an illustration, map, plan, sketch or three-dimensional work
|
||||
relative to geography, topography, architecture or science; a
|
||||
performance; a broadcast; a phonogram; a compilation of data to the
|
||||
extent it is protected as a copyrightable work; or a work performed by
|
||||
a variety or circus performer to the extent it is not otherwise
|
||||
considered a literary or artistic work.
|
||||
g. "You" means an individual or entity exercising rights under this
|
||||
License who has not previously violated the terms of this License with
|
||||
respect to the Work, or who has received express permission from the
|
||||
Licensor to exercise rights under this License despite a previous
|
||||
violation.
|
||||
h. "Publicly Perform" means to perform public recitations of the Work and
|
||||
to communicate to the public those public recitations, by any means or
|
||||
process, including by wire or wireless means or public digital
|
||||
performances; to make available to the public Works in such a way that
|
||||
members of the public may access these Works from a place and at a
|
||||
place individually chosen by them; to perform the Work to the public
|
||||
by any means or process and the communication to the public of the
|
||||
performances of the Work, including by public digital performance; to
|
||||
broadcast and rebroadcast the Work by any means including signs,
|
||||
sounds or images.
|
||||
i. "Reproduce" means to make copies of the Work by any means including
|
||||
without limitation by sound or visual recordings and the right of
|
||||
fixation and reproducing fixations of the Work, including storage of a
|
||||
protected performance or phonogram in digital form or other electronic
|
||||
medium.
|
||||
|
||||
2. Fair Dealing Rights. Nothing in this License is intended to reduce,
|
||||
limit, or restrict any uses free from copyright or rights arising from
|
||||
limitations or exceptions that are provided for in connection with the
|
||||
copyright protection under copyright law or other applicable laws.
|
||||
|
||||
3. License Grant. Subject to the terms and conditions of this License,
|
||||
Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
|
||||
perpetual (for the duration of the applicable copyright) license to
|
||||
exercise the rights in the Work as stated below:
|
||||
|
||||
a. to Reproduce the Work, to incorporate the Work into one or more
|
||||
Collections, and to Reproduce the Work as incorporated in the
|
||||
Collections;
|
||||
b. to create and Reproduce Adaptations provided that any such Adaptation,
|
||||
including any translation in any medium, takes reasonable steps to
|
||||
clearly label, demarcate or otherwise identify that changes were made
|
||||
to the original Work. For example, a translation could be marked "The
|
||||
original work was translated from English to Spanish," or a
|
||||
modification could indicate "The original work has been modified.";
|
||||
c. to Distribute and Publicly Perform the Work including as incorporated
|
||||
in Collections; and,
|
||||
d. to Distribute and Publicly Perform Adaptations.
|
||||
|
||||
The above rights may be exercised in all media and formats whether now
|
||||
known or hereafter devised. The above rights include the right to make
|
||||
such modifications as are technically necessary to exercise the rights in
|
||||
other media and formats. Subject to Section 8(f), all rights not expressly
|
||||
granted by Licensor are hereby reserved, including but not limited to the
|
||||
rights set forth in Section 4(d).
|
||||
|
||||
4. Restrictions. The license granted in Section 3 above is expressly made
|
||||
subject to and limited by the following restrictions:
|
||||
|
||||
a. You may Distribute or Publicly Perform the Work only under the terms
|
||||
of this License. You must include a copy of, or the Uniform Resource
|
||||
Identifier (URI) for, this License with every copy of the Work You
|
||||
Distribute or Publicly Perform. You may not offer or impose any terms
|
||||
on the Work that restrict the terms of this License or the ability of
|
||||
the recipient of the Work to exercise the rights granted to that
|
||||
recipient under the terms of the License. You may not sublicense the
|
||||
Work. You must keep intact all notices that refer to this License and
|
||||
to the disclaimer of warranties with every copy of the Work You
|
||||
Distribute or Publicly Perform. When You Distribute or Publicly
|
||||
Perform the Work, You may not impose any effective technological
|
||||
measures on the Work that restrict the ability of a recipient of the
|
||||
Work from You to exercise the rights granted to that recipient under
|
||||
the terms of the License. This Section 4(a) applies to the Work as
|
||||
incorporated in a Collection, but this does not require the Collection
|
||||
apart from the Work itself to be made subject to the terms of this
|
||||
License. If You create a Collection, upon notice from any Licensor You
|
||||
must, to the extent practicable, remove from the Collection any credit
|
||||
as required by Section 4(c), as requested. If You create an
|
||||
Adaptation, upon notice from any Licensor You must, to the extent
|
||||
practicable, remove from the Adaptation any credit as required by
|
||||
Section 4(c), as requested.
|
||||
b. You may not exercise any of the rights granted to You in Section 3
|
||||
above in any manner that is primarily intended for or directed toward
|
||||
commercial advantage or private monetary compensation. The exchange of
|
||||
the Work for other copyrighted works by means of digital file-sharing
|
||||
or otherwise shall not be considered to be intended for or directed
|
||||
toward commercial advantage or private monetary compensation, provided
|
||||
there is no payment of any monetary compensation in connection with
|
||||
the exchange of copyrighted works.
|
||||
c. If You Distribute, or Publicly Perform the Work or any Adaptations or
|
||||
Collections, You must, unless a request has been made pursuant to
|
||||
Section 4(a), keep intact all copyright notices for the Work and
|
||||
provide, reasonable to the medium or means You are utilizing: (i) the
|
||||
name of the Original Author (or pseudonym, if applicable) if supplied,
|
||||
and/or if the Original Author and/or Licensor designate another party
|
||||
or parties (e.g., a sponsor institute, publishing entity, journal) for
|
||||
attribution ("Attribution Parties") in Licensor's copyright notice,
|
||||
terms of service or by other reasonable means, the name of such party
|
||||
or parties; (ii) the title of the Work if supplied; (iii) to the
|
||||
extent reasonably practicable, the URI, if any, that Licensor
|
||||
specifies to be associated with the Work, unless such URI does not
|
||||
refer to the copyright notice or licensing information for the Work;
|
||||
and, (iv) consistent with Section 3(b), in the case of an Adaptation,
|
||||
a credit identifying the use of the Work in the Adaptation (e.g.,
|
||||
"French translation of the Work by Original Author," or "Screenplay
|
||||
based on original Work by Original Author"). The credit required by
|
||||
this Section 4(c) may be implemented in any reasonable manner;
|
||||
provided, however, that in the case of a Adaptation or Collection, at
|
||||
a minimum such credit will appear, if a credit for all contributing
|
||||
authors of the Adaptation or Collection appears, then as part of these
|
||||
credits and in a manner at least as prominent as the credits for the
|
||||
other contributing authors. For the avoidance of doubt, You may only
|
||||
use the credit required by this Section for the purpose of attribution
|
||||
in the manner set out above and, by exercising Your rights under this
|
||||
License, You may not implicitly or explicitly assert or imply any
|
||||
connection with, sponsorship or endorsement by the Original Author,
|
||||
Licensor and/or Attribution Parties, as appropriate, of You or Your
|
||||
use of the Work, without the separate, express prior written
|
||||
permission of the Original Author, Licensor and/or Attribution
|
||||
Parties.
|
||||
d. For the avoidance of doubt:
|
||||
|
||||
i. Non-waivable Compulsory License Schemes. In those jurisdictions in
|
||||
which the right to collect royalties through any statutory or
|
||||
compulsory licensing scheme cannot be waived, the Licensor
|
||||
reserves the exclusive right to collect such royalties for any
|
||||
exercise by You of the rights granted under this License;
|
||||
ii. Waivable Compulsory License Schemes. In those jurisdictions in
|
||||
which the right to collect royalties through any statutory or
|
||||
compulsory licensing scheme can be waived, the Licensor reserves
|
||||
the exclusive right to collect such royalties for any exercise by
|
||||
You of the rights granted under this License if Your exercise of
|
||||
such rights is for a purpose or use which is otherwise than
|
||||
noncommercial as permitted under Section 4(b) and otherwise waives
|
||||
the right to collect royalties through any statutory or compulsory
|
||||
licensing scheme; and,
|
||||
iii. Voluntary License Schemes. The Licensor reserves the right to
|
||||
collect royalties, whether individually or, in the event that the
|
||||
Licensor is a member of a collecting society that administers
|
||||
voluntary licensing schemes, via that society, from any exercise
|
||||
by You of the rights granted under this License that is for a
|
||||
purpose or use which is otherwise than noncommercial as permitted
|
||||
under Section 4(c).
|
||||
e. Except as otherwise agreed in writing by the Licensor or as may be
|
||||
otherwise permitted by applicable law, if You Reproduce, Distribute or
|
||||
Publicly Perform the Work either by itself or as part of any
|
||||
Adaptations or Collections, You must not distort, mutilate, modify or
|
||||
take other derogatory action in relation to the Work which would be
|
||||
prejudicial to the Original Author's honor or reputation. Licensor
|
||||
agrees that in those jurisdictions (e.g. Japan), in which any exercise
|
||||
of the right granted in Section 3(b) of this License (the right to
|
||||
make Adaptations) would be deemed to be a distortion, mutilation,
|
||||
modification or other derogatory action prejudicial to the Original
|
||||
Author's honor and reputation, the Licensor will waive or not assert,
|
||||
as appropriate, this Section, to the fullest extent permitted by the
|
||||
applicable national law, to enable You to reasonably exercise Your
|
||||
right under Section 3(b) of this License (right to make Adaptations)
|
||||
but not otherwise.
|
||||
|
||||
5. Representations, Warranties and Disclaimer
|
||||
|
||||
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
|
||||
OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
|
||||
KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
|
||||
INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
|
||||
LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
|
||||
WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION
|
||||
OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
|
||||
|
||||
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
|
||||
LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR
|
||||
ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
|
||||
ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS
|
||||
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
7. Termination
|
||||
|
||||
a. This License and the rights granted hereunder will terminate
|
||||
automatically upon any breach by You of the terms of this License.
|
||||
Individuals or entities who have received Adaptations or Collections
|
||||
from You under this License, however, will not have their licenses
|
||||
terminated provided such individuals or entities remain in full
|
||||
compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will
|
||||
survive any termination of this License.
|
||||
b. Subject to the above terms and conditions, the license granted here is
|
||||
perpetual (for the duration of the applicable copyright in the Work).
|
||||
Notwithstanding the above, Licensor reserves the right to release the
|
||||
Work under different license terms or to stop distributing the Work at
|
||||
any time; provided, however that any such election will not serve to
|
||||
withdraw this License (or any other license that has been, or is
|
||||
required to be, granted under the terms of this License), and this
|
||||
License will continue in full force and effect unless terminated as
|
||||
stated above.
|
||||
|
||||
8. Miscellaneous
|
||||
|
||||
a. Each time You Distribute or Publicly Perform the Work or a Collection,
|
||||
the Licensor offers to the recipient a license to the Work on the same
|
||||
terms and conditions as the license granted to You under this License.
|
||||
b. Each time You Distribute or Publicly Perform an Adaptation, Licensor
|
||||
offers to the recipient a license to the original Work on the same
|
||||
terms and conditions as the license granted to You under this License.
|
||||
c. If any provision of this License is invalid or unenforceable under
|
||||
applicable law, it shall not affect the validity or enforceability of
|
||||
the remainder of the terms of this License, and without further action
|
||||
by the parties to this agreement, such provision shall be reformed to
|
||||
the minimum extent necessary to make such provision valid and
|
||||
enforceable.
|
||||
d. No term or provision of this License shall be deemed waived and no
|
||||
breach consented to unless such waiver or consent shall be in writing
|
||||
and signed by the party to be charged with such waiver or consent.
|
||||
e. This License constitutes the entire agreement between the parties with
|
||||
respect to the Work licensed here. There are no understandings,
|
||||
agreements or representations with respect to the Work not specified
|
||||
here. Licensor shall not be bound by any additional provisions that
|
||||
may appear in any communication from You. This License may not be
|
||||
modified without the mutual written agreement of the Licensor and You.
|
||||
f. The rights granted under, and the subject matter referenced, in this
|
||||
License were drafted utilizing the terminology of the Berne Convention
|
||||
for the Protection of Literary and Artistic Works (as amended on
|
||||
September 28, 1979), the Rome Convention of 1961, the WIPO Copyright
|
||||
Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996
|
||||
and the Universal Copyright Convention (as revised on July 24, 1971).
|
||||
These rights and subject matter take effect in the relevant
|
||||
jurisdiction in which the License terms are sought to be enforced
|
||||
according to the corresponding provisions of the implementation of
|
||||
those treaty provisions in the applicable national law. If the
|
||||
standard suite of rights granted under applicable copyright law
|
||||
includes additional rights not granted under this License, such
|
||||
additional rights are deemed to be included in the License; this
|
||||
License is not intended to restrict the license of any rights under
|
||||
applicable law.
|
||||
|
||||
|
||||
Creative Commons Notice
|
||||
|
||||
Creative Commons is not a party to this License, and makes no warranty
|
||||
whatsoever in connection with the Work. Creative Commons will not be
|
||||
liable to You or any party on any legal theory for any damages
|
||||
whatsoever, including without limitation any general, special,
|
||||
incidental or consequential damages arising in connection to this
|
||||
license. Notwithstanding the foregoing two (2) sentences, if Creative
|
||||
Commons has expressly identified itself as the Licensor hereunder, it
|
||||
shall have all rights and obligations of Licensor.
|
||||
|
||||
Except for the limited purpose of indicating to the public that the
|
||||
Work is licensed under the CCPL, Creative Commons does not authorize
|
||||
the use by either party of the trademark "Creative Commons" or any
|
||||
related trademark or logo of Creative Commons without the prior
|
||||
written consent of Creative Commons. Any permitted use will be in
|
||||
compliance with Creative Commons' then-current trademark usage
|
||||
guidelines, as may be published on its website or otherwise made
|
||||
available upon request from time to time. For the avoidance of doubt,
|
||||
this trademark restriction does not form part of the License.
|
||||
|
||||
Creative Commons may be contacted at https://creativecommons.org/.
|
37
README.md
37
README.md
|
@ -75,6 +75,28 @@ Lots of code changes and lot of testing have concluded in this amazing new rayli
|
|||
|
||||
In December 2014, new raylib 1.2.2 was published with support to compile directly for web (html5) using [emscripten](http://kripken.github.io/emscripten-site/) and [asm.js](http://asmjs.org/).
|
||||
|
||||
notes on raylib 1.3
|
||||
-------------------
|
||||
|
||||
On September 2015, after 1 year of raylib 1.2 release, arrives raylib 1.3. This version adds shaders functionality,
|
||||
improves textures module and provides some new modules (camera system, gestures system, IMGUI).
|
||||
|
||||
Shaders, the biggest addition to raylib, with support for simple and easy shaders loading and use. Loaded shaders can be
|
||||
assigned to models or used as fullscreen postrocessing shaders.
|
||||
|
||||
Textures module has been improved to support most of the internal texture formats available in OpenGL
|
||||
(RGB565, RGB888, RGBA5551, RGBA4444, etc.), including compressed texture formats (DXT, ETC1, ETC2, ASTC, PVRT).
|
||||
|
||||
New camera module offers the user multiple preconfigured ready-to-use camera systems (free camera, 1st person, third person),
|
||||
very easy to use, just calling functions: SetCameraMode() and UpdateCamera().
|
||||
|
||||
New gestures module simplifies getures detection on Android and HTML5 programs.
|
||||
|
||||
New IMGUI (Immediate Mode GUI) module: raygui, offers a set of functions to create simple user interfaces,
|
||||
primary intended for tools development, still in experimental state but already fully functional.
|
||||
|
||||
Lots of code changes and lot of testing have concluded in this amazing new raylib 1.3.
|
||||
|
||||
features
|
||||
--------
|
||||
|
||||
|
@ -82,6 +104,8 @@ features
|
|||
* Uses C# PascalCase/camelCase notation
|
||||
* Hardware accelerated with OpenGL (1.1, 3.3+ or ES2)
|
||||
* Unique OpenGL abstraction layer: [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.c)
|
||||
* 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, PKM and mipmaps generation
|
||||
* Basic 3d support for Shapes, Models, Heightmaps and Billboards
|
||||
|
@ -258,9 +282,16 @@ acknowledgments
|
|||
|
||||
The following people have contributed in some way to make raylib project a reality. Big thanks to them!
|
||||
|
||||
- [Zopokx](https://github.com/Zopokx) for testing and hosting the web.
|
||||
- [Zopokx](https://github.com/Zopokx) for testing the web.
|
||||
- [Elendow](http://www.elendow.com) for testing and helping on web development.
|
||||
- Victor Dual for implementation and testing of 3D shapes functions.
|
||||
- Marc Palau for implementation and testing of 3D shapes functions.
|
||||
- Victor Dual for implementating and testing of 3D shapes functions.
|
||||
- Marc Palau for implementating and testing of 3D shapes functions and helping on development of camera and getures modules.
|
||||
- Kevin Gato for improving texture internal formats support and helping on raygui development.
|
||||
- Daniel Nicolas for improving texture internal formats support and helping on raygui development.
|
||||
- Marc Agüera for testing and using raylib on a real product (Koala Seasons)
|
||||
- Daniel Moreno for testing and using raylib on a real product (Koala Seasons)
|
||||
- Daniel Gomez for testing and using raylib on a real product (Koala Seasons)
|
||||
- Sergio Martinez for helping on raygui development and tools development.
|
||||
|
||||
|
||||
[raysan5]: mailto:raysan@raysanweb.com "Ramon Santamaria - Ray San"
|
||||
|
|
22
ROADMAP.md
22
ROADMAP.md
|
@ -4,21 +4,21 @@ roadmap
|
|||
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.
|
||||
Around the source code there are multiple TODO points with pending revisions/bugs and here it is a list of desired features.
|
||||
|
||||
This roadmap is quite outdated... a full list of all the features we are working on should be listed here at some point...
|
||||
raylib v1.4
|
||||
|
||||
raylib v1.x
|
||||
- TTF fonts support (using stb_truetype)
|
||||
- Raycast system for 3D picking (including collisions detection)
|
||||
- Remove GLEW dependency (use another solution...)
|
||||
- Floyd-Steinberg dithering on 16bit image format conversion
|
||||
- Basic image manipulation functions (crop, resize, draw...)
|
||||
- Basic image procedural generation (spot, gradient, noise...)
|
||||
- Basic GPU stats sytem (memory, draws, time...)
|
||||
|
||||
- [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
|
||||
- [IN PROGRESS] Default scene Camera controls (zoom, pan, rotate)
|
||||
- Basic Procedural Image Generation (Gradient, Checked, Spot, Noise, Cellular)
|
||||
- [DONE] Software mipmapping generation and POT conversion (custom implementation)
|
||||
- [IN PROGRESS] TTF fonts support
|
||||
Check [GITHUB ISSUES][issues] for further details on implementation status for this features!
|
||||
|
||||
Any feature missing? Do you have a request? [Let me know!][raysan5]
|
||||
|
||||
[raysan5]: mailto:raysan@raysanweb.com "Ramon Santamaria - Ray San"
|
||||
[isssues]: https://github.com/raysan5/raylib/issues
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* This example 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)
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
@ -58,7 +58,12 @@ int main()
|
|||
SetMusicVolume(volume);
|
||||
}
|
||||
*/
|
||||
if (IsWindowMinimized()) PauseMusicStream();
|
||||
else ResumeMusicStream();
|
||||
|
||||
timePlayed = GetMusicTimePlayed() / GetMusicTimeLength() * 100 * 4; // We scale by 4 to fit 400 pixels
|
||||
|
||||
UpdateMusicStream();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - DDS Texture loading and drawing (compressed and uncompressed)
|
||||
* raylib [core] example - Picking in 3d mode
|
||||
*
|
||||
* NOTE: This example requires raylib OpenGL 3.3+ or ES2 versions for compressed texture,
|
||||
* OpenGL 1.1 does not support compressed textures, only uncompressed version.
|
||||
*
|
||||
* This example has been created using raylib 1.2 (www.raylib.com)
|
||||
* 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) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
|
@ -21,33 +18,48 @@ int main()
|
|||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - DDS texture loading and drawing");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d picking");
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = {{ 0.0, 10.0, 10.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }};
|
||||
|
||||
Texture2D texture = LoadTexture("resources/raylib_logo.dds"); // Texture loading (compressed)
|
||||
Vector3 cubePosition = { 0.0, 0.0, 0.0 };
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//---------------------------------------------------------------------------------------
|
||||
Ray pickingLine;
|
||||
|
||||
SetCameraMode(CAMERA_FREE);
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
camera = UpdateCamera(0);
|
||||
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pickingLine = GetMouseRay(GetMousePosition(), camera);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2, WHITE);
|
||||
Begin3dMode(camera);
|
||||
|
||||
DrawText("this may be a compressed texture!", 320, 370, 10, GRAY);
|
||||
DrawCube(cubePosition, 2, 2, 2, RED);
|
||||
DrawCubeWires(cubePosition, 2, 2, 2, MAROON);
|
||||
|
||||
DrawGrid(10.0, 1.0);
|
||||
|
||||
DrawRay(pickingLine, MAROON);
|
||||
|
||||
End3dMode();
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -55,9 +67,7 @@ int main()
|
|||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture); // Texture unloading
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
|
@ -15,7 +15,7 @@
|
|||
* 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) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
|
@ -164,8 +164,6 @@ EXAMPLES = \
|
|||
textures_logo_raylib \
|
||||
textures_image_loading \
|
||||
textures_rectangle \
|
||||
textures_compressed_dds \
|
||||
textures_mipmaps \
|
||||
textures_srcrec_dstrec \
|
||||
text_sprite_fonts \
|
||||
text_rbmf_fonts \
|
||||
|
@ -253,14 +251,6 @@ textures_image_loading: textures_image_loading.c
|
|||
textures_rectangle: textures_rectangle.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [textures] example - compressed texture loading (DDS)
|
||||
textures_compressed_dds: textures_compressed_dds.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [textures] example - texture mipmaps generation
|
||||
textures_mipmaps: textures_mipmaps.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [textures] example - texture source and destination rectangles
|
||||
textures_srcrec_dstrec: textures_srcrec_dstrec.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 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) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
@ -21,12 +21,12 @@ int main()
|
|||
InitWindow(screenWidth, screenHeight, "raylib [models] example - obj model loading");
|
||||
|
||||
// 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 }};
|
||||
Camera camera = {{ 3.0, 3.0, 3.0 }, { 0.0, 1.5, 0.0 }, { 0.0, 1.0, 0.0 }};
|
||||
|
||||
Texture2D texture = LoadTexture("resources/catsham.png"); // Load model texture
|
||||
Model cat = LoadModel("resources/cat.obj"); // Load OBJ model
|
||||
SetModelTexture(&cat, texture); // Bind texture to model
|
||||
Vector3 catPosition = { 0.0, 0.0, 0.0 }; // Set model position
|
||||
Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture
|
||||
Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model
|
||||
SetModelTexture(&dwarf, texture); // Bind texture to model
|
||||
Vector3 position = { 0.0, 0.0, 0.0 }; // Set model position
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
@ -36,10 +36,10 @@ int main()
|
|||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyDown(KEY_LEFT)) catPosition.x -= 0.2;
|
||||
if (IsKeyDown(KEY_RIGHT)) catPosition.x += 0.2;
|
||||
if (IsKeyDown(KEY_UP)) catPosition.z -= 0.2;
|
||||
if (IsKeyDown(KEY_DOWN)) catPosition.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,14 +50,16 @@ int main()
|
|||
|
||||
Begin3dMode(camera);
|
||||
|
||||
DrawModel(cat, catPosition, 0.1f, WHITE); // Draw 3d model with texture
|
||||
DrawModel(dwarf, position, 2.0f, WHITE); // Draw 3d model with texture
|
||||
|
||||
DrawGrid(10.0, 1.0); // Draw a grid
|
||||
|
||||
DrawGizmo(catPosition); // Draw gizmo
|
||||
DrawGizmo(position); // Draw gizmo
|
||||
|
||||
End3dMode();
|
||||
|
||||
DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
|
@ -67,7 +69,7 @@ int main()
|
|||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture); // Unload texture
|
||||
UnloadModel(cat); // Unload model
|
||||
UnloadModel(dwarf); // Unload model
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 308 KiB |
Binary file not shown.
Before Width: | Height: | Size: 302 KiB |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 1.2 MiB |
|
@ -5,7 +5,7 @@
|
|||
* 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) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
@ -16,7 +16,7 @@ int main()
|
|||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 150;
|
||||
int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [text] example - font selector");
|
||||
|
||||
|
@ -45,13 +45,15 @@ int main()
|
|||
|
||||
Vector2 mousePoint;
|
||||
|
||||
Rectangle btnNextRec = { 673, 18, 109, 44 }; // Button rectangle (useful for collision)
|
||||
|
||||
Color btnNextOutColor = DARKBLUE; // Button color (outside line)
|
||||
Color btnNextInColor = SKYBLUE; // Button color (inside)
|
||||
|
||||
int framesCounter = 0; // Useful to count frames button is 'active' = clicked
|
||||
|
||||
int positionY = 180; // Text selector and button Y position
|
||||
|
||||
Rectangle btnNextRec = { 673, positionY, 109, 44 }; // Button rectangle (useful for collision)
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -72,6 +74,15 @@ int main()
|
|||
if (currentFont > 0) currentFont--;
|
||||
}
|
||||
|
||||
if (IsKeyPressed('0')) currentFont = 0;
|
||||
else if (IsKeyPressed('1')) currentFont = 1;
|
||||
else if (IsKeyPressed('2')) currentFont = 2;
|
||||
else if (IsKeyPressed('3')) currentFont = 3;
|
||||
else if (IsKeyPressed('4')) currentFont = 4;
|
||||
else if (IsKeyPressed('5')) currentFont = 5;
|
||||
else if (IsKeyPressed('6')) currentFont = 6;
|
||||
else if (IsKeyPressed('7')) currentFont = 7;
|
||||
|
||||
// Mouse-based font selection (NEXT button logic)
|
||||
mousePoint = GetMousePosition();
|
||||
|
||||
|
@ -116,17 +127,20 @@ int main()
|
|||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawRectangle(18, 18, 644, 44, DARKGRAY);
|
||||
DrawRectangle(20, 20, 640, 40, LIGHTGRAY);
|
||||
DrawText(fontNames[currentFont], 30, 31, 20, BLACK);
|
||||
DrawText("< >", 610, 26, 30, BLACK);
|
||||
DrawText("font selector - use arroys, button or numbers", 160, 80, 20, DARKGRAY);
|
||||
DrawLine(120, 120, 680, 120, DARKGRAY);
|
||||
|
||||
DrawRectangle(18, positionY, 644, 44, DARKGRAY);
|
||||
DrawRectangle(20, positionY + 2, 640, 40, LIGHTGRAY);
|
||||
DrawText(fontNames[currentFont], 30, positionY + 13, 20, BLACK);
|
||||
DrawText("< >", 610, positionY + 8, 30, BLACK);
|
||||
|
||||
DrawRectangleRec(btnNextRec, btnNextOutColor);
|
||||
DrawRectangle(675, 20, 105, 40, btnNextInColor);
|
||||
DrawText("NEXT", 700, 31, 20, btnNextOutColor);
|
||||
DrawRectangle(675, positionY + 2, 105, 40, btnNextInColor);
|
||||
DrawText("NEXT", 700, positionY + 13, 20, btnNextOutColor);
|
||||
|
||||
DrawTextEx(fonts[currentFont], text, (Vector2){ screenWidth/2 - textSize.x/2,
|
||||
75 + (70 - textSize.y)/2 }, GetFontBaseSize(fonts[currentFont])*3,
|
||||
260 + (70 - textSize.y)/2 }, GetFontBaseSize(fonts[currentFont])*3,
|
||||
1, colors[currentFont]);
|
||||
|
||||
EndDrawing();
|
||||
|
|
|
@ -18,20 +18,43 @@ int main()
|
|||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 560;
|
||||
int screenHeight = 800;
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [text] example - rBMF fonts");
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
SpriteFont font1 = LoadSpriteFont("resources/fonts/alagard.rbmf"); // rBMF font loading
|
||||
SpriteFont font2 = LoadSpriteFont("resources/fonts/pixelplay.rbmf"); // rBMF font loading
|
||||
SpriteFont font3 = LoadSpriteFont("resources/fonts/mecha.rbmf"); // rBMF font loading
|
||||
SpriteFont font4 = LoadSpriteFont("resources/fonts/setback.rbmf"); // rBMF font loading
|
||||
SpriteFont font5 = LoadSpriteFont("resources/fonts/romulus.rbmf"); // rBMF font loading
|
||||
SpriteFont font6 = LoadSpriteFont("resources/fonts/pixantiqua.rbmf"); // rBMF font loading
|
||||
SpriteFont font7 = LoadSpriteFont("resources/fonts/alpha_beta.rbmf"); // rBMF font loading
|
||||
SpriteFont font8 = LoadSpriteFont("resources/fonts/jupiter_crash.rbmf"); // rBMF font loading
|
||||
SpriteFont fonts[8];
|
||||
|
||||
fonts[0] = LoadSpriteFont("resources/fonts/alagard.rbmf"); // rBMF font loading
|
||||
fonts[1] = LoadSpriteFont("resources/fonts/pixelplay.rbmf"); // rBMF font loading
|
||||
fonts[2] = LoadSpriteFont("resources/fonts/mecha.rbmf"); // rBMF font loading
|
||||
fonts[3] = LoadSpriteFont("resources/fonts/setback.rbmf"); // rBMF font loading
|
||||
fonts[4] = LoadSpriteFont("resources/fonts/romulus.rbmf"); // rBMF font loading
|
||||
fonts[5] = LoadSpriteFont("resources/fonts/pixantiqua.rbmf"); // rBMF font loading
|
||||
fonts[6] = LoadSpriteFont("resources/fonts/alpha_beta.rbmf"); // rBMF font loading
|
||||
fonts[7] = LoadSpriteFont("resources/fonts/jupiter_crash.rbmf"); // rBMF font loading
|
||||
|
||||
const char *messages[8] = { "ALAGARD FONT designed by Hewett Tsoi",
|
||||
"PIXELPLAY FONT designed by Aleksander Shevchuk",
|
||||
"MECHA FONT designed by Captain Falcon",
|
||||
"SETBACK FONT designed by Brian Kent (AEnigma)",
|
||||
"ROMULUS FONT designed by Hewett Tsoi",
|
||||
"PIXANTIQUA FONT designed by Gerhard Grossmann",
|
||||
"ALPHA_BETA FONT designed by Brian Kent (AEnigma)",
|
||||
"JUPITER_CRASH FONT designed by Brian Kent (AEnigma)" };
|
||||
|
||||
const int spacings[8] = { 2, 4, 8, 4, 3, 4, 4, 1 };
|
||||
|
||||
Vector2 positions[8];
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
positions[i].x = screenWidth/2 - MeasureTextEx(fonts[i], messages[i], GetFontBaseSize(fonts[i])*2, spacings[i]).x/2;
|
||||
positions[i].y = 60 + GetFontBaseSize(fonts[i]) + 50*i;
|
||||
}
|
||||
|
||||
Color colors[8] = { MAROON, ORANGE, DARKGREEN, DARKBLUE, DARKPURPLE, LIME, GOLD };
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
|
@ -48,14 +71,13 @@ int main()
|
|||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawTextEx(font1, "TESTING ALAGARD FONT", (Vector2){ 100, 100 }, GetFontBaseSize(font1)*2, 2, MAROON);
|
||||
DrawTextEx(font2, "TESTING PIXELPLAY FONT", (Vector2){ 100, 180 }, GetFontBaseSize(font2)*2, 4, ORANGE);
|
||||
DrawTextEx(font3, "TESTING MECHA FONT", (Vector2){ 100, 260 }, GetFontBaseSize(font3)*2, 8, DARKGREEN);
|
||||
DrawTextEx(font4, "TESTING SETBACK FONT", (Vector2){ 100, 350 }, GetFontBaseSize(font4)*2, 4, DARKBLUE);
|
||||
DrawTextEx(font5, "TESTING ROMULUS FONT", (Vector2){ 100, 430 }, GetFontBaseSize(font5)*2, 3, DARKPURPLE);
|
||||
DrawTextEx(font6, "TESTING PIXANTIQUA FONT", (Vector2){ 100, 510 }, GetFontBaseSize(font6)*2, 4, LIME);
|
||||
DrawTextEx(font7, "TESTING ALPHA_BETA FONT", (Vector2){ 100, 590 }, GetFontBaseSize(font7)*2, 4, GOLD);
|
||||
DrawTextEx(font8, "TESTING JUPITER_CRASH FONT", (Vector2){ 100, 660 }, GetFontBaseSize(font8)*2, 1, RED);
|
||||
DrawText("free fonts included with raylib", 250, 20, 20, DARKGRAY);
|
||||
DrawLine(220, 50, 590, 50, DARKGRAY);
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
DrawTextEx(fonts[i], messages[i], positions[i], GetFontBaseSize(fonts[i])*2, spacings[i], colors[i]);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -63,14 +85,10 @@ int main()
|
|||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadSpriteFont(font1); // SpriteFont unloading
|
||||
UnloadSpriteFont(font2); // SpriteFont unloading
|
||||
UnloadSpriteFont(font3); // SpriteFont unloading
|
||||
UnloadSpriteFont(font4); // SpriteFont unloading
|
||||
UnloadSpriteFont(font5); // SpriteFont unloading
|
||||
UnloadSpriteFont(font6); // SpriteFont unloading
|
||||
UnloadSpriteFont(font7); // SpriteFont unloading
|
||||
UnloadSpriteFont(font8); // SpriteFont unloading
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
UnloadSpriteFont(fonts[i]); // SpriteFont unloading
|
||||
}
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 15 KiB |
|
@ -7,7 +7,7 @@
|
|||
* This example 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)
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
@ -25,7 +25,7 @@ int main()
|
|||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
Image image = LoadImage("resources/raylib_logo.png"); // Loaded in CPU memory (RAM)
|
||||
Texture2D texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (VRAM)
|
||||
Texture2D texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (VRAM)
|
||||
|
||||
UnloadImage(image); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Texture loading with mipmaps, mipmaps generation
|
||||
*
|
||||
* NOTE: On OpenGL 1.1, mipmaps are calculated 'manually', original image must be power-of-two
|
||||
* On OpenGL 3.3 and ES2, mipmaps are generated automatically
|
||||
*
|
||||
* This example 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 [textures] example - texture mipmaps generation");
|
||||
|
||||
// NOTE: To generate mipmaps for an image, image must be loaded first and converted to texture
|
||||
|
||||
Image image = LoadImage("resources/raylib_logo.png"); // Load image to CPU memory (RAM)
|
||||
Texture2D texture = LoadTextureFromImage(image); // Load texture into GPU memory (VRAM)
|
||||
GenTextureMipmaps(texture); // Generate mipmaps for texture
|
||||
|
||||
UnloadImage(image); // Once texture has been created, we can unload image data from RAM
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// 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 - 30, WHITE);
|
||||
|
||||
DrawText("this IS a texture with mipmaps! really!", 210, 360, 20, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture); // Texture unloading
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 17 KiB |
139
src/audio.c
139
src/audio.c
|
@ -8,7 +8,7 @@
|
|||
* OpenAL Soft - Audio device management lib (http://kcat.strangesoft.net/openal.html)
|
||||
* stb_vorbis - Ogg audio files loading (http://www.nothings.org/stb_vorbis/)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
@ -27,7 +27,13 @@
|
|||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
//#define AUDIO_STANDALONE // NOTE: To use the audio module as standalone lib, just uncomment this line
|
||||
|
||||
#if defined(AUDIO_STANDALONE)
|
||||
#include "audio.h"
|
||||
#else
|
||||
#include "raylib.h"
|
||||
#endif
|
||||
|
||||
#include "AL/al.h" // OpenAL basic header
|
||||
#include "AL/alc.h" // OpenAL context header (like OpenGL, OpenAL requires a context to work)
|
||||
|
@ -36,8 +42,12 @@
|
|||
#include <string.h> // Required for strcmp()
|
||||
#include <stdio.h> // Used for .WAV loading
|
||||
|
||||
#include "utils.h" // rRES data decompression utility function
|
||||
#if defined(AUDIO_STANDALONE)
|
||||
#include <stdarg.h> // Used for functions with variable number of parameters (TraceLog())
|
||||
#else
|
||||
#include "utils.h" // rRES data decompression utility function
|
||||
// NOTE: Includes Android fopen function map
|
||||
#endif
|
||||
|
||||
//#define STB_VORBIS_HEADER_ONLY
|
||||
#include "stb_vorbis.h" // OGG loading functions
|
||||
|
@ -75,6 +85,10 @@ typedef struct Music {
|
|||
|
||||
} Music;
|
||||
|
||||
#if defined(AUDIO_STANDALONE)
|
||||
typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -85,13 +99,18 @@ static Music currentMusic; // Current music loaded
|
|||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
static Wave LoadWAV(const char *fileName); // Load WAV file
|
||||
static Wave LoadOGG(char *fileName); // Load OGG file
|
||||
static void UnloadWave(Wave wave); // Unload wave data
|
||||
static Wave LoadWAV(const char *fileName); // Load WAV file
|
||||
static Wave LoadOGG(char *fileName); // Load OGG file
|
||||
static void UnloadWave(Wave wave); // Unload wave data
|
||||
|
||||
static bool BufferMusicStream(ALuint buffer); // Fill music buffers with data
|
||||
static void EmptyMusicStream(void); // Empty music buffers
|
||||
extern void UpdateMusicStream(void); // Updates buffers (refill) for music streaming
|
||||
static bool BufferMusicStream(ALuint buffer); // Fill music buffers with data
|
||||
static void EmptyMusicStream(void); // Empty music buffers
|
||||
extern void UpdateMusicStream(void); // Updates buffers (refill) for music streaming
|
||||
|
||||
#if defined(AUDIO_STANDALONE)
|
||||
const char *GetExtension(const char *fileName); // Get the extension for a filename
|
||||
void TraceLog(int msgType, const char *text, ...); // Outputs a trace log message (INFO, ERROR, WARNING)
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition - Audio Device initialization and Closing
|
||||
|
@ -273,6 +292,11 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
|
|||
{
|
||||
// NOTE: rresName could be directly a char array with all the data!!! --> TODO
|
||||
Sound sound;
|
||||
|
||||
#if defined(AUDIO_STANDALONE)
|
||||
TraceLog(WARNING, "Sound loading from rRES resource file not supported on standalone mode");
|
||||
#else
|
||||
|
||||
bool found = false;
|
||||
|
||||
char id[4]; // rRES file identifier
|
||||
|
@ -416,7 +440,7 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
|
|||
}
|
||||
|
||||
if (!found) TraceLog(WARNING, "[%s] Required resource id [%i] could not be found in the raylib resource file", rresName, resId);
|
||||
|
||||
#endif
|
||||
return sound;
|
||||
}
|
||||
|
||||
|
@ -425,6 +449,8 @@ void UnloadSound(Sound sound)
|
|||
{
|
||||
alDeleteSources(1, &sound.source);
|
||||
alDeleteBuffers(1, &sound.buffer);
|
||||
|
||||
TraceLog(INFO, "Unloaded sound data");
|
||||
}
|
||||
|
||||
// Play a sound
|
||||
|
@ -777,6 +803,7 @@ static Wave LoadWAV(const char *fileName)
|
|||
if (wavFile == NULL)
|
||||
{
|
||||
TraceLog(WARNING, "[%s] WAV file could not be opened", fileName);
|
||||
wave.data = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -846,40 +873,49 @@ 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;
|
||||
if (oggFile == NULL)
|
||||
{
|
||||
TraceLog(WARNING, "[%s] OGG file could not be opened", fileName);
|
||||
wave.data = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
stb_vorbis_info info = stb_vorbis_get_info(oggFile);
|
||||
|
||||
TraceLog(DEBUG, "[%s] Ogg sample rate: %i", fileName, info.sample_rate);
|
||||
TraceLog(DEBUG, "[%s] Ogg channels: %i", fileName, info.channels);
|
||||
wave.sampleRate = info.sample_rate;
|
||||
wave.bitsPerSample = 16;
|
||||
wave.channels = info.channels;
|
||||
|
||||
int totalSamplesLength = (stb_vorbis_stream_length_in_samples(oggFile) * info.channels);
|
||||
TraceLog(DEBUG, "[%s] Ogg sample rate: %i", fileName, info.sample_rate);
|
||||
TraceLog(DEBUG, "[%s] Ogg channels: %i", fileName, info.channels);
|
||||
|
||||
wave.dataSize = totalSamplesLength*sizeof(short); // Size must be in bytes
|
||||
int totalSamplesLength = (stb_vorbis_stream_length_in_samples(oggFile) * info.channels);
|
||||
|
||||
TraceLog(DEBUG, "[%s] Samples length: %i", fileName, totalSamplesLength);
|
||||
wave.dataSize = totalSamplesLength*sizeof(short); // Size must be in bytes
|
||||
|
||||
float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile);
|
||||
TraceLog(DEBUG, "[%s] Samples length: %i", fileName, totalSamplesLength);
|
||||
|
||||
TraceLog(DEBUG, "[%s] Total seconds: %f", fileName, totalSeconds);
|
||||
float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile);
|
||||
|
||||
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);
|
||||
TraceLog(DEBUG, "[%s] Total seconds: %f", fileName, totalSeconds);
|
||||
|
||||
int totalSamples = totalSeconds*info.sample_rate*info.channels;
|
||||
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);
|
||||
|
||||
TraceLog(DEBUG, "[%s] Total samples calculated: %i", fileName, totalSamples);
|
||||
int totalSamples = totalSeconds*info.sample_rate*info.channels;
|
||||
|
||||
wave.data = malloc(sizeof(short)*totalSamplesLength);
|
||||
TraceLog(DEBUG, "[%s] Total samples calculated: %i", fileName, totalSamples);
|
||||
|
||||
int samplesObtained = stb_vorbis_get_samples_short_interleaved(oggFile, info.channels, wave.data, totalSamplesLength);
|
||||
wave.data = malloc(sizeof(short)*totalSamplesLength);
|
||||
|
||||
TraceLog(DEBUG, "[%s] Samples obtained: %i", fileName, samplesObtained);
|
||||
int samplesObtained = stb_vorbis_get_samples_short_interleaved(oggFile, info.channels, wave.data, totalSamplesLength);
|
||||
|
||||
TraceLog(INFO, "[%s] OGG file loaded successfully (SampleRate: %i, BitRate: %i, Channels: %i)", fileName, wave.sampleRate, wave.bitsPerSample, wave.channels);
|
||||
TraceLog(DEBUG, "[%s] Samples obtained: %i", fileName, samplesObtained);
|
||||
|
||||
stb_vorbis_close(oggFile);
|
||||
TraceLog(INFO, "[%s] OGG file loaded successfully (SampleRate: %i, BitRate: %i, Channels: %i)", fileName, wave.sampleRate, wave.bitsPerSample, wave.channels);
|
||||
|
||||
stb_vorbis_close(oggFile);
|
||||
}
|
||||
|
||||
return wave;
|
||||
}
|
||||
|
@ -888,4 +924,49 @@ static Wave LoadOGG(char *fileName)
|
|||
static void UnloadWave(Wave wave)
|
||||
{
|
||||
free(wave.data);
|
||||
|
||||
TraceLog(INFO, "Unloaded wave data");
|
||||
}
|
||||
|
||||
// Some required functions for audio standalone module version
|
||||
#if defined(AUDIO_STANDALONE)
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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 = 0;
|
||||
|
||||
#ifdef DO_NOT_TRACE_DEBUG_MSGS
|
||||
traceDebugMsgs = 0;
|
||||
#endif
|
||||
|
||||
switch(msgType)
|
||||
{
|
||||
case INFO: fprintf(stdout, "INFO: "); break;
|
||||
case ERROR: fprintf(stdout, "ERROR: "); break;
|
||||
case WARNING: fprintf(stdout, "WARNING: "); break;
|
||||
case DEBUG: if (traceDebugMsgs) fprintf(stdout, "DEBUG: "); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if ((msgType != DEBUG) || ((msgType == DEBUG) && (traceDebugMsgs)))
|
||||
{
|
||||
va_start(args, text);
|
||||
vfprintf(stdout, text, args);
|
||||
va_end(args);
|
||||
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
|
||||
if (msgType == ERROR) exit(1); // If ERROR message, exit program
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,102 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raylib.audio
|
||||
*
|
||||
* Basic functions to manage Audio: InitAudioDevice, LoadAudioFiles, PlayAudioFiles
|
||||
*
|
||||
* Uses external lib:
|
||||
* OpenAL Soft - Audio device management lib (http://kcat.strangesoft.net/openal.html)
|
||||
* stb_vorbis - Ogg audio files loading (http://www.nothings.org/stb_vorbis/)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||
* in the product documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||
* as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef AUDIO_H
|
||||
#define AUDIO_H
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
// NOTE: Below types are required for CAMERA_STANDALONE usage
|
||||
//----------------------------------------------------------------------------------
|
||||
#ifndef __cplusplus
|
||||
// Boolean type
|
||||
typedef enum { false, true } bool;
|
||||
#endif
|
||||
|
||||
// Sound source type
|
||||
typedef struct Sound {
|
||||
unsigned int source;
|
||||
unsigned int buffer;
|
||||
} Sound;
|
||||
|
||||
// Wave type, defines audio wave data
|
||||
typedef struct Wave {
|
||||
void *data; // Buffer data pointer
|
||||
unsigned int dataSize; // Data size in bytes
|
||||
unsigned int sampleRate;
|
||||
short bitsPerSample;
|
||||
short channels;
|
||||
} Wave;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void InitAudioDevice(void); // Initialize audio device and context
|
||||
void CloseAudioDevice(void); // Close the audio device and context (and music stream)
|
||||
|
||||
Sound LoadSound(char *fileName); // Load sound to memory
|
||||
Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
|
||||
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 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 UpdateMusicStream(void); // Updates buffers for music streaming
|
||||
void StopMusicStream(void); // Stop music playing (close stream)
|
||||
void PauseMusicStream(void); // Pause music playing
|
||||
void ResumeMusicStream(void); // Resume playing paused music
|
||||
bool MusicIsPlaying(void); // Check if music is playing
|
||||
void SetMusicVolume(float volume); // Set volume for music (1.0 is max level)
|
||||
float GetMusicTimeLength(void); // Get current music time length (in seconds)
|
||||
float GetMusicTimePlayed(void); // Get current music time played (in seconds)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // AUDIO_H
|
309
src/camera.c
309
src/camera.c
|
@ -1,8 +1,6 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raylib.camera
|
||||
*
|
||||
* Camera Modes Setup and Control Functions
|
||||
* raylib Camera System - Camera Modes Setup and Control Functions
|
||||
*
|
||||
* Copyright (c) 2015 Marc Palau and Ramon Santamaria
|
||||
*
|
||||
|
@ -23,7 +21,14 @@
|
|||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "camera.h"
|
||||
//#define CAMERA_STANDALONE // NOTE: To use the camera module as standalone lib, just uncomment this line
|
||||
// NOTE: ProcessCamera() should be reviewed to adapt inputs to other systems
|
||||
|
||||
#if defined(CAMERA_STANDALONE)
|
||||
#include "camera.h"
|
||||
#else
|
||||
#include "raylib.h"
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
@ -49,7 +54,7 @@
|
|||
//#define FIRST_PERSON_MOUSE_SENSITIVITY 0.003
|
||||
#define FIRST_PERSON_FOCUS_DISTANCE 25
|
||||
#define FIRST_PERSON_MIN_CLAMP 85
|
||||
#define FIRST_PERSON_MAX_CLAMP -85
|
||||
#define FIRST_PERSON_MAX_CLAMP -85
|
||||
|
||||
#define FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 5.0
|
||||
#define FIRST_PERSON_STEP_DIVIDER 30.0
|
||||
|
@ -61,7 +66,7 @@
|
|||
//#define THIRD_PERSON_MOUSE_SENSITIVITY 0.003
|
||||
#define THIRD_PERSON_DISTANCE_CLAMP 1.2
|
||||
#define THIRD_PERSON_MIN_CLAMP 5
|
||||
#define THIRD_PERSON_MAX_CLAMP -85
|
||||
#define THIRD_PERSON_MAX_CLAMP -85
|
||||
#define THIRD_PERSON_OFFSET (Vector3){ 0.4, 0, 0 }
|
||||
|
||||
// PLAYER (used by camera)
|
||||
|
@ -70,23 +75,27 @@
|
|||
#define PLAYER_DEPTH 0.4
|
||||
#define PLAYER_MOVEMENT_DIVIDER 20.0
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// Camera move modes (first person and third person cameras)
|
||||
typedef enum { MOVE_FRONT = 0, MOVE_LEFT, MOVE_BACK, MOVE_RIGHT, MOVE_UP, MOVE_DOWN } CameraMove;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
static Camera internalCamera = {{2,0,2},{0,0,0},{0,1,0}};
|
||||
static Vector2 cameraAngle = { 0, 0 };
|
||||
static float cameraTargetDistance = 5;
|
||||
static Vector3 resetingPosition = { 0, 0, 0 };
|
||||
static int resetingKey = 'Z';
|
||||
static Vector2 cameraMousePosition = { 0, 0 };
|
||||
static Vector2 cameraMouseVariation = { 0, 0 };
|
||||
static float mouseSensitivity = 0.003;
|
||||
static int cameraMovementController[6] = { 'W', 'A', 'S', 'D', 'E', 'Q' };
|
||||
static int cameraMovementCounter = 0;
|
||||
static bool cameraUseGravity = true;
|
||||
static int pawnControllingKey = MOUSE_MIDDLE_BUTTON;
|
||||
static int fnControllingKey = KEY_LEFT_ALT;
|
||||
static int smoothZoomControllingKey = KEY_LEFT_CONTROL;
|
||||
static int cameraMoveControl[6] = { 'W', 'A', 'S', 'D', 'E', 'Q' };
|
||||
static int cameraMoveCounter = 0;
|
||||
static int cameraUseGravity = 1;
|
||||
static int panControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON
|
||||
static int altControlKey = 342; // raylib: KEY_LEFT_ALT
|
||||
static int smoothZoomControlKey = 341; // raylib: KEY_LEFT_CONTROL
|
||||
|
||||
static int cameraMode = CAMERA_CUSTOM;
|
||||
|
||||
|
@ -95,6 +104,20 @@ static int cameraMode = CAMERA_CUSTOM;
|
|||
//----------------------------------------------------------------------------------
|
||||
static void ProcessCamera(Camera *camera, Vector3 *playerPosition);
|
||||
|
||||
#if defined(CAMERA_STANDALONE)
|
||||
// NOTE: Camera controls depend on some raylib input functions
|
||||
// TODO: Set your own input functions (used in ProcessCamera())
|
||||
static Vector2 GetMousePosition() { return (Vector2){ 0, 0}; }
|
||||
static void SetMousePosition(Vector2 pos) {}
|
||||
static int IsMouseButtonDown(int button) { return 0;}
|
||||
static int GetMouseWheelMove() { return 0; }
|
||||
static int GetScreenWidth() { return 1280; }
|
||||
static int GetScreenHeight() { return 720; }
|
||||
static void ShowCursor() {}
|
||||
static void HideCursor() {}
|
||||
static int IsKeyDown(int key) { return 0; }
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -123,6 +146,8 @@ void SetCameraMode(int mode)
|
|||
cameraAngle.y = -40 * DEG2RAD;
|
||||
internalCamera.target = (Vector3){ 0, 0, 0};
|
||||
ProcessCamera(&internalCamera, &internalCamera.position);
|
||||
|
||||
ShowCursor();
|
||||
}
|
||||
else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_ORBITAL))
|
||||
{
|
||||
|
@ -145,15 +170,14 @@ Camera UpdateCamera(Vector3 *position)
|
|||
return internalCamera;
|
||||
}
|
||||
|
||||
|
||||
void SetCameraControls(int frontKey, int leftKey, int backKey, int rightKey, int upKey, int downKey)
|
||||
void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, int upKey, int downKey)
|
||||
{
|
||||
cameraMovementController[0] = frontKey;
|
||||
cameraMovementController[1] = leftKey;
|
||||
cameraMovementController[2] = backKey;
|
||||
cameraMovementController[3] = rightKey;
|
||||
cameraMovementController[4] = upKey;
|
||||
cameraMovementController[5] = downKey;
|
||||
cameraMoveControl[MOVE_FRONT] = frontKey;
|
||||
cameraMoveControl[MOVE_LEFT] = leftKey;
|
||||
cameraMoveControl[MOVE_BACK] = backKey;
|
||||
cameraMoveControl[MOVE_RIGHT] = rightKey;
|
||||
cameraMoveControl[MOVE_UP] = upKey;
|
||||
cameraMoveControl[MOVE_DOWN] = downKey;
|
||||
}
|
||||
|
||||
void SetCameraMouseSensitivity(float sensitivity)
|
||||
|
@ -161,32 +185,22 @@ void SetCameraMouseSensitivity(float sensitivity)
|
|||
mouseSensitivity = (sensitivity / 10000.0);
|
||||
}
|
||||
|
||||
void SetCameraResetPosition(Vector3 resetPosition)
|
||||
void SetCameraPanControl(int panKey)
|
||||
{
|
||||
resetingPosition = resetPosition;
|
||||
panControlKey = panKey;
|
||||
}
|
||||
|
||||
void SetCameraResetControl(int resetKey)
|
||||
void SetCameraAltControl(int altKey)
|
||||
{
|
||||
resetingKey = resetKey;
|
||||
altControlKey = altKey;
|
||||
}
|
||||
|
||||
void SetCameraPawnControl(int pawnControlKey)
|
||||
void SetCameraSmoothZoomControl(int szKey)
|
||||
{
|
||||
pawnControllingKey = pawnControlKey;
|
||||
smoothZoomControlKey = szKey;
|
||||
}
|
||||
|
||||
void SetCameraFnControl(int fnControlKey)
|
||||
{
|
||||
fnControllingKey = fnControlKey;
|
||||
}
|
||||
|
||||
void SetCameraSmoothZoomControl(int smoothZoomControlKey)
|
||||
{
|
||||
smoothZoomControllingKey = smoothZoomControlKey;
|
||||
}
|
||||
|
||||
void SetCameraOrbitalTarget(Vector3 target)
|
||||
void SetCameraTarget(Vector3 target)
|
||||
{
|
||||
internalCamera.target = target;
|
||||
}
|
||||
|
@ -197,33 +211,43 @@ void SetCameraOrbitalTarget(Vector3 target)
|
|||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Process desired camera mode and controls
|
||||
// NOTE: Camera controls depend on some raylib functions:
|
||||
// Mouse: GetMousePosition(), SetMousePosition(), IsMouseButtonDown(), GetMouseWheelMove()
|
||||
// System: GetScreenWidth(), GetScreenHeight(), ShowCursor(), HideCursor()
|
||||
// Keys: IsKeyDown()
|
||||
static void ProcessCamera(Camera *camera, Vector3 *playerPosition)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) || defined(PLATFORM_RPI)
|
||||
// Mouse movement detection
|
||||
Vector2 mousePosition = GetMousePosition();
|
||||
int mouseWheelMove = GetMouseWheelMove();
|
||||
int panKey = IsMouseButtonDown(panControlKey); // bool value
|
||||
|
||||
int screenWidth = GetScreenWidth();
|
||||
int screenHeight = GetScreenHeight();
|
||||
|
||||
if ((cameraMode != CAMERA_FREE) && (cameraMode != CAMERA_ORBITAL))
|
||||
{
|
||||
HideCursor();
|
||||
|
||||
if (GetMousePosition().x < GetScreenHeight() / 3) SetMousePosition((Vector2){ GetScreenWidth() - GetScreenHeight() / 3, GetMousePosition().y});
|
||||
else if (GetMousePosition().y < GetScreenHeight() / 3) SetMousePosition((Vector2){ GetMousePosition().x, GetScreenHeight() - GetScreenHeight() / 3});
|
||||
else if (GetMousePosition().x > GetScreenWidth() - GetScreenHeight() / 3) SetMousePosition((Vector2) { GetScreenHeight() / 3, GetMousePosition().y});
|
||||
else if (GetMousePosition().y > GetScreenHeight() - GetScreenHeight() / 3) SetMousePosition((Vector2){ GetMousePosition().x, GetScreenHeight() / 3});
|
||||
if (mousePosition.x < screenHeight/3) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y});
|
||||
else if (mousePosition.y < screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3});
|
||||
else if (mousePosition.x > screenWidth - screenHeight/3) SetMousePosition((Vector2) { screenHeight/3, mousePosition.y});
|
||||
else if (mousePosition.y > screenHeight - screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3});
|
||||
else
|
||||
{
|
||||
cameraMouseVariation.x = GetMousePosition().x - cameraMousePosition.x;
|
||||
cameraMouseVariation.y = GetMousePosition().y - cameraMousePosition.y;
|
||||
cameraMouseVariation.x = mousePosition.x - cameraMousePosition.x;
|
||||
cameraMouseVariation.y = mousePosition.y - cameraMousePosition.y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowCursor();
|
||||
|
||||
cameraMouseVariation.x = GetMousePosition().x - cameraMousePosition.x;
|
||||
cameraMouseVariation.y = GetMousePosition().y - cameraMousePosition.y;
|
||||
cameraMouseVariation.x = mousePosition.x - cameraMousePosition.x;
|
||||
cameraMouseVariation.y = mousePosition.y - cameraMousePosition.y;
|
||||
}
|
||||
|
||||
cameraMousePosition = GetMousePosition();
|
||||
cameraMousePosition = mousePosition;
|
||||
|
||||
// Support for multiple automatic camera modes
|
||||
switch (cameraMode)
|
||||
|
@ -231,92 +255,93 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition)
|
|||
case CAMERA_FREE:
|
||||
{
|
||||
// Camera zoom
|
||||
if ((cameraTargetDistance < FREE_CAMERA_DISTANCE_MAX_CLAMP) && (GetMouseWheelMove() < 0))
|
||||
if ((cameraTargetDistance < FREE_CAMERA_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
|
||||
{
|
||||
cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY);
|
||||
cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY);
|
||||
|
||||
if (cameraTargetDistance > FREE_CAMERA_DISTANCE_MAX_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MAX_CLAMP;
|
||||
}
|
||||
// Camera looking down
|
||||
else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == FREE_CAMERA_DISTANCE_MAX_CLAMP) && (GetMouseWheelMove() < 0))
|
||||
else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == FREE_CAMERA_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
|
||||
{
|
||||
camera->target.x += GetMouseWheelMove() * (camera->target.x - camera->position.x) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.y += GetMouseWheelMove() * (camera->target.y - camera->position.y) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.z += GetMouseWheelMove() * (camera->target.z - camera->position.z) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
|
||||
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
|
||||
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
|
||||
}
|
||||
else if ((camera->position.y > camera->target.y) && (camera->target.y >= 0))
|
||||
{
|
||||
camera->target.x += GetMouseWheelMove() * (camera->target.x - camera->position.x) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.y += GetMouseWheelMove() * (camera->target.y - camera->position.y) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.z += GetMouseWheelMove() * (camera->target.z - camera->position.z) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
|
||||
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
|
||||
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
|
||||
|
||||
if (camera->target.y < 0) camera->target.y = -0.001;
|
||||
}
|
||||
else if ((camera->position.y > camera->target.y) && (camera->target.y < 0) && (GetMouseWheelMove() > 0))
|
||||
else if ((camera->position.y > camera->target.y) && (camera->target.y < 0) && (mouseWheelMove > 0))
|
||||
{
|
||||
cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY);
|
||||
cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY);
|
||||
if (cameraTargetDistance < FREE_CAMERA_DISTANCE_MIN_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MIN_CLAMP;
|
||||
}
|
||||
// Camera looking up
|
||||
else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == FREE_CAMERA_DISTANCE_MAX_CLAMP) && (GetMouseWheelMove() < 0))
|
||||
else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == FREE_CAMERA_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
|
||||
{
|
||||
camera->target.x += GetMouseWheelMove() * (camera->target.x - camera->position.x) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.y += GetMouseWheelMove() * (camera->target.y - camera->position.y) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.z += GetMouseWheelMove() * (camera->target.z - camera->position.z) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
|
||||
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
|
||||
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
|
||||
}
|
||||
else if ((camera->position.y < camera->target.y) && (camera->target.y <= 0))
|
||||
{
|
||||
camera->target.x += GetMouseWheelMove() * (camera->target.x - camera->position.x) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.y += GetMouseWheelMove() * (camera->target.y - camera->position.y) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.z += GetMouseWheelMove() * (camera->target.z - camera->position.z) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
|
||||
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
|
||||
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
|
||||
|
||||
if (camera->target.y > 0) camera->target.y = 0.001;
|
||||
}
|
||||
else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (GetMouseWheelMove() > 0))
|
||||
else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (mouseWheelMove > 0))
|
||||
{
|
||||
cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY);
|
||||
cameraTargetDistance -= (mouseWheelMove * CAMERA_SCROLL_SENSITIVITY);
|
||||
if (cameraTargetDistance < FREE_CAMERA_DISTANCE_MIN_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MIN_CLAMP;
|
||||
}
|
||||
|
||||
// Inputs
|
||||
if (IsKeyDown(fnControllingKey))
|
||||
if (IsKeyDown(altControlKey))
|
||||
{
|
||||
if (IsKeyDown(smoothZoomControllingKey))
|
||||
if (IsKeyDown(smoothZoomControlKey))
|
||||
{
|
||||
// Camera smooth zoom
|
||||
if (IsMouseButtonDown(pawnControllingKey)) cameraTargetDistance += (cameraMouseVariation.y * FREE_CAMERA_SMOOTH_ZOOM_SENSITIVITY);
|
||||
if (panKey) cameraTargetDistance += (cameraMouseVariation.y*FREE_CAMERA_SMOOTH_ZOOM_SENSITIVITY);
|
||||
}
|
||||
// Camera orientation calculation
|
||||
else if (IsMouseButtonDown(pawnControllingKey))
|
||||
else if (panKey)
|
||||
{
|
||||
// Camera orientation calculation
|
||||
// Get the mouse sensitivity
|
||||
cameraAngle.x += cameraMouseVariation.x * -FREE_CAMERA_MOUSE_SENSITIVITY;
|
||||
cameraAngle.y += cameraMouseVariation.y * -FREE_CAMERA_MOUSE_SENSITIVITY;
|
||||
cameraAngle.x += cameraMouseVariation.x*-FREE_CAMERA_MOUSE_SENSITIVITY;
|
||||
cameraAngle.y += cameraMouseVariation.y*-FREE_CAMERA_MOUSE_SENSITIVITY;
|
||||
|
||||
// Angle clamp
|
||||
if (cameraAngle.y > FREE_CAMERA_MIN_CLAMP * DEG2RAD) cameraAngle.y = FREE_CAMERA_MIN_CLAMP * DEG2RAD;
|
||||
else if (cameraAngle.y < FREE_CAMERA_MAX_CLAMP * DEG2RAD) cameraAngle.y = FREE_CAMERA_MAX_CLAMP * DEG2RAD;
|
||||
if (cameraAngle.y > FREE_CAMERA_MIN_CLAMP*DEG2RAD) cameraAngle.y = FREE_CAMERA_MIN_CLAMP*DEG2RAD;
|
||||
else if (cameraAngle.y < FREE_CAMERA_MAX_CLAMP*DEG2RAD) cameraAngle.y = FREE_CAMERA_MAX_CLAMP*DEG2RAD;
|
||||
}
|
||||
}
|
||||
// Paning
|
||||
else if (IsMouseButtonDown(pawnControllingKey))
|
||||
else if (panKey)
|
||||
{
|
||||
camera->target.x += ((cameraMouseVariation.x * -FREE_CAMERA_MOUSE_SENSITIVITY) * cos(cameraAngle.x) + (cameraMouseVariation.y * FREE_CAMERA_MOUSE_SENSITIVITY) * sin(cameraAngle.x) * sin(cameraAngle.y)) * (cameraTargetDistance / FREE_CAMERA_PANNING_DIVIDER);
|
||||
camera->target.y += ((cameraMouseVariation.y * FREE_CAMERA_MOUSE_SENSITIVITY) * cos(cameraAngle.y)) * (cameraTargetDistance / FREE_CAMERA_PANNING_DIVIDER);
|
||||
camera->target.z += ((cameraMouseVariation.x * FREE_CAMERA_MOUSE_SENSITIVITY) * sin(cameraAngle.x) + (cameraMouseVariation.y * FREE_CAMERA_MOUSE_SENSITIVITY) * cos(cameraAngle.x) * sin(cameraAngle.y)) * (cameraTargetDistance / FREE_CAMERA_PANNING_DIVIDER);
|
||||
camera->target.x += ((cameraMouseVariation.x*-FREE_CAMERA_MOUSE_SENSITIVITY)*cos(cameraAngle.x) + (cameraMouseVariation.y*FREE_CAMERA_MOUSE_SENSITIVITY)*sin(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/FREE_CAMERA_PANNING_DIVIDER);
|
||||
camera->target.y += ((cameraMouseVariation.y*FREE_CAMERA_MOUSE_SENSITIVITY)*cos(cameraAngle.y))*(cameraTargetDistance/FREE_CAMERA_PANNING_DIVIDER);
|
||||
camera->target.z += ((cameraMouseVariation.x*FREE_CAMERA_MOUSE_SENSITIVITY)*sin(cameraAngle.x) + (cameraMouseVariation.y*FREE_CAMERA_MOUSE_SENSITIVITY)*cos(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/FREE_CAMERA_PANNING_DIVIDER);
|
||||
}
|
||||
|
||||
// Focus to center
|
||||
if (IsKeyDown(resetingKey)) camera->target = resetingPosition;
|
||||
// TODO: Move this function out of the module?
|
||||
if (IsKeyDown('Z')) camera->target = (Vector3){ 0, 0, 0 };
|
||||
|
||||
// Camera position update
|
||||
camera->position.x = sin(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.x;
|
||||
camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x;
|
||||
|
||||
if (cameraAngle.y <= 0) camera->position.y = sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
else camera->position.y = -sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
if (cameraAngle.y <= 0) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
|
||||
else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
|
||||
|
||||
camera->position.z = cos(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.z;
|
||||
camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z;
|
||||
|
||||
} break;
|
||||
case CAMERA_ORBITAL:
|
||||
|
@ -324,126 +349,126 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition)
|
|||
cameraAngle.x += ORBITAL_CAMERA_SPEED;
|
||||
|
||||
// Camera zoom
|
||||
cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY);
|
||||
cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY);
|
||||
|
||||
// Camera distance clamp
|
||||
if (cameraTargetDistance < THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = THIRD_PERSON_DISTANCE_CLAMP;
|
||||
|
||||
// Focus to center
|
||||
if (IsKeyDown('Z')) camera->target = (Vector3) { 0, 0, 0 };
|
||||
if (IsKeyDown('Z')) camera->target = (Vector3){ 0, 0, 0 };
|
||||
|
||||
// Camera position update
|
||||
camera->position.x = sin(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.x;
|
||||
camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x;
|
||||
|
||||
if (cameraAngle.y <= 0) camera->position.y = sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
else camera->position.y = -sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
if (cameraAngle.y <= 0) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
|
||||
else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
|
||||
|
||||
camera->position.z = cos(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.z;
|
||||
camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z;
|
||||
|
||||
} break;
|
||||
case CAMERA_FIRST_PERSON:
|
||||
case CAMERA_THIRD_PERSON:
|
||||
{
|
||||
bool isMoving = false;
|
||||
int isMoving = 0;
|
||||
|
||||
// Keyboard inputs
|
||||
if (IsKeyDown(cameraMovementController[0]))
|
||||
if (IsKeyDown(cameraMoveControl[MOVE_FRONT]))
|
||||
{
|
||||
playerPosition->x -= sin(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->z -= cos(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
if (!cameraUseGravity) camera->position.y += sin(cameraAngle.y) / PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->x -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->z -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER;
|
||||
|
||||
isMoving = true;
|
||||
if (!cameraUseGravity) camera->position.y += sin(cameraAngle.y)/PLAYER_MOVEMENT_DIVIDER;
|
||||
|
||||
isMoving = 1;
|
||||
}
|
||||
else if (IsKeyDown(cameraMovementController[2]))
|
||||
else if (IsKeyDown(cameraMoveControl[MOVE_BACK]))
|
||||
{
|
||||
playerPosition->x += sin(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->z += cos(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
if (!cameraUseGravity) camera->position.y -= sin(cameraAngle.y) / PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->x += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->z += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER;
|
||||
|
||||
isMoving = true;
|
||||
if (!cameraUseGravity) camera->position.y -= sin(cameraAngle.y)/PLAYER_MOVEMENT_DIVIDER;
|
||||
|
||||
isMoving = 1;
|
||||
}
|
||||
|
||||
if (IsKeyDown(cameraMovementController[1]))
|
||||
if (IsKeyDown(cameraMoveControl[MOVE_LEFT]))
|
||||
{
|
||||
playerPosition->x -= cos(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->z += sin(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->x -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->z += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER;
|
||||
|
||||
isMoving = true;
|
||||
isMoving = 1;
|
||||
}
|
||||
else if (IsKeyDown(cameraMovementController[3]))
|
||||
else if (IsKeyDown(cameraMoveControl[MOVE_RIGHT]))
|
||||
{
|
||||
playerPosition->x += cos(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->z -= sin(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->x += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->z -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER;
|
||||
|
||||
isMoving = true;
|
||||
isMoving = 1;
|
||||
}
|
||||
|
||||
if (IsKeyDown(cameraMovementController[4]))
|
||||
if (IsKeyDown(cameraMoveControl[MOVE_UP]))
|
||||
{
|
||||
if (!cameraUseGravity) playerPosition->y += 1 / PLAYER_MOVEMENT_DIVIDER;
|
||||
if (!cameraUseGravity) playerPosition->y += 1/PLAYER_MOVEMENT_DIVIDER;
|
||||
}
|
||||
else if (IsKeyDown(cameraMovementController[5]))
|
||||
else if (IsKeyDown(cameraMoveControl[MOVE_DOWN]))
|
||||
{
|
||||
if (!cameraUseGravity) playerPosition->y -= 1 / PLAYER_MOVEMENT_DIVIDER;
|
||||
if (!cameraUseGravity) playerPosition->y -= 1/PLAYER_MOVEMENT_DIVIDER;
|
||||
}
|
||||
|
||||
if (cameraMode == CAMERA_THIRD_PERSON)
|
||||
{
|
||||
// Camera orientation calculation
|
||||
// Get the mouse sensitivity
|
||||
cameraAngle.x += cameraMouseVariation.x * -mouseSensitivity;
|
||||
cameraAngle.y += cameraMouseVariation.y * -mouseSensitivity;
|
||||
cameraAngle.x += cameraMouseVariation.x*-mouseSensitivity;
|
||||
cameraAngle.y += cameraMouseVariation.y*-mouseSensitivity;
|
||||
|
||||
// Angle clamp
|
||||
if (cameraAngle.y > THIRD_PERSON_MIN_CLAMP * DEG2RAD) cameraAngle.y = THIRD_PERSON_MIN_CLAMP * DEG2RAD;
|
||||
else if (cameraAngle.y < THIRD_PERSON_MAX_CLAMP * DEG2RAD) cameraAngle.y = THIRD_PERSON_MAX_CLAMP * DEG2RAD;
|
||||
if (cameraAngle.y > THIRD_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = THIRD_PERSON_MIN_CLAMP*DEG2RAD;
|
||||
else if (cameraAngle.y < THIRD_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = THIRD_PERSON_MAX_CLAMP*DEG2RAD;
|
||||
|
||||
// Camera zoom
|
||||
cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY);
|
||||
cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY);
|
||||
|
||||
// Camera distance clamp
|
||||
if (cameraTargetDistance < THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = THIRD_PERSON_DISTANCE_CLAMP;
|
||||
|
||||
// Camera is always looking at player
|
||||
camera->target.x = playerPosition->x + THIRD_PERSON_OFFSET.x * cos(cameraAngle.x) + THIRD_PERSON_OFFSET.z * sin(cameraAngle.x);
|
||||
camera->target.y = playerPosition->y + PLAYER_HEIGHT * FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION + THIRD_PERSON_OFFSET.y;
|
||||
camera->target.z = playerPosition->z + THIRD_PERSON_OFFSET.z * sin(cameraAngle.x) - THIRD_PERSON_OFFSET.x * sin(cameraAngle.x);
|
||||
camera->target.x = playerPosition->x + THIRD_PERSON_OFFSET.x*cos(cameraAngle.x) + THIRD_PERSON_OFFSET.z*sin(cameraAngle.x);
|
||||
camera->target.y = playerPosition->y + PLAYER_HEIGHT*FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION + THIRD_PERSON_OFFSET.y;
|
||||
camera->target.z = playerPosition->z + THIRD_PERSON_OFFSET.z*sin(cameraAngle.x) - THIRD_PERSON_OFFSET.x*sin(cameraAngle.x);
|
||||
|
||||
// Camera position update
|
||||
camera->position.x = sin(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.x;
|
||||
camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x;
|
||||
|
||||
if (cameraAngle.y <= 0) camera->position.y = sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
else camera->position.y = -sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
if (cameraAngle.y <= 0) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
|
||||
else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
|
||||
|
||||
camera->position.z = cos(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.z;
|
||||
camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z;
|
||||
}
|
||||
else
|
||||
else // CAMERA_FIRST_PERSON
|
||||
{
|
||||
if (isMoving) cameraMovementCounter++;
|
||||
if (isMoving) cameraMoveCounter++;
|
||||
|
||||
// Camera orientation calculation
|
||||
// Get the mouse sensitivity
|
||||
cameraAngle.x += cameraMouseVariation.x * -mouseSensitivity;
|
||||
cameraAngle.y += cameraMouseVariation.y * -mouseSensitivity;
|
||||
cameraAngle.x += cameraMouseVariation.x*-mouseSensitivity;
|
||||
cameraAngle.y += cameraMouseVariation.y*-mouseSensitivity;
|
||||
|
||||
// Angle clamp
|
||||
if (cameraAngle.y > FIRST_PERSON_MIN_CLAMP * DEG2RAD) cameraAngle.y = FIRST_PERSON_MIN_CLAMP * DEG2RAD;
|
||||
else if (cameraAngle.y < FIRST_PERSON_MAX_CLAMP * DEG2RAD) cameraAngle.y = FIRST_PERSON_MAX_CLAMP * DEG2RAD;
|
||||
if (cameraAngle.y > FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = FIRST_PERSON_MIN_CLAMP*DEG2RAD;
|
||||
else if (cameraAngle.y < FIRST_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = FIRST_PERSON_MAX_CLAMP*DEG2RAD;
|
||||
|
||||
// Camera is always looking at player
|
||||
camera->target.x = camera->position.x - sin(cameraAngle.x) * FIRST_PERSON_FOCUS_DISTANCE;
|
||||
camera->target.y = camera->position.y + sin(cameraAngle.y) * FIRST_PERSON_FOCUS_DISTANCE;
|
||||
camera->target.z = camera->position.z - cos(cameraAngle.x) * FIRST_PERSON_FOCUS_DISTANCE;
|
||||
camera->target.x = camera->position.x - sin(cameraAngle.x)*FIRST_PERSON_FOCUS_DISTANCE;
|
||||
camera->target.y = camera->position.y + sin(cameraAngle.y)*FIRST_PERSON_FOCUS_DISTANCE;
|
||||
camera->target.z = camera->position.z - cos(cameraAngle.x)*FIRST_PERSON_FOCUS_DISTANCE;
|
||||
|
||||
camera->position.x = playerPosition->x;
|
||||
camera->position.y = (playerPosition->y + PLAYER_HEIGHT * FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION) - sin(cameraMovementCounter / FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER) / FIRST_PERSON_STEP_DIVIDER;
|
||||
camera->position.y = (playerPosition->y + PLAYER_HEIGHT*FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION) - sin(cameraMoveCounter/FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/FIRST_PERSON_STEP_DIVIDER;
|
||||
camera->position.z = playerPosition->z;
|
||||
|
||||
camera->up.x = sin(cameraMovementCounter / (FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER * 2)) / FIRST_PERSON_WAVING_DIVIDER;
|
||||
camera->up.z = -sin(cameraMovementCounter / (FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER * 2)) / FIRST_PERSON_WAVING_DIVIDER;
|
||||
camera->up.x = sin(cameraMoveCounter/(FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/FIRST_PERSON_WAVING_DIVIDER;
|
||||
camera->up.z = -sin(cameraMoveCounter/(FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/FIRST_PERSON_WAVING_DIVIDER;
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
#endif
|
||||
}
|
49
src/camera.h
49
src/camera.h
|
@ -24,7 +24,12 @@
|
|||
#ifndef CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
#include "raylib.h"
|
||||
#ifndef PI
|
||||
#define PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define DEG2RAD (PI / 180.0f)
|
||||
#define RAD2DEG (180.0f / PI)
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
|
@ -33,10 +38,30 @@
|
|||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
// NOTE: Below types are required for CAMERA_STANDALONE usage
|
||||
//----------------------------------------------------------------------------------
|
||||
// Camera modes
|
||||
typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode;
|
||||
|
||||
// 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;
|
||||
Vector3 target;
|
||||
Vector3 up;
|
||||
} Camera;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
|
@ -50,17 +75,19 @@ extern "C" { // Prevents name mangling of functions
|
|||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void SetCameraMode(int mode); // Select camera mode (multiple camera modes available)
|
||||
Camera UpdateCamera(Vector3 *position); // Update camera with position
|
||||
void SetCameraMode(int mode); // Set camera mode (multiple camera modes available)
|
||||
Camera UpdateCamera(Vector3 *playerPosition); // Update camera and player position (1st person and 3rd person cameras)
|
||||
|
||||
void SetCameraControls(int front, int left, int back, int right, int up, int down);
|
||||
void SetCameraMouseSensitivity(float sensitivity);
|
||||
void SetCameraResetPosition(Vector3 resetPosition);
|
||||
void SetCameraResetControl(int resetKey);
|
||||
void SetCameraPawnControl(int pawnControlKey);
|
||||
void SetCameraFnControl(int fnControlKey);
|
||||
void SetCameraSmoothZoomControl(int smoothZoomControlKey);
|
||||
void SetCameraOrbitalTarget(Vector3 target);
|
||||
void SetCameraMoveControls(int frontKey, int backKey,
|
||||
int leftKey, int rightKey,
|
||||
int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras)
|
||||
|
||||
void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera)
|
||||
void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera)
|
||||
void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera)
|
||||
|
||||
void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras)
|
||||
void SetCameraTarget(Vector3 target); // Set internal camera target
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
208
src/core.c
208
src/core.c
|
@ -17,7 +17,7 @@
|
|||
*
|
||||
* On PLATFORM_RPI, graphic device is managed by EGL and input system is coded in raw mode.
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
@ -164,7 +164,7 @@ static bool customCursor = false; // Tracks if custom cursor has been
|
|||
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
|
||||
static Texture2D cursor; // Cursor texture
|
||||
|
||||
static Vector2 mousePosition;
|
||||
static Vector2 mousePosition; // Mouse position on screen
|
||||
|
||||
static char previousKeyState[512] = { 0 }; // Required to check if key pressed/released once
|
||||
static char currentKeyState[512] = { 0 }; // Required to check if key pressed/released once
|
||||
|
@ -179,9 +179,12 @@ static int previousMouseWheelY = 0; // Required to track mouse wheel var
|
|||
static int currentMouseWheelY = 0; // Required to track mouse wheel variation
|
||||
|
||||
static int exitKey = KEY_ESCAPE; // Default exit key (ESC)
|
||||
static int lastKeyPressed = -1;
|
||||
static int lastKeyPressed = -1; // Register last key pressed
|
||||
|
||||
static bool cursorHidden;
|
||||
static bool cursorHidden; // Track if cursor is hidden
|
||||
|
||||
static char **dropFilesPath; // Store dropped files paths as strings
|
||||
static int dropFilesCount = 0; // Count stored strings
|
||||
#endif
|
||||
|
||||
static double currentTime, previousTime; // Used to track timmings
|
||||
|
@ -189,8 +192,8 @@ static double updateTime, drawTime; // Time measures for update and draw
|
|||
static double frameTime; // Time measure for one frame
|
||||
static double targetTime = 0.0; // Desired time for one frame, if 0 not applied
|
||||
|
||||
static char configFlags = 0;
|
||||
static bool showLogo = false;
|
||||
static char configFlags = 0; // Configuration flags (bit based)
|
||||
static bool showLogo = false; // Track if showing logo at init is enabled
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Other Modules Functions Declaration (required by core)
|
||||
|
@ -198,19 +201,6 @@ static bool showLogo = false;
|
|||
extern void LoadDefaultFont(void); // [Module: text] Loads default font on InitWindow()
|
||||
extern void UnloadDefaultFont(void); // [Module: text] Unloads default font from GPU memory
|
||||
|
||||
extern void UpdateMusicStream(void); // [Module: audio] Updates buffers for music streaming
|
||||
|
||||
extern Vector2 GetRawPosition(void);
|
||||
extern void ResetGestures(void);
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
extern void InitAndroidGestures(struct android_app *app);
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
extern void InitWebGestures(void); // [Module: gestures] Initializes emscripten gestures for web
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -241,7 +231,11 @@ static void CharCallback(GLFWwindow *window, unsigned int key);
|
|||
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 WindowIconifyCallback(GLFWwindow* window, int iconified); // GLFW3 WindowIconify Callback, runs when window is minimized/restored
|
||||
static void WindowIconifyCallback(GLFWwindow *window, int iconified); // GLFW3 WindowIconify Callback, runs when window is minimized/restored
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
static void WindowDropCallback(GLFWwindow *window, int count, const char **paths); // GLFW3 Window Drop Callback, runs when drop files into window
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
|
@ -284,10 +278,6 @@ void InitWindow(int width, int height, const char *title)
|
|||
InitGamepad(); // Gamepad init
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
InitWebGestures(); // Init touch input events for web
|
||||
#endif
|
||||
|
||||
mousePosition.x = screenWidth/2;
|
||||
mousePosition.y = screenHeight/2;
|
||||
|
||||
|
@ -341,7 +331,7 @@ void InitWindow(int width, int height, struct android_app *state)
|
|||
//state->userData = &engine;
|
||||
app->onAppCmd = AndroidCommandCallback;
|
||||
|
||||
InitAndroidGestures(app);
|
||||
//InitGesturesSystem(app); // NOTE: Must be called by user
|
||||
|
||||
InitAssetManager(app->activity->assetManager);
|
||||
|
||||
|
@ -412,6 +402,16 @@ bool WindowShouldClose(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
// Detect if window has been minimized (or lost focus)
|
||||
bool IsWindowMinimized(void)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
return windowMinimized;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Fullscreen toggle
|
||||
void ToggleFullscreen(void)
|
||||
{
|
||||
|
@ -497,14 +497,8 @@ void EndDrawing(void)
|
|||
|
||||
SwapBuffers(); // Copy back buffer to front buffer
|
||||
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
|
||||
ResetGestures();
|
||||
#endif
|
||||
|
||||
PollInputEvents(); // Poll user events
|
||||
|
||||
UpdateMusicStream(); // NOTE: Function checks if music is enabled
|
||||
|
||||
currentTime = GetTime();
|
||||
drawTime = currentTime - previousTime;
|
||||
previousTime = currentTime;
|
||||
|
@ -538,6 +532,7 @@ void Begin3dMode(Camera camera)
|
|||
double top = 0.1f*tan(45.0f*PI / 360.0f);
|
||||
double right = top*aspect;
|
||||
|
||||
// NOTE: zNear and zFar values are important when computing depth buffer values
|
||||
rlFrustum(-right, right, -top, top, 0.1f, 1000.0f);
|
||||
|
||||
rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
|
||||
|
@ -565,7 +560,7 @@ void End3dMode(void)
|
|||
// Set target FPS for the game
|
||||
void SetTargetFPS(int fps)
|
||||
{
|
||||
targetTime = 1 / (float)fps;
|
||||
targetTime = 1 / (double)fps;
|
||||
|
||||
TraceLog(INFO, "Target time per frame: %02.03f milliseconds", (float)targetTime*1000);
|
||||
}
|
||||
|
@ -573,16 +568,16 @@ void SetTargetFPS(int fps)
|
|||
// Returns current FPS
|
||||
float GetFPS(void)
|
||||
{
|
||||
return (1/(float)frameTime);
|
||||
return (float)(1/frameTime);
|
||||
}
|
||||
|
||||
// Returns time in seconds for one frame
|
||||
float GetFrameTime(void)
|
||||
{
|
||||
// As we are operating quite a lot with frameTime, it could be no stable
|
||||
// so we round it before before passing around to be used
|
||||
// As we are operate quite a lot with frameTime,
|
||||
// it could be no stable, so we round it before passing it around
|
||||
// NOTE: There are still problems with high framerates (>500fps)
|
||||
double roundedFrameTime = round(frameTime*10000) / 10000;
|
||||
double roundedFrameTime = round(frameTime*10000)/10000;
|
||||
|
||||
return (float)roundedFrameTime; // Time in seconds to run a frame
|
||||
}
|
||||
|
@ -643,6 +638,34 @@ void ShowLogo(void)
|
|||
showLogo = true;
|
||||
}
|
||||
|
||||
// Check if a file have been dropped into window
|
||||
bool IsFileDropped(void)
|
||||
{
|
||||
if (dropFilesCount > 0) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
// Retrieve dropped files into window
|
||||
char **GetDroppedFiles(int *count)
|
||||
{
|
||||
*count = dropFilesCount;
|
||||
return dropFilesPath;
|
||||
}
|
||||
|
||||
// Clear dropped files paths buffer
|
||||
void ClearDroppedFiles(void)
|
||||
{
|
||||
if (dropFilesCount > 0)
|
||||
{
|
||||
for (int i = 0; i < dropFilesCount; i++) free(dropFilesPath[i]);
|
||||
|
||||
free(dropFilesPath);
|
||||
|
||||
dropFilesCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Gives the ray trace from mouse position
|
||||
Ray GetMouseRay(Vector2 mousePosition, Camera camera)
|
||||
{
|
||||
Ray ray;
|
||||
|
@ -650,24 +673,28 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera)
|
|||
Matrix proj = MatrixIdentity();
|
||||
Matrix view = MatrixLookAt(camera.position, camera.target, camera.up);
|
||||
|
||||
// Calculate projection matrix for the camera
|
||||
float aspect = (GLfloat)GetScreenWidth()/(GLfloat)GetScreenHeight();
|
||||
double top = 0.1f*tanf(45.0f*PI / 360.0f);
|
||||
double top = 0.1f*tanf(45.0f*PI/360.0f);
|
||||
double right = top*aspect;
|
||||
|
||||
// NOTE: zNear and zFar values are important for depth
|
||||
proj = MatrixFrustum(-right, right, -top, top, 0.01f, 1000.0f);
|
||||
MatrixTranspose(&proj);
|
||||
|
||||
float realy = (float)GetScreenHeight() - mousePosition.y;
|
||||
// NOTE: Our screen origin is top-left instead of bottom-left: transform required!
|
||||
float invertedMouseY = (float)GetScreenHeight() - mousePosition.y;
|
||||
|
||||
// NOTE: Do I really need to get z value from depth buffer?
|
||||
//float z;
|
||||
// glReadPixels(mousePosition.x, mousePosition.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);
|
||||
//glReadPixels(mousePosition.x, mousePosition.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);
|
||||
//http://www.bfilipek.com/2012/06/select-mouse-opengl.html
|
||||
|
||||
Vector3 nearPoint = { mousePosition.x, realy, 0.0f };
|
||||
Vector3 farPoint = { mousePosition.x, realy, 1.0f };
|
||||
Vector3 nearPoint = { mousePosition.x, invertedMouseY, 0.0f };
|
||||
Vector3 farPoint = { mousePosition.x, invertedMouseY, 1.0f };
|
||||
|
||||
//nearPoint = internalCamera.position;
|
||||
farPoint = rlglUnproject(farPoint, proj, view);
|
||||
nearPoint = rlglUnproject(nearPoint, proj, view);
|
||||
farPoint = rlglUnproject(farPoint, proj, view); // TODO: it seems it doesn't work...
|
||||
|
||||
Vector3 direction = VectorSubtract(farPoint, nearPoint);
|
||||
VectorNormalize(&direction);
|
||||
|
@ -791,7 +818,11 @@ void SetMousePosition(Vector2 position)
|
|||
// Returns mouse wheel movement Y
|
||||
int GetMouseWheelMove(void)
|
||||
{
|
||||
#if defined(PLATFORM_WEB)
|
||||
return previousMouseWheelY/100;
|
||||
#else
|
||||
return previousMouseWheelY;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Hide mouse cursor
|
||||
|
@ -933,40 +964,6 @@ bool IsGamepadButtonUp(int gamepad, int button)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
|
||||
// Returns touch position X
|
||||
int GetTouchX(void)
|
||||
{
|
||||
return (int)GetRawPosition().x;
|
||||
}
|
||||
|
||||
// Returns touch position Y
|
||||
int GetTouchY(void)
|
||||
{
|
||||
return (int)GetRawPosition().y;
|
||||
}
|
||||
|
||||
// Returns touch position XY
|
||||
Vector2 GetTouchPosition(void)
|
||||
{
|
||||
Vector2 position = GetRawPosition();
|
||||
|
||||
if ((screenWidth > displayWidth) || (screenHeight > displayHeight))
|
||||
{
|
||||
// TODO: Seems to work ok but... review!
|
||||
position.x = position.x*((float)screenWidth / (float)(displayWidth - renderOffsetX)) - renderOffsetX/2;
|
||||
position.y = position.y*((float)screenHeight / (float)(displayHeight - renderOffsetY)) - renderOffsetY/2;
|
||||
}
|
||||
else
|
||||
{
|
||||
position.x = position.x*((float)renderWidth / (float)displayWidth) - renderOffsetX/2;
|
||||
position.y = position.y*((float)renderHeight / (float)displayHeight) - renderOffsetY/2;
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -1010,7 +1007,8 @@ static void InitDisplay(int width, int height)
|
|||
|
||||
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable
|
||||
//glfwWindowHint(GLFW_DECORATED, GL_TRUE); // Border and buttons on Window
|
||||
//glfwWindowHint(GLFW_RED_BITS, 8); // Bit depths of color components for default framebuffer
|
||||
//glfwWindowHint(GLFW_RED_BITS, 8); // Color framebuffer red component bits
|
||||
//glfwWindowHint(GLFW_DEPTH_BITS, 16); // Depth buffer bits (24 by default)
|
||||
//glfwWindowHint(GLFW_REFRESH_RATE, 0); // Refresh rate for fullscreen window
|
||||
//glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); // Default OpenGL API to use. Alternative: GLFW_OPENGL_ES_API
|
||||
//glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers
|
||||
|
@ -1074,6 +1072,9 @@ static void InitDisplay(int width, int height)
|
|||
glfwSetCharCallback(window, CharCallback);
|
||||
glfwSetScrollCallback(window, ScrollCallback);
|
||||
glfwSetWindowIconifyCallback(window, WindowIconifyCallback);
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
glfwSetDropCallback(window, WindowDropCallback);
|
||||
#endif
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
|
@ -1106,7 +1107,14 @@ static void InitDisplay(int width, int height)
|
|||
VC_RECT_T srcRect;
|
||||
#endif
|
||||
|
||||
// TODO: if (configFlags & FLAG_MSAA_4X_HINT) activate (EGL_SAMPLES, 4)
|
||||
EGLint samples = 0;
|
||||
EGLint sampleBuffer = 0;
|
||||
if (configFlags & FLAG_MSAA_4X_HINT)
|
||||
{
|
||||
samples = 4;
|
||||
sampleBuffer = 1;
|
||||
}
|
||||
|
||||
const EGLint framebufferAttribs[] =
|
||||
{
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Type of context support -> Required on RPI?
|
||||
|
@ -1115,10 +1123,10 @@ static void InitDisplay(int width, int height)
|
|||
EGL_GREEN_SIZE, 8, // GREEN color bit depth (alternative: 6)
|
||||
EGL_BLUE_SIZE, 8, // BLUE color bit depth (alternative: 5)
|
||||
//EGL_ALPHA_SIZE, 8, // ALPHA bit depth
|
||||
EGL_DEPTH_SIZE, 8, // Depth buffer size (Required to use Depth testing!)
|
||||
EGL_DEPTH_SIZE, 16, // Depth buffer size (Required to use Depth testing!)
|
||||
//EGL_STENCIL_SIZE, 8, // Stencil buffer size
|
||||
//EGL_SAMPLE_BUFFERS, 1, // Activate MSAA
|
||||
//EGL_SAMPLES, 4, // 4x Antialiasing (Free on MALI GPUs)
|
||||
EGL_SAMPLE_BUFFERS, sampleBuffer, // Activate MSAA
|
||||
EGL_SAMPLES, samples, // 4x Antialiasing if activated (Free on MALI GPUs)
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
|
@ -1317,20 +1325,28 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height)
|
|||
// GLFW3 WindowIconify Callback, runs when window is minimized/restored
|
||||
static void WindowIconifyCallback(GLFWwindow* window, int iconified)
|
||||
{
|
||||
if (iconified)
|
||||
{
|
||||
// The window was iconified
|
||||
PauseMusicStream();
|
||||
if (iconified) windowMinimized = true; // The window was iconified
|
||||
else windowMinimized = false; // The window was restored
|
||||
}
|
||||
#endif
|
||||
|
||||
windowMinimized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The window was restored
|
||||
ResumeMusicStream();
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
// GLFW3 Window Drop Callback, runs when drop files into window
|
||||
// NOTE: Paths are stored in dinamic memory for further retrieval
|
||||
// Everytime new files are dropped, old ones are discarded
|
||||
static void WindowDropCallback(GLFWwindow *window, int count, const char **paths)
|
||||
{
|
||||
ClearDroppedFiles();
|
||||
|
||||
windowMinimized = false;
|
||||
dropFilesPath = (char **)malloc(sizeof(char *)*count);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
dropFilesPath[i] = (char *)malloc(sizeof(char)*256); // Max path length set to 256 char
|
||||
strcpy(dropFilesPath[i], paths[i]);
|
||||
}
|
||||
|
||||
dropFilesCount = count;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1379,7 +1395,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||
case APP_CMD_GAINED_FOCUS:
|
||||
{
|
||||
TraceLog(INFO, "APP_CMD_GAINED_FOCUS");
|
||||
ResumeMusicStream();
|
||||
//ResumeMusicStream();
|
||||
} break;
|
||||
case APP_CMD_PAUSE:
|
||||
{
|
||||
|
@ -1389,7 +1405,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||
{
|
||||
//DrawFrame();
|
||||
TraceLog(INFO, "APP_CMD_LOST_FOCUS");
|
||||
PauseMusicStream();
|
||||
//PauseMusicStream();
|
||||
} break;
|
||||
case APP_CMD_TERM_WINDOW:
|
||||
{
|
||||
|
@ -1476,7 +1492,7 @@ static double GetTime(void)
|
|||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
uint64_t time = ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec;
|
||||
|
||||
return (double)(time - baseTime) * 1e-9;
|
||||
return (double)(time - baseTime)*1e-9;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
219
src/gestures.c
219
src/gestures.c
|
@ -1,8 +1,6 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raylib.gestures
|
||||
*
|
||||
* Gestures Detection and Usage Functions Definitions
|
||||
* raylib Gestures System - Gestures Detection and Usage Functions (Android and HTML5)
|
||||
*
|
||||
* Copyright (c) 2015 Marc Palau and Ramon Santamaria
|
||||
*
|
||||
|
@ -23,8 +21,13 @@
|
|||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "utils.h"
|
||||
//#define GESTURES_STANDALONE // NOTE: To use the gestures module as standalone lib, just uncomment this line
|
||||
|
||||
#if defined(GESTURES_STANDALONE)
|
||||
#include "gestures.h"
|
||||
#else
|
||||
#include "raylib.h" // Required for typedef(s): Vector2, Gestures
|
||||
#endif
|
||||
|
||||
#include <stdlib.h> // malloc(), free()
|
||||
#include <stdio.h> // printf(), fprintf()
|
||||
|
@ -53,9 +56,11 @@
|
|||
//----------------------------------------------------------------------------------
|
||||
#define FORCE_TO_SWIPE 20
|
||||
#define TAP_TIMEOUT 300
|
||||
|
||||
#define MAX_TOUCH_POINTS 4
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef enum {
|
||||
TYPE_MOTIONLESS,
|
||||
TYPE_DRAG,
|
||||
|
@ -75,72 +80,56 @@ typedef struct {
|
|||
Vector2 position[MAX_TOUCH_POINTS];
|
||||
} GestureEvent;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
static GestureType gestureType = TYPE_MOTIONLESS;
|
||||
static double eventTime = 0;
|
||||
//static int32_t touchId; // Not used...
|
||||
//static int32_t touchId; // Not used...
|
||||
|
||||
// Tap
|
||||
// Our initial press position on tap
|
||||
// Tap gesture variables
|
||||
static Vector2 initialTapPosition = { 0, 0 };
|
||||
|
||||
// Double tap
|
||||
// If we are double tapping or not
|
||||
// Double Tap gesture variables
|
||||
static bool doubleTapping = false;
|
||||
// If we recently made a tap
|
||||
static bool untap = false;
|
||||
static bool untap = false; // Check if recently done a tap
|
||||
|
||||
// Drag
|
||||
// Our initial press position on drag
|
||||
// Drag gesture variables
|
||||
static Vector2 initialDragPosition = { 0, 0 };
|
||||
// Position that will compare itself with the mouse one
|
||||
static Vector2 endDragPosition = { 0, 0 };
|
||||
// Position of the last event detection
|
||||
static Vector2 lastDragPosition = { 0, 0 };
|
||||
// The total drag vector
|
||||
static Vector2 dragVector = { 0, 0 };
|
||||
// The distance traveled dragging
|
||||
static float magnitude = 0;
|
||||
// The angle direction of the drag
|
||||
static float angle = 0;
|
||||
// A magnitude to calculate how fast we did the drag ( pixels per frame )
|
||||
static float intensity = 0;
|
||||
// Time that have passed while dragging
|
||||
static int draggingTimeCounter = 0;
|
||||
|
||||
// Pinch
|
||||
// First initial pinch position
|
||||
static float magnitude = 0; // Distance traveled dragging
|
||||
static float angle = 0; // Angle direction of the drag
|
||||
static float intensity = 0; // How fast we did the drag (pixels per frame)
|
||||
static int draggingTimeCounter = 0; // Time that have passed while dragging
|
||||
|
||||
// Pinch gesture variables
|
||||
static Vector2 firstInitialPinchPosition = { 0, 0 };
|
||||
// Second initial pinch position
|
||||
static Vector2 secondInitialPinchPosition = { 0, 0 };
|
||||
// First end pinch position
|
||||
static Vector2 firstEndPinchPosition = { 0, 0 };
|
||||
// Second end pinch position
|
||||
static Vector2 secondEndPinchPosition = { 0, 0 };
|
||||
// Delta Displacement
|
||||
static float pinchDelta = 0;
|
||||
static float pinchDelta = 0; // Pinch delta displacement
|
||||
|
||||
// Detected gesture
|
||||
// Detected gestures
|
||||
static int previousGesture = GESTURE_NONE;
|
||||
static int currentGesture = GESTURE_NONE;
|
||||
unsigned int enabledGestures = 0; // TODO: Currently not in use...
|
||||
|
||||
static unsigned int enabledGestures = 0; // TODO: Currently not in use...
|
||||
|
||||
static Vector2 touchPosition;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
extern void ResetGestures(void);
|
||||
extern Vector2 GetRawPosition(void);
|
||||
|
||||
static void ProcessMotionEvent(GestureEvent event);
|
||||
|
||||
static void InitPinchGesture(Vector2 posA, Vector2 posB);
|
||||
static float CalculateAngle(Vector2 initialPosition, Vector2 actualPosition, float magnitude);
|
||||
static float OnPinch();
|
||||
static void SetDualInput(GestureEvent event);
|
||||
static float Distance(Vector2 v1, Vector2 v2);
|
||||
static float DotProduct(Vector2 v1, Vector2 v2);
|
||||
static float VectorDistance(Vector2 v1, Vector2 v2);
|
||||
static float VectorDotProduct(Vector2 v1, Vector2 v2);
|
||||
static double GetCurrentTime();
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
|
@ -155,15 +144,43 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
|||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Returns tap position XY
|
||||
extern Vector2 GetRawPosition(void)
|
||||
// Returns touch position X
|
||||
int GetTouchX(void)
|
||||
{
|
||||
return touchPosition;
|
||||
return (int)touchPosition.x;
|
||||
}
|
||||
|
||||
// Returns touch position Y
|
||||
int GetTouchY(void)
|
||||
{
|
||||
return (int)touchPosition.y;
|
||||
}
|
||||
|
||||
// Returns touch position XY
|
||||
// TODO: touch position should be scaled depending on display size and render size
|
||||
Vector2 GetTouchPosition(void)
|
||||
{
|
||||
Vector2 position = touchPosition;
|
||||
/*
|
||||
if ((screenWidth > displayWidth) || (screenHeight > displayHeight))
|
||||
{
|
||||
// TODO: Seems to work ok but... review!
|
||||
position.x = position.x*((float)screenWidth / (float)(displayWidth - renderOffsetX)) - renderOffsetX/2;
|
||||
position.y = position.y*((float)screenHeight / (float)(displayHeight - renderOffsetY)) - renderOffsetY/2;
|
||||
}
|
||||
else
|
||||
{
|
||||
position.x = position.x*((float)renderWidth / (float)displayWidth) - renderOffsetX/2;
|
||||
position.y = position.y*((float)renderHeight / (float)displayHeight) - renderOffsetY/2;
|
||||
}
|
||||
*/
|
||||
return position;
|
||||
}
|
||||
|
||||
// Check if a gesture have been detected
|
||||
bool IsGestureDetected(void)
|
||||
{
|
||||
/*
|
||||
if (currentGesture == GESTURE_DRAG) TraceLog(INFO, "DRAG");
|
||||
else if (currentGesture == GESTURE_TAP) TraceLog(INFO, "TAP");
|
||||
else if (currentGesture == GESTURE_DOUBLETAP) TraceLog(INFO, "DOUBLE");
|
||||
|
@ -174,6 +191,7 @@ bool IsGestureDetected(void)
|
|||
else if (currentGesture == GESTURE_SWIPE_DOWN) TraceLog(INFO, "DOWN");
|
||||
else if (currentGesture == GESTURE_PINCH_IN) TraceLog(INFO, "PINCH IN");
|
||||
else if (currentGesture == GESTURE_PINCH_OUT) TraceLog(INFO, "PINCH OUT");
|
||||
*/
|
||||
|
||||
if (currentGesture != GESTURE_NONE) return true;
|
||||
else return false;
|
||||
|
@ -228,33 +246,24 @@ float GetGesturePinchAngle(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
extern void ResetGestures(void)
|
||||
{
|
||||
if (currentGesture == GESTURE_TAP) currentGesture = GESTURE_HOLD;
|
||||
else if (currentGesture != GESTURE_HOLD) currentGesture = GESTURE_NONE;
|
||||
}
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
extern void InitWebGestures(void)
|
||||
// Init gestures system (web)
|
||||
void InitGesturesSystem(void)
|
||||
{
|
||||
/*
|
||||
emscripten_set_touchstart_callback("#canvas", data, 0, Emscripten_HandleTouch);
|
||||
emscripten_set_touchend_callback("#canvas", data, 0, Emscripten_HandleTouch);
|
||||
emscripten_set_touchmove_callback("#canvas", data, 0, Emscripten_HandleTouch);
|
||||
emscripten_set_touchcancel_callback("#canvas", data, 0, Emscripten_HandleTouch);
|
||||
*/
|
||||
// Init gestures system web (emscripten)
|
||||
|
||||
// NOTE: Some code examples
|
||||
//emscripten_set_touchstart_callback(0, NULL, 1, Emscripten_HandleTouch);
|
||||
//emscripten_set_touchend_callback("#canvas", data, 0, Emscripten_HandleTouch);
|
||||
|
||||
emscripten_set_touchstart_callback("#canvas", NULL, 1, EmscriptenInputCallback);
|
||||
emscripten_set_touchend_callback("#canvas", NULL, 1, EmscriptenInputCallback);
|
||||
emscripten_set_touchmove_callback("#canvas", NULL, 1, EmscriptenInputCallback);
|
||||
emscripten_set_touchcancel_callback("#canvas", NULL, 1, EmscriptenInputCallback);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
extern void InitAndroidGestures(struct android_app *app)
|
||||
#elif defined(PLATFORM_ANDROID)
|
||||
// Init gestures system (android)
|
||||
void InitGesturesSystem(struct android_app *app)
|
||||
{
|
||||
app->onInputEvent = AndroidInputCallback;
|
||||
|
||||
|
@ -262,6 +271,15 @@ extern void InitAndroidGestures(struct android_app *app)
|
|||
}
|
||||
#endif
|
||||
|
||||
// Update gestures detected (must be called every frame)
|
||||
void UpdateGestures(void)
|
||||
{
|
||||
// NOTE: Gestures are processed through system callbacks on touch events
|
||||
|
||||
if ((previousGesture == GESTURE_TAP) && (currentGesture == GESTURE_TAP)) currentGesture = GESTURE_HOLD;
|
||||
else if (currentGesture != GESTURE_HOLD) currentGesture = GESTURE_NONE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -271,13 +289,15 @@ static void ProcessMotionEvent(GestureEvent event)
|
|||
dragVector = (Vector2){ 0, 0 };
|
||||
pinchDelta = 0;
|
||||
|
||||
previousGesture = currentGesture;
|
||||
|
||||
switch (gestureType)
|
||||
{
|
||||
case TYPE_MOTIONLESS: // Detect TAP, DOUBLE_TAP and HOLD events
|
||||
{
|
||||
if (event.action == DOWN)
|
||||
{
|
||||
if (event.pointCount > 1) SetDualInput(event);
|
||||
if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]);
|
||||
else
|
||||
{
|
||||
// Set the press position
|
||||
|
@ -317,7 +337,7 @@ static void ProcessMotionEvent(GestureEvent event)
|
|||
// Begin dragging
|
||||
else if (event.action == MOVE)
|
||||
{
|
||||
if (event.pointCount > 1) SetDualInput(event);
|
||||
if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]);
|
||||
else
|
||||
{
|
||||
// Set the drag starting position
|
||||
|
@ -354,7 +374,7 @@ static void ProcessMotionEvent(GestureEvent event)
|
|||
// Update while we are dragging
|
||||
else if (event.action == MOVE)
|
||||
{
|
||||
if (event.pointCount > 1) SetDualInput(event);
|
||||
if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]);
|
||||
else
|
||||
{
|
||||
lastDragPosition = endDragPosition;
|
||||
|
@ -395,8 +415,17 @@ static void ProcessMotionEvent(GestureEvent event)
|
|||
// If there is no more than two inputs
|
||||
if (event.pointCount == 2)
|
||||
{
|
||||
// Detect pinch delta
|
||||
pinchDelta = OnPinch();
|
||||
// Calculate distances
|
||||
float initialDistance = VectorDistance(firstInitialPinchPosition, secondInitialPinchPosition);
|
||||
float endDistance = VectorDistance(firstEndPinchPosition, secondEndPinchPosition);
|
||||
|
||||
// Calculate Vectors
|
||||
Vector2 firstTouchVector = { firstEndPinchPosition.x - firstInitialPinchPosition.x, firstEndPinchPosition.y - firstInitialPinchPosition.y };
|
||||
Vector2 secondTouchVector = { secondEndPinchPosition.x - secondInitialPinchPosition.x, secondEndPinchPosition.y - secondInitialPinchPosition.y };
|
||||
|
||||
// Detect the pinch gesture
|
||||
if (VectorDotProduct(firstTouchVector, secondTouchVector) < -0.5) pinchDelta = initialDistance - endDistance;
|
||||
else pinchDelta = 0;
|
||||
|
||||
// Pinch gesture resolution
|
||||
if (pinchDelta != 0)
|
||||
|
@ -422,36 +451,30 @@ static void ProcessMotionEvent(GestureEvent event)
|
|||
//--------------------------------------------------------------------
|
||||
}
|
||||
|
||||
static float CalculateAngle(Vector2 initialPosition, Vector2 actualPosition, float magnitude)
|
||||
static float CalculateAngle(Vector2 initialPosition, Vector2 finalPosition, float magnitude)
|
||||
{
|
||||
float angle;
|
||||
|
||||
// Calculate arcsinus of the movement ( Our sinus is (actualPosition.y - initialPosition.y) / magnitude)
|
||||
angle = asin((actualPosition.y - initialPosition.y) / magnitude);
|
||||
// Calculate arcsinus of the movement
|
||||
angle = asin((finalPosition.y - initialPosition.y)/magnitude);
|
||||
angle *= RAD2DEG;
|
||||
|
||||
// Calculate angle depending on the sector
|
||||
if (actualPosition.x - initialPosition.x >= 0)
|
||||
if ((finalPosition.x - initialPosition.x) >= 0)
|
||||
{
|
||||
// Sector 4
|
||||
if (actualPosition.y - initialPosition.y >= 0)
|
||||
if ((finalPosition.y - initialPosition.y) >= 0)
|
||||
{
|
||||
angle *= -1;
|
||||
angle += 360;
|
||||
}
|
||||
// Sector 1
|
||||
else
|
||||
{
|
||||
angle *= -1;
|
||||
}
|
||||
else angle *= -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sector 3
|
||||
if (actualPosition.y - initialPosition.y >= 0)
|
||||
{
|
||||
angle += 180;
|
||||
}
|
||||
if ((finalPosition.y - initialPosition.y) >= 0) angle += 180;
|
||||
// Sector 2
|
||||
else
|
||||
{
|
||||
|
@ -463,31 +486,15 @@ static float CalculateAngle(Vector2 initialPosition, Vector2 actualPosition, flo
|
|||
return angle;
|
||||
}
|
||||
|
||||
static float OnPinch()
|
||||
{
|
||||
// Calculate distances
|
||||
float initialDistance = Distance(firstInitialPinchPosition, secondInitialPinchPosition);
|
||||
float endDistance = Distance(firstEndPinchPosition, secondEndPinchPosition);
|
||||
|
||||
// Calculate Vectors
|
||||
Vector2 firstTouchVector = { firstEndPinchPosition.x - firstInitialPinchPosition.x, firstEndPinchPosition.y - firstInitialPinchPosition.y };
|
||||
Vector2 secondTouchVector = { secondEndPinchPosition.x - secondInitialPinchPosition.x, secondEndPinchPosition.y - secondInitialPinchPosition.y };
|
||||
|
||||
// Detect the pinch gesture
|
||||
// Calculate Distances
|
||||
if (DotProduct(firstTouchVector, secondTouchVector) < -0.5) return initialDistance - endDistance;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
static void SetDualInput(GestureEvent event)
|
||||
static void InitPinchGesture(Vector2 posA, Vector2 posB)
|
||||
{
|
||||
initialDragPosition = (Vector2){ 0, 0 };
|
||||
endDragPosition = (Vector2){ 0, 0 };
|
||||
lastDragPosition = (Vector2){ 0, 0 };
|
||||
|
||||
// Initialize positions
|
||||
firstInitialPinchPosition = event.position[0];
|
||||
secondInitialPinchPosition = event.position[1];
|
||||
firstInitialPinchPosition = posA;
|
||||
secondInitialPinchPosition = posB;
|
||||
|
||||
firstEndPinchPosition = firstInitialPinchPosition;
|
||||
secondEndPinchPosition = secondInitialPinchPosition;
|
||||
|
@ -500,7 +507,7 @@ static void SetDualInput(GestureEvent event)
|
|||
gestureType = TYPE_DUAL_INPUT;
|
||||
}
|
||||
|
||||
static float Distance(Vector2 v1, Vector2 v2)
|
||||
static float VectorDistance(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
float result;
|
||||
|
||||
|
@ -512,7 +519,7 @@ static float Distance(Vector2 v1, Vector2 v2)
|
|||
return result;
|
||||
}
|
||||
|
||||
static float DotProduct(Vector2 v1, Vector2 v2)
|
||||
static float VectorDotProduct(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
float result;
|
||||
|
||||
|
@ -569,7 +576,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
|||
//int32_t key = AKeyEvent_getKeyCode(event);
|
||||
//int32_t AKeyEvent_getMetaState(event);
|
||||
|
||||
int32_t code = AKeyEvent_getKeyCode((const AInputEvent *)event);
|
||||
//int32_t code = AKeyEvent_getKeyCode((const AInputEvent *)event);
|
||||
|
||||
// If we are in active mode, we eat the back button and move into pause mode.
|
||||
// If we are already in pause mode, we allow the back button to be handled by the OS, which means we'll be shut down.
|
||||
|
@ -653,9 +660,3 @@ static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent
|
|||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raylib Gestures System - Gestures Detection and Usage Functions (Android and HTML5)
|
||||
*
|
||||
* Copyright (c) 2015 Marc Palau and Ramon Santamaria
|
||||
*
|
||||
* 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 GESTURES_H
|
||||
#define GESTURES_H
|
||||
|
||||
#ifndef PI
|
||||
#define PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define DEG2RAD (PI / 180.0f)
|
||||
#define RAD2DEG (180.0f / PI)
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
// NOTE: Below types are required for GESTURES_STANDALONE usage
|
||||
//----------------------------------------------------------------------------------
|
||||
#ifndef __cplusplus
|
||||
// Boolean type
|
||||
typedef enum { false, true } bool;
|
||||
#endif
|
||||
|
||||
// Vector2 type
|
||||
typedef struct Vector2 {
|
||||
float x;
|
||||
float y;
|
||||
} Vector2;
|
||||
|
||||
// Gestures type
|
||||
// NOTE: It could be used as flags to enable only some gestures
|
||||
typedef enum {
|
||||
GESTURE_NONE = 1,
|
||||
GESTURE_TAP = 2,
|
||||
GESTURE_DOUBLETAP = 4,
|
||||
GESTURE_HOLD = 8,
|
||||
GESTURE_DRAG = 16,
|
||||
GESTURE_SWIPE_RIGHT = 32,
|
||||
GESTURE_SWIPE_LEFT = 64,
|
||||
GESTURE_SWIPE_UP = 128,
|
||||
GESTURE_SWIPE_DOWN = 256,
|
||||
GESTURE_PINCH_IN = 512,
|
||||
GESTURE_PINCH_OUT = 1024
|
||||
} Gestures;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
int GetTouchX(void); // Returns touch position X (relative to screen size)
|
||||
int GetTouchY(void); // Returns touch position Y (relative to screen size)
|
||||
Vector2 GetTouchPosition(void); // Returns touch position XY (relative to screen size)
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
void InitGesturesSystem(void); // Init gestures system (web)
|
||||
#elif defined(PLATFORM_ANDROID)
|
||||
void InitGesturesSystem(struct android_app *app); // Init gestures system (android)
|
||||
#endif
|
||||
void UpdateGestures(void); // Update gestures detected (must be called every frame)
|
||||
bool IsGestureDetected(void); // Check if a gesture have been detected
|
||||
int GetGestureType(void); // Get latest detected gesture
|
||||
void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags
|
||||
|
||||
float GetGestureDragIntensity(void); // Get gesture drag intensity
|
||||
float GetGestureDragAngle(void); // Get gesture drag angle
|
||||
Vector2 GetGestureDragVector(void); // Get gesture drag vector
|
||||
int GetGestureHoldDuration(void); // Get gesture hold time in frames
|
||||
float GetGesturePinchDelta(void); // Get gesture pinch delta
|
||||
float GetGesturePinchAngle(void); // Get gesture pinch angle
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // GESTURES_H
|
|
@ -93,7 +93,7 @@ else
|
|||
endif
|
||||
|
||||
# define all object files required
|
||||
OBJS = core.o rlgl.o raymath.o shapes.o text.o textures.o models.o audio.o utils.o camera.o gestures.o
|
||||
OBJS = core.o rlgl.o raymath.o shapes.o text.o textures.o models.o audio.o utils.o camera.o gestures.o stb_vorbis.o
|
||||
|
||||
# typing 'make' will invoke the first target entry in the file,
|
||||
# in this case, the 'default' target entry is raylib
|
||||
|
@ -140,6 +140,10 @@ models.o: models.c
|
|||
audio.o: audio.c
|
||||
$(CC) -c audio.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile stb_vorbis library
|
||||
stb_vorbis.o: stb_vorbis.c
|
||||
$(CC) -c stb_vorbis.c -O1 $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile utils module
|
||||
utils.o: utils.c
|
||||
$(CC) -c utils.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
|
33
src/models.c
33
src/models.c
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* Basic functions to draw 3d shapes and load/draw 3d models (.OBJ)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
@ -559,21 +559,32 @@ Model LoadModel(const char *fileName)
|
|||
{
|
||||
VertexData vData;
|
||||
|
||||
Model model;
|
||||
|
||||
// TODO: Initialize default data for model in case loading fails, maybe a cube?
|
||||
|
||||
if (strcmp(GetExtension(fileName),"obj") == 0) vData = LoadOBJ(fileName);
|
||||
else TraceLog(WARNING, "[%s] Model extension not recognized, it can't be loaded", fileName);
|
||||
|
||||
// NOTE: At this point we have all vertex, texcoord, normal data for the model in vData struct
|
||||
|
||||
// NOTE: model properties (transform, texture, shader) are initialized inside rlglLoadModel()
|
||||
Model model = rlglLoadModel(vData); // Upload vertex data to GPU
|
||||
|
||||
// Now that vertex data is uploaded to GPU, we can free arrays
|
||||
// NOTE: We don't need CPU vertex data on OpenGL 3.3 or ES2
|
||||
if (rlGetVersion() != OPENGL_11)
|
||||
if (vData.vertexCount == 0)
|
||||
{
|
||||
free(vData.vertices);
|
||||
free(vData.texcoords);
|
||||
free(vData.normals);
|
||||
TraceLog(WARNING, "Model could not be loaded");
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: model properties (transform, texture, shader) are initialized inside rlglLoadModel()
|
||||
model = rlglLoadModel(vData); // Upload vertex data to GPU
|
||||
|
||||
// Now that vertex data is uploaded to GPU, we can free arrays
|
||||
// NOTE: We don't need CPU vertex data on OpenGL 3.3 or ES2
|
||||
if (rlGetVersion() != OPENGL_11)
|
||||
{
|
||||
free(vData.vertices);
|
||||
free(vData.texcoords);
|
||||
free(vData.normals);
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
|
@ -1105,6 +1116,8 @@ void UnloadModel(Model model)
|
|||
rlDeleteBuffers(model.mesh.vboId[2]);
|
||||
|
||||
rlDeleteVertexArrays(model.mesh.vaoId);
|
||||
|
||||
TraceLog(INFO, "Unloaded model data");
|
||||
}
|
||||
|
||||
// Link a texture to a model
|
||||
|
|
78
src/raylib.h
78
src/raylib.h
|
@ -36,7 +36,7 @@
|
|||
* 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:
|
||||
*
|
||||
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
* Copyright (c) 2013 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
@ -176,7 +176,6 @@
|
|||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
#ifndef __cplusplus
|
||||
// Boolean type
|
||||
typedef enum { false, true } bool;
|
||||
|
@ -354,6 +353,9 @@ typedef enum {
|
|||
COMPRESSED_ASTC_8x8_RGBA // 2 bpp
|
||||
} TextureFormat;
|
||||
|
||||
// Color blending modes (pre-defined)
|
||||
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
|
||||
|
||||
// Gestures type
|
||||
// NOTE: It could be used as flags to enable only some gestures
|
||||
typedef enum {
|
||||
|
@ -370,6 +372,9 @@ typedef enum {
|
|||
GESTURE_PINCH_OUT = 1024
|
||||
} Gestures;
|
||||
|
||||
// Camera system modes
|
||||
typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
|
@ -383,13 +388,14 @@ extern "C" { // Prevents name mangling of functions
|
|||
// Window and Graphics Device Functions (Module: core)
|
||||
//------------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
void InitWindow(int width, int height, struct android_app *state); // Init Android activity
|
||||
void InitWindow(int width, int height, struct android_app *state); // Init Android Activity and OpenGL Graphics
|
||||
#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics
|
||||
#endif
|
||||
|
||||
void CloseWindow(void); // Close Window and Terminate Context
|
||||
bool WindowShouldClose(void); // Detect if KEY_ESCAPE pressed or Close icon pressed
|
||||
bool IsWindowMinimized(void); // Detect if window has been minimized (or lost focus)
|
||||
void ToggleFullscreen(void); // Fullscreen toggle (only PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
void SetCustomCursor(const char *cursorImage); // Set a custom cursor icon/image
|
||||
|
@ -418,6 +424,10 @@ Color Fade(Color color, float alpha); // Color fade-in or
|
|||
void SetConfigFlags(char flags); // Enable some window configurations
|
||||
void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
|
||||
|
||||
bool IsFileDropped(void); // Check if a file have been dropped into window
|
||||
char **GetDroppedFiles(int *count); // Retrieve dropped files into window
|
||||
void ClearDroppedFiles(void); // Clear dropped files paths buffer
|
||||
|
||||
Ray GetMouseRay(Vector2 mousePosition, Camera camera); // TODO: Gives the ray trace from mouse position
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
@ -441,6 +451,8 @@ void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D textu
|
|||
void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture); // Specular map texture shader assignment
|
||||
void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textureUnit); // TODO: Generic shader map assignment
|
||||
|
||||
void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied)
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Input Handling Functions (Module: core)
|
||||
//------------------------------------------------------------------------------------
|
||||
|
@ -461,9 +473,9 @@ Vector2 GetMousePosition(void); // Returns mouse positio
|
|||
void SetMousePosition(Vector2 position); // Set mouse position XY
|
||||
int GetMouseWheelMove(void); // Returns mouse wheel movement Y
|
||||
|
||||
void ShowCursor(void); // Shows cursor
|
||||
void HideCursor(void); // Hides cursor
|
||||
bool IsCursorHidden(void); // Returns true if cursor is not visible
|
||||
void ShowCursor(void); // Shows cursor
|
||||
void HideCursor(void); // Hides cursor
|
||||
bool IsCursorHidden(void); // Returns true if cursor is not visible
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
|
@ -476,22 +488,47 @@ bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad b
|
|||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
|
||||
int GetTouchX(void); // Returns touch position X
|
||||
int GetTouchY(void); // Returns touch position Y
|
||||
Vector2 GetTouchPosition(void); // Returns touch position XY
|
||||
//------------------------------------------------------------------------------------
|
||||
// Gestures and Touch Handling Functions (Module: gestures)
|
||||
//------------------------------------------------------------------------------------
|
||||
int GetTouchX(void); // Returns touch position X (relative to screen size)
|
||||
int GetTouchY(void); // Returns touch position Y (relative to screen size)
|
||||
Vector2 GetTouchPosition(void); // Returns touch position XY (relative to screen size)
|
||||
|
||||
// Gestures System (module: gestures)
|
||||
bool IsGestureDetected(void);
|
||||
int GetGestureType(void);
|
||||
void SetGesturesEnabled(unsigned int gestureFlags);
|
||||
|
||||
float GetGestureDragIntensity(void);
|
||||
float GetGestureDragAngle(void);
|
||||
Vector2 GetGestureDragVector(void);
|
||||
int GetGestureHoldDuration(void); // Hold time in frames
|
||||
float GetGesturePinchDelta(void);
|
||||
float GetGesturePinchAngle(void);
|
||||
#if defined(PLATFORM_WEB)
|
||||
void InitGesturesSystem(void); // Init gestures system (web)
|
||||
#elif defined(PLATFORM_ANDROID)
|
||||
void InitGesturesSystem(struct android_app *app); // Init gestures system (android)
|
||||
#endif
|
||||
void UpdateGestures(void); // Update gestures detected (must be called every frame)
|
||||
bool IsGestureDetected(void); // Check if a gesture have been detected
|
||||
int GetGestureType(void); // Get latest detected gesture
|
||||
void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags
|
||||
|
||||
float GetGestureDragIntensity(void); // Get gesture drag intensity
|
||||
float GetGestureDragAngle(void); // Get gesture drag angle
|
||||
Vector2 GetGestureDragVector(void); // Get gesture drag vector
|
||||
int GetGestureHoldDuration(void); // Get gesture hold time in frames
|
||||
float GetGesturePinchDelta(void); // Get gesture pinch delta
|
||||
float GetGesturePinchAngle(void); // Get gesture pinch angle
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Camera System Functions (Module: camera)
|
||||
//------------------------------------------------------------------------------------
|
||||
void SetCameraMode(int mode); // Set camera mode (multiple camera modes available)
|
||||
Camera UpdateCamera(Vector3 *playerPosition); // Update camera and player position (1st person and 3rd person cameras)
|
||||
|
||||
void SetCameraMoveControls(int frontKey, int backKey,
|
||||
int leftKey, int rightKey,
|
||||
int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras)
|
||||
|
||||
void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera)
|
||||
void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera)
|
||||
void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera)
|
||||
|
||||
void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras)
|
||||
void SetCameraTarget(Vector3 target); // Set internal camera target
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Basic Shapes Drawing Functions (Module: shapes)
|
||||
|
@ -625,6 +662,7 @@ void SetSoundVolume(Sound sound, float volume); // Set volume fo
|
|||
void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
|
||||
|
||||
void PlayMusicStream(char *fileName); // Start music playing (open stream)
|
||||
void UpdateMusicStream(void); // Updates buffers for music streaming
|
||||
void StopMusicStream(void); // Stop music playing (close stream)
|
||||
void PauseMusicStream(void); // Pause music playing
|
||||
void ResumeMusicStream(void); // Resume playing paused music
|
||||
|
|
513
src/rlgl.c
513
src/rlgl.c
|
@ -7,7 +7,7 @@
|
|||
* OpenGL 3.3+ - Vertex data is stored in VAOs, call rlglDraw() to render
|
||||
* OpenGL ES 2 - Same behaviour as OpenGL 3.3+
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
@ -33,20 +33,21 @@
|
|||
#include <string.h> // Declares strcmp(), strlen(), strtok()
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
#ifdef __APPLE__ // OpenGL include for OSX
|
||||
#ifdef __APPLE__ // OpenGL include for OSX
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <GL/gl.h> // Basic OpenGL include
|
||||
#include <GL/gl.h> // Basic OpenGL include
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33)
|
||||
#define GLEW_STATIC
|
||||
#ifdef __APPLE__ // OpenGL include for OSX
|
||||
#ifdef __APPLE__ // OpenGL include for OSX
|
||||
#include <OpenGL/gl3.h>
|
||||
#else
|
||||
#include <GL/glew.h> // Extensions loading lib
|
||||
//#include "glad.h" // TODO: Other extensions loading lib? --> REVIEW
|
||||
#include <GL/glew.h> // GLEW extensions loading lib
|
||||
//#include "glad.h" // glad extensions loading lib: ERRORS: windows.h
|
||||
//#include "gl_core_3_3.h" // glLoadGen extension loading lib: ERRORS: windows.h
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -56,6 +57,10 @@
|
|||
#include <GLES2/gl2ext.h>
|
||||
#endif
|
||||
|
||||
#if defined(RLGL_STANDALONE)
|
||||
#include <stdarg.h> // Used for functions with variable number of parameters (TraceLog())
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -177,6 +182,10 @@ typedef struct {
|
|||
unsigned char a;
|
||||
} pixel;
|
||||
|
||||
#if defined(RLGL_STANDALONE)
|
||||
typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -218,7 +227,6 @@ static bool useTempBuffer = false;
|
|||
|
||||
// Flags for supported extensions
|
||||
static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support VAO extension)
|
||||
static bool npotSupported = false; // NPOT textures full support
|
||||
|
||||
// Compressed textures support flags
|
||||
//static bool texCompDXTSupported = false; // DDS texture compression support
|
||||
|
@ -236,7 +244,8 @@ static bool enabledPostpro = false;
|
|||
#endif
|
||||
|
||||
// Compressed textures support flags
|
||||
static bool texCompDXTSupported = false; // DDS texture compression support
|
||||
static bool texCompDXTSupported = false; // DDS texture compression support
|
||||
static bool npotSupported = false; // NPOT textures full support
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// NOTE: VAO functionality is exposed through extensions (OES)
|
||||
|
@ -246,6 +255,11 @@ static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays;
|
|||
//static PFNGLISVERTEXARRAYOESPROC glIsVertexArray; // NOTE: Fails in WebGL, omitted
|
||||
#endif
|
||||
|
||||
// Save screen size data (render size), required for postpro quad
|
||||
static int screenWidth, screenHeight;
|
||||
|
||||
static int blendMode = 0;
|
||||
|
||||
// White texture useful for plain color polys (required by shader)
|
||||
// NOTE: It's required in shapes and models modules!
|
||||
unsigned int whiteTexture;
|
||||
|
@ -273,6 +287,10 @@ static pixel *GenNextMipmap(pixel *srcData, int srcWidth, int srcHeight);
|
|||
static char** StringSplit(char *baseString, const char delimiter, int *numExt);
|
||||
#endif
|
||||
|
||||
#if defined(RLGL_STANDALONE)
|
||||
static void TraceLog(int msgType, const char *text, ...);
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition - Matrix operations
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -839,34 +857,68 @@ void rlglInit(void)
|
|||
|
||||
// NOTE: We don't need that much data on screen... right now...
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
TraceLog(INFO, "OpenGL 1.1 profile initialized");
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// Get supported extensions list
|
||||
GLint numExt;
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33)
|
||||
|
||||
#define GLEW_EXTENSIONS_LOADER
|
||||
#if defined(GLEW_EXTENSIONS_LOADER)
|
||||
// Initialize extensions using GLEW
|
||||
glewExperimental = 1; // Needed for core profile
|
||||
|
||||
GLenum error = glewInit();
|
||||
|
||||
if (error != GLEW_OK) TraceLog(ERROR, "Failed to initialize GLEW - Error Code: %s\n", glewGetErrorString(error));
|
||||
|
||||
if (glewIsSupported("GL_VERSION_3_3"))
|
||||
{
|
||||
TraceLog(INFO, "OpenGL 3.3 Core profile");
|
||||
TraceLog(INFO, "OpenGL 3.3 Core profile supported");
|
||||
|
||||
vaoSupported = true;
|
||||
npotSupported = true;
|
||||
}
|
||||
else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported");
|
||||
|
||||
// NOTE: GLEW is a big library that loads ALL extensions, we can use some alternative to load only required ones
|
||||
// Alternatives: glLoadGen, glad, libepoxy
|
||||
//if (!gladLoadGL()) TraceLog("ERROR: Failed to initialize glad\n");
|
||||
|
||||
// With GLEW we can check if an extension has been loaded in two ways:
|
||||
// With GLEW, we can check if an extension has been loaded in two ways:
|
||||
//if (GLEW_ARB_vertex_array_object) { }
|
||||
//if (glewIsSupported("GL_ARB_vertex_array_object")) { }
|
||||
|
||||
// NOTE: GLEW is a big library that loads ALL extensions, we can use some alternative to load only required ones
|
||||
// Alternatives: glLoadGen, glad, libepoxy
|
||||
|
||||
#elif defined(GLAD_EXTENSIONS_LOADER)
|
||||
// NOTE: glad is generated and contains only required OpenGL version and core extensions
|
||||
if (!gladLoadGL()) TraceLog(ERROR, "Failed to initialize glad\n");
|
||||
//if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) TraceLog(ERROR, "Failed to initialize glad\n");
|
||||
|
||||
if (GLAD_GL_VERSION_3_3)
|
||||
{
|
||||
TraceLog(INFO, "OpenGL 3.3 Core profile supported");
|
||||
|
||||
vaoSupported = true;
|
||||
npotSupported = true;
|
||||
}
|
||||
else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported");
|
||||
|
||||
// With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans
|
||||
//if (GLAD_GL_ARB_vertex_array_object) // Use GL_ARB_vertex_array_object
|
||||
|
||||
#elif defined(GLLOADGEN_EXTENSIONS_LOADER)
|
||||
// NOTE: glLoadGen already generates a header with required OpenGL version and core extensions
|
||||
if (ogl_LoadFunctions() != ogl_LOAD_FAILED)
|
||||
{
|
||||
TraceLog(INFO, "OpenGL 3.3 Core profile supported");
|
||||
|
||||
vaoSupported = true;
|
||||
npotSupported = true;
|
||||
}
|
||||
else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported");
|
||||
#endif
|
||||
|
||||
// NOTE: We don't need to check again supported extensions but we do (in case GLEW is replaced sometime)
|
||||
// We get a list of available extensions and we check for some of them (compressed textures)
|
||||
|
@ -995,6 +1047,7 @@ void rlglInit(void)
|
|||
}
|
||||
|
||||
// Init postpro system
|
||||
// NOTE: Uses global variables screenWidth and screenHeight
|
||||
void rlglInitPostpro(void)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
|
@ -1003,57 +1056,82 @@ void rlglInitPostpro(void)
|
|||
glBindTexture(GL_TEXTURE_2D, fboColorTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GetScreenWidth(), GetScreenHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screenWidth, screenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
// Create the texture that will serve as the depth attachment for the framebuffer.
|
||||
// Create the renderbuffer that will serve as the depth attachment for the framebuffer.
|
||||
glGenRenderbuffers(1, &fboDepthTexture);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, fboDepthTexture);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screenWidth, screenHeight);
|
||||
|
||||
// NOTE: We can also use a texture for depth buffer (GL_ARB_depth_texture/GL_OES_depth_texture extensions)
|
||||
// A renderbuffer is simpler than a texture and could offer better performance on embedded devices
|
||||
/*
|
||||
glGenTextures(1, &fboDepthTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, fboDepthTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GetScreenWidth(), GetScreenHeight(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
*/
|
||||
|
||||
// Create the framebuffer object
|
||||
glGenFramebuffers(1, &fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
|
||||
// Attach color texture and depth texture to FBO
|
||||
// Attach color texture and depth renderbuffer to FBO
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboColorTexture, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fboDepthTexture, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fboDepthTexture);
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) TraceLog(WARNING, "Framebuffer object could not be created...");
|
||||
else TraceLog(INFO, "[FBO ID %i] Framebuffer object created successfully", fbo);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
TraceLog(WARNING, "Framebuffer object could not be created...");
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
switch(status)
|
||||
{
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED: TraceLog(WARNING, "Framebuffer is unsupported"); break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: TraceLog(WARNING, "Framebuffer incomplete attachment"); break;
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: TraceLog(WARNING, "Framebuffer incomplete dimensions"); break;
|
||||
#endif
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: TraceLog(WARNING, "Framebuffer incomplete missing attachment"); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceLog(INFO, "[FBO ID %i] Framebuffer object created successfully", fbo);
|
||||
|
||||
// Create a simple quad model to render fbo texture
|
||||
VertexData quadData;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
quadData.vertexCount = 6;
|
||||
// Create a simple quad model to render fbo texture
|
||||
VertexData quadData;
|
||||
|
||||
float w = GetScreenWidth();
|
||||
float h = GetScreenHeight();
|
||||
quadData.vertexCount = 6;
|
||||
|
||||
float quadPositions[6*3] = { w, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, h, 0.0, 0, h, 0.0, w, h, 0.0, w, 0.0, 0.0 };
|
||||
float quadTexcoords[6*2] = { 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0 };
|
||||
float quadNormals[6*3] = { 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0 };
|
||||
unsigned char quadColors[6*4] = { 255 };
|
||||
float w = screenWidth;
|
||||
float h = screenHeight;
|
||||
|
||||
quadData.vertices = quadPositions;
|
||||
quadData.texcoords = quadTexcoords;
|
||||
quadData.normals = quadNormals;
|
||||
quadData.colors = quadColors;
|
||||
float quadPositions[6*3] = { w, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, h, 0.0, 0, h, 0.0, w, h, 0.0, w, 0.0, 0.0 };
|
||||
float quadTexcoords[6*2] = { 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0 };
|
||||
float quadNormals[6*3] = { 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0 };
|
||||
unsigned char quadColors[6*4] = { 255 };
|
||||
|
||||
postproQuad = rlglLoadModel(quadData);
|
||||
quadData.vertices = quadPositions;
|
||||
quadData.texcoords = quadTexcoords;
|
||||
quadData.normals = quadNormals;
|
||||
quadData.colors = quadColors;
|
||||
|
||||
// NOTE: fboColorTexture id must be assigned to postproQuad model shader
|
||||
postproQuad = rlglLoadModel(quadData);
|
||||
|
||||
// NOTE: fboColorTexture id must be assigned to postproQuad model shader
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1116,7 +1194,20 @@ void rlglClose(void)
|
|||
{
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
|
||||
UnloadModel(postproQuad);
|
||||
// Unload postpro quad model data
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
free(postproQuad.mesh.vertices);
|
||||
free(postproQuad.mesh.texcoords);
|
||||
free(postproQuad.mesh.normals);
|
||||
#endif
|
||||
|
||||
rlDeleteBuffers(postproQuad.mesh.vboId[0]);
|
||||
rlDeleteBuffers(postproQuad.mesh.vboId[1]);
|
||||
rlDeleteBuffers(postproQuad.mesh.vboId[2]);
|
||||
|
||||
rlDeleteVertexArrays(postproQuad.mesh.vaoId);
|
||||
|
||||
TraceLog(INFO, "Unloaded postpro quad data");
|
||||
}
|
||||
|
||||
free(draws);
|
||||
|
@ -1287,7 +1378,7 @@ void rlglDrawPostpro(void)
|
|||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
rlglDrawModel(postproQuad, (Vector3){0,0,0}, 0.0f, (Vector3){0,0,0}, (Vector3){1.0f, 1.0f, 1.0f}, WHITE, false);
|
||||
rlglDrawModel(postproQuad, (Vector3){0,0,0}, 0.0f, (Vector3){0,0,0}, (Vector3){1.0f, 1.0f, 1.0f}, (Color){ 255, 255, 255, 255 }, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1361,6 +1452,7 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r
|
|||
// Set shader textures (diffuse, normal, specular)
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, model.shader.texDiffuseId);
|
||||
glUniform1i(model.shader.mapDiffuseLoc, 0);
|
||||
|
||||
if (model.shader.texNormalId != 0)
|
||||
{
|
||||
|
@ -1390,14 +1482,21 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r
|
|||
glEnableVertexAttribArray(model.shader.texcoordLoc);
|
||||
|
||||
// Add normals support
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model.mesh.vboId[2]);
|
||||
glVertexAttribPointer(model.shader.normalLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||
glEnableVertexAttribArray(model.shader.normalLoc);
|
||||
if (model.shader.normalLoc != -1)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model.mesh.vboId[2]);
|
||||
glVertexAttribPointer(model.shader.normalLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||
glEnableVertexAttribArray(model.shader.normalLoc);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw call!
|
||||
glDrawArrays(GL_TRIANGLES, 0, model.mesh.vertexCount);
|
||||
|
||||
//glDisableVertexAttribArray(model.shader.vertexLoc);
|
||||
//glDisableVertexAttribArray(model.shader.texcoordLoc);
|
||||
//if (model.shader.normalLoc != -1) glDisableVertexAttribArray(model.shader.normalLoc);
|
||||
|
||||
if (model.shader.texNormalId != 0)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
|
@ -1426,17 +1525,23 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r
|
|||
}
|
||||
|
||||
// Initialize Graphics Device (OpenGL stuff)
|
||||
// NOTE: Stores global variables screenWidth and screenHeight
|
||||
void rlglInitGraphics(int offsetX, int offsetY, int width, int height)
|
||||
{
|
||||
// Save screen size data (global vars), required on postpro quad
|
||||
// NOTE: Size represents render size, it could differ from screen size!
|
||||
screenWidth = width;
|
||||
screenHeight = height;
|
||||
|
||||
// NOTE: Required! viewport must be recalculated if screen resized!
|
||||
glViewport(offsetX/2, offsetY/2, width - offsetX, height - offsetY); // Set viewport width and height
|
||||
|
||||
// NOTE: Don't confuse glViewport with the transformation matrix
|
||||
// NOTE: glViewport just defines the area of the context that you will actually draw to.
|
||||
|
||||
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, 1.0f); // Set background color (black)
|
||||
//glClearDepth(1.0f); // Clear depth buffer (default)
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear used buffers, depth buffer is used for 3D
|
||||
|
||||
glEnable(GL_DEPTH_TEST); // Enables depth testing (required for 3D)
|
||||
glDepthFunc(GL_LEQUAL); // Type of depth testing to apply
|
||||
|
@ -1468,170 +1573,61 @@ void rlglInitGraphics(int offsetX, int offsetY, int width, int height)
|
|||
// Possible options: GL_SMOOTH (Color interpolation) or GL_FLAT (no interpolation)
|
||||
#endif
|
||||
|
||||
TraceLog(INFO, "OpenGL Graphics initialized successfully");
|
||||
TraceLog(INFO, "OpenGL graphic device initialized successfully");
|
||||
}
|
||||
|
||||
// Get world coordinates from screen coordinates
|
||||
// TODO: It doesn't work! It drives me crazy!
|
||||
// NOTE: Using global variables: screenWidth, screenHeight
|
||||
Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view)
|
||||
{
|
||||
Vector3 result = { 0, 0, 0 }; // Object coordinates
|
||||
|
||||
//GLint viewport[4];
|
||||
//glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
//glGetIntegerv(GL_VIEWPORT, viewport); // Not available on OpenGL ES 2.0
|
||||
|
||||
// Viewport data
|
||||
/*
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int width = GetScreenWidth();
|
||||
int height = GetScreenHeight();
|
||||
float minDepth = 0.0f;
|
||||
float maxDepth = 1.0f;
|
||||
*/
|
||||
/*
|
||||
Matrix modelviewprojection = MatrixMultiply(modelview, projection);
|
||||
int x = 0; // viewport[0]
|
||||
int y = 0; // viewport[1]
|
||||
int width = screenWidth; // viewport[2]
|
||||
int height = screenHeight; // viewport[3]
|
||||
|
||||
Matrix modelviewprojection = MatrixMultiply(view, proj);
|
||||
MatrixInvert(&modelviewprojection);
|
||||
|
||||
Vector3 vector;
|
||||
|
||||
vector.x = (((source.x - x) / ((float)width)) * 2.0f) - 1.0f;
|
||||
vector.y = -((((source.y - y) / ((float)height)) * 2.0f) - 1.0f);
|
||||
vector.z = (source.z - minDepth) / (maxDepth - minDepth);
|
||||
|
||||
//float a = (((vector.x * matrix.M14) + (vector.y * matrix.M24)) + (vector.z * matrix.M34)) + matrix.M44;
|
||||
//float a = (((vector.x * modelviewprojection.m3) + (vector.y * modelviewprojection.m7)) + (vector.z * modelviewprojection.m11)) + modelviewprojection.m15;
|
||||
VectorTransform(&vector, modelviewprojection);
|
||||
|
||||
//if (!MathUtil.IsOne(a)) vector = (vector / a);
|
||||
//VectorScale(&vector, 1/a);
|
||||
|
||||
return vector;
|
||||
*/
|
||||
/*
|
||||
Vector3 worldPoint;
|
||||
|
||||
// Transformation matrices
|
||||
Matrix modelviewprojection = MatrixIdentity();
|
||||
Quaternion quat;
|
||||
|
||||
// Calculation for inverting a matrix, compute projection x modelview
|
||||
modelviewprojection = MatrixMultiply(proj, view);
|
||||
MatrixInvert(&modelviewprojection);
|
||||
// NOTE: Compute unproject using Vector3
|
||||
|
||||
// Transformation of normalized coordinates between -1 and 1
|
||||
quat.x = ((source.x - (float)x)/(float)width*2.0) - 1.0f;
|
||||
quat.y = ((source.y - (float)y)/(float)height*2.0) - 1.0f;
|
||||
quat.z = 2.0*source.z - 1.0;
|
||||
result.x = ((source.x - (float)x)/(float)width)*2.0f - 1.0f;
|
||||
result.y = ((source.y - (float)y)/(float)height)*2.0f - 1.0f;
|
||||
result.z = source.z*2.0f - 1.0f;
|
||||
|
||||
// Object coordinates (multiply vector by matrix)
|
||||
VectorTransform(&result, modelviewprojection);
|
||||
*/
|
||||
|
||||
// NOTE: Compute unproject using Quaternion (Vector4)
|
||||
Quaternion quat;
|
||||
|
||||
quat.x = ((source.x - (float)x)/(float)width)*2.0f - 1.0f;
|
||||
quat.y = ((source.y - (float)y)/(float)height)*2.0f - 1.0f;
|
||||
quat.z = source.z*2.0f - 1.0f;
|
||||
quat.w = 1.0;
|
||||
|
||||
// Objects coordinates
|
||||
QuaternionTransform(&quat, modelviewprojection);
|
||||
|
||||
//if (quat.w == 0.0) return 0;
|
||||
if (quat.w != 0.0)
|
||||
{
|
||||
quat.x /= quat.w;
|
||||
quat.y /= quat.w;
|
||||
quat.z /= quat.w;
|
||||
}
|
||||
|
||||
worldPoint.x = quat.x/quat.w;
|
||||
worldPoint.y = quat.y/quat.w;
|
||||
worldPoint.z = quat.z/quat.w;
|
||||
result.x = quat.x;
|
||||
result.y = quat.y;
|
||||
result.z = quat.z;
|
||||
|
||||
return worldPoint;
|
||||
*/
|
||||
/*
|
||||
Quaternion quat;
|
||||
Vector3 vec;
|
||||
|
||||
quat.x = 2.0f * GetMousePosition().x / (float)width - 1;
|
||||
quat.y = -(2.0f * GetMousePosition().y / (float)height - 1);
|
||||
quat.z = 0;
|
||||
quat.w = 1;
|
||||
|
||||
Matrix invView;
|
||||
MatrixInvert(&view);
|
||||
Matrix invProj;
|
||||
MatrixInvert(&proj);
|
||||
|
||||
quat.x = invProj.m0 * quat.x + invProj.m4 * quat.y + invProj.m8 * quat.z + invProj.m12 * quat.w;
|
||||
quat.y = invProj.m1 * quat.x + invProj.m5 * quat.y + invProj.m9 * quat.z + invProj.m13 * quat.w;
|
||||
quat.z = invProj.m2 * quat.x + invProj.m6 * quat.y + invProj.m10 * quat.z + invProj.m14 * quat.w;
|
||||
quat.w = invProj.m3 * quat.x + invProj.m7 * quat.y + invProj.m11 * quat.z + invProj.m15 * quat.w;
|
||||
|
||||
quat.x = invView.m0 * quat.x + invView.m4 * quat.y + invView.m8 * quat.z + invView.m12 * quat.w;
|
||||
quat.y = invView.m1 * quat.x + invView.m5 * quat.y + invView.m9 * quat.z + invView.m13 * quat.w;
|
||||
quat.z = invView.m2 * quat.x + invView.m6 * quat.y + invView.m10 * quat.z + invView.m14 * quat.w;
|
||||
quat.w = invView.m3 * quat.x + invView.m7 * quat.y + invView.m11 * quat.z + invView.m15 * quat.w;
|
||||
|
||||
vec.x /= quat.w;
|
||||
vec.y /= quat.w;
|
||||
vec.z /= quat.w;
|
||||
|
||||
return vec;
|
||||
*/
|
||||
/*
|
||||
Vector3 worldPoint;
|
||||
|
||||
// Transformation matrices
|
||||
Matrix modelviewprojection;
|
||||
Quaternion quat;
|
||||
|
||||
// Calculation for inverting a matrix, compute projection x modelview
|
||||
modelviewprojection = MatrixMultiply(view, proj);
|
||||
|
||||
// Now compute the inverse of matrix A
|
||||
MatrixInvert(&modelviewprojection);
|
||||
|
||||
// Transformation of normalized coordinates between -1 and 1
|
||||
quat.x = ((source.x - (float)x)/(float)width*2.0) - 1.0f;
|
||||
quat.y = ((source.y - (float)y)/(float)height*2.0) - 1.0f;
|
||||
quat.z = 2.0*source.z - 1.0;
|
||||
quat.w = 1.0;
|
||||
|
||||
// Traspose quaternion and multiply
|
||||
Quaternion result;
|
||||
result.x = modelviewprojection.m0 * quad.x + modelviewprojection.m4 * quad.y + modelviewprojection.m8 * quad.z + modelviewprojection.m12 * quad.w;
|
||||
result.y = modelviewprojection.m1 * quad.x + modelviewprojection.m5 * quad.y + modelviewprojection.m9 * quad.z + modelviewprojection.m13 * quad.w;
|
||||
result.z = modelviewprojection.m2 * quad.x + modelviewprojection.m6 * quad.y + modelviewprojection.m10 * quad.z + modelviewprojection.m14 * quad.w;
|
||||
result.w = modelviewprojection.m3 * quad.x + modelviewprojection.m7 * quad.y + modelviewprojection.m11 * quad.z + modelviewprojection.m15 * quad.w;
|
||||
|
||||
// Invert
|
||||
result.w = 1.0f / result.w;
|
||||
|
||||
//if (quat.w == 0.0) return 0;
|
||||
|
||||
worldPoint.x = quat.x * quat.w;
|
||||
worldPoint.y = quat.y * quat.w;
|
||||
worldPoint.z = quat.z * quat.w;
|
||||
|
||||
return worldPoint;
|
||||
*/
|
||||
/*
|
||||
// Needed Vectors
|
||||
Vector3 normalDeviceCoordinates;
|
||||
Quaternion rayClip;
|
||||
Quaternion rayEye;
|
||||
Vector3 rayWorld;
|
||||
|
||||
// Getting normal device coordinates
|
||||
float x = (2.0 * mousePosition.x) / GetScreenWidth() - 1.0;
|
||||
float y = 1.0 - (2.0 * mousePosition.y) / GetScreenHeight();
|
||||
float z = 1.0;
|
||||
normalDeviceCoordinates = (Vector3){ x, y, z };
|
||||
|
||||
// Getting clip vector
|
||||
rayClip = (Quaternion){ normalDeviceCoordinates.x, normalDeviceCoordinates.y, -1, 1 };
|
||||
|
||||
Matrix invProjection = projection;
|
||||
MatrixInvert(&invProjection);
|
||||
|
||||
rayEye = MatrixQuaternionMultiply(invProjection, rayClip);
|
||||
rayEye = (Quaternion){ rayEye.x, rayEye.y, -1, 0 };
|
||||
|
||||
Matrix invModelview = modelview;
|
||||
MatrixInvert(&invModelview);
|
||||
|
||||
rayWorld = MatrixVector3Multiply(invModelview, (Vector3){rayEye.x, rayEye.y, rayEye.z} );
|
||||
VectorNormalize(&rayWorld);
|
||||
|
||||
return rayWorld;
|
||||
*/
|
||||
return (Vector3){ 0, 0, 0 };
|
||||
return result;
|
||||
}
|
||||
|
||||
// Convert image data to OpenGL texture (returns OpenGL valid Id)
|
||||
|
@ -1780,8 +1776,8 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma
|
|||
#endif
|
||||
|
||||
// Magnification and minification filters
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
|
||||
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); // Alternative: GL_LINEAR
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Alternative: GL_LINEAR
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33)
|
||||
if (mipmapCount > 1)
|
||||
|
@ -1883,9 +1879,10 @@ Model rlglLoadModel(VertexData mesh)
|
|||
model.shader.id = 0; // No shader used
|
||||
|
||||
#elif defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
model.texture.id = whiteTexture; // Default whiteTexture
|
||||
model.texture.width = 1; // Default whiteTexture width
|
||||
model.texture.height = 1; // Default whiteTexture height
|
||||
model.texture.id = whiteTexture; // Default whiteTexture
|
||||
model.texture.width = 1; // Default whiteTexture width
|
||||
model.texture.height = 1; // Default whiteTexture height
|
||||
model.shader = simpleShader; // Default model shader
|
||||
|
||||
GLuint vaoModel = 0; // Vertex Array Objects (VAO)
|
||||
GLuint vertexBuffer[3]; // Vertex Buffer Objects (VBO)
|
||||
|
@ -1903,22 +1900,20 @@ Model rlglLoadModel(VertexData mesh)
|
|||
// Enable vertex attributes: position
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh.vertexCount, mesh.vertices, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(simpleShader.vertexLoc);
|
||||
glVertexAttribPointer(simpleShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||
glVertexAttribPointer(model.shader.vertexLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||
glEnableVertexAttribArray(model.shader.vertexLoc);
|
||||
|
||||
// Enable vertex attributes: texcoords
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*mesh.vertexCount, mesh.texcoords, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(simpleShader.texcoordLoc);
|
||||
glVertexAttribPointer(simpleShader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
|
||||
glVertexAttribPointer(model.shader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
|
||||
glEnableVertexAttribArray(model.shader.texcoordLoc);
|
||||
|
||||
// Enable vertex attributes: normals
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[2]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh.vertexCount, mesh.normals, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(simpleShader.normalLoc);
|
||||
glVertexAttribPointer(simpleShader.normalLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||
|
||||
model.shader = simpleShader; // By default, simple shader will be used
|
||||
glVertexAttribPointer(model.shader.normalLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||
glEnableVertexAttribArray(model.shader.normalLoc);
|
||||
|
||||
model.mesh.vboId[0] = vertexBuffer[0]; // Vertex position VBO
|
||||
model.mesh.vboId[1] = vertexBuffer[1]; // Texcoords VBO
|
||||
|
@ -1975,6 +1970,8 @@ void *rlglReadTexturePixels(unsigned int textureId, unsigned int format)
|
|||
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
|
||||
int width, height;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
|
||||
//glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format);
|
||||
|
@ -1996,8 +1993,6 @@ void *rlglReadTexturePixels(unsigned int textureId, unsigned int format)
|
|||
default: TraceLog(WARNING, "Texture format not suported"); break;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
|
||||
// NOTE: Each row written to or read from by OpenGL pixel operations like glGetTexImage are aligned to a 4 byte boundary by default, which may add some padding.
|
||||
// Use glPixelStorei to modify padding with the GL_[UN]PACK_ALIGNMENT setting.
|
||||
// GL_PACK_ALIGNMENT affects operations that read from OpenGL memory (glReadPixels, glGetTexImage, etc.)
|
||||
|
@ -2028,38 +2023,53 @@ Shader LoadShader(char *vsFileName, char *fsFileName)
|
|||
char *vShaderStr = TextFileRead(vsFileName);
|
||||
char *fShaderStr = TextFileRead(fsFileName);
|
||||
|
||||
shader.id = LoadShaderProgram(vShaderStr, fShaderStr);
|
||||
if ((vShaderStr != NULL) && (fShaderStr != NULL))
|
||||
{
|
||||
shader.id = LoadShaderProgram(vShaderStr, fShaderStr);
|
||||
|
||||
if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Custom shader loaded successfully", shader.id);
|
||||
else TraceLog(WARNING, "[SHDR ID %i] Custom shader could not be loaded", shader.id);
|
||||
if (shader.id != 0)
|
||||
{
|
||||
TraceLog(INFO, "[SHDR ID %i] Custom shader loaded successfully", shader.id);
|
||||
|
||||
// Shader strings must be freed
|
||||
free(vShaderStr);
|
||||
free(fShaderStr);
|
||||
// Set shader textures ids (all 0 by default)
|
||||
shader.texDiffuseId = 0;
|
||||
shader.texNormalId = 0;
|
||||
shader.texSpecularId = 0;
|
||||
|
||||
// Set shader textures ids (all 0 by default)
|
||||
shader.texDiffuseId = 0;
|
||||
shader.texNormalId = 0;
|
||||
shader.texSpecularId = 0;
|
||||
// Get handles to GLSL input attibute locations
|
||||
//-------------------------------------------------------------------
|
||||
shader.vertexLoc = glGetAttribLocation(shader.id, "vertexPosition");
|
||||
shader.texcoordLoc = glGetAttribLocation(shader.id, "vertexTexCoord");
|
||||
shader.normalLoc = glGetAttribLocation(shader.id, "vertexNormal");
|
||||
// NOTE: custom shader does not use colorLoc
|
||||
shader.colorLoc = -1;
|
||||
|
||||
// Get handles to GLSL input attibute locations
|
||||
//-------------------------------------------------------------------
|
||||
shader.vertexLoc = glGetAttribLocation(shader.id, "vertexPosition");
|
||||
shader.texcoordLoc = glGetAttribLocation(shader.id, "vertexTexCoord");
|
||||
shader.normalLoc = glGetAttribLocation(shader.id, "vertexNormal");
|
||||
// NOTE: custom shader does not use colorLoc
|
||||
shader.colorLoc = -1;
|
||||
// Get handles to GLSL uniform locations (vertex shader)
|
||||
shader.modelviewLoc = glGetUniformLocation(shader.id, "modelviewMatrix");
|
||||
shader.projectionLoc = glGetUniformLocation(shader.id, "projectionMatrix");
|
||||
|
||||
// Get handles to GLSL uniform locations (vertex shader)
|
||||
shader.modelviewLoc = glGetUniformLocation(shader.id, "modelviewMatrix");
|
||||
shader.projectionLoc = glGetUniformLocation(shader.id, "projectionMatrix");
|
||||
// Get handles to GLSL uniform locations (fragment shader)
|
||||
shader.tintColorLoc = glGetUniformLocation(shader.id, "tintColor");
|
||||
shader.mapDiffuseLoc = glGetUniformLocation(shader.id, "texture0");
|
||||
shader.mapNormalLoc = -1; // It can be set later
|
||||
shader.mapSpecularLoc = -1; // It can be set later
|
||||
//--------------------------------------------------------------------
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceLog(WARNING, "Custom shader could not be loaded");
|
||||
shader = simpleShader;
|
||||
}
|
||||
|
||||
// Get handles to GLSL uniform locations (fragment shader)
|
||||
shader.tintColorLoc = glGetUniformLocation(shader.id, "tintColor");
|
||||
shader.mapDiffuseLoc = glGetUniformLocation(shader.id, "texture0");
|
||||
shader.mapNormalLoc = -1; // It can be set later
|
||||
shader.mapSpecularLoc = -1; // It can be set later
|
||||
//--------------------------------------------------------------------
|
||||
// Shader strings must be freed
|
||||
free(vShaderStr);
|
||||
free(fShaderStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceLog(WARNING, "Custom shader could not be loaded");
|
||||
shader = simpleShader;
|
||||
}
|
||||
#endif
|
||||
|
||||
return shader;
|
||||
|
@ -2169,6 +2179,8 @@ unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr)
|
|||
void UnloadShader(Shader shader)
|
||||
{
|
||||
rlDeleteShader(shader.id);
|
||||
|
||||
TraceLog(INFO, "[SHDR ID %i] Unloaded shader program data", shader.id);
|
||||
}
|
||||
|
||||
// Set custom shader to be used on batch draw
|
||||
|
@ -2205,6 +2217,7 @@ void SetCustomShader(Shader shader)
|
|||
}
|
||||
|
||||
// Set postprocessing shader
|
||||
// NOTE: Uses global variables screenWidth and screenHeight
|
||||
void SetPostproShader(Shader shader)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
|
@ -2218,8 +2231,8 @@ void SetPostproShader(Shader shader)
|
|||
|
||||
Texture2D texture;
|
||||
texture.id = fboColorTexture;
|
||||
texture.width = GetScreenWidth();
|
||||
texture.height = GetScreenHeight();
|
||||
texture.width = screenWidth;
|
||||
texture.height = screenHeight;
|
||||
|
||||
SetShaderMapDiffuse(&postproQuad.shader, texture);
|
||||
|
||||
|
@ -2236,9 +2249,12 @@ void SetDefaultShader(void)
|
|||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
SetCustomShader(defaultShader);
|
||||
SetPostproShader(defaultShader);
|
||||
|
||||
enabledPostpro = false;
|
||||
if (enabledPostpro)
|
||||
{
|
||||
SetPostproShader(defaultShader);
|
||||
enabledPostpro = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -2267,7 +2283,8 @@ void SetModelShader(Model *model, Shader shader)
|
|||
|
||||
if (vaoSupported) glBindVertexArray(0); // Unbind VAO
|
||||
|
||||
//if (model->texture.id > 0) model->shader.texDiffuseId = model->texture.id;
|
||||
// NOTE: If SetModelTexture() is called previously, texture is not assigned to new shader
|
||||
if (model->texture.id > 0) model->shader.texDiffuseId = model->texture.id;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -2423,6 +2440,26 @@ void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textur
|
|||
*/
|
||||
}
|
||||
|
||||
// Set blending mode (alpha, additive, multiplied)
|
||||
// NOTE: Only 3 blending modes predefined
|
||||
void SetBlendMode(int mode)
|
||||
{
|
||||
if ((blendMode != mode) && (mode < 3))
|
||||
{
|
||||
rlglDraw();
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case BLEND_ALPHA: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break;
|
||||
case BLEND_ADDITIVE: glBlendFunc(GL_SRC_ALPHA, GL_ONE); break; // Alternative: glBlendFunc(GL_ONE, GL_ONE);
|
||||
case BLEND_MULTIPLIED: glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
blendMode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
void PrintProjectionMatrix(void)
|
||||
{
|
||||
|
@ -3026,7 +3063,7 @@ typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
|
|||
|
||||
// Output a trace log message
|
||||
// NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning
|
||||
void TraceLog(int msgType, const char *text, ...)
|
||||
static void TraceLog(int msgType, const char *text, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, text);
|
||||
|
|
92
src/rlgl.h
92
src/rlgl.h
|
@ -7,7 +7,7 @@
|
|||
* OpenGL 3.3+ - Vertex data is stored in VAOs, call rlglDraw() to render
|
||||
* OpenGL ES 2 - Vertex data is stored in VBOs or VAOs (when available), call rlglDraw() to render
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
@ -36,6 +36,10 @@
|
|||
#include "utils.h" // Required for function TraceLog()
|
||||
#endif
|
||||
|
||||
#if defined(RLGL_STANDALONE)
|
||||
#define RAYMATH_STANDALONE
|
||||
#endif
|
||||
|
||||
#include "raymath.h" // Required for data type Matrix and Matrix functions
|
||||
|
||||
// Select desired OpenGL version
|
||||
|
@ -89,9 +93,26 @@ typedef enum { RL_LINES, RL_TRIANGLES, RL_QUADS } DrawMode;
|
|||
typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
|
||||
|
||||
#ifdef RLGL_STANDALONE
|
||||
#ifndef __cplusplus
|
||||
// Boolean type
|
||||
typedef enum { false, true } bool;
|
||||
#endif
|
||||
|
||||
// byte type
|
||||
typedef unsigned char byte;
|
||||
|
||||
// Color type, RGBA (32bit)
|
||||
typedef struct Color {
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
unsigned char a;
|
||||
} Color;
|
||||
|
||||
// Texture formats (support depends on OpenGL version)
|
||||
typedef enum {
|
||||
UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha)
|
||||
UNCOMPRESSED_GRAY_ALPHA,
|
||||
UNCOMPRESSED_R5G6B5, // 16 bpp
|
||||
UNCOMPRESSED_R8G8B8, // 24 bpp
|
||||
UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha)
|
||||
|
@ -106,7 +127,8 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
|
|||
COMPRESSED_ETC2_EAC_RGBA, // 8 bpp
|
||||
COMPRESSED_PVRT_RGB, // 4 bpp
|
||||
COMPRESSED_PVRT_RGBA, // 4 bpp
|
||||
/*COMPRESSED_ASTC_RGBA_4x4*/ // 8 bpp
|
||||
COMPRESSED_ASTC_4x4_RGBA, // 8 bpp
|
||||
COMPRESSED_ASTC_8x8_RGBA // 2 bpp
|
||||
} TextureFormat;
|
||||
|
||||
// VertexData type
|
||||
|
@ -123,21 +145,36 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
|
|||
|
||||
// Shader type
|
||||
typedef struct Shader {
|
||||
unsigned int id; // Shader program id
|
||||
unsigned int id; // Shader program id
|
||||
|
||||
// TODO: This should be Texture2D objects
|
||||
unsigned int texDiffuseId; // Diffuse texture id
|
||||
unsigned int texNormalId; // Normal texture id
|
||||
unsigned int texSpecularId; // Specular texture id
|
||||
|
||||
// Variable attributes
|
||||
unsigned int vertexLoc; // Vertex attribute location point (vertex shader)
|
||||
unsigned int texcoordLoc; // Texcoord attribute location point (vertex shader)
|
||||
unsigned int normalLoc; // Normal attribute location point (vertex shader)
|
||||
unsigned int colorLoc; // Color attibute location point (vertex shader)
|
||||
int vertexLoc; // Vertex attribute location point (vertex shader)
|
||||
int texcoordLoc; // Texcoord attribute location point (vertex shader)
|
||||
int normalLoc; // Normal attribute location point (vertex shader)
|
||||
int colorLoc; // Color attibute location point (vertex shader)
|
||||
|
||||
// Uniforms
|
||||
unsigned int projectionLoc; // Projection matrix uniform location point (vertex shader)
|
||||
unsigned int modelviewLoc; // ModeView matrix uniform location point (vertex shader)
|
||||
unsigned int textureLoc; // Texture uniform location point (fragment shader)
|
||||
unsigned int tintColorLoc; // Color uniform location point (fragment shader)
|
||||
int projectionLoc; // Projection matrix uniform location point (vertex shader)
|
||||
int modelviewLoc; // ModeView matrix uniform location point (vertex shader)
|
||||
int tintColorLoc; // Color uniform location point (fragment shader)
|
||||
|
||||
int mapDiffuseLoc; // Diffuse map texture uniform location point (fragment shader)
|
||||
int mapNormalLoc; // Normal map texture uniform location point (fragment shader)
|
||||
int mapSpecularLoc; // Specular map texture uniform location point (fragment shader)
|
||||
} Shader;
|
||||
|
||||
// Texture2D type
|
||||
typedef struct Texture2D {
|
||||
unsigned int id; // Texture id
|
||||
int width;
|
||||
int height;
|
||||
} Texture2D;
|
||||
|
||||
// 3d Model type
|
||||
typedef struct Model {
|
||||
VertexData mesh;
|
||||
|
@ -146,12 +183,8 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
|
|||
Shader shader;
|
||||
} Model;
|
||||
|
||||
// Texture2D type
|
||||
typedef struct Texture2D {
|
||||
unsigned int id; // Texture id
|
||||
int width;
|
||||
int height;
|
||||
} Texture2D;
|
||||
// Color blending modes (pre-defined)
|
||||
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -231,6 +264,31 @@ void PrintProjectionMatrix(void); // DEBUG: Print projection matrix
|
|||
void PrintModelviewMatrix(void); // DEBUG: Print modelview matrix
|
||||
#endif
|
||||
|
||||
#if defined(RLGL_STANDALONE)
|
||||
//------------------------------------------------------------------------------------
|
||||
// Shaders System Functions (Module: rlgl)
|
||||
// NOTE: This functions are useless when using OpenGL 1.1
|
||||
//------------------------------------------------------------------------------------
|
||||
Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations
|
||||
unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr); // Load a custom shader and return program id
|
||||
void UnloadShader(Shader shader); // Unload a custom shader from memory
|
||||
void SetPostproShader(Shader shader); // Set fullscreen postproduction shader
|
||||
void SetCustomShader(Shader shader); // Set custom shader to be used in batch draw
|
||||
void SetDefaultShader(void); // Set default shader to be used in batch draw
|
||||
void SetModelShader(Model *model, Shader shader); // Link a shader to a model
|
||||
bool IsPosproShaderEnabled(void); // Check if postprocessing shader is enabled
|
||||
|
||||
int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
|
||||
void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
|
||||
void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
|
||||
void SetShaderMapDiffuse(Shader *shader, Texture2D texture); // Default diffuse shader map texture assignment
|
||||
void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D texture); // Normal map texture shader assignment
|
||||
void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture); // Specular map texture shader assignment
|
||||
void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textureUnit); // TODO: Generic shader map assignment
|
||||
|
||||
void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* Basic functions to draw 2d Shapes and check collisions
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* Basic functions to load SpriteFonts and draw Text
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
@ -216,6 +216,8 @@ extern void UnloadDefaultFont(void)
|
|||
{
|
||||
UnloadTexture(defaultFont.texture);
|
||||
free(defaultFont.charSet);
|
||||
|
||||
TraceLog(INFO, "Unloaded default font data");
|
||||
}
|
||||
|
||||
// Get the default font, useful to be used with extended parameters
|
||||
|
@ -266,6 +268,8 @@ void UnloadSpriteFont(SpriteFont spriteFont)
|
|||
{
|
||||
UnloadTexture(spriteFont.texture);
|
||||
free(spriteFont.charSet);
|
||||
|
||||
TraceLog(INFO, "Unloaded sprite font data");
|
||||
}
|
||||
|
||||
// Draw text (using default font)
|
||||
|
|
261
src/textures.c
261
src/textures.c
|
@ -8,7 +8,7 @@
|
|||
* stb_image - Multiple formats image loading (JPEG, PNG, BMP, TGA, PSD, GIF, PIC)
|
||||
* NOTE: stb_image has been slightly modified, original library: https://github.com/nothings/stb
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
@ -330,7 +330,6 @@ Texture2D LoadTexture(const char *fileName)
|
|||
else
|
||||
{
|
||||
TraceLog(WARNING, "Texture could not be created");
|
||||
|
||||
texture.id = 0;
|
||||
}
|
||||
|
||||
|
@ -390,12 +389,17 @@ Texture2D LoadTextureFromImage(Image image)
|
|||
void UnloadImage(Image image)
|
||||
{
|
||||
free(image.data);
|
||||
|
||||
// NOTE: It becomes anoying every time a texture is loaded
|
||||
//TraceLog(INFO, "Unloaded image data");
|
||||
}
|
||||
|
||||
// Unload texture from GPU memory
|
||||
void UnloadTexture(Texture2D texture)
|
||||
{
|
||||
rlDeleteTextures(texture.id);
|
||||
|
||||
TraceLog(INFO, "[TEX ID %i] Unloaded texture data", texture.id);
|
||||
}
|
||||
|
||||
// Get pixel data from image in the form of Color struct array
|
||||
|
@ -486,20 +490,28 @@ Color *GetImageData(Image image)
|
|||
}
|
||||
|
||||
// Get pixel data from GPU texture and return an Image
|
||||
// NOTE: Compressed texture formats not supported
|
||||
Image GetTextureData(Texture2D texture)
|
||||
{
|
||||
Image image;
|
||||
image.data = NULL;
|
||||
|
||||
image.data = rlglReadTexturePixels(texture.id, texture.format);
|
||||
|
||||
if (image.data != NULL)
|
||||
if (texture.format < 8)
|
||||
{
|
||||
image.width = texture.width;
|
||||
image.height = texture.height;
|
||||
image.format = texture.format;
|
||||
image.mipmaps = 1;
|
||||
image.data = rlglReadTexturePixels(texture.id, texture.format);
|
||||
|
||||
if (image.data != NULL)
|
||||
{
|
||||
image.width = texture.width;
|
||||
image.height = texture.height;
|
||||
image.format = texture.format;
|
||||
image.mipmaps = 1;
|
||||
|
||||
TraceLog(INFO, "Texture pixel data obtained successfully");
|
||||
}
|
||||
else TraceLog(WARNING, "Texture pixel data could not be obtained");
|
||||
}
|
||||
else TraceLog(WARNING, "Texture pixel data could not be obtained");
|
||||
else TraceLog(WARNING, "Compressed texture data could not be obtained");
|
||||
|
||||
return image;
|
||||
}
|
||||
|
@ -507,136 +519,139 @@ Image GetTextureData(Texture2D texture)
|
|||
// Convert image data to desired format
|
||||
void ImageConvertFormat(Image *image, int newFormat)
|
||||
{
|
||||
if ((image->format != newFormat) && (image->format < 8) && (newFormat < 8))
|
||||
if (image->format != newFormat)
|
||||
{
|
||||
Color *pixels = GetImageData(*image);
|
||||
|
||||
free(image->data);
|
||||
|
||||
image->format = newFormat;
|
||||
|
||||
int k = 0;
|
||||
|
||||
switch (image->format)
|
||||
if ((image->format < 8) && (newFormat < 8))
|
||||
{
|
||||
case UNCOMPRESSED_GRAYSCALE:
|
||||
Color *pixels = GetImageData(*image);
|
||||
|
||||
free(image->data);
|
||||
|
||||
image->format = newFormat;
|
||||
|
||||
int k = 0;
|
||||
|
||||
switch (image->format)
|
||||
{
|
||||
image->data = (unsigned char *)malloc(image->width*image->height*sizeof(unsigned char));
|
||||
|
||||
for (int i = 0; i < image->width*image->height; i++)
|
||||
case UNCOMPRESSED_GRAYSCALE:
|
||||
{
|
||||
((unsigned char *)image->data)[i] = (unsigned char)((float)pixels[k].r*0.299f + (float)pixels[k].g*0.587f + (float)pixels[k].b*0.114f);
|
||||
k++;
|
||||
}
|
||||
image->data = (unsigned char *)malloc(image->width*image->height*sizeof(unsigned char));
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_GRAY_ALPHA:
|
||||
{
|
||||
image->data = (unsigned char *)malloc(image->width*image->height*2*sizeof(unsigned char));
|
||||
for (int i = 0; i < image->width*image->height; i++)
|
||||
{
|
||||
((unsigned char *)image->data)[i] = (unsigned char)((float)pixels[k].r*0.299f + (float)pixels[k].g*0.587f + (float)pixels[k].b*0.114f);
|
||||
k++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < image->width*image->height*2; i += 2)
|
||||
} break;
|
||||
case UNCOMPRESSED_GRAY_ALPHA:
|
||||
{
|
||||
((unsigned char *)image->data)[i] = (unsigned char)((float)pixels[k].r*0.299f + (float)pixels[k].g*0.587f + (float)pixels[k].b*0.114f);
|
||||
((unsigned char *)image->data)[i + 1] = pixels[k].a;
|
||||
k++;
|
||||
}
|
||||
image->data = (unsigned char *)malloc(image->width*image->height*2*sizeof(unsigned char));
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_R5G6B5:
|
||||
{
|
||||
image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short));
|
||||
for (int i = 0; i < image->width*image->height*2; i += 2)
|
||||
{
|
||||
((unsigned char *)image->data)[i] = (unsigned char)((float)pixels[k].r*0.299f + (float)pixels[k].g*0.587f + (float)pixels[k].b*0.114f);
|
||||
((unsigned char *)image->data)[i + 1] = pixels[k].a;
|
||||
k++;
|
||||
}
|
||||
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
|
||||
for (int i = 0; i < image->width*image->height; i++)
|
||||
} break;
|
||||
case UNCOMPRESSED_R5G6B5:
|
||||
{
|
||||
r = (unsigned char)(round((float)pixels[k].r*31/255));
|
||||
g = (unsigned char)(round((float)pixels[k].g*63/255));
|
||||
b = (unsigned char)(round((float)pixels[k].b*31/255));
|
||||
image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short));
|
||||
|
||||
((unsigned short *)image->data)[i] = (unsigned short)r << 11 | (unsigned short)g << 5 | (unsigned short)b;
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
|
||||
k++;
|
||||
}
|
||||
for (int i = 0; i < image->width*image->height; i++)
|
||||
{
|
||||
r = (unsigned char)(round((float)pixels[k].r*31/255));
|
||||
g = (unsigned char)(round((float)pixels[k].g*63/255));
|
||||
b = (unsigned char)(round((float)pixels[k].b*31/255));
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_R8G8B8:
|
||||
{
|
||||
image->data = (unsigned char *)malloc(image->width*image->height*3*sizeof(unsigned char));
|
||||
((unsigned short *)image->data)[i] = (unsigned short)r << 11 | (unsigned short)g << 5 | (unsigned short)b;
|
||||
|
||||
for (int i = 0; i < image->width*image->height*3; i += 3)
|
||||
k++;
|
||||
}
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_R8G8B8:
|
||||
{
|
||||
((unsigned char *)image->data)[i] = pixels[k].r;
|
||||
((unsigned char *)image->data)[i + 1] = pixels[k].g;
|
||||
((unsigned char *)image->data)[i + 2] = pixels[k].b;
|
||||
k++;
|
||||
}
|
||||
} break;
|
||||
case UNCOMPRESSED_R5G5B5A1:
|
||||
{
|
||||
image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short));
|
||||
image->data = (unsigned char *)malloc(image->width*image->height*3*sizeof(unsigned char));
|
||||
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
unsigned char a = 1;
|
||||
|
||||
for (int i = 0; i < image->width*image->height; i++)
|
||||
for (int i = 0; i < image->width*image->height*3; i += 3)
|
||||
{
|
||||
((unsigned char *)image->data)[i] = pixels[k].r;
|
||||
((unsigned char *)image->data)[i + 1] = pixels[k].g;
|
||||
((unsigned char *)image->data)[i + 2] = pixels[k].b;
|
||||
k++;
|
||||
}
|
||||
} break;
|
||||
case UNCOMPRESSED_R5G5B5A1:
|
||||
{
|
||||
r = (unsigned char)(round((float)pixels[k].r*31/255));
|
||||
g = (unsigned char)(round((float)pixels[k].g*31/255));
|
||||
b = (unsigned char)(round((float)pixels[k].b*31/255));
|
||||
a = (pixels[k].a > 50) ? 1 : 0;
|
||||
image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short));
|
||||
|
||||
((unsigned short *)image->data)[i] = (unsigned short)r << 11 | (unsigned short)g << 6 | (unsigned short)b << 1| (unsigned short)a;
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
unsigned char a = 1;
|
||||
|
||||
k++;
|
||||
}
|
||||
for (int i = 0; i < image->width*image->height; i++)
|
||||
{
|
||||
r = (unsigned char)(round((float)pixels[k].r*31/255));
|
||||
g = (unsigned char)(round((float)pixels[k].g*31/255));
|
||||
b = (unsigned char)(round((float)pixels[k].b*31/255));
|
||||
a = (pixels[k].a > 50) ? 1 : 0;
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_R4G4B4A4:
|
||||
{
|
||||
image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short));
|
||||
((unsigned short *)image->data)[i] = (unsigned short)r << 11 | (unsigned short)g << 6 | (unsigned short)b << 1| (unsigned short)a;
|
||||
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
unsigned char a;
|
||||
k++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < image->width*image->height; i++)
|
||||
} break;
|
||||
case UNCOMPRESSED_R4G4B4A4:
|
||||
{
|
||||
r = (unsigned char)(round((float)pixels[k].r*15/255));
|
||||
g = (unsigned char)(round((float)pixels[k].g*15/255));
|
||||
b = (unsigned char)(round((float)pixels[k].b*15/255));
|
||||
a = (unsigned char)(round((float)pixels[k].a*15/255));
|
||||
image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short));
|
||||
|
||||
((unsigned short *)image->data)[i] = (unsigned short)r << 12 | (unsigned short)g << 8| (unsigned short)b << 4| (unsigned short)a;
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
unsigned char a;
|
||||
|
||||
k++;
|
||||
}
|
||||
for (int i = 0; i < image->width*image->height; i++)
|
||||
{
|
||||
r = (unsigned char)(round((float)pixels[k].r*15/255));
|
||||
g = (unsigned char)(round((float)pixels[k].g*15/255));
|
||||
b = (unsigned char)(round((float)pixels[k].b*15/255));
|
||||
a = (unsigned char)(round((float)pixels[k].a*15/255));
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_R8G8B8A8:
|
||||
{
|
||||
image->data = (unsigned char *)malloc(image->width*image->height*4*sizeof(unsigned char));
|
||||
((unsigned short *)image->data)[i] = (unsigned short)r << 12 | (unsigned short)g << 8| (unsigned short)b << 4| (unsigned short)a;
|
||||
|
||||
for (int i = 0; i < image->width*image->height*4; i += 4)
|
||||
k++;
|
||||
}
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_R8G8B8A8:
|
||||
{
|
||||
((unsigned char *)image->data)[i] = pixels[k].r;
|
||||
((unsigned char *)image->data)[i + 1] = pixels[k].g;
|
||||
((unsigned char *)image->data)[i + 2] = pixels[k].b;
|
||||
((unsigned char *)image->data)[i + 3] = pixels[k].a;
|
||||
k++;
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
image->data = (unsigned char *)malloc(image->width*image->height*4*sizeof(unsigned char));
|
||||
|
||||
for (int i = 0; i < image->width*image->height*4; i += 4)
|
||||
{
|
||||
((unsigned char *)image->data)[i] = pixels[k].r;
|
||||
((unsigned char *)image->data)[i + 1] = pixels[k].g;
|
||||
((unsigned char *)image->data)[i + 2] = pixels[k].b;
|
||||
((unsigned char *)image->data)[i + 3] = pixels[k].a;
|
||||
k++;
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
free(pixels);
|
||||
}
|
||||
|
||||
free(pixels);
|
||||
else TraceLog(WARNING, "Image data format is compressed, can not be converted");
|
||||
}
|
||||
else TraceLog(WARNING, "Image data format is compressed, can not be converted");
|
||||
}
|
||||
|
||||
|
||||
|
@ -644,8 +659,8 @@ void ImageConvertFormat(Image *image, int newFormat)
|
|||
// NOTE: Requirement on OpenGL ES 2.0 (RPI, HTML5)
|
||||
void ImageConvertToPOT(Image *image, Color fillColor)
|
||||
{
|
||||
// TODO: Review for new image struct
|
||||
/*
|
||||
Color *pixels = GetImageData(*image); // Get pixels data
|
||||
|
||||
// Just add the required amount of pixels at the right and bottom sides of image...
|
||||
int potWidth = GetNextPOT(image->width);
|
||||
int potHeight = GetNextPOT(image->height);
|
||||
|
@ -653,29 +668,33 @@ void ImageConvertToPOT(Image *image, Color fillColor)
|
|||
// Check if POT texture generation is required (if texture is not already POT)
|
||||
if ((potWidth != image->width) || (potHeight != image->height))
|
||||
{
|
||||
Color *imgDataPixelPOT = NULL;
|
||||
Color *pixelsPOT = NULL;
|
||||
|
||||
// Generate POT array from NPOT data
|
||||
imgDataPixelPOT = (Color *)malloc(potWidth * potHeight * sizeof(Color));
|
||||
pixelsPOT = (Color *)malloc(potWidth * potHeight * sizeof(Color));
|
||||
|
||||
for (int j = 0; j < potHeight; j++)
|
||||
{
|
||||
for (int i = 0; i < potWidth; i++)
|
||||
{
|
||||
if ((j < image->height) && (i < image->width)) imgDataPixelPOT[j*potWidth + i] = image->data[j*image->width + i];
|
||||
else imgDataPixelPOT[j*potWidth + i] = fillColor;
|
||||
if ((j < image->height) && (i < image->width)) pixelsPOT[j*potWidth + i] = pixels[j*image->width + i];
|
||||
else pixelsPOT[j*potWidth + i] = fillColor;
|
||||
}
|
||||
}
|
||||
|
||||
TraceLog(WARNING, "Image converted to POT: (%ix%i) -> (%ix%i)", image->width, image->height, potWidth, potHeight);
|
||||
|
||||
free(image->pixels);
|
||||
free(pixels); // Free pixels data
|
||||
free(image->data); // Free old image data
|
||||
|
||||
image->pixels = imgDataPixelPOT;
|
||||
image->width = potWidth;
|
||||
image->height = potHeight;
|
||||
int format = image->format; // Store image data format to reconvert later
|
||||
|
||||
*image = LoadImageEx(pixelsPOT, potWidth, potHeight);
|
||||
|
||||
free(pixelsPOT); // Free POT pixels data
|
||||
|
||||
ImageConvertFormat(image, format); // Reconvert image to previous format
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Copy an image to a new image
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* tinfl - zlib DEFLATE algorithm decompression lib
|
||||
* stb_image_write - PNG writting functions
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
|
Loading…
Reference in New Issue