Initial commit
This commit is contained in:
parent
c20520df41
commit
8e3cf419ab
31 changed files with 30719 additions and 4 deletions
368
LICENSE.txt
Normal file
368
LICENSE.txt
Normal file
|
|
@ -0,0 +1,368 @@
|
|||
License for:
|
||||
gltools
|
||||
|
||||
Truetype code:
|
||||
stb_truetype.h - v0.6c - public domain
|
||||
authored from 2009-2012 by Sean Barrett / RAD Game Tools
|
||||
|
||||
UTF-8 decoder:
|
||||
http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
|
||||
Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
|
||||
fontstash (with modifications marked in code)
|
||||
recastnavigation - Mikko Mononen
|
||||
http://digestingduck.blogspot.com/
|
||||
License - MIT License
|
||||
|
||||
TTF font DroidSans:
|
||||
http://www.droidfonts.com/
|
||||
License - Apache License, Version 2.0
|
||||
|
||||
IMGUI (with modifications marked in code)
|
||||
recastnavigation - Mikko Mononen
|
||||
http://digestingduck.blogspot.com/
|
||||
License - MIT License
|
||||
|
||||
Copyright (C) 2012 Runar Tenfjord, Tenko
|
||||
|
||||
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
gltools
|
||||
=======
|
||||
|
||||
Library for quickly creating OpenGL based application
|
||||
30
README.rst
Normal file
30
README.rst
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
Introduction
|
||||
============
|
||||
|
||||
gltools is library for quickly creating OpenGL based
|
||||
application with support for:
|
||||
|
||||
* Access to vertex buffers and GLSL shaders
|
||||
* Access to truetype fonts
|
||||
* Windows handling through GLFW
|
||||
* Simple GUI controls
|
||||
|
||||
OpenGL version 2.1 is targeted which should be available
|
||||
in most computers these days, even in a laptop's integrated
|
||||
graphics.
|
||||
|
||||
The license is GPL v2.
|
||||
|
||||
Building
|
||||
========
|
||||
|
||||
* Python 2.6 or later and Cython 0.17.
|
||||
* GLFW v3.0 (not released, must be build from repo)
|
||||
* OpenGL headers
|
||||
|
||||
The extension have only been build on the Linux platform.
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
||||
ToDo
|
||||
23764
gltools/@contrib/droidsans_ttf.h
Normal file
23764
gltools/@contrib/droidsans_ttf.h
Normal file
File diff suppressed because it is too large
Load diff
510
gltools/@contrib/fontstash.c
Normal file
510
gltools/@contrib/fontstash.c
Normal file
|
|
@ -0,0 +1,510 @@
|
|||
//
|
||||
// Copyright (c) 2009 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
// default font
|
||||
#include "droidsans_ttf.h"
|
||||
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#define STBTT_malloc(x,u) malloc(x)
|
||||
#define STBTT_free(x,u) free(x)
|
||||
#include "stb_truetype.h"
|
||||
|
||||
#define HASH_LUT_SIZE 256
|
||||
#define MAX_ROWS 128
|
||||
#define MAX_FONTS 4
|
||||
#define VERT_COUNT (6*128)
|
||||
#define VERT_STRIDE (sizeof(float)*4)
|
||||
|
||||
static unsigned int hashint(unsigned int a)
|
||||
{
|
||||
a += ~(a<<15);
|
||||
a ^= (a>>10);
|
||||
a += (a<<3);
|
||||
a ^= (a>>6);
|
||||
a += ~(a<<11);
|
||||
a ^= (a>>16);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
struct sth_quad
|
||||
{
|
||||
float x0,y0,s0,t0;
|
||||
float x1,y1,s1,t1;
|
||||
};
|
||||
|
||||
struct sth_row
|
||||
{
|
||||
short x,y,h;
|
||||
};
|
||||
|
||||
struct sth_glyph
|
||||
{
|
||||
unsigned int codepoint;
|
||||
short size;
|
||||
int x0,y0,x1,y1;
|
||||
float xadv,xoff,yoff;
|
||||
int next;
|
||||
};
|
||||
|
||||
struct sth_font
|
||||
{
|
||||
stbtt_fontinfo font;
|
||||
unsigned char* data;
|
||||
int datasize;
|
||||
int freedata; // rute : added flag
|
||||
struct sth_glyph* glyphs;
|
||||
int lut[HASH_LUT_SIZE];
|
||||
int nglyphs;
|
||||
float ascender;
|
||||
float descender;
|
||||
float lineh;
|
||||
};
|
||||
|
||||
struct sth_stash
|
||||
{
|
||||
int tw,th;
|
||||
float itw,ith;
|
||||
GLuint tex;
|
||||
struct sth_row rows[MAX_ROWS];
|
||||
int nrows;
|
||||
struct sth_font fonts[MAX_FONTS];
|
||||
float verts[4*VERT_COUNT];
|
||||
int nverts;
|
||||
int drawing;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
|
||||
|
||||
#define UTF8_ACCEPT 0
|
||||
#define UTF8_REJECT 1
|
||||
|
||||
static const unsigned char utf8d[] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
|
||||
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
|
||||
0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
|
||||
0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
|
||||
0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
|
||||
1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
|
||||
1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
|
||||
1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
|
||||
};
|
||||
|
||||
static unsigned int decutf8(unsigned int* state, unsigned int* codep, unsigned int byte)
|
||||
{
|
||||
unsigned int type = utf8d[byte];
|
||||
*codep = (*state != UTF8_ACCEPT) ?
|
||||
(byte & 0x3fu) | (*codep << 6) :
|
||||
(0xff >> type) & (byte);
|
||||
*state = utf8d[256 + *state*16 + type];
|
||||
return *state;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct sth_stash* sth_create(int cachew, int cacheh)
|
||||
{
|
||||
struct sth_stash* stash;
|
||||
|
||||
// Allocate memory for the font stash.
|
||||
stash = (struct sth_stash*)malloc(sizeof(struct sth_stash));
|
||||
if (stash == NULL) goto error;
|
||||
memset(stash,0,sizeof(struct sth_stash));
|
||||
|
||||
// Create texture for the cache.
|
||||
stash->tw = cachew;
|
||||
stash->th = cacheh;
|
||||
stash->itw = 1.0f/cachew;
|
||||
stash->ith = 1.0f/cacheh;
|
||||
glGenTextures(1, &stash->tex);
|
||||
if (!stash->tex) goto error;
|
||||
glBindTexture(GL_TEXTURE_2D, stash->tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, stash->tw,stash->th, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
return stash;
|
||||
|
||||
error:
|
||||
if (stash != NULL)
|
||||
free(stash);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int sth_add_font(struct sth_stash* stash, int idx, const char* path)
|
||||
{
|
||||
FILE* fp = 0;
|
||||
int i, ascent, descent, fh, lineGap;
|
||||
struct sth_font* fnt;
|
||||
|
||||
if (idx < 0 || idx >= MAX_FONTS) return 0;
|
||||
|
||||
fnt = &stash->fonts[idx];
|
||||
if (fnt->data)
|
||||
free(fnt->data);
|
||||
if (fnt->glyphs)
|
||||
free(fnt->glyphs);
|
||||
memset(fnt,0,sizeof(struct sth_font));
|
||||
|
||||
// Init hash lookup.
|
||||
for (i = 0; i < HASH_LUT_SIZE; ++i) fnt->lut[i] = -1;
|
||||
|
||||
if (path != NULL) {
|
||||
// Read in the font data.
|
||||
fp = fopen(path, "rb");
|
||||
if (!fp) goto error;
|
||||
fseek(fp,0,SEEK_END);
|
||||
fnt->datasize = (int)ftell(fp);
|
||||
fseek(fp,0,SEEK_SET);
|
||||
fnt->data = (unsigned char*)malloc(fnt->datasize);
|
||||
fnt->freedata = 1;
|
||||
if (fnt->data == NULL) goto error;
|
||||
fread(fnt->data, 1, fnt->datasize, fp);
|
||||
fclose(fp);
|
||||
fp = 0;
|
||||
} else {
|
||||
fnt->data = &droidsans_ttf[0];
|
||||
fnt->freedata = 0;
|
||||
}
|
||||
|
||||
// Init stb_truetype
|
||||
if (!stbtt_InitFont(&fnt->font, fnt->data, 0)) goto error;
|
||||
|
||||
// Store normalized line height. The real line height is got
|
||||
// by multiplying the lineh by font size.
|
||||
stbtt_GetFontVMetrics(&fnt->font, &ascent, &descent, &lineGap);
|
||||
fh = ascent - descent;
|
||||
fnt->ascender = (float)ascent / (float)fh;
|
||||
fnt->descender = (float)descent / (float)fh;
|
||||
fnt->lineh = (float)(fh + lineGap) / (float)fh;
|
||||
|
||||
return 1;
|
||||
|
||||
error:
|
||||
if (fnt->freedata && fnt->data) free(fnt->data);
|
||||
if (fnt->glyphs) free(fnt->glyphs);
|
||||
memset(fnt,0,sizeof(struct sth_font));
|
||||
if (fp) fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sth_glyph* get_glyph(struct sth_stash* stash, struct sth_font* fnt, unsigned int codepoint, short isize)
|
||||
{
|
||||
int i,g,advance,lsb,x0,y0,x1,y1,gw,gh;
|
||||
float scale;
|
||||
struct sth_glyph* glyph;
|
||||
unsigned char* bmp;
|
||||
unsigned int h;
|
||||
float size = isize/10.0f;
|
||||
int rh;
|
||||
struct sth_row* br;
|
||||
|
||||
// Find code point and size.
|
||||
h = hashint(codepoint) & (HASH_LUT_SIZE-1);
|
||||
i = fnt->lut[h];
|
||||
while (i != -1)
|
||||
{
|
||||
if (fnt->glyphs[i].codepoint == codepoint && fnt->glyphs[i].size == isize)
|
||||
return &fnt->glyphs[i];
|
||||
i = fnt->glyphs[i].next;
|
||||
}
|
||||
|
||||
// Could not find glyph, create it.
|
||||
scale = stbtt_ScaleForPixelHeight(&fnt->font, size);
|
||||
g = stbtt_FindGlyphIndex(&fnt->font, codepoint);
|
||||
stbtt_GetGlyphHMetrics(&fnt->font, g, &advance, &lsb);
|
||||
stbtt_GetGlyphBitmapBox(&fnt->font, g, scale,scale, &x0,&y0,&x1,&y1);
|
||||
gw = x1-x0;
|
||||
gh = y1-y0;
|
||||
|
||||
|
||||
// Find row where the glyph can be fit.
|
||||
br = NULL;
|
||||
rh = (gh+7) & ~7;
|
||||
for (i = 0; i < stash->nrows; ++i)
|
||||
{
|
||||
if (stash->rows[i].h == rh && stash->rows[i].x+gw+1 <= stash->tw)
|
||||
br = &stash->rows[i];
|
||||
}
|
||||
|
||||
// If no row found, add new.
|
||||
if (br == NULL)
|
||||
{
|
||||
short py = 0;
|
||||
// Check that there is enough space.
|
||||
if (stash->nrows)
|
||||
{
|
||||
py = stash->rows[stash->nrows-1].y + stash->rows[stash->nrows-1].h+1;
|
||||
if (py+rh > stash->th)
|
||||
return 0;
|
||||
}
|
||||
// Init and add row
|
||||
br = &stash->rows[stash->nrows];
|
||||
br->x = 0;
|
||||
br->y = py;
|
||||
br->h = rh;
|
||||
stash->nrows++;
|
||||
}
|
||||
|
||||
// Alloc space for new glyph.
|
||||
fnt->nglyphs++;
|
||||
fnt->glyphs = realloc(fnt->glyphs, fnt->nglyphs*sizeof(struct sth_glyph));
|
||||
if (!fnt->glyphs) return 0;
|
||||
|
||||
// Init glyph.
|
||||
glyph = &fnt->glyphs[fnt->nglyphs-1];
|
||||
memset(glyph, 0, sizeof(struct sth_glyph));
|
||||
glyph->codepoint = codepoint;
|
||||
glyph->size = isize;
|
||||
glyph->x0 = br->x;
|
||||
glyph->y0 = br->y;
|
||||
glyph->x1 = glyph->x0+gw;
|
||||
glyph->y1 = glyph->y0+gh;
|
||||
glyph->xadv = scale * advance;
|
||||
glyph->xoff = (float)x0;
|
||||
glyph->yoff = (float)y0;
|
||||
glyph->next = 0;
|
||||
|
||||
// Advance row location.
|
||||
br->x += gw+1;
|
||||
|
||||
// Insert char to hash lookup.
|
||||
glyph->next = fnt->lut[h];
|
||||
fnt->lut[h] = fnt->nglyphs-1;
|
||||
|
||||
// Rasterize
|
||||
bmp = (unsigned char*)malloc(gw*gh);
|
||||
if (bmp)
|
||||
{
|
||||
stbtt_MakeGlyphBitmap(&fnt->font, bmp, gw,gh,gw, scale,scale, g);
|
||||
// Update texture
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, glyph->x0,glyph->y0, gw,gh, GL_ALPHA,GL_UNSIGNED_BYTE,bmp);
|
||||
free(bmp);
|
||||
}
|
||||
|
||||
return glyph;
|
||||
}
|
||||
|
||||
static int get_quad(struct sth_stash* stash, struct sth_font* fnt, unsigned int codepoint, short isize, float* x, float* y, struct sth_quad* q)
|
||||
{
|
||||
int rx,ry;
|
||||
struct sth_glyph* glyph = get_glyph(stash, fnt, codepoint, isize);
|
||||
if (!glyph) return 0;
|
||||
|
||||
rx = floorf(*x + glyph->xoff);
|
||||
ry = floorf(*y - glyph->yoff);
|
||||
|
||||
q->x0 = rx;
|
||||
q->y0 = ry;
|
||||
q->x1 = rx + glyph->x1 - glyph->x0;
|
||||
q->y1 = ry - glyph->y1 + glyph->y0;
|
||||
|
||||
q->s0 = (glyph->x0) * stash->itw;
|
||||
q->t0 = (glyph->y0) * stash->ith;
|
||||
q->s1 = (glyph->x1) * stash->itw;
|
||||
q->t1 = (glyph->y1) * stash->ith;
|
||||
|
||||
*x += glyph->xadv;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static float* setv(float* v, float x, float y, float s, float t)
|
||||
{
|
||||
v[0] = x;
|
||||
v[1] = y;
|
||||
v[2] = s;
|
||||
v[3] = t;
|
||||
return v+4;
|
||||
}
|
||||
|
||||
static void flush_draw(struct sth_stash* stash)
|
||||
{
|
||||
if (stash->nverts == 0)
|
||||
return;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, stash->tex);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glVertexPointer(2, GL_FLOAT, VERT_STRIDE, stash->verts);
|
||||
glTexCoordPointer(2, GL_FLOAT, VERT_STRIDE, stash->verts+2);
|
||||
glDrawArrays(GL_TRIANGLES, 0, stash->nverts);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
stash->nverts = 0;
|
||||
}
|
||||
|
||||
void sth_begin_draw(struct sth_stash* stash)
|
||||
{
|
||||
if (stash == NULL) return;
|
||||
if (stash->drawing)
|
||||
flush_draw(stash);
|
||||
stash->drawing = 1;
|
||||
}
|
||||
|
||||
void sth_end_draw(struct sth_stash* stash)
|
||||
{
|
||||
if (stash == NULL) return;
|
||||
if (!stash->drawing) return;
|
||||
|
||||
/*
|
||||
// Debug dump.
|
||||
if (stash->nverts+6 < VERT_COUNT)
|
||||
{
|
||||
float x = 500, y = 100;
|
||||
float* v = &stash->verts[stash->nverts*4];
|
||||
|
||||
v = setv(v, x, y, 0, 0);
|
||||
v = setv(v, x+stash->tw, y, 1, 0);
|
||||
v = setv(v, x+stash->tw, y+stash->th, 1, 1);
|
||||
|
||||
v = setv(v, x, y, 0, 0);
|
||||
v = setv(v, x+stash->tw, y+stash->th, 1, 1);
|
||||
v = setv(v, x, y+stash->th, 0, 1);
|
||||
|
||||
stash->nverts += 6;
|
||||
}
|
||||
*/
|
||||
|
||||
flush_draw(stash);
|
||||
stash->drawing = 0;
|
||||
}
|
||||
|
||||
int sth_draw_text(struct sth_stash* stash,
|
||||
int idx, float size,
|
||||
float x, float y,
|
||||
const char* s, float* dx)
|
||||
{
|
||||
unsigned int codepoint;
|
||||
unsigned int state = 0;
|
||||
struct sth_quad q;
|
||||
short isize = (short)(size*10.0f);
|
||||
float* v;
|
||||
struct sth_font* fnt;
|
||||
|
||||
if (stash == NULL) return 0;
|
||||
if (!stash->tex) return 0;
|
||||
if (idx < 0 || idx >= MAX_FONTS) return 0;
|
||||
fnt = &stash->fonts[idx];
|
||||
if (!fnt->data) return 0;
|
||||
|
||||
for (; *s; ++s)
|
||||
{
|
||||
if (decutf8(&state, &codepoint, *(unsigned char*)s)) continue;
|
||||
|
||||
if (stash->nverts+6 >= VERT_COUNT)
|
||||
flush_draw(stash);
|
||||
|
||||
if (!get_quad(stash, fnt, codepoint, isize, &x, &y, &q)) continue;
|
||||
|
||||
v = &stash->verts[stash->nverts*4];
|
||||
|
||||
v = setv(v, q.x0, q.y0, q.s0, q.t0);
|
||||
v = setv(v, q.x1, q.y0, q.s1, q.t0);
|
||||
v = setv(v, q.x1, q.y1, q.s1, q.t1);
|
||||
|
||||
v = setv(v, q.x0, q.y0, q.s0, q.t0);
|
||||
v = setv(v, q.x1, q.y1, q.s1, q.t1);
|
||||
v = setv(v, q.x0, q.y1, q.s0, q.t1);
|
||||
|
||||
stash->nverts += 6;
|
||||
}
|
||||
|
||||
if (dx) *dx = x;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void sth_dim_text(struct sth_stash* stash,
|
||||
int idx, float size,
|
||||
const char* s,
|
||||
float* minx, float* miny, float* maxx, float* maxy)
|
||||
{
|
||||
unsigned int codepoint;
|
||||
unsigned int state = 0;
|
||||
struct sth_quad q;
|
||||
short isize = (short)(size*10.0f);
|
||||
struct sth_font* fnt;
|
||||
float x = 0, y = 0;
|
||||
|
||||
if (stash == NULL) return;
|
||||
if (!stash->tex) return;
|
||||
if (idx < 0 || idx >= MAX_FONTS) return;
|
||||
fnt = &stash->fonts[idx];
|
||||
if (!fnt->data) return;
|
||||
|
||||
*minx = *maxx = x;
|
||||
*miny = *maxy = y;
|
||||
|
||||
for (; *s; ++s)
|
||||
{
|
||||
if (decutf8(&state, &codepoint, *(unsigned char*)s)) continue;
|
||||
if (!get_quad(stash, fnt, codepoint, isize, &x, &y, &q)) continue;
|
||||
if (q.x0 < *minx) *minx = q.x0;
|
||||
if (q.x1 > *maxx) *maxx = q.x1;
|
||||
if (q.y1 < *miny) *miny = q.y1;
|
||||
if (q.y0 > *maxy) *maxy = q.y0;
|
||||
}
|
||||
}
|
||||
|
||||
void sth_vmetrics(struct sth_stash* stash,
|
||||
int idx, float size,
|
||||
float* ascender, float* descender, float* lineh)
|
||||
{
|
||||
if (stash == NULL) return;
|
||||
if (!stash->tex) return;
|
||||
if (idx < 0 || idx >= MAX_FONTS) return;
|
||||
if (!stash->fonts[idx].data) return;
|
||||
if (ascender)
|
||||
*ascender = stash->fonts[idx].ascender*size;
|
||||
if (descender)
|
||||
*descender = stash->fonts[idx].descender*size;
|
||||
if (lineh)
|
||||
*lineh = stash->fonts[idx].lineh*size;
|
||||
}
|
||||
|
||||
void sth_delete(struct sth_stash* stash)
|
||||
{
|
||||
int i;
|
||||
if (!stash) return;
|
||||
if (stash->tex) glDeleteTextures(1,&stash->tex);
|
||||
for (i = 0; i < MAX_FONTS; ++i)
|
||||
{
|
||||
if (stash->fonts[i].glyphs)
|
||||
free(stash->fonts[i].glyphs);
|
||||
if (stash->fonts[i].freedata && stash->fonts[i].data)
|
||||
free(stash->fonts[i].data);
|
||||
}
|
||||
free(stash);
|
||||
}
|
||||
50
gltools/@contrib/fontstash.h
Normal file
50
gltools/@contrib/fontstash.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// Copyright (c) 2009 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef FONTSTASH_H
|
||||
#define FONTSTASH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct sth_stash* sth_create(int cachew, int cacheh);
|
||||
|
||||
int sth_add_font(struct sth_stash*, int idx, const char* path);
|
||||
|
||||
void sth_begin_draw(struct sth_stash* stash);
|
||||
void sth_end_draw(struct sth_stash* stash);
|
||||
|
||||
int sth_draw_text(struct sth_stash* stash,
|
||||
int idx, float size,
|
||||
float x, float y, const char* string, float* dx);
|
||||
|
||||
void sth_dim_text(struct sth_stash* stash, int idx, float size, const char* string,
|
||||
float* minx, float* miny, float* maxx, float* maxy);
|
||||
|
||||
void sth_vmetrics(struct sth_stash* stash,
|
||||
int idx, float size,
|
||||
float* ascender, float* descender, float * lineh);
|
||||
|
||||
void sth_delete(struct sth_stash* stash);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // FONTSTASH_H
|
||||
693
gltools/@contrib/imgui.cpp
Normal file
693
gltools/@contrib/imgui.cpp
Normal file
|
|
@ -0,0 +1,693 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
// Copyright (c) 2011 Mario 'rlyeh' Rodriguez
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include "imgui.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const unsigned TEXT_POOL_SIZE = 8000;
|
||||
static char g_textPool[TEXT_POOL_SIZE];
|
||||
static unsigned g_textPoolSize = 0;
|
||||
static const char* allocText(const char* text)
|
||||
{
|
||||
unsigned len = strlen(text)+1;
|
||||
if (g_textPoolSize + len >= TEXT_POOL_SIZE)
|
||||
return 0;
|
||||
char* dst = &g_textPool[g_textPoolSize];
|
||||
memcpy(dst, text, len);
|
||||
g_textPoolSize += len;
|
||||
return dst;
|
||||
}
|
||||
|
||||
static const unsigned GFXCMD_QUEUE_SIZE = 5000;
|
||||
static imguiGfxCmd g_gfxCmdQueue[GFXCMD_QUEUE_SIZE];
|
||||
static unsigned g_gfxCmdQueueSize = 0;
|
||||
|
||||
static void resetGfxCmdQueue()
|
||||
{
|
||||
g_gfxCmdQueueSize = 0;
|
||||
g_textPoolSize = 0;
|
||||
}
|
||||
|
||||
static void addGfxCmdScissor(int x, int y, int w, int h)
|
||||
{
|
||||
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
|
||||
return;
|
||||
imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
|
||||
cmd.type = IMGUI_GFXCMD_SCISSOR;
|
||||
cmd.flags = x < 0 ? 0 : 1; // on/off flag.
|
||||
cmd.col = 0;
|
||||
cmd.rect.x = (short)x;
|
||||
cmd.rect.y = (short)y;
|
||||
cmd.rect.w = (short)w;
|
||||
cmd.rect.h = (short)h;
|
||||
}
|
||||
|
||||
static void addGfxCmdRect(float x, float y, float w, float h, unsigned int color)
|
||||
{
|
||||
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
|
||||
return;
|
||||
imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
|
||||
cmd.type = IMGUI_GFXCMD_RECT;
|
||||
cmd.flags = 0;
|
||||
cmd.col = color;
|
||||
cmd.rect.x = (short)(x*8.0f);
|
||||
cmd.rect.y = (short)(y*8.0f);
|
||||
cmd.rect.w = (short)(w*8.0f);
|
||||
cmd.rect.h = (short)(h*8.0f);
|
||||
cmd.rect.r = 0;
|
||||
}
|
||||
|
||||
static void addGfxCmdLine(float x0, float y0, float x1, float y1, float r, unsigned int color)
|
||||
{
|
||||
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
|
||||
return;
|
||||
imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
|
||||
cmd.type = IMGUI_GFXCMD_LINE;
|
||||
cmd.flags = 0;
|
||||
cmd.col = color;
|
||||
cmd.line.x0 = (short)(x0*8.0f);
|
||||
cmd.line.y0 = (short)(y0*8.0f);
|
||||
cmd.line.x1 = (short)(x1*8.0f);
|
||||
cmd.line.y1 = (short)(y1*8.0f);
|
||||
cmd.line.r = (short)(r*8.0f);
|
||||
}
|
||||
|
||||
static void addGfxCmdRoundedRect(float x, float y, float w, float h, float r, unsigned int color)
|
||||
{
|
||||
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
|
||||
return;
|
||||
imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
|
||||
cmd.type = IMGUI_GFXCMD_RECT;
|
||||
cmd.flags = 0;
|
||||
cmd.col = color;
|
||||
cmd.rect.x = (short)(x*8.0f);
|
||||
cmd.rect.y = (short)(y*8.0f);
|
||||
cmd.rect.w = (short)(w*8.0f);
|
||||
cmd.rect.h = (short)(h*8.0f);
|
||||
cmd.rect.r = (short)(r*8.0f);
|
||||
}
|
||||
|
||||
static void addGfxCmdTriangle(int x, int y, int w, int h, int flags, unsigned int color)
|
||||
{
|
||||
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
|
||||
return;
|
||||
imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
|
||||
cmd.type = IMGUI_GFXCMD_TRIANGLE;
|
||||
cmd.flags = (char)flags;
|
||||
cmd.col = color;
|
||||
cmd.rect.x = (short)(x*8.0f);
|
||||
cmd.rect.y = (short)(y*8.0f);
|
||||
cmd.rect.w = (short)(w*8.0f);
|
||||
cmd.rect.h = (short)(h*8.0f);
|
||||
}
|
||||
|
||||
static void addGfxCmdText(int x, int y, int align, const char* text, unsigned int color)
|
||||
{
|
||||
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
|
||||
return;
|
||||
imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
|
||||
cmd.type = IMGUI_GFXCMD_TEXT;
|
||||
cmd.flags = 0;
|
||||
cmd.col = color;
|
||||
cmd.text.x = (short)x;
|
||||
cmd.text.y = (short)y;
|
||||
cmd.text.align = (short)align;
|
||||
cmd.text.text = allocText(text);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
struct GuiState
|
||||
{
|
||||
GuiState() :
|
||||
left(false), leftPressed(false), leftReleased(false),
|
||||
mx(-1), my(-1), scroll(0),
|
||||
active(0), hot(0), hotToBe(0), isHot(false), isActive(false), wentActive(false),
|
||||
dragX(0), dragY(0), dragOrig(0), widgetX(0), widgetY(0), widgetW(100),
|
||||
insideCurrentScroll(false), areaId(0), widgetId(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool left;
|
||||
bool leftPressed, leftReleased;
|
||||
int mx,my;
|
||||
int scroll;
|
||||
unsigned int active;
|
||||
unsigned int hot;
|
||||
unsigned int hotToBe;
|
||||
bool isHot;
|
||||
bool isActive;
|
||||
bool wentActive;
|
||||
int dragX, dragY;
|
||||
float dragOrig;
|
||||
int widgetX, widgetY, widgetW;
|
||||
bool insideCurrentScroll;
|
||||
|
||||
unsigned int areaId;
|
||||
unsigned int widgetId;
|
||||
};
|
||||
|
||||
static GuiState g_state;
|
||||
|
||||
inline bool anyActive()
|
||||
{
|
||||
return g_state.active != 0;
|
||||
}
|
||||
|
||||
inline bool anyHot() // @rlyeh: new method
|
||||
{
|
||||
return g_state.hot != 0;
|
||||
}
|
||||
|
||||
inline bool isActive(unsigned int id)
|
||||
{
|
||||
return g_state.active == id;
|
||||
}
|
||||
|
||||
inline bool isHot(unsigned int id)
|
||||
{
|
||||
return g_state.hot == id;
|
||||
}
|
||||
|
||||
inline bool inRect(int x, int y, int w, int h, bool checkScroll = true)
|
||||
{
|
||||
return (!checkScroll || g_state.insideCurrentScroll) && g_state.mx >= x && g_state.mx <= x+w && g_state.my >= y && g_state.my <= y+h;
|
||||
}
|
||||
|
||||
inline void clearInput()
|
||||
{
|
||||
g_state.leftPressed = false;
|
||||
g_state.leftReleased = false;
|
||||
g_state.scroll = 0;
|
||||
}
|
||||
|
||||
inline void clearActive()
|
||||
{
|
||||
g_state.active = 0;
|
||||
// mark all UI for this frame as processed
|
||||
clearInput();
|
||||
}
|
||||
|
||||
inline void setActive(unsigned int id)
|
||||
{
|
||||
g_state.active = id;
|
||||
g_state.wentActive = true;
|
||||
}
|
||||
|
||||
inline void setHot(unsigned int id)
|
||||
{
|
||||
g_state.hotToBe = id;
|
||||
}
|
||||
|
||||
|
||||
static bool buttonLogic(unsigned int id, bool over)
|
||||
{
|
||||
bool res = false;
|
||||
// process down
|
||||
if (!anyActive())
|
||||
{
|
||||
if (over)
|
||||
setHot(id);
|
||||
if (isHot(id) && g_state.leftPressed)
|
||||
setActive(id);
|
||||
}
|
||||
|
||||
// if button is active, then react on left up
|
||||
if (isActive(id))
|
||||
{
|
||||
g_state.isActive = true;
|
||||
if (over)
|
||||
setHot(id);
|
||||
if (g_state.leftReleased)
|
||||
{
|
||||
if (isHot(id))
|
||||
res = true;
|
||||
clearActive();
|
||||
}
|
||||
}
|
||||
|
||||
if (isHot(id))
|
||||
g_state.isHot = true;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void updateInput(int mx, int my, unsigned char mbut, int scroll)
|
||||
{
|
||||
bool left = (mbut & IMGUI_MBUT_LEFT) != 0;
|
||||
|
||||
g_state.mx = mx;
|
||||
g_state.my = my;
|
||||
g_state.leftPressed = !g_state.left && left;
|
||||
g_state.leftReleased = g_state.left && !left;
|
||||
g_state.left = left;
|
||||
|
||||
g_state.scroll = scroll;
|
||||
}
|
||||
|
||||
bool imguiAnyActive() // added by rute
|
||||
{
|
||||
return g_state.active != 0;
|
||||
}
|
||||
|
||||
void imguiBeginFrame(int mx, int my, unsigned char mbut, int scroll)
|
||||
{
|
||||
updateInput(mx,my,mbut,scroll);
|
||||
|
||||
g_state.hot = g_state.hotToBe;
|
||||
g_state.hotToBe = 0;
|
||||
|
||||
g_state.wentActive = false;
|
||||
g_state.isActive = false;
|
||||
g_state.isHot = false;
|
||||
|
||||
g_state.widgetX = 0;
|
||||
g_state.widgetY = 0;
|
||||
g_state.widgetW = 0;
|
||||
|
||||
g_state.areaId = 1;
|
||||
g_state.widgetId = 1;
|
||||
|
||||
resetGfxCmdQueue();
|
||||
}
|
||||
|
||||
void imguiEndFrame()
|
||||
{
|
||||
clearInput();
|
||||
}
|
||||
|
||||
const imguiGfxCmd* imguiGetRenderQueue()
|
||||
{
|
||||
return g_gfxCmdQueue;
|
||||
}
|
||||
|
||||
int imguiGetRenderQueueSize()
|
||||
{
|
||||
return g_gfxCmdQueueSize;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static const int BUTTON_HEIGHT = 20;
|
||||
static const int SLIDER_HEIGHT = 20;
|
||||
static const int SLIDER_MARKER_WIDTH = 10;
|
||||
static const int CHECK_SIZE = 8;
|
||||
static const int DEFAULT_SPACING = 4;
|
||||
static const int TEXT_HEIGHT = 8;
|
||||
static const int SCROLL_AREA_PADDING = 6;
|
||||
static const int INDENT_SIZE = 16;
|
||||
static const int AREA_HEADER = 28;
|
||||
|
||||
static int g_scrollTop = 0;
|
||||
static int g_scrollBottom = 0;
|
||||
static int g_scrollRight = 0;
|
||||
static int g_scrollAreaTop = 0;
|
||||
static int* g_scrollVal = 0;
|
||||
static int g_focusTop = 0;
|
||||
static int g_focusBottom = 0;
|
||||
static unsigned int g_scrollId = 0;
|
||||
static bool g_insideScrollArea = false;
|
||||
|
||||
bool imguiBeginScrollArea(const char* name, int x, int y, int w, int h, int* scroll)
|
||||
{
|
||||
g_state.areaId++;
|
||||
g_state.widgetId = 0;
|
||||
g_scrollId = (g_state.areaId<<16) | g_state.widgetId;
|
||||
|
||||
g_state.widgetX = x + SCROLL_AREA_PADDING;
|
||||
g_state.widgetY = y+h-AREA_HEADER + (*scroll);
|
||||
g_state.widgetW = w - SCROLL_AREA_PADDING*4;
|
||||
g_scrollTop = y-AREA_HEADER+h;
|
||||
g_scrollBottom = y+SCROLL_AREA_PADDING;
|
||||
g_scrollRight = x+w - SCROLL_AREA_PADDING*3;
|
||||
g_scrollVal = scroll;
|
||||
|
||||
g_scrollAreaTop = g_state.widgetY;
|
||||
|
||||
g_focusTop = y-AREA_HEADER;
|
||||
g_focusBottom = y-AREA_HEADER+h;
|
||||
|
||||
g_insideScrollArea = inRect(x, y, w, h, false);
|
||||
g_state.insideCurrentScroll = g_insideScrollArea;
|
||||
|
||||
addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 6, imguiRGBA(0,0,0,192));
|
||||
|
||||
addGfxCmdText(x+AREA_HEADER/2, y+h-AREA_HEADER/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, name, imguiRGBA(255,255,255,128));
|
||||
|
||||
if( g_scrollVal ) // @rlyeh: support for fixed areas
|
||||
addGfxCmdScissor(
|
||||
x < 0 ? 0 : x+SCROLL_AREA_PADDING, //@rlyeh: fix scissor clipping problem when scroll area is on left rect client
|
||||
y+SCROLL_AREA_PADDING,
|
||||
w-SCROLL_AREA_PADDING*4 + ( x < 0 ? x : 0 ), // @rlyeh: small optimization; @todo: on the right as well
|
||||
h > (AREA_HEADER + SCROLL_AREA_PADDING ) ? h - (AREA_HEADER + SCROLL_AREA_PADDING) : h ); // @rlyeh: fix when collapsing areas ( h <= AREA_HEADER )
|
||||
|
||||
return g_insideScrollArea;
|
||||
}
|
||||
|
||||
void imguiEndScrollArea()
|
||||
{
|
||||
if( g_scrollVal ) // @rlyeh: support for fixed areas
|
||||
// Disable scissoring.
|
||||
addGfxCmdScissor(-1,-1,-1,-1);
|
||||
|
||||
// Draw scroll bar
|
||||
int x = g_scrollRight+SCROLL_AREA_PADDING/2;
|
||||
int y = g_scrollBottom;
|
||||
int w = SCROLL_AREA_PADDING*2;
|
||||
int h = g_scrollTop - g_scrollBottom;
|
||||
|
||||
int stop = g_scrollAreaTop;
|
||||
int sbot = g_state.widgetY;
|
||||
int sh = stop - sbot; // The scrollable area height.
|
||||
|
||||
float barHeight = (float)h/(float)sh;
|
||||
|
||||
if (h > AREA_HEADER && barHeight < 1) // @rlyeh: fix when area size is too small
|
||||
{
|
||||
float barY = (float)(y - sbot)/(float)sh;
|
||||
if (barY < 0) barY = 0;
|
||||
if (barY > 1) barY = 1;
|
||||
|
||||
// Handle scroll bar logic.
|
||||
unsigned int hid = g_scrollId;
|
||||
int hx = x;
|
||||
int hy = y + (int)(barY*h);
|
||||
int hw = w;
|
||||
int hh = (int)(barHeight*h);
|
||||
|
||||
const int range = h - (hh-1);
|
||||
bool over = inRect(hx, hy, hw, hh);
|
||||
buttonLogic(hid, over);
|
||||
if (isActive(hid))
|
||||
{
|
||||
float u = (float)(hy-y) / (float)range;
|
||||
if (g_state.wentActive)
|
||||
{
|
||||
g_state.dragY = g_state.my;
|
||||
g_state.dragOrig = u;
|
||||
}
|
||||
if (g_state.dragY != g_state.my)
|
||||
{
|
||||
u = g_state.dragOrig + (g_state.my - g_state.dragY) / (float)range;
|
||||
if (u < 0) u = 0;
|
||||
if (u > 1) u = 1;
|
||||
*g_scrollVal = (int)((1-u) * (sh - h));
|
||||
}
|
||||
}
|
||||
|
||||
// BG
|
||||
addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, (float)w/2-1, imguiRGBA(0,0,0,196));
|
||||
// Bar
|
||||
if (isActive(hid))
|
||||
addGfxCmdRoundedRect((float)hx, (float)hy, (float)hw, (float)hh, (float)w/2-1, imguiRGBA(255,196,0,196));
|
||||
else
|
||||
addGfxCmdRoundedRect((float)hx, (float)hy, (float)hw, (float)hh, (float)w/2-1, isHot(hid) ? imguiRGBA(255,196,0,96) : imguiRGBA(255,255,255,64));
|
||||
|
||||
// Handle mouse scrolling.
|
||||
if (g_insideScrollArea) // && !anyActive())
|
||||
{
|
||||
if (g_state.scroll)
|
||||
{
|
||||
*g_scrollVal += 20*g_state.scroll;
|
||||
if (*g_scrollVal < 0) *g_scrollVal = 0;
|
||||
if (*g_scrollVal > (sh - h)) *g_scrollVal = (sh - h);
|
||||
}
|
||||
}
|
||||
} else
|
||||
*g_scrollVal = 0; // @rlyeh: fix for mismatching scroll when collapsing/uncollapsing content larger than container height
|
||||
g_state.insideCurrentScroll = false;
|
||||
}
|
||||
|
||||
bool imguiButton(const char* text, bool enabled)
|
||||
{
|
||||
g_state.widgetId++;
|
||||
unsigned int id = (g_state.areaId<<16) | g_state.widgetId;
|
||||
|
||||
int x = g_state.widgetX;
|
||||
int y = g_state.widgetY - BUTTON_HEIGHT;
|
||||
int w = g_state.widgetW;
|
||||
int h = BUTTON_HEIGHT;
|
||||
g_state.widgetY -= BUTTON_HEIGHT + DEFAULT_SPACING;
|
||||
|
||||
bool over = enabled && inRect(x, y, w, h);
|
||||
bool res = buttonLogic(id, over);
|
||||
|
||||
addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, (float)BUTTON_HEIGHT/2-1, imguiRGBA(128,128,128, isActive(id)?196:96));
|
||||
if (enabled)
|
||||
addGfxCmdText(x+BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200));
|
||||
else
|
||||
addGfxCmdText(x+BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool imguiItem(const char* text, bool enabled)
|
||||
{
|
||||
g_state.widgetId++;
|
||||
unsigned int id = (g_state.areaId<<16) | g_state.widgetId;
|
||||
|
||||
int x = g_state.widgetX;
|
||||
int y = g_state.widgetY - BUTTON_HEIGHT;
|
||||
int w = g_state.widgetW;
|
||||
int h = BUTTON_HEIGHT;
|
||||
g_state.widgetY -= BUTTON_HEIGHT + DEFAULT_SPACING;
|
||||
|
||||
bool over = enabled && inRect(x, y, w, h);
|
||||
bool res = buttonLogic(id, over);
|
||||
|
||||
if (isHot(id))
|
||||
addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 2.0f, imguiRGBA(255,196,0,isActive(id)?196:96));
|
||||
|
||||
if (enabled)
|
||||
addGfxCmdText(x+BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(255,255,255,200));
|
||||
else
|
||||
addGfxCmdText(x+BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool imguiCheck(const char* text, bool checked, bool enabled)
|
||||
{
|
||||
g_state.widgetId++;
|
||||
unsigned int id = (g_state.areaId<<16) | g_state.widgetId;
|
||||
|
||||
int x = g_state.widgetX;
|
||||
int y = g_state.widgetY - BUTTON_HEIGHT;
|
||||
int w = g_state.widgetW;
|
||||
int h = BUTTON_HEIGHT;
|
||||
g_state.widgetY -= BUTTON_HEIGHT + DEFAULT_SPACING;
|
||||
|
||||
bool over = enabled && inRect(x, y, w, h);
|
||||
bool res = buttonLogic(id, over);
|
||||
|
||||
const int cx = x+BUTTON_HEIGHT/2-CHECK_SIZE/2;
|
||||
const int cy = y+BUTTON_HEIGHT/2-CHECK_SIZE/2;
|
||||
addGfxCmdRoundedRect((float)cx-3, (float)cy-3, (float)CHECK_SIZE+6, (float)CHECK_SIZE+6, 4, imguiRGBA(128,128,128, isActive(id)?196:96));
|
||||
if (checked)
|
||||
{
|
||||
if (enabled)
|
||||
addGfxCmdRoundedRect((float)cx, (float)cy, (float)CHECK_SIZE, (float)CHECK_SIZE, (float)CHECK_SIZE/2-1, imguiRGBA(255,255,255,isActive(id)?255:200));
|
||||
else
|
||||
addGfxCmdRoundedRect((float)cx, (float)cy, (float)CHECK_SIZE, (float)CHECK_SIZE, (float)CHECK_SIZE/2-1, imguiRGBA(128,128,128,200));
|
||||
}
|
||||
|
||||
if (enabled)
|
||||
addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200));
|
||||
else
|
||||
addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool imguiCollapse(const char* text, const char* subtext, bool checked, bool enabled)
|
||||
{
|
||||
g_state.widgetId++;
|
||||
unsigned int id = (g_state.areaId<<16) | g_state.widgetId;
|
||||
|
||||
int x = g_state.widgetX;
|
||||
int y = g_state.widgetY - BUTTON_HEIGHT;
|
||||
int w = g_state.widgetW;
|
||||
int h = BUTTON_HEIGHT;
|
||||
g_state.widgetY -= BUTTON_HEIGHT; // + DEFAULT_SPACING;
|
||||
|
||||
const int cx = x+BUTTON_HEIGHT/2-CHECK_SIZE/2;
|
||||
const int cy = y+BUTTON_HEIGHT/2-CHECK_SIZE/2;
|
||||
|
||||
bool over = enabled && inRect(x, y, w, h);
|
||||
bool res = buttonLogic(id, over);
|
||||
|
||||
if (checked)
|
||||
addGfxCmdTriangle(cx, cy, CHECK_SIZE, CHECK_SIZE, 2, imguiRGBA(255,255,255,isActive(id)?255:200));
|
||||
else
|
||||
addGfxCmdTriangle(cx, cy, CHECK_SIZE, CHECK_SIZE, 1, imguiRGBA(255,255,255,isActive(id)?255:200));
|
||||
|
||||
if (enabled)
|
||||
addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200));
|
||||
else
|
||||
addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200));
|
||||
|
||||
if (subtext)
|
||||
addGfxCmdText(x+w-BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, subtext, imguiRGBA(255,255,255,128));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void imguiLabel(const char* text)
|
||||
{
|
||||
int x = g_state.widgetX;
|
||||
int y = g_state.widgetY - BUTTON_HEIGHT;
|
||||
g_state.widgetY -= BUTTON_HEIGHT;
|
||||
addGfxCmdText(x, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(255,255,255,255));
|
||||
}
|
||||
|
||||
void imguiValue(const char* text)
|
||||
{
|
||||
const int x = g_state.widgetX;
|
||||
const int y = g_state.widgetY - BUTTON_HEIGHT;
|
||||
const int w = g_state.widgetW;
|
||||
g_state.widgetY -= BUTTON_HEIGHT;
|
||||
|
||||
addGfxCmdText(x+w-BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, text, imguiRGBA(255,255,255,200));
|
||||
}
|
||||
|
||||
bool imguiSlider(const char* text, float* val, float vmin, float vmax, float vinc, bool enabled)
|
||||
{
|
||||
g_state.widgetId++;
|
||||
unsigned int id = (g_state.areaId<<16) | g_state.widgetId;
|
||||
|
||||
int x = g_state.widgetX;
|
||||
int y = g_state.widgetY - BUTTON_HEIGHT;
|
||||
int w = g_state.widgetW;
|
||||
int h = SLIDER_HEIGHT;
|
||||
g_state.widgetY -= SLIDER_HEIGHT + DEFAULT_SPACING;
|
||||
|
||||
addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 4.0f, imguiRGBA(0,0,0,128));
|
||||
|
||||
const int range = w - SLIDER_MARKER_WIDTH;
|
||||
|
||||
float u = (*val - vmin) / (vmax-vmin);
|
||||
if (u < 0) u = 0;
|
||||
if (u > 1) u = 1;
|
||||
int m = (int)(u * range);
|
||||
|
||||
bool over = enabled && inRect(x+m, y, SLIDER_MARKER_WIDTH, SLIDER_HEIGHT);
|
||||
bool res = buttonLogic(id, over);
|
||||
bool valChanged = false;
|
||||
|
||||
if (isActive(id))
|
||||
{
|
||||
if (g_state.wentActive)
|
||||
{
|
||||
g_state.dragX = g_state.mx;
|
||||
g_state.dragOrig = u;
|
||||
}
|
||||
if (g_state.dragX != g_state.mx)
|
||||
{
|
||||
u = g_state.dragOrig + (float)(g_state.mx - g_state.dragX) / (float)range;
|
||||
if (u < 0) u = 0;
|
||||
if (u > 1) u = 1;
|
||||
*val = vmin + u*(vmax-vmin);
|
||||
*val = floorf(*val/vinc+0.5f)*vinc; // Snap to vinc
|
||||
m = (int)(u * range);
|
||||
valChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isActive(id))
|
||||
addGfxCmdRoundedRect((float)(x+m), (float)y, (float)SLIDER_MARKER_WIDTH, (float)SLIDER_HEIGHT, 4.0f, imguiRGBA(255,255,255,255));
|
||||
else
|
||||
addGfxCmdRoundedRect((float)(x+m), (float)y, (float)SLIDER_MARKER_WIDTH, (float)SLIDER_HEIGHT, 4.0f, isHot(id) ? imguiRGBA(255,196,0,128) : imguiRGBA(255,255,255,64));
|
||||
|
||||
// TODO: fix this, take a look at 'nicenum'.
|
||||
int digits = (int)(ceilf(log10f(vinc)));
|
||||
char fmt[16];
|
||||
snprintf(fmt, 16, "%%.%df", digits >= 0 ? 0 : -digits);
|
||||
char msg[128];
|
||||
snprintf(msg, 128, fmt, *val);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
addGfxCmdText(x+SLIDER_HEIGHT/2, y+SLIDER_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200));
|
||||
addGfxCmdText(x+w-SLIDER_HEIGHT/2, y+SLIDER_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, msg, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200));
|
||||
}
|
||||
else
|
||||
{
|
||||
addGfxCmdText(x+SLIDER_HEIGHT/2, y+SLIDER_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200));
|
||||
addGfxCmdText(x+w-SLIDER_HEIGHT/2, y+SLIDER_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, msg, imguiRGBA(128,128,128,200));
|
||||
}
|
||||
|
||||
return res || valChanged;
|
||||
}
|
||||
|
||||
|
||||
void imguiIndent()
|
||||
{
|
||||
g_state.widgetX += INDENT_SIZE;
|
||||
g_state.widgetW -= INDENT_SIZE;
|
||||
}
|
||||
|
||||
void imguiUnindent()
|
||||
{
|
||||
g_state.widgetX -= INDENT_SIZE;
|
||||
g_state.widgetW += INDENT_SIZE;
|
||||
}
|
||||
|
||||
void imguiSeparator()
|
||||
{
|
||||
g_state.widgetY -= DEFAULT_SPACING*3;
|
||||
}
|
||||
|
||||
void imguiSeparatorLine()
|
||||
{
|
||||
int x = g_state.widgetX;
|
||||
int y = g_state.widgetY - DEFAULT_SPACING*2;
|
||||
int w = g_state.widgetW;
|
||||
int h = 1;
|
||||
g_state.widgetY -= DEFAULT_SPACING*4;
|
||||
|
||||
addGfxCmdRect((float)x, (float)y, (float)w, (float)h, imguiRGBA(255,255,255,32));
|
||||
}
|
||||
|
||||
void imguiDrawText(int x, int y, int align, const char* text, unsigned int color)
|
||||
{
|
||||
addGfxCmdText(x, y, align, text, color);
|
||||
}
|
||||
|
||||
void imguiDrawLine(float x0, float y0, float x1, float y1, float r, unsigned int color)
|
||||
{
|
||||
addGfxCmdLine(x0, y0, x1, y1, r, color);
|
||||
}
|
||||
|
||||
void imguiDrawRect(float x, float y, float w, float h, unsigned int color)
|
||||
{
|
||||
addGfxCmdRect(x, y, w, h, color);
|
||||
}
|
||||
|
||||
void imguiDrawRoundedRect(float x, float y, float w, float h, float r, unsigned int color)
|
||||
{
|
||||
addGfxCmdRoundedRect(x, y, w, h, r, color);
|
||||
}
|
||||
110
gltools/@contrib/imgui.h
Normal file
110
gltools/@contrib/imgui.h
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef IMGUI_H
|
||||
#define IMGUI_H
|
||||
|
||||
enum imguiMouseButton
|
||||
{
|
||||
IMGUI_MBUT_LEFT = 0x01,
|
||||
IMGUI_MBUT_RIGHT = 0x02,
|
||||
};
|
||||
|
||||
enum imguiTextAlign
|
||||
{
|
||||
IMGUI_ALIGN_LEFT,
|
||||
IMGUI_ALIGN_CENTER,
|
||||
IMGUI_ALIGN_RIGHT,
|
||||
};
|
||||
|
||||
inline unsigned int imguiRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a=255)
|
||||
{
|
||||
return (r) | (g << 8) | (b << 16) | (a << 24);
|
||||
}
|
||||
|
||||
bool imguiAnyActive();
|
||||
|
||||
void imguiBeginFrame(int mx, int my, unsigned char mbut, int scroll);
|
||||
void imguiEndFrame();
|
||||
|
||||
bool imguiBeginScrollArea(const char* name, int x, int y, int w, int h, int* scroll);
|
||||
void imguiEndScrollArea();
|
||||
|
||||
bool imguiButton(const char* text, bool enabled = true);
|
||||
bool imguiItem(const char* text, bool enabled = true);
|
||||
bool imguiCheck(const char* text, bool checked, bool enabled = true);
|
||||
bool imguiCollapse(const char* text, const char* subtext, bool checked, bool enabled = true);
|
||||
void imguiLabel(const char* text);
|
||||
void imguiValue(const char* text);
|
||||
bool imguiSlider(const char* text, float* val, float vmin, float vmax, float vinc, bool enabled = true);
|
||||
|
||||
void imguiIndent();
|
||||
void imguiUnindent();
|
||||
void imguiSeparator();
|
||||
void imguiSeparatorLine();
|
||||
|
||||
void imguiDrawText(int x, int y, int align, const char* text, unsigned int color);
|
||||
void imguiDrawLine(float x0, float y0, float x1, float y1, float r, unsigned int color);
|
||||
void imguiDrawRoundedRect(float x, float y, float w, float h, float r, unsigned int color);
|
||||
void imguiDrawRect(float x, float y, float w, float h, unsigned int color);
|
||||
|
||||
// Pull render interface.
|
||||
enum imguiGfxCmdType
|
||||
{
|
||||
IMGUI_GFXCMD_RECT,
|
||||
IMGUI_GFXCMD_TRIANGLE,
|
||||
IMGUI_GFXCMD_LINE,
|
||||
IMGUI_GFXCMD_TEXT,
|
||||
IMGUI_GFXCMD_SCISSOR,
|
||||
};
|
||||
|
||||
struct imguiGfxRect
|
||||
{
|
||||
short x,y,w,h,r;
|
||||
};
|
||||
|
||||
struct imguiGfxText
|
||||
{
|
||||
short x,y,align;
|
||||
const char* text;
|
||||
};
|
||||
|
||||
struct imguiGfxLine
|
||||
{
|
||||
short x0,y0,x1,y1,r;
|
||||
};
|
||||
|
||||
struct imguiGfxCmd
|
||||
{
|
||||
char type;
|
||||
char flags;
|
||||
char pad[2];
|
||||
unsigned int col;
|
||||
union
|
||||
{
|
||||
imguiGfxLine line;
|
||||
imguiGfxRect rect;
|
||||
imguiGfxText text;
|
||||
};
|
||||
};
|
||||
|
||||
const imguiGfxCmd* imguiGetRenderQueue();
|
||||
int imguiGetRenderQueueSize();
|
||||
|
||||
|
||||
#endif // IMGUI_H
|
||||
376
gltools/@contrib/imguiRenderGL.cpp
Normal file
376
gltools/@contrib/imguiRenderGL.cpp
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "imgui.h"
|
||||
#include "fontstash.h"
|
||||
#include "GLTools.h"
|
||||
|
||||
// Some math headers don't have PI defined.
|
||||
static const float PI = 3.14159265f;
|
||||
|
||||
static const unsigned TEMP_COORD_COUNT = 100;
|
||||
static float g_tempCoords[TEMP_COORD_COUNT*2];
|
||||
static float g_tempNormals[TEMP_COORD_COUNT*2];
|
||||
|
||||
static const int CIRCLE_VERTS = 8*4;
|
||||
static float g_circleVerts[CIRCLE_VERTS*2];
|
||||
|
||||
inline unsigned int RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
|
||||
{
|
||||
return (r) | (g << 8) | (b << 16) | (a << 24);
|
||||
}
|
||||
|
||||
static void drawPolygon(const float* coords, unsigned numCoords, float r, unsigned int col)
|
||||
{
|
||||
if (numCoords > TEMP_COORD_COUNT) numCoords = TEMP_COORD_COUNT;
|
||||
|
||||
for (unsigned i = 0, j = numCoords-1; i < numCoords; j=i++)
|
||||
{
|
||||
const float* v0 = &coords[j*2];
|
||||
const float* v1 = &coords[i*2];
|
||||
float dx = v1[0] - v0[0];
|
||||
float dy = v1[1] - v0[1];
|
||||
float d = sqrtf(dx*dx+dy*dy);
|
||||
if (d > 0)
|
||||
{
|
||||
d = 1.0f/d;
|
||||
dx *= d;
|
||||
dy *= d;
|
||||
}
|
||||
g_tempNormals[j*2+0] = dy;
|
||||
g_tempNormals[j*2+1] = -dx;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, j = numCoords-1; i < numCoords; j=i++)
|
||||
{
|
||||
float dlx0 = g_tempNormals[j*2+0];
|
||||
float dly0 = g_tempNormals[j*2+1];
|
||||
float dlx1 = g_tempNormals[i*2+0];
|
||||
float dly1 = g_tempNormals[i*2+1];
|
||||
float dmx = (dlx0 + dlx1) * 0.5f;
|
||||
float dmy = (dly0 + dly1) * 0.5f;
|
||||
float dmr2 = dmx*dmx + dmy*dmy;
|
||||
if (dmr2 > 0.000001f)
|
||||
{
|
||||
float scale = 1.0f / dmr2;
|
||||
if (scale > 10.0f) scale = 10.0f;
|
||||
dmx *= scale;
|
||||
dmy *= scale;
|
||||
}
|
||||
g_tempCoords[i*2+0] = coords[i*2+0]+dmx*r;
|
||||
g_tempCoords[i*2+1] = coords[i*2+1]+dmy*r;
|
||||
}
|
||||
|
||||
unsigned int colTrans = RGBA(col&0xff, (col>>8)&0xff, (col>>16)&0xff, 0);
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
|
||||
glColor4ubv((GLubyte*)&col);
|
||||
|
||||
for (unsigned i = 0, j = numCoords-1; i < numCoords; j=i++)
|
||||
{
|
||||
glVertex2fv(&coords[i*2]);
|
||||
glVertex2fv(&coords[j*2]);
|
||||
glColor4ubv((GLubyte*)&colTrans);
|
||||
glVertex2fv(&g_tempCoords[j*2]);
|
||||
|
||||
glVertex2fv(&g_tempCoords[j*2]);
|
||||
glVertex2fv(&g_tempCoords[i*2]);
|
||||
|
||||
glColor4ubv((GLubyte*)&col);
|
||||
glVertex2fv(&coords[i*2]);
|
||||
}
|
||||
|
||||
glColor4ubv((GLubyte*)&col);
|
||||
for (unsigned i = 2; i < numCoords; ++i)
|
||||
{
|
||||
glVertex2fv(&coords[0]);
|
||||
glVertex2fv(&coords[(i-1)*2]);
|
||||
glVertex2fv(&coords[i*2]);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
static void drawRect(float x, float y, float w, float h, float fth, unsigned int col)
|
||||
{
|
||||
float verts[4*2] =
|
||||
{
|
||||
x+0.5f, y+0.5f,
|
||||
x+w-0.5f, y+0.5f,
|
||||
x+w-0.5f, y+h-0.5f,
|
||||
x+0.5f, y+h-0.5f,
|
||||
};
|
||||
drawPolygon(verts, 4, fth, col);
|
||||
}
|
||||
|
||||
static void drawRoundedRect(float x, float y, float w, float h, float r, float fth, unsigned int col)
|
||||
{
|
||||
const unsigned n = CIRCLE_VERTS/4;
|
||||
float verts[(n+1)*4*2];
|
||||
const float* cverts = g_circleVerts;
|
||||
float* v = verts;
|
||||
|
||||
for (unsigned i = 0; i <= n; ++i)
|
||||
{
|
||||
*v++ = x+w-r + cverts[i*2]*r;
|
||||
*v++ = y+h-r + cverts[i*2+1]*r;
|
||||
}
|
||||
|
||||
for (unsigned i = n; i <= n*2; ++i)
|
||||
{
|
||||
*v++ = x+r + cverts[i*2]*r;
|
||||
*v++ = y+h-r + cverts[i*2+1]*r;
|
||||
}
|
||||
|
||||
for (unsigned i = n*2; i <= n*3; ++i)
|
||||
{
|
||||
*v++ = x+r + cverts[i*2]*r;
|
||||
*v++ = y+r + cverts[i*2+1]*r;
|
||||
}
|
||||
|
||||
for (unsigned i = n*3; i < n*4; ++i)
|
||||
{
|
||||
*v++ = x+w-r + cverts[i*2]*r;
|
||||
*v++ = y+r + cverts[i*2+1]*r;
|
||||
}
|
||||
*v++ = x+w-r + cverts[0]*r;
|
||||
*v++ = y+r + cverts[1]*r;
|
||||
|
||||
drawPolygon(verts, (n+1)*4, fth, col);
|
||||
}
|
||||
|
||||
|
||||
static void drawLine(float x0, float y0, float x1, float y1, float r, float fth, unsigned int col)
|
||||
{
|
||||
float dx = x1-x0;
|
||||
float dy = y1-y0;
|
||||
float d = sqrtf(dx*dx+dy*dy);
|
||||
if (d > 0.0001f)
|
||||
{
|
||||
d = 1.0f/d;
|
||||
dx *= d;
|
||||
dy *= d;
|
||||
}
|
||||
float nx = dy;
|
||||
float ny = -dx;
|
||||
float verts[4*2];
|
||||
r -= fth;
|
||||
r *= 0.5f;
|
||||
if (r < 0.01f) r = 0.01f;
|
||||
dx *= r;
|
||||
dy *= r;
|
||||
nx *= r;
|
||||
ny *= r;
|
||||
|
||||
verts[0] = x0-dx-nx;
|
||||
verts[1] = y0-dy-ny;
|
||||
|
||||
verts[2] = x0-dx+nx;
|
||||
verts[3] = y0-dy+ny;
|
||||
|
||||
verts[4] = x1+dx+nx;
|
||||
verts[5] = y1+dy+ny;
|
||||
|
||||
verts[6] = x1+dx-nx;
|
||||
verts[7] = y1+dy-ny;
|
||||
|
||||
drawPolygon(verts, 4, fth, col);
|
||||
}
|
||||
|
||||
|
||||
void imguiRenderGLInit(void)
|
||||
{
|
||||
for (int i = 0; i < CIRCLE_VERTS; ++i)
|
||||
{
|
||||
float a = (float)i/(float)CIRCLE_VERTS * PI*2;
|
||||
g_circleVerts[i*2+0] = cosf(a);
|
||||
g_circleVerts[i*2+1] = sinf(a);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void drawText(float x, float y, const char *text, int align, unsigned int col)
|
||||
{
|
||||
float minx, miny, maxx, maxy, dx, hsize;
|
||||
if (!_fonts) return;
|
||||
|
||||
if (align != IMGUI_ALIGN_LEFT) {
|
||||
// adjust for alignment
|
||||
sth_dim_text(_fonts, 0, 15.0f, text, &minx, &miny, &maxx, &maxy);
|
||||
hsize = maxx - minx;
|
||||
if (align == IMGUI_ALIGN_CENTER)
|
||||
x -= hsize/2;
|
||||
else if (align == IMGUI_ALIGN_RIGHT)
|
||||
x -= hsize;
|
||||
}
|
||||
|
||||
glColor4ub(col&0xff, (col>>8)&0xff, (col>>16)&0xff, (col>>24)&0xff);
|
||||
sth_begin_draw(_fonts);
|
||||
sth_draw_text(_fonts, 0, 15.0f, x, y, text, &dx);
|
||||
sth_end_draw(_fonts);
|
||||
}
|
||||
|
||||
/*
|
||||
static void drawText(float x, float y, const char *text, int align, unsigned int col)
|
||||
{
|
||||
if (!g_ftex) return;
|
||||
if (!text) return;
|
||||
|
||||
if (align == IMGUI_ALIGN_CENTER)
|
||||
x -= getTextLength(g_cdata, text)/2;
|
||||
else if (align == IMGUI_ALIGN_RIGHT)
|
||||
x -= getTextLength(g_cdata, text);
|
||||
|
||||
glColor4ub(col&0xff, (col>>8)&0xff, (col>>16)&0xff, (col>>24)&0xff);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
// assume orthographic projection with units = screen pixels, origin at top left
|
||||
glBindTexture(GL_TEXTURE_2D, g_ftex);
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
|
||||
const float ox = x;
|
||||
|
||||
while (*text)
|
||||
{
|
||||
int c = (unsigned char)*text;
|
||||
if (c == '\t')
|
||||
{
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
if (x < g_tabStops[i]+ox)
|
||||
{
|
||||
x = g_tabStops[i]+ox;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c >= 32 && c < 128)
|
||||
{
|
||||
stbtt_aligned_quad q;
|
||||
getBakedQuad(g_cdata, 512,512, c-32, &x,&y,&q);
|
||||
|
||||
glTexCoord2f(q.s0, q.t0);
|
||||
glVertex2f(q.x0, q.y0);
|
||||
glTexCoord2f(q.s1, q.t1);
|
||||
glVertex2f(q.x1, q.y1);
|
||||
glTexCoord2f(q.s1, q.t0);
|
||||
glVertex2f(q.x1, q.y0);
|
||||
|
||||
glTexCoord2f(q.s0, q.t0);
|
||||
glVertex2f(q.x0, q.y0);
|
||||
glTexCoord2f(q.s0, q.t1);
|
||||
glVertex2f(q.x0, q.y1);
|
||||
glTexCoord2f(q.s1, q.t1);
|
||||
glVertex2f(q.x1, q.y1);
|
||||
}
|
||||
++text;
|
||||
}
|
||||
|
||||
glEnd();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
*/
|
||||
|
||||
void imguiRenderGLDraw()
|
||||
{
|
||||
const imguiGfxCmd* q = imguiGetRenderQueue();
|
||||
int nq = imguiGetRenderQueueSize();
|
||||
|
||||
const float s = 1.0f/8.0f;
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
for (int i = 0; i < nq; ++i)
|
||||
{
|
||||
const imguiGfxCmd& cmd = q[i];
|
||||
if (cmd.type == IMGUI_GFXCMD_RECT)
|
||||
{
|
||||
if (cmd.rect.r == 0)
|
||||
{
|
||||
drawRect((float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f,
|
||||
(float)cmd.rect.w*s-1, (float)cmd.rect.h*s-1,
|
||||
1.0f, cmd.col);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawRoundedRect((float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f,
|
||||
(float)cmd.rect.w*s-1, (float)cmd.rect.h*s-1,
|
||||
(float)cmd.rect.r*s, 1.0f, cmd.col);
|
||||
}
|
||||
}
|
||||
else if (cmd.type == IMGUI_GFXCMD_LINE)
|
||||
{
|
||||
drawLine(cmd.line.x0*s, cmd.line.y0*s, cmd.line.x1*s, cmd.line.y1*s, cmd.line.r*s, 1.0f, cmd.col);
|
||||
}
|
||||
else if (cmd.type == IMGUI_GFXCMD_TRIANGLE)
|
||||
{
|
||||
if (cmd.flags == 1)
|
||||
{
|
||||
const float verts[3*2] =
|
||||
{
|
||||
(float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f,
|
||||
(float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s-1, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s/2-0.5f,
|
||||
(float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1,
|
||||
};
|
||||
drawPolygon(verts, 3, 1.0f, cmd.col);
|
||||
}
|
||||
if (cmd.flags == 2)
|
||||
{
|
||||
const float verts[3*2] =
|
||||
{
|
||||
(float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1,
|
||||
(float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s/2-0.5f, (float)cmd.rect.y*s+0.5f,
|
||||
(float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s-1, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1,
|
||||
};
|
||||
drawPolygon(verts, 3, 1.0f, cmd.col);
|
||||
}
|
||||
if (cmd.flags == 3) // @rlyeh new rotation: left
|
||||
{
|
||||
const float verts[3*2] =
|
||||
{
|
||||
(float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s-1, (float)cmd.rect.y*s+0.5f,
|
||||
(float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s-1, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1,
|
||||
(float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s/2-0.5f,
|
||||
};
|
||||
drawPolygon(verts, 3, 1.0f, cmd.col);
|
||||
}
|
||||
}
|
||||
else if (cmd.type == IMGUI_GFXCMD_TEXT)
|
||||
{
|
||||
drawText(cmd.text.x, cmd.text.y, cmd.text.text, cmd.text.align, cmd.col);
|
||||
}
|
||||
else if (cmd.type == IMGUI_GFXCMD_SCISSOR)
|
||||
{
|
||||
if (cmd.flags)
|
||||
{
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(cmd.rect.x, cmd.rect.y, cmd.rect.w, cmd.rect.h);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
}
|
||||
}
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
25
gltools/@contrib/imguiRenderGL.h
Normal file
25
gltools/@contrib/imguiRenderGL.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef IMGUI_RENDER_GL_H
|
||||
#define IMGUI_RENDER_GL_H
|
||||
|
||||
void imguiRenderGLInit();
|
||||
void imguiRenderGLDraw();
|
||||
|
||||
#endif // IMGUI_RENDER_GL_H
|
||||
1806
gltools/@contrib/stb_truetype.h
Normal file
1806
gltools/@contrib/stb_truetype.h
Normal file
File diff suppressed because it is too large
Load diff
61
gltools/@src/ClientBuffer.pxi
Normal file
61
gltools/@src/ClientBuffer.pxi
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This file is part of gltools - See LICENSE.txt
|
||||
#
|
||||
|
||||
cdef class ClientBuffer:
|
||||
'''
|
||||
Abstraction of OpenGL vertex buffer
|
||||
'''
|
||||
def __init__(self, target = GL_ARRAY_BUFFER):
|
||||
if not isGLExtLoaded:
|
||||
raise GLError('OpenGL 2.1 function pointers not found')
|
||||
|
||||
self.thisptr = new c_ClientBuffer(target)
|
||||
|
||||
def __dealloc__(self):
|
||||
cdef c_ClientBuffer *tmp
|
||||
|
||||
if self.thisptr != NULL:
|
||||
tmp = <c_ClientBuffer *>self.thisptr
|
||||
del tmp
|
||||
|
||||
def __str__(self):
|
||||
return "ClientBuffer%s" % repr(self)
|
||||
|
||||
def __repr__(self):
|
||||
return "()"
|
||||
|
||||
cpdef bind(self):
|
||||
cdef c_ClientBuffer *buf = <c_ClientBuffer *>self.thisptr
|
||||
buf.bind()
|
||||
|
||||
cpdef unBind(self):
|
||||
cdef c_ClientBuffer *buf = <c_ClientBuffer *>self.thisptr
|
||||
buf.unBind()
|
||||
|
||||
cpdef setDataType(self, int type, int dataType, int dataTypeSize,
|
||||
int stride, size_t pointer):
|
||||
'''
|
||||
Set datatye for data in buffer. Pointer is an integer with an
|
||||
offset into the buffer with optional stride.
|
||||
'''
|
||||
cdef c_ClientBuffer *buf = <c_ClientBuffer *>self.thisptr
|
||||
|
||||
if not buf.setDataType(type, dataType, dataTypeSize, stride, pointer):
|
||||
raise GLError(errorMessage)
|
||||
|
||||
cdef cloadData(self, void *data, ssize_t size, ssize_t offset, int usage):
|
||||
cdef c_ClientBuffer *buf = <c_ClientBuffer *>self.thisptr
|
||||
if not buf.loadData(data, size, offset, usage):
|
||||
raise GLError(errorMessage)
|
||||
|
||||
cpdef loadData(self, data, ssize_t size, ssize_t offset = 0, int usage = GL_STATIC_DRAW):
|
||||
'''
|
||||
Upload data to client side buffer. Passing None
|
||||
for data will reserve capacity.
|
||||
'''
|
||||
if data is None:
|
||||
self.cloadData(NULL, size, offset, usage)
|
||||
else:
|
||||
self.cloadData(getVoidPtr(data), size, offset, usage)
|
||||
192
gltools/@src/Color.pxi
Normal file
192
gltools/@src/Color.pxi
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This file is part of gltools - See LICENSE.txt
|
||||
#
|
||||
cdef class ColorRGBA:
|
||||
'''RGBA color'''
|
||||
def __init__(self, GLubyte red = 255, GLubyte green = 255, GLubyte blue = 255,
|
||||
GLubyte alpha = 255):
|
||||
self.red = red
|
||||
self.green = green
|
||||
self.blue = blue
|
||||
self.alpha = alpha
|
||||
|
||||
def __str__(self):
|
||||
return "ColorRGBA%s" % repr(self)
|
||||
|
||||
def __repr__(self):
|
||||
args = self.red, self.green, self.blue, self.alpha
|
||||
return "(red=%d, green=%d, blue=%d, alpha=%d)" % args
|
||||
|
||||
def __len__(self):
|
||||
return 4
|
||||
|
||||
def __getitem__(self, int key):
|
||||
if key == 0:
|
||||
return self.red
|
||||
elif key == 1:
|
||||
return self.green
|
||||
elif key == 2:
|
||||
return self.blue
|
||||
elif key == 3:
|
||||
return self.alpha
|
||||
raise IndexError('index out of range')
|
||||
|
||||
def __mul__(double factor, ColorRGBA rhs):
|
||||
'''
|
||||
Leaves alpha unchanged
|
||||
'''
|
||||
cdef ColorRGBA ret = ColorRGBA.__new__(ColorRGBA)
|
||||
|
||||
if factor < 0.:
|
||||
raise GLError('factor < 0.')
|
||||
|
||||
ret.red = <unsigned char>fmin(255, factor*rhs.red)
|
||||
ret.green = <unsigned char>fmin(255, factor*rhs.green)
|
||||
ret.blue = <unsigned char>fmin(255, factor*rhs.blue)
|
||||
ret.alpha = rhs.alpha
|
||||
|
||||
return ret
|
||||
|
||||
cpdef ColorRGBA copy(self, int red = -1, int green = -1, int blue = -1, alpha = -1):
|
||||
cdef ColorRGBA ret = ColorRGBA.__new__(ColorRGBA)
|
||||
|
||||
ret.red = self.red
|
||||
ret.green = self.green
|
||||
ret.blue = self.blue
|
||||
ret.alpha = self.alpha
|
||||
|
||||
if red >= 0 and red < 256:
|
||||
ret.red = red
|
||||
|
||||
if green >= 0 and green < 256:
|
||||
ret.green = green
|
||||
|
||||
if blue >= 0 and blue < 256:
|
||||
ret.blue = blue
|
||||
|
||||
if alpha >= 0 and alpha < 256:
|
||||
ret.alpha = alpha
|
||||
|
||||
return ret
|
||||
|
||||
cpdef unsigned toInt(self):
|
||||
return self.alpha << 24 | self.blue << 16 | self.green << 8 | self.red
|
||||
|
||||
cpdef tuple toFloatVector(self):
|
||||
return (self.red / 255., self.green / 255., self.blue / 255., self.alpha / 255.)
|
||||
|
||||
cdef setFloatVector(self, float *vec):
|
||||
vec[0] = self.red / 255.
|
||||
vec[1] = self.green / 255.
|
||||
vec[2] = self.blue / 255.
|
||||
vec[3] = self.alpha / 255.
|
||||
|
||||
WHITE = ColorRGBA(255,255,255,255)
|
||||
BLACK = ColorRGBA(0,0,0,255)
|
||||
|
||||
cdef class Material:
|
||||
'''
|
||||
Abstrction of OpenGL material
|
||||
'''
|
||||
def __init__(self, int mode = GL_FRONT_AND_BACK, **kwargs):
|
||||
self.mode = mode
|
||||
self.shininess = -1.
|
||||
|
||||
for name, value in kwargs.iteritems():
|
||||
if name in {'ambient','diffuse','specular','emissive','shininess'}:
|
||||
setattr(self, name, value)
|
||||
else:
|
||||
raise GLError("attribute '%s' not known")
|
||||
|
||||
def __str__(self):
|
||||
return "Material%s" % repr(self)
|
||||
|
||||
def __repr__(self):
|
||||
return "()"
|
||||
|
||||
cpdef enable(self):
|
||||
cdef float mat[4]
|
||||
cdef int i
|
||||
if not self.ambient is None:
|
||||
self.ambient.setFloatVector(mat)
|
||||
glMaterialfv(self.mode, GL_AMBIENT, mat)
|
||||
|
||||
if not self.diffuse is None:
|
||||
self.diffuse.setFloatVector(mat)
|
||||
glMaterialfv(self.mode, GL_DIFFUSE, mat)
|
||||
|
||||
if not self.specular is None:
|
||||
self.specular.setFloatVector(mat)
|
||||
glMaterialfv(self.mode, GL_SPECULAR, mat)
|
||||
|
||||
if not self.emissive is None:
|
||||
self.emissive.setFloatVector(mat)
|
||||
glMaterialfv(self.mode, GL_EMISSION, mat)
|
||||
|
||||
if self.shininess > 0:
|
||||
mat[0] = fmin(fmax(0., self.shininess), 128)
|
||||
glMaterialfv(self.mode, GL_SHININESS, mat)
|
||||
|
||||
cdef class Light:
|
||||
'''
|
||||
Abstraction of OpenGL light
|
||||
'''
|
||||
def __init__(self, int index = 0, Material material = None,
|
||||
Point position = None, directional = True):
|
||||
if index == 0:
|
||||
self.index = GL_LIGHT0
|
||||
elif index == 1:
|
||||
self.index = GL_LIGHT1
|
||||
elif index == 2:
|
||||
self.index = GL_LIGHT2
|
||||
elif index == 3:
|
||||
self.index = GL_LIGHT3
|
||||
elif index == 4:
|
||||
self.index = GL_LIGHT4
|
||||
elif index == 5:
|
||||
self.index = GL_LIGHT5
|
||||
elif index == 6:
|
||||
self.index = GL_LIGHT6
|
||||
elif index == 7:
|
||||
self.index = GL_LIGHT7
|
||||
else:
|
||||
raise GLError('Light index out of range (0-7)')
|
||||
|
||||
self.material = material
|
||||
self.position = position
|
||||
self.directional = directional
|
||||
|
||||
def __str__(self):
|
||||
return "Light%s" % repr(self)
|
||||
|
||||
def __repr__(self):
|
||||
return "()"
|
||||
|
||||
cpdef enable(self):
|
||||
cdef float mat[4]
|
||||
|
||||
glEnable(self.index)
|
||||
|
||||
if not self.material.ambient is None:
|
||||
self.material.ambient.setFloatVector(mat)
|
||||
glLightfv(self.index, GL_AMBIENT, mat)
|
||||
|
||||
if not self.material.diffuse is None:
|
||||
self.material.diffuse.setFloatVector(mat)
|
||||
glLightfv(self.index, GL_DIFFUSE, mat)
|
||||
|
||||
if not self.material.specular is None:
|
||||
self.material.specular.setFloatVector(mat)
|
||||
glLightfv(self.index, GL_SPECULAR, mat)
|
||||
|
||||
if not self.position is None:
|
||||
mat[0], mat[1], mat[2] = self.position
|
||||
if self.directional:
|
||||
mat[3] = 0.
|
||||
else:
|
||||
mat[3] = 1.
|
||||
glLightfv(self.index, GL_POSITION, mat)
|
||||
|
||||
cpdef disable(self):
|
||||
glDisable(self.index)
|
||||
186
gltools/@src/Constants.pxi
Normal file
186
gltools/@src/Constants.pxi
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
class ACTION:
|
||||
RELEASE = GLFW_RELEASE
|
||||
PRESS = GLFW_PRESS
|
||||
|
||||
class KEY:
|
||||
ESCAPE = GLFW_KEY_ESCAPE
|
||||
ENTER = GLFW_KEY_ENTER
|
||||
TAB = GLFW_KEY_TAB
|
||||
BACKSPACE = GLFW_KEY_BACKSPACE
|
||||
INSERT = GLFW_KEY_INSERT
|
||||
DELETE = GLFW_KEY_DELETE
|
||||
RIGHT = GLFW_KEY_RIGHT
|
||||
LEFT = GLFW_KEY_LEFT
|
||||
DOWN = GLFW_KEY_DOWN
|
||||
UP = GLFW_KEY_UP
|
||||
PAGE_UP = GLFW_KEY_PAGE_UP
|
||||
PAGE_DOWN = GLFW_KEY_PAGE_DOWN
|
||||
HOME = GLFW_KEY_HOME
|
||||
END = GLFW_KEY_END
|
||||
CAPS_LOCK = GLFW_KEY_CAPS_LOCK
|
||||
SCROLL_LOCK = GLFW_KEY_SCROLL_LOCK
|
||||
NUM_LOCK = GLFW_KEY_NUM_LOCK
|
||||
PRINT_SCREEN = GLFW_KEY_PRINT_SCREEN
|
||||
PAUSE = GLFW_KEY_PAUSE
|
||||
F1 = GLFW_KEY_F1
|
||||
F2 = GLFW_KEY_F2
|
||||
F3 = GLFW_KEY_F3
|
||||
F4 = GLFW_KEY_F4
|
||||
F5 = GLFW_KEY_F5
|
||||
F6 = GLFW_KEY_F6
|
||||
F7 = GLFW_KEY_F7
|
||||
F8 = GLFW_KEY_F8
|
||||
F9 = GLFW_KEY_F9
|
||||
F10 = GLFW_KEY_F10
|
||||
F11 = GLFW_KEY_F11
|
||||
F12 = GLFW_KEY_F12
|
||||
|
||||
class MOUSE:
|
||||
LEFT = GLFW_MOUSE_BUTTON_LEFT
|
||||
RIGHT = GLFW_MOUSE_BUTTON_RIGHT
|
||||
MIDDLE = GLFW_MOUSE_BUTTON_MIDDLE
|
||||
|
||||
|
||||
# AlphaFunction
|
||||
NEVER = GL_NEVER
|
||||
LESS = GL_LESS
|
||||
EQUAL = GL_EQUAL
|
||||
LEQUAL = GL_LEQUAL
|
||||
GREATER = GL_GREATER
|
||||
NOTEQUAL = GL_NOTEQUAL
|
||||
GEQUAL = GL_GEQUAL
|
||||
ALWAYS = GL_ALWAYS
|
||||
|
||||
# AttribMask
|
||||
CURRENT_BIT = GL_CURRENT_BIT
|
||||
POINT_BIT = GL_POINT_BIT
|
||||
LINE_BIT = GL_LINE_BIT
|
||||
POLYGON_BIT = GL_POLYGON_BIT
|
||||
POLYGON_STIPPLE_BIT = GL_POLYGON_STIPPLE_BIT
|
||||
PIXEL_MODE_BIT = GL_PIXEL_MODE_BIT
|
||||
LIGHTING_BIT = GL_LIGHTING_BIT
|
||||
FOG_BIT = GL_FOG_BIT
|
||||
DEPTH_BUFFER_BIT = GL_DEPTH_BUFFER_BIT
|
||||
ACCUM_BUFFER_BIT = GL_ACCUM_BUFFER_BIT
|
||||
STENCIL_BUFFER_BIT = GL_STENCIL_BUFFER_BIT
|
||||
VIEWPORT_BIT = GL_VIEWPORT_BIT
|
||||
TRANSFORM_BIT = GL_TRANSFORM_BIT
|
||||
ENABLE_BIT = GL_ENABLE_BIT
|
||||
COLOR_BUFFER_BIT = GL_COLOR_BUFFER_BIT
|
||||
HINT_BIT = GL_HINT_BIT
|
||||
EVAL_BIT = GL_EVAL_BIT
|
||||
LIST_BIT = GL_LIST_BIT
|
||||
TEXTURE_BIT = GL_TEXTURE_BIT
|
||||
SCISSOR_BIT = GL_SCISSOR_BIT
|
||||
ALL_ATTRIB_BITS = GL_ALL_ATTRIB_BITS
|
||||
|
||||
# BeginMode
|
||||
POINTS = GL_POINTS
|
||||
LINES = GL_LINES
|
||||
LINE_LOOP = GL_LINE_LOOP
|
||||
LINE_STRIP = GL_LINE_STRIP
|
||||
TRIANGLES = GL_TRIANGLES
|
||||
TRIANGLE_STRIP = GL_TRIANGLE_STRIP
|
||||
TRIANGLE_FAN = GL_TRIANGLE_FAN
|
||||
QUADS = GL_QUADS
|
||||
QUAD_STRIP = GL_QUAD_STRIP
|
||||
POLYGON = GL_POLYGON
|
||||
|
||||
# Vertex Arrays
|
||||
VERTEX_ARRAY = GL_VERTEX_ARRAY
|
||||
NORMAL_ARRAY = GL_NORMAL_ARRAY
|
||||
COLOR_ARRAY = GL_COLOR_ARRAY
|
||||
INDEX_ARRAY = GL_INDEX_ARRAY
|
||||
TEXTURE_COORD_ARRAY = GL_TEXTURE_COORD_ARRAY
|
||||
EDGE_FLAG_ARRAY = GL_EDGE_FLAG_ARRAY
|
||||
|
||||
# BlendingFactorDest
|
||||
ZERO = GL_ZERO
|
||||
ONE = GL_ONE
|
||||
SRC_COLOR = GL_SRC_COLOR
|
||||
ONE_MINUS_SRC_COLOR = GL_ONE_MINUS_SRC_COLOR
|
||||
SRC_ALPHA = GL_SRC_ALPHA
|
||||
ONE_MINUS_SRC_ALPHA = GL_ONE_MINUS_SRC_ALPHA
|
||||
DST_ALPHA = GL_DST_ALPHA
|
||||
ONE_MINUS_DST_ALPHA = GL_ONE_MINUS_DST_ALPHA
|
||||
|
||||
# BlendingFactorSrc
|
||||
DST_COLOR = GL_DST_COLOR
|
||||
ONE_MINUS_DST_COLOR = GL_ONE_MINUS_DST_COLOR
|
||||
SRC_ALPHA_SATURATE = GL_SRC_ALPHA_SATURATE
|
||||
|
||||
# Boolean values
|
||||
FALSE = GL_FALSE
|
||||
TRUE = GL_TRUE
|
||||
|
||||
BYTE = GL_BYTE
|
||||
UNSIGNED_BYTE = GL_UNSIGNED_BYTE
|
||||
SHORT = GL_SHORT
|
||||
UNSIGNED_SHORT = GL_UNSIGNED_SHORT
|
||||
INT = GL_INT
|
||||
UNSIGNED_INT = GL_UNSIGNED_INT
|
||||
FLOAT = GL_FLOAT
|
||||
DOUBLE = GL_DOUBLE
|
||||
|
||||
# DrawBufferMode
|
||||
NONE = GL_NONE
|
||||
FRONT_LEFT = GL_FRONT_LEFT
|
||||
FRONT_RIGHT = GL_FRONT_RIGHT
|
||||
BACK_LEFT = GL_BACK_LEFT
|
||||
BACK_RIGHT = GL_BACK_RIGHT
|
||||
FRONT = GL_FRONT
|
||||
BACK = GL_BACK
|
||||
LEFT = GL_LEFT
|
||||
RIGHT = GL_RIGHT
|
||||
FRONT_AND_BACK = GL_FRONT_AND_BACK
|
||||
AUX0 = GL_AUX0
|
||||
AUX1 = GL_AUX1
|
||||
AUX2 = GL_AUX2
|
||||
AUX3 = GL_AUX3
|
||||
CW = GL_CW
|
||||
CCW = GL_CCW
|
||||
|
||||
# GetTarget
|
||||
DEPTH_TEST = GL_DEPTH_TEST
|
||||
BLEND = GL_BLEND
|
||||
DITHER = GL_DITHER
|
||||
CULL_FACE = GL_CULL_FACE
|
||||
|
||||
# MatrixMode
|
||||
MODELVIEW = GL_MODELVIEW
|
||||
PROJECTION = GL_PROJECTION
|
||||
TEXTURE = GL_TEXTURE
|
||||
|
||||
# Lines
|
||||
LINE_SMOOTH = GL_LINE_SMOOTH
|
||||
|
||||
# PolygonMode
|
||||
POINT = GL_POINT
|
||||
LINE = GL_LINE
|
||||
FILL = GL_FILL
|
||||
|
||||
# ShadingModel
|
||||
FLAT = GL_FLAT
|
||||
SMOOTH = GL_SMOOTH
|
||||
|
||||
# Lighting
|
||||
LIGHTING = GL_LIGHTING
|
||||
LIGHT0 = GL_LIGHT0
|
||||
LIGHT1 = GL_LIGHT1
|
||||
LIGHT2 = GL_LIGHT2
|
||||
LIGHT3 = GL_LIGHT3
|
||||
LIGHT4 = GL_LIGHT4
|
||||
LIGHT5 = GL_LIGHT5
|
||||
LIGHT6 = GL_LIGHT6
|
||||
LIGHT7 = GL_LIGHT7
|
||||
LIGHT_MODEL_TWO_SIDE = GL_LIGHT_MODEL_TWO_SIDE
|
||||
|
||||
# Texture
|
||||
TEXTURE_2D = GL_TEXTURE_2D
|
||||
|
||||
# glext.h
|
||||
MULTISAMPLE = GL_MULTISAMPLE
|
||||
STATIC_DRAW = GL_STATIC_DRAW
|
||||
ARRAY_BUFFER = GL_ARRAY_BUFFER
|
||||
ELEMENT_ARRAY_BUFFER = GL_ELEMENT_ARRAY_BUFFER
|
||||
95
gltools/@src/GL.pxi
Normal file
95
gltools/@src/GL.pxi
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This file is part of gltools - See LICENSE.txt
|
||||
#
|
||||
|
||||
from glLib cimport *
|
||||
|
||||
# init OpenGL function pointers
|
||||
cpdef InitGLExt():
|
||||
if not c_initGLExt():
|
||||
raise GLError(errorMessage)
|
||||
|
||||
cpdef BlendFunc(unsigned int sfactor, unsigned int dfactor):
|
||||
glBlendFunc(sfactor, dfactor)
|
||||
|
||||
cpdef Clear(unsigned int mask):
|
||||
glClear(mask)
|
||||
|
||||
cpdef ClearColor(ColorRGBA col):
|
||||
glClearColor(col.red / 255., col.green / 255., col.blue / 255., col.alpha / 255.)
|
||||
|
||||
cpdef ClearDepth(double depth):
|
||||
glClearDepth(depth)
|
||||
|
||||
cpdef Color(ColorRGBA col):
|
||||
glColor4ub(col.red, col.green, col.blue, col.alpha )
|
||||
|
||||
cpdef Disable(unsigned int cap):
|
||||
glDisable(cap)
|
||||
|
||||
cpdef DrawArrays(unsigned int mode, int first, int count):
|
||||
glDrawArrays(mode, first, count)
|
||||
|
||||
cpdef DrawElements(unsigned int mode, int count, int type, indices):
|
||||
cdef size_t offset
|
||||
if isinstance(indices, int):
|
||||
offset = indices
|
||||
glDrawElements(mode, count, type, <void *>offset)
|
||||
else:
|
||||
glDrawElements(mode, count, type, getVoidPtr(indices))
|
||||
|
||||
cpdef Enable(unsigned int cap):
|
||||
glEnable(cap)
|
||||
|
||||
cpdef LineWidth(float width):
|
||||
glLineWidth(width)
|
||||
|
||||
cpdef LightModeli(int pname, int param):
|
||||
glLightModeli(pname, param)
|
||||
|
||||
cpdef LoadIdentity():
|
||||
glLoadIdentity()
|
||||
|
||||
cpdef LoadMatrixd(Transform tr):
|
||||
cdef double cm[16]
|
||||
|
||||
# col 1
|
||||
cm[0] = tr.m[0][0]
|
||||
cm[1] = tr.m[1][0]
|
||||
cm[2] = tr.m[2][0]
|
||||
cm[3] = tr.m[3][0]
|
||||
|
||||
# col 2
|
||||
cm[4] = tr.m[0][1]
|
||||
cm[5] = tr.m[1][1]
|
||||
cm[6] = tr.m[2][1]
|
||||
cm[7] = tr.m[3][1]
|
||||
|
||||
# col 3
|
||||
cm[8] = tr.m[0][2]
|
||||
cm[9] = tr.m[1][2]
|
||||
cm[10] = tr.m[2][2]
|
||||
cm[11] = tr.m[3][2]
|
||||
|
||||
# col 4
|
||||
cm[12] = tr.m[0][3]
|
||||
cm[13] = tr.m[1][3]
|
||||
cm[14] = tr.m[2][3]
|
||||
cm[15] = tr.m[3][3]
|
||||
|
||||
glLoadMatrixd(cm)
|
||||
|
||||
cpdef MatrixMode(unsigned int mode):
|
||||
glMatrixMode(mode)
|
||||
|
||||
cpdef Ortho(double left, double right, double bottom, double top, double zNear,
|
||||
double zFar):
|
||||
glOrtho(left, right, bottom, top, zNear, zFar)
|
||||
|
||||
cpdef PolygonMode(unsigned int face, unsigned int mode):
|
||||
glPolygonMode(face, mode)
|
||||
|
||||
cpdef Viewport(int x, int y, int width, int height):
|
||||
glViewport(x, y, width, height)
|
||||
|
||||
266
gltools/@src/GLFW.pxi
Normal file
266
gltools/@src/GLFW.pxi
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from glfwLib cimport *
|
||||
|
||||
cpdef Init():
|
||||
if not glfwInit():
|
||||
raise GLError('failed to initialize glfw')
|
||||
|
||||
# timer functions
|
||||
cpdef double getTime():
|
||||
Init()
|
||||
return glfwGetTime()
|
||||
|
||||
cpdef SetTime(double time):
|
||||
Init()
|
||||
glfwSetTime(time)
|
||||
|
||||
# gamma value
|
||||
cpdef SetGamma(float gamma):
|
||||
Init()
|
||||
glfwSetGamma(gamma)
|
||||
|
||||
# get desktop size
|
||||
cpdef tuple GetDesktopSize():
|
||||
cdef GLFWvidmode vidmode
|
||||
|
||||
Init()
|
||||
glfwGetDesktopMode(&vidmode)
|
||||
return vidmode.width, vidmode.height
|
||||
|
||||
|
||||
cdef class Window:
|
||||
def __init__(self, int width = -1, int height = -1, title = None,
|
||||
bint fullscreen = False):
|
||||
cdef GLFWvidmode vidmode
|
||||
cdef int mode = GLFW_WINDOWED
|
||||
cdef char *c_title
|
||||
|
||||
# Initialise GLFW
|
||||
if not glfwInit():
|
||||
raise GLError('failed to initialize glfw')
|
||||
|
||||
# set window hints
|
||||
glfwWindowHint(GLFW_RED_BITS, 8)
|
||||
glfwWindowHint(GLFW_GREEN_BITS, 8)
|
||||
glfwWindowHint(GLFW_BLUE_BITS, 8)
|
||||
glfwWindowHint(GLFW_ALPHA_BITS, 8)
|
||||
glfwWindowHint(GLFW_DEPTH_BITS, 24)
|
||||
glfwWindowHint(GLFW_STENCIL_BITS, 8)
|
||||
|
||||
glfwWindowHint(GLFW_OPENGL_VERSION_MAJOR, 2)
|
||||
glfwWindowHint(GLFW_OPENGL_VERSION_MINOR, 1)
|
||||
|
||||
# open window
|
||||
if width < 0 or height < 0:
|
||||
# default to desktop size
|
||||
glfwGetDesktopMode(&vidmode)
|
||||
width, height = vidmode.width, vidmode.height
|
||||
glfwWindowHint(GLFW_RED_BITS, vidmode.redBits)
|
||||
glfwWindowHint(GLFW_GREEN_BITS, vidmode.greenBits)
|
||||
glfwWindowHint(GLFW_BLUE_BITS, vidmode.blueBits)
|
||||
|
||||
if fullscreen:
|
||||
mode = GLFW_FULLSCREEN
|
||||
|
||||
# decode to UTF-8
|
||||
if title is None:
|
||||
title = ''
|
||||
bytetext = unicode(title).encode('UTF-8','ignore')
|
||||
c_title = bytetext
|
||||
|
||||
self.thisptr = glfwCreateWindow(width, height, mode, c_title, NULL)
|
||||
if self.thisptr == NULL:
|
||||
raise GLError('failed to open window')
|
||||
|
||||
# Set pointer back to this class for callbacks
|
||||
glfwSetWindowUserPointer(<GLFWwindow>self.thisptr, <void *>self)
|
||||
|
||||
# Set callback functions
|
||||
glfwSetWindowSizeCallback(cb_onSize)
|
||||
glfwSetWindowRefreshCallback(cb_onRefresh)
|
||||
glfwSetMouseButtonCallback(cb_onMouseButton)
|
||||
glfwSetKeyCallback(cb_onKey)
|
||||
glfwSetCharCallback(cb_onChar)
|
||||
glfwSetWindowCloseCallback(cb_onClose)
|
||||
glfwSetWindowFocusCallback(cb_onFocus)
|
||||
glfwSetCursorEnterCallback(cb_onEnter)
|
||||
glfwSetScrollCallback(cb_onScroll)
|
||||
glfwSetWindowIconifyCallback(cb_onIconify)
|
||||
|
||||
# Get window size (may be different than the requested size)
|
||||
glfwGetWindowSize(<GLFWwindow>self.thisptr, &width, &height);
|
||||
self.onSize(width, max(1, height))
|
||||
|
||||
def __dealloc__(self):
|
||||
glfwTerminate()
|
||||
|
||||
cpdef setTitle(self, title):
|
||||
cdef char *c_title
|
||||
|
||||
# decode to UTF-8
|
||||
bytetext = unicode(title).encode('UTF-8','ignore')
|
||||
c_title = bytetext
|
||||
|
||||
glfwSetWindowTitle(<GLFWwindow>self.thisptr, c_title)
|
||||
|
||||
cpdef tuple getSize(self):
|
||||
cdef int width, height
|
||||
glfwGetWindowSize(<GLFWwindow>self.thisptr, &width, &height)
|
||||
return width, height
|
||||
|
||||
cpdef setSize(self, int width, int height):
|
||||
if width <= 0 or height <= 0:
|
||||
raise GLError('window size not valid')
|
||||
glfwSetWindowSize(<GLFWwindow>self.thisptr, width, height)
|
||||
|
||||
cpdef tuple getPos(self):
|
||||
cdef int x, y
|
||||
glfwGetWindowPos(<GLFWwindow>self.thisptr, &x, &y)
|
||||
return x, y
|
||||
|
||||
cpdef setPos(self, int x, int y):
|
||||
glfwSetWindowPos(<GLFWwindow>self.thisptr, x, y)
|
||||
|
||||
cpdef setClipboard(self, content):
|
||||
glfwSetClipboardString(<GLFWwindow>self.thisptr, content)
|
||||
|
||||
cpdef getClipboard(self):
|
||||
cdef char *content = glfwGetClipboardString(<GLFWwindow>self.thisptr)
|
||||
return content
|
||||
|
||||
cpdef iconify(self):
|
||||
glfwIconifyWindow(<GLFWwindow>self.thisptr)
|
||||
|
||||
cpdef restore(self):
|
||||
glfwRestoreWindow(<GLFWwindow>self.thisptr)
|
||||
|
||||
cpdef show(self):
|
||||
glfwShowWindow(<GLFWwindow>self.thisptr)
|
||||
|
||||
cpdef hide(self):
|
||||
glfwHideWindow(<GLFWwindow>self.thisptr)
|
||||
|
||||
cpdef close(self):
|
||||
self.running = False
|
||||
glfwDestroyWindow(<GLFWwindow>self.thisptr)
|
||||
glfwTerminate()
|
||||
|
||||
cpdef makeContextCurrent(self):
|
||||
glfwMakeContextCurrent(<GLFWwindow>self.thisptr)
|
||||
|
||||
cpdef swapBuffers(self):
|
||||
glfwSwapBuffers(<GLFWwindow>self.thisptr)
|
||||
|
||||
cpdef mainLoop(self):
|
||||
# keep waiting for events until running is False
|
||||
cdef int x, y, lastX, lastY
|
||||
cdef double t
|
||||
|
||||
glfwGetCursorPos(<GLFWwindow>self.thisptr, &lastX, &lastY)
|
||||
self.running = True
|
||||
while True:
|
||||
# Wait for new events
|
||||
glfwWaitEvents()
|
||||
|
||||
# Avoid to quick update due to mouse move
|
||||
glfwGetCursorPos(<GLFWwindow>self.thisptr, &x, &y)
|
||||
if x != lastX or y != lastY:
|
||||
# in mouse move
|
||||
t = glfwGetTime()
|
||||
while True and self.running:
|
||||
glfwWaitEvents()
|
||||
if glfwGetTime() - t > .025:
|
||||
break
|
||||
|
||||
glfwGetCursorPos(<GLFWwindow>self.thisptr, &x, &y)
|
||||
self.onCursorPos(x, y)
|
||||
|
||||
lastX, lastY = x, y
|
||||
|
||||
if not self.running:
|
||||
break
|
||||
|
||||
cpdef onSize(self, int w, int h):
|
||||
pass
|
||||
|
||||
cpdef onRefresh(self):
|
||||
pass
|
||||
|
||||
cpdef onCursorPos(self, int x, int y):
|
||||
pass
|
||||
|
||||
cpdef onMouseButton(self, int button, int action):
|
||||
pass
|
||||
|
||||
cpdef onKey(self, int key, int action):
|
||||
pass
|
||||
|
||||
cpdef onChar(self, ch):
|
||||
pass
|
||||
|
||||
cpdef onFocus(self, int status):
|
||||
pass
|
||||
|
||||
cpdef onEnter(self, int status):
|
||||
pass
|
||||
|
||||
cpdef onScroll(self, double dx, double dy):
|
||||
pass
|
||||
|
||||
cpdef onIconify(self, int status):
|
||||
pass
|
||||
|
||||
cpdef bint onClose(self):
|
||||
return False
|
||||
|
||||
# callback functions
|
||||
cdef void cb_onSize(GLFWwindow window, int w, int h):
|
||||
cdef Window self = <Window>glfwGetWindowUserPointer(window)
|
||||
self.onSize(w, max(1, h))
|
||||
|
||||
cdef void cb_onRefresh(GLFWwindow window):
|
||||
cdef Window self = <Window>glfwGetWindowUserPointer(window)
|
||||
# avoid refresh when request closing
|
||||
self.onRefresh()
|
||||
|
||||
cdef void cb_onMouseButton(GLFWwindow window, int button, int action):
|
||||
cdef Window self = <Window>glfwGetWindowUserPointer(window)
|
||||
self.onMouseButton(button, action)
|
||||
|
||||
cdef void cb_onKey(GLFWwindow window, int key, int action):
|
||||
cdef Window self = <Window>glfwGetWindowUserPointer(window)
|
||||
self.onKey(key, action)
|
||||
|
||||
cdef void cb_onChar(GLFWwindow window, int ch):
|
||||
cdef Window self = <Window>glfwGetWindowUserPointer(window)
|
||||
cdef char st[2]
|
||||
|
||||
st[0] = <char>(ch & 0xff)
|
||||
st[1] = 0
|
||||
|
||||
self.onChar(st.decode('UTF-8', 'ignore'))
|
||||
|
||||
cdef void cb_onFocus(GLFWwindow window, int status):
|
||||
cdef Window self = <Window>glfwGetWindowUserPointer(window)
|
||||
self.onFocus(status)
|
||||
|
||||
cdef void cb_onEnter(GLFWwindow window, int status):
|
||||
cdef Window self = <Window>glfwGetWindowUserPointer(window)
|
||||
self.onEnter(status)
|
||||
|
||||
cdef void cb_onScroll(GLFWwindow window, double dx, double dy):
|
||||
cdef Window self = <Window>glfwGetWindowUserPointer(window)
|
||||
self.onScroll(dx, dy)
|
||||
|
||||
cdef void cb_onIconify(GLFWwindow window, int status):
|
||||
cdef Window self = <Window>glfwGetWindowUserPointer(window)
|
||||
self.onIconify(status)
|
||||
|
||||
cdef int cb_onClose(GLFWwindow window):
|
||||
cdef Window self = <Window>glfwGetWindowUserPointer(window)
|
||||
cdef int ret = self.onClose()
|
||||
if ret:
|
||||
self.running = False
|
||||
return ret
|
||||
|
||||
441
gltools/@src/GLTools.cpp
Normal file
441
gltools/@src/GLTools.cpp
Normal file
|
|
@ -0,0 +1,441 @@
|
|||
#include "GLTools.h"
|
||||
#include "fontstash.h"
|
||||
|
||||
// error handling
|
||||
char errorMessage[256];
|
||||
|
||||
void setErrorMessage(const char *err) {
|
||||
strncpy(errorMessage, err, 255);
|
||||
}
|
||||
|
||||
// load font
|
||||
void *_fonts;
|
||||
|
||||
void destroyFont(void)
|
||||
{
|
||||
sth_delete(_fonts);
|
||||
_fonts = NULL;
|
||||
}
|
||||
|
||||
int initFont(void)
|
||||
{
|
||||
_fonts = sth_create(512,512);
|
||||
if (!_fonts) {
|
||||
setErrorMessage("failed to initialize font structure");
|
||||
printf("failed to initialize font structure\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
atexit(destroyFont);
|
||||
|
||||
if (!sth_add_font(_fonts, 0, NULL)) {
|
||||
setErrorMessage("failed to initialize default font");
|
||||
printf("failed to initialize default font\n");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int initText(void)
|
||||
{
|
||||
if (!_fonts) {
|
||||
if (!initFont())
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int beginText(void)
|
||||
{
|
||||
if (!_fonts) {
|
||||
if (!initFont())
|
||||
return 0;
|
||||
}
|
||||
sth_begin_draw(_fonts);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int endText(void)
|
||||
{
|
||||
if (!_fonts) {
|
||||
if (!initFont())
|
||||
return 0;
|
||||
}
|
||||
sth_end_draw(_fonts);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int drawText(int idx, float size, float x, float y, const char *text, float *dx)
|
||||
{
|
||||
if (!_fonts) {
|
||||
if (!initFont())
|
||||
return 0;
|
||||
}
|
||||
if (!sth_draw_text(_fonts, idx, size, x, y, text, dx)) {
|
||||
setErrorMessage("failed to draw text string");
|
||||
printf("failed to draw text string\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// opengl 2.1 extensions
|
||||
#define GLEXTPROCSIZE 27
|
||||
int isGLExtLoaded = 0;
|
||||
|
||||
int initGLExt(void)
|
||||
{
|
||||
// OpenGL 2.1 functions
|
||||
int status = 0;
|
||||
|
||||
pglCreateShader = (PFNGLCREATESHADERPROC) glfwGetProcAddress("glCreateShader");
|
||||
if (pglCreateShader) status++;
|
||||
|
||||
pglShaderSource = (PFNGLSHADERSOURCEPROC) glfwGetProcAddress("glShaderSource");
|
||||
if (pglShaderSource) status++;
|
||||
|
||||
pglCompileShader = (PFNGLCOMPILESHADERPROC) glfwGetProcAddress("glCompileShader");
|
||||
if (pglCompileShader) status++;
|
||||
|
||||
pglGetShaderiv = (PFNGLGETSHADERIVPROC) glfwGetProcAddress("glGetShaderiv");
|
||||
if (pglGetShaderiv) status++;
|
||||
|
||||
pglGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) glfwGetProcAddress("glGetShaderInfoLog");
|
||||
if (pglGetShaderInfoLog) status++;
|
||||
|
||||
pglDeleteShader = (PFNGLDELETESHADERPROC) glfwGetProcAddress("glDeleteShader");
|
||||
if (pglDeleteShader) status++;
|
||||
|
||||
pglCreateProgram = (PFNGLCREATEPROGRAMPROC) glfwGetProcAddress("glCreateProgram");
|
||||
if (pglCreateProgram) status++;
|
||||
|
||||
pglAttachShader = (PFNGLATTACHSHADERPROC) glfwGetProcAddress("glAttachShader");
|
||||
if (pglAttachShader) status++;
|
||||
|
||||
pglLinkProgram = (PFNGLLINKPROGRAMPROC) glfwGetProcAddress("glLinkProgram");
|
||||
if (pglLinkProgram) status++;
|
||||
|
||||
pglUseProgram = (PFNGLUSEPROGRAMPROC) glfwGetProcAddress("glUseProgram");
|
||||
if (pglUseProgram) status++;
|
||||
|
||||
pglGetProgramiv = (PFNGLGETPROGRAMIVPROC) glfwGetProcAddress("glGetProgramiv");
|
||||
if (pglGetProgramiv) status++;
|
||||
|
||||
pglGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) glfwGetProcAddress("glGetProgramInfoLog");
|
||||
if (pglGetProgramInfoLog) status++;
|
||||
|
||||
pglDeleteProgram = (PFNGLDELETEPROGRAMPROC) glfwGetProcAddress("glDeleteProgram");
|
||||
if (pglDeleteProgram) status++;
|
||||
|
||||
pglGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) glfwGetProcAddress("glGetUniformLocation");
|
||||
if (pglGetUniformLocation) status++;
|
||||
|
||||
pglUniform1i = (PFNGLUNIFORM1IPROC) glfwGetProcAddress("glUniform1i");
|
||||
if (pglUniform1i) status++;
|
||||
|
||||
pglUniform1f = (PFNGLUNIFORM1FPROC) glfwGetProcAddress("glUniform1f");
|
||||
if (pglUniform1f) status++;
|
||||
|
||||
pglUniform4f = (PFNGLUNIFORM4FPROC) glfwGetProcAddress("glUniform4f");
|
||||
if (pglUniform4f) status++;
|
||||
|
||||
pglUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) glfwGetProcAddress("glUniformMatrix4fv");
|
||||
if (pglUniformMatrix4fv) status++;
|
||||
|
||||
pglGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) glfwGetProcAddress("glGetAttribLocation");
|
||||
if (pglGetAttribLocation) status++;
|
||||
|
||||
pglGenBuffers = (PFNGLGENBUFFERSPROC) glfwGetProcAddress("glGenBuffers");
|
||||
if (pglGenBuffers) status++;
|
||||
|
||||
pglDeleteBuffers = (PFNGLDELETEBUFFERSPROC) glfwGetProcAddress("glDeleteBuffers");
|
||||
if (pglDeleteBuffers) status++;
|
||||
|
||||
pglBindBuffer = (PFNGLBINDBUFFERPROC) glfwGetProcAddress("glBindBuffer");
|
||||
if (pglBindBuffer) status++;
|
||||
|
||||
pglBufferData = (PFNGLBUFFERDATAPROC) glfwGetProcAddress("glBufferData");
|
||||
if (pglBufferData) status++;
|
||||
|
||||
pglBufferSubData = (PFNGLBUFFERSUBDATAPROC) glfwGetProcAddress("glBufferSubData");
|
||||
if (pglBufferSubData) status++;
|
||||
|
||||
pglGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) glfwGetProcAddress("glGetBufferParameteriv");
|
||||
if (pglGetBufferParameteriv) status++;
|
||||
|
||||
pglEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) glfwGetProcAddress("glEnableVertexAttribArray");
|
||||
if (pglEnableVertexAttribArray) status++;
|
||||
|
||||
pglVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) glfwGetProcAddress("glVertexAttribPointer");
|
||||
if (pglVertexAttribPointer) status++;
|
||||
|
||||
if (status != GLEXTPROCSIZE) {
|
||||
setErrorMessage("Failed to load OpenGL 2.1 function pointers");
|
||||
return 0;
|
||||
}
|
||||
isGLExtLoaded = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// opengl buffer interface
|
||||
ClientBuffer::ClientBuffer(GLenum target = GL_ARRAY_BUFFER) {
|
||||
pglGenBuffers(1, &m_id);
|
||||
m_target = target;
|
||||
m_loaded = false;
|
||||
for (unsigned i = 0; i < VERTEXBUFFERATTRIBSIZE; i++) {
|
||||
m_attrib[i].enabled = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ClientBuffer::~ClientBuffer() {
|
||||
pglDeleteBuffers(1, &m_id);
|
||||
}
|
||||
|
||||
void ClientBuffer::bind() {
|
||||
pglBindBuffer(m_target, m_id);
|
||||
if (m_target != GL_ARRAY_BUFFER)
|
||||
return;
|
||||
|
||||
for (unsigned i = 0; i < VERTEXBUFFERATTRIBSIZE; i++) {
|
||||
ClientBufferAttrib *attr = &m_attrib[i];
|
||||
|
||||
if(m_attrib[i].enabled) {
|
||||
glEnableClientState(attr->type);
|
||||
if (attr->type == GL_VERTEX_ARRAY) {
|
||||
glVertexPointer(attr->dataTypeSize, attr->dataType,
|
||||
attr->stride, attr->pointer);
|
||||
|
||||
} else if (attr->type == GL_NORMAL_ARRAY) {
|
||||
glNormalPointer(attr->dataType, attr->stride, attr->pointer);
|
||||
|
||||
} else if (attr->type == GL_COLOR_ARRAY) {
|
||||
glColorPointer(attr->dataTypeSize, attr->dataType,
|
||||
attr->stride, attr->pointer);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClientBuffer::unBind() {
|
||||
if (m_target == GL_ARRAY_BUFFER) {
|
||||
for (unsigned i = 0; i < VERTEXBUFFERATTRIBSIZE; i++) {
|
||||
if(m_attrib[i].enabled) {
|
||||
glDisableClientState(m_attrib[i].type);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
glDisableClientState(GL_INDEX_ARRAY);
|
||||
}
|
||||
pglBindBuffer(m_target, 0);
|
||||
}
|
||||
|
||||
int ClientBuffer::setDataType(GLenum type, GLenum dataType, GLenum dataTypeSize,
|
||||
GLsizei stride, const uintptr_t pointer) {
|
||||
int idx;
|
||||
switch (type)
|
||||
{
|
||||
case GL_VERTEX_ARRAY:
|
||||
{
|
||||
idx = 0;
|
||||
break;
|
||||
}
|
||||
case GL_COLOR_ARRAY:
|
||||
{
|
||||
idx = 1;
|
||||
break;
|
||||
}
|
||||
case GL_NORMAL_ARRAY:
|
||||
{
|
||||
idx = 2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
setErrorMessage("Failed to allocate memory for buffer");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
m_attrib[idx].enabled = 1;
|
||||
m_attrib[idx].type = type;
|
||||
m_attrib[idx].dataType = dataType;
|
||||
m_attrib[idx].dataTypeSize = dataTypeSize;
|
||||
m_attrib[idx].stride = stride;
|
||||
m_attrib[idx].pointer = (void*)pointer;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ClientBuffer::loadData(const GLvoid *data, GLsizeiptr size,
|
||||
GLintptr offset, GLenum usage) {
|
||||
int bufferSize = 0;
|
||||
if (!m_loaded) {
|
||||
pglBindBuffer(m_target, m_id);
|
||||
pglBufferData(m_target, size, data, usage);
|
||||
pglGetBufferParameteriv(m_target, GL_BUFFER_SIZE_ARB, &bufferSize);
|
||||
pglBindBuffer(m_target, 0);
|
||||
if (bufferSize != size) {
|
||||
setErrorMessage("Failed to allocate memory for buffer");
|
||||
return 0;
|
||||
}
|
||||
m_loaded = true;
|
||||
} else {
|
||||
pglBindBuffer(m_target, m_id);
|
||||
pglBufferSubData(m_target, offset, size, data);
|
||||
pglBindBuffer(m_target, 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// opengl shader program interface
|
||||
ShaderProgram::ShaderProgram() {
|
||||
m_id = 0u;
|
||||
m_vertex_id = 0u;
|
||||
m_fragment_id = 0u;
|
||||
}
|
||||
|
||||
ShaderProgram::~ShaderProgram() {
|
||||
if (m_vertex_id) pglDeleteShader(m_vertex_id);
|
||||
if (m_fragment_id) pglDeleteShader(m_fragment_id);
|
||||
if (m_id) pglDeleteProgram(m_id);
|
||||
}
|
||||
|
||||
bool ShaderProgram::isValid() {
|
||||
return (m_id != 0u && m_vertex_id != 0u && m_fragment_id != 0u);
|
||||
}
|
||||
|
||||
void ShaderProgram::begin() {
|
||||
pglUseProgram(m_id);
|
||||
}
|
||||
|
||||
void ShaderProgram::end() {
|
||||
pglUseProgram(0);
|
||||
}
|
||||
|
||||
GLint ShaderProgram::attribLocation(const GLchar *name) {
|
||||
GLint uloc = pglGetAttribLocation(m_id, name);
|
||||
if (uloc == -1) {
|
||||
setErrorMessage("Failed to find attrib variable");
|
||||
return -1;
|
||||
}
|
||||
return uloc;
|
||||
}
|
||||
|
||||
int ShaderProgram::loadUniform1i(const char *name, const GLint value) {
|
||||
GLint uloc = pglGetUniformLocation(m_id, name);
|
||||
if (uloc == -1) {
|
||||
setErrorMessage("Failed to find uniform variable");
|
||||
return 0;
|
||||
}
|
||||
pglUniform1i(uloc, value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ShaderProgram::loadUniform1f(const char *name, const GLfloat value) {
|
||||
GLint uloc = pglGetUniformLocation(m_id, name);
|
||||
if (uloc == -1) {
|
||||
setErrorMessage("Failed to find uniform variable");
|
||||
return 0;
|
||||
}
|
||||
pglUniform1f(uloc, value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ShaderProgram::loadUniform4f(const char *name, const GLfloat v0, const GLfloat v1,
|
||||
const GLfloat v2, const GLfloat v3) {
|
||||
GLint uloc = pglGetUniformLocation(m_id, name);
|
||||
if (uloc == -1) {
|
||||
setErrorMessage("Failed to find uniform variable");
|
||||
return 0;
|
||||
}
|
||||
pglUniform4f(uloc, v0, v1, v2, v3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ShaderProgram::loadUniformMatrix4vf(const char *name, const GLfloat *value,
|
||||
GLsizei count) {
|
||||
GLint uloc = pglGetUniformLocation(m_id, name);
|
||||
if (uloc == -1) {
|
||||
setErrorMessage("Failed to find uniform variable");
|
||||
return 0;
|
||||
}
|
||||
pglUniformMatrix4fv(uloc, count, GL_FALSE, value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ShaderProgram::build(const char* vertex_src,
|
||||
const char* fragment_src) {
|
||||
GLint status;
|
||||
GLsizei log_length;
|
||||
char info_log[256];
|
||||
|
||||
if (!vertex_src) vertex_src = default_vertex_shader;
|
||||
if (!fragment_src) fragment_src = default_fragment_shader;
|
||||
|
||||
// build vertex shader
|
||||
m_vertex_id = pglCreateShader(GL_VERTEX_SHADER);
|
||||
if (m_vertex_id == 0u) {
|
||||
setErrorMessage("Failed to create vertex shader");
|
||||
return 0;
|
||||
}
|
||||
pglShaderSource(m_vertex_id, 1, (const GLchar**)&vertex_src, NULL);
|
||||
pglCompileShader(m_vertex_id);
|
||||
pglGetShaderiv(m_vertex_id, GL_COMPILE_STATUS, &status);
|
||||
if (status != GL_TRUE)
|
||||
{
|
||||
pglGetShaderInfoLog(m_vertex_id, sizeof(info_log), &log_length,info_log);
|
||||
setErrorMessage(info_log);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// build fragment shader
|
||||
m_fragment_id = pglCreateShader(GL_FRAGMENT_SHADER);
|
||||
if (m_fragment_id == 0u) {
|
||||
setErrorMessage("Failed to create fragment shader");
|
||||
return 0;
|
||||
}
|
||||
pglShaderSource(m_fragment_id, 1, (const GLchar**)&fragment_src, NULL);
|
||||
pglCompileShader(m_fragment_id);
|
||||
pglGetShaderiv(m_fragment_id, GL_COMPILE_STATUS, &status);
|
||||
if (status != GL_TRUE)
|
||||
{
|
||||
pglGetShaderInfoLog(m_fragment_id, sizeof(info_log), &log_length,info_log);
|
||||
setErrorMessage(info_log);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// create program and link shaders
|
||||
m_id = pglCreateProgram();
|
||||
if (m_id == 0u) {
|
||||
setErrorMessage("Failed to create program");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pglAttachShader(m_id, m_vertex_id);
|
||||
pglAttachShader(m_id, m_fragment_id);
|
||||
pglLinkProgram(m_id);
|
||||
pglGetProgramiv(m_id, GL_LINK_STATUS, &status);
|
||||
if (status != GL_TRUE)
|
||||
{
|
||||
pglGetShaderInfoLog(m_id, 8192, &log_length,info_log);
|
||||
setErrorMessage(info_log);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* ShaderProgram::default_vertex_shader =
|
||||
"#version 130\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FrontColor = gl_Color;\n"
|
||||
" gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n"
|
||||
"}\n";
|
||||
|
||||
const char* ShaderProgram::default_fragment_shader =
|
||||
"#version 130\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = gl_Color;\n"
|
||||
"}\n";
|
||||
|
||||
106
gltools/@src/GLTools.h
Normal file
106
gltools/@src/GLTools.h
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
// Copyright 2012 by Runar Tenfjord, Tenko as.
|
||||
// See LICENSE.txt for details on conditions.
|
||||
#ifndef GLTOOLS_H
|
||||
#define GLTOOLS_H
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <GL/glfw3.h>
|
||||
#include <GL/glext.h>
|
||||
|
||||
#define GLEXTPROCSIZE 27
|
||||
#define VERTEXBUFFERATTRIBSIZE 8
|
||||
|
||||
extern char errorMessage[256];
|
||||
void setErrorMessage(const char *err);
|
||||
|
||||
// opengl font
|
||||
extern void *_fonts;
|
||||
int initText(void);
|
||||
int beginText(void);
|
||||
int endText(void);
|
||||
int drawText(int idx, float size, float x, float y, const char *text, float *dx);
|
||||
|
||||
/* OpenGL 2.1 function pointers */
|
||||
extern int isGLExtLoaded;
|
||||
|
||||
static PFNGLGENBUFFERSPROC pglGenBuffers = NULL;
|
||||
static PFNGLDELETEBUFFERSPROC pglDeleteBuffers = NULL;
|
||||
static PFNGLCREATESHADERPROC pglCreateShader = NULL;
|
||||
static PFNGLSHADERSOURCEPROC pglShaderSource = NULL;
|
||||
static PFNGLCOMPILESHADERPROC pglCompileShader = NULL;
|
||||
static PFNGLGETSHADERIVPROC pglGetShaderiv = NULL;
|
||||
static PFNGLGETSHADERINFOLOGPROC pglGetShaderInfoLog = NULL;
|
||||
static PFNGLDELETESHADERPROC pglDeleteShader = NULL;
|
||||
static PFNGLCREATEPROGRAMPROC pglCreateProgram = NULL;
|
||||
static PFNGLATTACHSHADERPROC pglAttachShader = NULL;
|
||||
static PFNGLLINKPROGRAMPROC pglLinkProgram = NULL;
|
||||
static PFNGLUSEPROGRAMPROC pglUseProgram = NULL;
|
||||
static PFNGLGETPROGRAMIVPROC pglGetProgramiv = NULL;
|
||||
static PFNGLGETPROGRAMINFOLOGPROC pglGetProgramInfoLog = NULL;
|
||||
static PFNGLDELETEPROGRAMPROC pglDeleteProgram = NULL;
|
||||
static PFNGLGETUNIFORMLOCATIONPROC pglGetUniformLocation = NULL;
|
||||
static PFNGLUNIFORM1IPROC pglUniform1i = NULL;
|
||||
static PFNGLUNIFORM1FPROC pglUniform1f = NULL;
|
||||
static PFNGLUNIFORM4FPROC pglUniform4f = NULL;
|
||||
static PFNGLUNIFORMMATRIX4FVPROC pglUniformMatrix4fv = NULL;
|
||||
static PFNGLGETATTRIBLOCATIONPROC pglGetAttribLocation = NULL;
|
||||
static PFNGLBUFFERDATAPROC pglBufferData = NULL;
|
||||
static PFNGLBINDBUFFERPROC pglBindBuffer = NULL;
|
||||
static PFNGLBUFFERSUBDATAPROC pglBufferSubData = NULL;
|
||||
static PFNGLGETBUFFERPARAMETERIVPROC pglGetBufferParameteriv = NULL;
|
||||
static PFNGLENABLEVERTEXATTRIBARRAYPROC pglEnableVertexAttribArray = NULL;
|
||||
static PFNGLVERTEXATTRIBPOINTERPROC pglVertexAttribPointer = NULL;
|
||||
|
||||
int initGLExt(void);
|
||||
|
||||
struct ClientBufferAttrib {
|
||||
int enabled;
|
||||
GLenum type;
|
||||
GLenum dataType;
|
||||
GLint dataTypeSize;
|
||||
GLsizei stride;
|
||||
const GLvoid *pointer;
|
||||
};
|
||||
|
||||
class ClientBuffer {
|
||||
public:
|
||||
GLuint m_id;
|
||||
GLenum m_target;
|
||||
bool m_loaded;
|
||||
ClientBufferAttrib m_attrib[VERTEXBUFFERATTRIBSIZE];
|
||||
|
||||
ClientBuffer(GLenum target);
|
||||
~ClientBuffer();
|
||||
void bind();
|
||||
void unBind();
|
||||
int setDataType(GLenum type, GLenum dataType, GLenum dataTypeSize,
|
||||
GLsizei stride, const uintptr_t pointer);
|
||||
int loadData(const GLvoid *data, GLsizeiptr size, GLintptr offset = 0,
|
||||
GLenum usage = GL_STATIC_DRAW);
|
||||
};
|
||||
|
||||
class ShaderProgram {
|
||||
public:
|
||||
GLuint m_id;
|
||||
GLuint m_vertex_id;
|
||||
GLuint m_fragment_id;
|
||||
ShaderProgram();
|
||||
~ShaderProgram();
|
||||
bool isValid();
|
||||
void begin();
|
||||
void end();
|
||||
GLint attribLocation(const GLchar *name);
|
||||
int loadUniform1i(const char *name, const GLint value);
|
||||
int loadUniform1f(const char *name, const GLfloat value);
|
||||
int loadUniform4f(const char *name, const GLfloat v0, const GLfloat v1,
|
||||
const GLfloat v2, const GLfloat v3);
|
||||
int loadUniformMatrix4vf(const char *name, const GLfloat *value, GLsizei count = 1);
|
||||
int build(const char* vertex_src = NULL, const char* fragment_src = NULL);
|
||||
private:
|
||||
static const char* default_vertex_shader;
|
||||
static const char* default_fragment_shader;
|
||||
};
|
||||
#endif
|
||||
50
gltools/@src/GLToolsLib.pxd
Normal file
50
gltools/@src/GLToolsLib.pxd
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
cdef extern from "GLTools.h":
|
||||
ctypedef unsigned int GLenum
|
||||
ctypedef unsigned char GLboolean
|
||||
ctypedef unsigned int GLbitfield
|
||||
ctypedef signed char GLbyte
|
||||
ctypedef short GLshort
|
||||
ctypedef int GLint
|
||||
ctypedef int GLsizei
|
||||
ctypedef unsigned char GLubyte
|
||||
ctypedef unsigned short GLushort
|
||||
ctypedef unsigned int GLuint
|
||||
ctypedef float GLfloat
|
||||
ctypedef float GLclampf
|
||||
ctypedef double GLdouble
|
||||
ctypedef double GLclampd
|
||||
ctypedef void GLvoid
|
||||
ctypedef ssize_t GLintptr
|
||||
ctypedef ssize_t GLsizeiptr
|
||||
|
||||
char errorMessage[256]
|
||||
|
||||
int c_initText "initText"()
|
||||
int c_beginText "beginText"()
|
||||
int c_endText "endText"()
|
||||
int c_drawText "drawText"(int idx, float size, float x, float y, char *text, float *dx)
|
||||
|
||||
int isGLExtLoaded
|
||||
int c_initGLExt "initGLExt"()
|
||||
|
||||
cdef cppclass c_ClientBuffer "ClientBuffer":
|
||||
c_ClientBuffer(GLenum target)
|
||||
void bind()
|
||||
void unBind()
|
||||
int setDataType(GLenum type, GLenum dataType, GLenum dataTypeSize,
|
||||
GLsizei stride, size_t pointer)
|
||||
int loadData(GLvoid *data, GLsizeiptr size, GLintptr offset, GLenum usage)
|
||||
|
||||
cdef cppclass c_ShaderProgram "ShaderProgram":
|
||||
c_ShaderProgram()
|
||||
bint isValid()
|
||||
void begin()
|
||||
void end()
|
||||
GLint attribLocation(char *name)
|
||||
int loadUniform1i(char *name, GLint value)
|
||||
int loadUniform1f(char *name, GLfloat value)
|
||||
int loadUniform4f(char *name, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
|
||||
int loadUniformMatrix4vf(char *name, GLfloat *value, GLsizei count)
|
||||
int build(char *vertex_src, char *fragment_src)
|
||||
|
||||
67
gltools/@src/ShaderProgram.pxi
Normal file
67
gltools/@src/ShaderProgram.pxi
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This file is part of gltools - See LICENSE.txt
|
||||
#
|
||||
cdef class ShaderProgram:
|
||||
def __init__(self):
|
||||
if not isGLExtLoaded:
|
||||
raise GLError('OpenGL 2.1 function pointers not found')
|
||||
self.thisptr = new c_ShaderProgram()
|
||||
|
||||
def __dealloc__(self):
|
||||
cdef c_ShaderProgram *tmp
|
||||
|
||||
if self.thisptr != NULL:
|
||||
tmp = <c_ShaderProgram *>self.thisptr
|
||||
del tmp
|
||||
|
||||
def __str__(self):
|
||||
return "ShaderProgram%s" % repr(self)
|
||||
|
||||
def __repr__(self):
|
||||
return "()"
|
||||
|
||||
cpdef bint isValid(self):
|
||||
cdef c_ShaderProgram *prog = <c_ShaderProgram *>self.thisptr
|
||||
return prog.isValid()
|
||||
|
||||
cpdef begin(self):
|
||||
cdef c_ShaderProgram *prog = <c_ShaderProgram *>self.thisptr
|
||||
prog.begin()
|
||||
|
||||
cpdef end(self):
|
||||
cdef c_ShaderProgram *prog = <c_ShaderProgram *>self.thisptr
|
||||
prog.end()
|
||||
|
||||
cpdef loadUniform1i(self, char *name, int value):
|
||||
cdef c_ShaderProgram *prog = <c_ShaderProgram *>self.thisptr
|
||||
if not prog.loadUniform1i(name, value):
|
||||
raise GLError(errorMessage)
|
||||
|
||||
cpdef loadUniform1f(self, char *name, float value):
|
||||
cdef c_ShaderProgram *prog = <c_ShaderProgram *>self.thisptr
|
||||
if not prog.loadUniform1f(name, value):
|
||||
raise GLError(errorMessage)
|
||||
|
||||
cpdef loadUniform4f(self, char *name, float v0, float v1, float v2, float v3):
|
||||
print name, v0, v1, v2, v3
|
||||
cdef c_ShaderProgram *prog = <c_ShaderProgram *>self.thisptr
|
||||
if not prog.loadUniform4f(name, v0, v1, v2, v3):
|
||||
raise GLError(errorMessage)
|
||||
|
||||
cpdef loadUniformMatrix4vf(self, char *name, float [::1] value, int count = 1):
|
||||
cdef c_ShaderProgram *prog = <c_ShaderProgram *>self.thisptr
|
||||
if not prog.loadUniformMatrix4vf(name, &value[0], count):
|
||||
raise GLError(errorMessage)
|
||||
|
||||
cpdef build(self, vertex_src = None, fragment_src = None):
|
||||
cdef c_ShaderProgram *prog = <c_ShaderProgram *>self.thisptr
|
||||
cdef int ret
|
||||
|
||||
if vertex_src is None and fragment_src is None:
|
||||
ret = prog.build(NULL,NULL)
|
||||
else:
|
||||
ret = prog.build(vertex_src, fragment_src)
|
||||
|
||||
if not ret:
|
||||
raise GLError(errorMessage)
|
||||
23
gltools/@src/Text.pxi
Normal file
23
gltools/@src/Text.pxi
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This file is part of gltools - See LICENSE.txt
|
||||
#
|
||||
cpdef BeginText():
|
||||
if not c_beginText():
|
||||
raise GLError(errorMessage)
|
||||
|
||||
cpdef float DrawText(size, float x, float y, text):
|
||||
cdef float dx
|
||||
cdef char *c_str
|
||||
|
||||
bytetext = unicode(text).encode('UTF-8','ignore')
|
||||
c_str = bytetext
|
||||
|
||||
if not c_drawText(0, size, x, y, c_str, &dx):
|
||||
raise GLError(errorMessage)
|
||||
|
||||
return dx
|
||||
|
||||
cpdef EndText():
|
||||
if not c_endText():
|
||||
raise GLError(errorMessage)
|
||||
139
gltools/@src/UI.pxi
Normal file
139
gltools/@src/UI.pxi
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from imguiLib cimport *
|
||||
|
||||
cdef class UI:
|
||||
def __init__(self):
|
||||
self.scrollIdx = 0
|
||||
imguiRenderGLInit()
|
||||
|
||||
if not c_initText():
|
||||
raise GLError(errorMessage)
|
||||
|
||||
cpdef bint anyActive(self):
|
||||
return imguiAnyActive()
|
||||
|
||||
cpdef flush(self):
|
||||
self.scrollIdx = 0
|
||||
imguiRenderGLDraw()
|
||||
|
||||
cpdef beginFrame(self, int mx, int my, char mbut, int scroll):
|
||||
if mbut == GLFW_MOUSE_BUTTON_LEFT:
|
||||
mbut = IMGUI_MBUT_LEFT
|
||||
elif mbut == GLFW_MOUSE_BUTTON_RIGHT:
|
||||
mbut = IMGUI_MBUT_RIGHT
|
||||
elif mbut == -1:
|
||||
mbut = 0
|
||||
|
||||
imguiBeginFrame(mx, my, mbut, scroll)
|
||||
|
||||
cpdef endFrame(self):
|
||||
imguiEndFrame()
|
||||
|
||||
cpdef bint beginScrollArea(self, name, int x, int y, int w, int h):
|
||||
cdef char *c_name
|
||||
cdef bint ret
|
||||
|
||||
bytetext = unicode(name).encode('UTF-8','ignore')
|
||||
c_name = bytetext
|
||||
|
||||
ret = imguiBeginScrollArea(c_name, x, y, w, h, &self.scroll[self.scrollIdx])
|
||||
self.scrollIdx += 1
|
||||
if self.scrollIdx >= 10:
|
||||
raise GLError('Only 10 scrool areas supported')
|
||||
|
||||
return ret
|
||||
|
||||
cpdef endScrollArea(self):
|
||||
imguiEndScrollArea()
|
||||
|
||||
cpdef indent(self):
|
||||
imguiIndent()
|
||||
|
||||
cpdef unindent(self):
|
||||
imguiUnindent()
|
||||
|
||||
cpdef separator(self):
|
||||
imguiSeparator()
|
||||
|
||||
cpdef separatorLine(self):
|
||||
imguiSeparatorLine()
|
||||
|
||||
cpdef bint button(self, text, bint enabled):
|
||||
cdef char *c_text
|
||||
|
||||
bytetext = unicode(text).encode('UTF-8','ignore')
|
||||
c_text = bytetext
|
||||
|
||||
return imguiButton(c_text, enabled)
|
||||
|
||||
cpdef bint item(self, text, bint enabled):
|
||||
cdef char *c_text
|
||||
|
||||
bytetext = unicode(text).encode('UTF-8','ignore')
|
||||
c_text = bytetext
|
||||
|
||||
return imguiItem(c_text, enabled)
|
||||
|
||||
|
||||
cpdef bint check(self, text, bint checked, bint enabled):
|
||||
cdef char *c_text
|
||||
|
||||
bytetext = unicode(text).encode('UTF-8','ignore')
|
||||
c_text = bytetext
|
||||
|
||||
return imguiCheck(c_text, checked, enabled)
|
||||
|
||||
|
||||
cpdef bint collapse(self, text, char* subtext, bint checked, bint enabled):
|
||||
cdef char *c_text
|
||||
|
||||
bytetext = unicode(text).encode('UTF-8','ignore')
|
||||
c_text = bytetext
|
||||
|
||||
return imguiCollapse(c_text, subtext, checked, enabled)
|
||||
|
||||
cpdef label(self, text):
|
||||
cdef char *c_text
|
||||
|
||||
bytetext = unicode(text).encode('UTF-8','ignore')
|
||||
c_text = bytetext
|
||||
|
||||
imguiLabel(c_text)
|
||||
|
||||
cpdef value(self, text):
|
||||
cdef char *c_text
|
||||
|
||||
bytetext = unicode(text).encode('UTF-8','ignore')
|
||||
c_text = bytetext
|
||||
|
||||
imguiValue(c_text)
|
||||
|
||||
cpdef float slider(self, text, float val, float vmin, float vmax,
|
||||
float vinc, bint enabled):
|
||||
cdef float c_val = val
|
||||
cdef char *c_text
|
||||
|
||||
bytetext = unicode(text).encode('UTF-8','ignore')
|
||||
c_text = bytetext
|
||||
|
||||
imguiSlider(c_text, &c_val, vmin, vmax, vinc, enabled)
|
||||
return c_val
|
||||
|
||||
cpdef drawText(self, int x, int y, int align, text, ColorRGBA color):
|
||||
cdef char *c_text
|
||||
|
||||
bytetext = unicode(text).encode('UTF-8','ignore')
|
||||
c_text = bytetext
|
||||
|
||||
imguiDrawText(x, y, align, c_text, color.toInt())
|
||||
|
||||
|
||||
cpdef drawLine(self, float x0, float y0, float x1, float y1, float r, ColorRGBA color):
|
||||
imguiDrawLine(x0, y0, x1, y1, r, color.toInt())
|
||||
|
||||
|
||||
cpdef drawRoundedRect(self, float x, float y, float w, float h, float r, ColorRGBA color):
|
||||
imguiDrawRoundedRect(x, y, w, h, r, color.toInt())
|
||||
|
||||
cpdef drawRect(self, float x, float y, float w, float h, ColorRGBA color):
|
||||
imguiDrawRect(x, y, w, h, color.toInt())
|
||||
82
gltools/@src/Utilities.pxi
Normal file
82
gltools/@src/Utilities.pxi
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This file is part of gltools - See LICENSE.txt
|
||||
#
|
||||
|
||||
# general imports
|
||||
from libc.stdint cimport uintptr_t
|
||||
from libc.stdlib cimport malloc, free
|
||||
|
||||
from libc.math cimport fmin, fmax, fabs, copysign
|
||||
from libc.math cimport M_PI, sqrt, sin, cos, tan
|
||||
|
||||
cimport cpython.array
|
||||
|
||||
# utility to get pointer from memoryview
|
||||
cdef void *getVoidPtr(arr):
|
||||
cdef double [::1] d_view
|
||||
cdef float [::1] f_view
|
||||
cdef long [::1] l_view
|
||||
cdef int [::1] i_view
|
||||
cdef unsigned int [::1] I_view
|
||||
cdef char [::1] b_view
|
||||
cdef unsigned char [::1] B_view
|
||||
cdef void *ptr
|
||||
|
||||
try:
|
||||
d_view = arr
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
ptr = <void *>(&d_view[0])
|
||||
return ptr
|
||||
|
||||
try:
|
||||
f_view = arr
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
ptr = <void *>(&f_view[0])
|
||||
return ptr
|
||||
|
||||
try:
|
||||
l_view = arr
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
ptr = <void *>(&l_view[0])
|
||||
return ptr
|
||||
|
||||
try:
|
||||
i_view = arr
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
ptr = <void *>(&i_view[0])
|
||||
return ptr
|
||||
|
||||
try:
|
||||
I_view = arr
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
ptr = <void *>(&I_view[0])
|
||||
return ptr
|
||||
|
||||
try:
|
||||
b_view = arr
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
ptr = <void *>(&b_view[0])
|
||||
return ptr
|
||||
|
||||
try:
|
||||
B_view = arr
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
ptr = <void *>(&B_view[0])
|
||||
return ptr
|
||||
|
||||
raise TypeError('no valid array type found')
|
||||
257
gltools/@src/glLib.pxd
Normal file
257
gltools/@src/glLib.pxd
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
cdef extern from "GL/glfw3.h":
|
||||
ctypedef unsigned int GLenum
|
||||
ctypedef unsigned char GLboolean
|
||||
ctypedef unsigned int GLbitfield
|
||||
ctypedef signed char GLbyte
|
||||
ctypedef short GLshort
|
||||
ctypedef int GLint
|
||||
ctypedef int GLsizei
|
||||
ctypedef unsigned char GLubyte
|
||||
ctypedef unsigned short GLushort
|
||||
ctypedef unsigned int GLuint
|
||||
ctypedef float GLfloat
|
||||
ctypedef float GLclampf
|
||||
ctypedef double GLdouble
|
||||
ctypedef double GLclampd
|
||||
ctypedef void GLvoid
|
||||
|
||||
void glBlendFunc(GLenum sfactor, GLenum dfactor)
|
||||
void glClear(GLbitfield mask)
|
||||
void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
|
||||
void glClearDepth(GLclampd depth)
|
||||
void glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha )
|
||||
void glDisable(GLenum cap)
|
||||
void glDrawArrays(GLenum mode, GLint first, GLsizei count)
|
||||
void glDrawElements(GLenum mode, GLsizei count, GLenum type, GLvoid *indices)
|
||||
void glEnable(GLenum cap)
|
||||
void glLineWidth(GLfloat width)
|
||||
void glLightfv(GLenum light, GLenum pname, GLfloat *params )
|
||||
void glLightModeli(GLenum pname, GLint param)
|
||||
void glLoadIdentity()
|
||||
void glLoadMatrixd(GLdouble *m)
|
||||
void glMaterialfv(GLenum face, GLenum pname, GLfloat *params)
|
||||
void glMatrixMode(GLenum mode)
|
||||
void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
|
||||
void glPolygonMode(GLenum face, GLenum mode)
|
||||
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
|
||||
|
||||
cdef enum:
|
||||
# Boolean values
|
||||
GL_FALSE
|
||||
GL_TRUE
|
||||
|
||||
# DataType
|
||||
GL_BYTE
|
||||
GL_UNSIGNED_BYTE
|
||||
GL_SHORT
|
||||
GL_UNSIGNED_SHORT
|
||||
GL_INT
|
||||
GL_UNSIGNED_INT
|
||||
GL_FLOAT
|
||||
GL_2_BYTES
|
||||
GL_3_BYTES
|
||||
GL_4_BYTES
|
||||
GL_DOUBLE
|
||||
|
||||
# BeginMode
|
||||
GL_POINTS
|
||||
GL_LINES
|
||||
GL_LINE_LOOP
|
||||
GL_LINE_STRIP
|
||||
GL_TRIANGLES
|
||||
GL_TRIANGLE_STRIP
|
||||
GL_TRIANGLE_FAN
|
||||
GL_QUADS
|
||||
GL_QUAD_STRIP
|
||||
GL_POLYGON
|
||||
|
||||
# AlphaFunction
|
||||
GL_NEVER
|
||||
GL_LESS
|
||||
GL_EQUAL
|
||||
GL_LEQUAL
|
||||
GL_GREATER
|
||||
GL_NOTEQUAL
|
||||
GL_GEQUAL
|
||||
GL_ALWAYS
|
||||
|
||||
# AttribMask
|
||||
GL_CURRENT_BIT
|
||||
GL_POINT_BIT
|
||||
GL_LINE_BIT
|
||||
GL_POLYGON_BIT
|
||||
GL_POLYGON_STIPPLE_BIT
|
||||
GL_PIXEL_MODE_BIT
|
||||
GL_LIGHTING_BIT
|
||||
GL_FOG_BIT
|
||||
GL_DEPTH_BUFFER_BIT
|
||||
GL_ACCUM_BUFFER_BIT
|
||||
GL_STENCIL_BUFFER_BIT
|
||||
GL_VIEWPORT_BIT
|
||||
GL_TRANSFORM_BIT
|
||||
GL_ENABLE_BIT
|
||||
GL_COLOR_BUFFER_BIT
|
||||
GL_HINT_BIT
|
||||
GL_EVAL_BIT
|
||||
GL_LIST_BIT
|
||||
GL_TEXTURE_BIT
|
||||
GL_SCISSOR_BIT
|
||||
GL_ALL_ATTRIB_BITS
|
||||
|
||||
# Vertex Arrays
|
||||
GL_VERTEX_ARRAY
|
||||
GL_NORMAL_ARRAY
|
||||
GL_COLOR_ARRAY
|
||||
GL_INDEX_ARRAY
|
||||
GL_TEXTURE_COORD_ARRAY
|
||||
GL_EDGE_FLAG_ARRAY
|
||||
|
||||
# BlendingFactorDest
|
||||
GL_ZERO
|
||||
GL_ONE
|
||||
GL_SRC_COLOR
|
||||
GL_ONE_MINUS_SRC_COLOR
|
||||
GL_SRC_ALPHA
|
||||
GL_ONE_MINUS_SRC_ALPHA
|
||||
GL_DST_ALPHA
|
||||
GL_ONE_MINUS_DST_ALPHA
|
||||
|
||||
# BlendingFactorSrc
|
||||
GL_DST_COLOR
|
||||
GL_ONE_MINUS_DST_COLOR
|
||||
GL_SRC_ALPHA_SATURATE
|
||||
|
||||
# DrawBufferMode
|
||||
GL_NONE
|
||||
GL_FRONT_LEFT
|
||||
GL_FRONT_RIGHT
|
||||
GL_BACK_LEFT
|
||||
GL_BACK_RIGHT
|
||||
GL_FRONT
|
||||
GL_BACK
|
||||
GL_LEFT
|
||||
GL_RIGHT
|
||||
GL_FRONT_AND_BACK
|
||||
GL_AUX0
|
||||
GL_AUX1
|
||||
GL_AUX2
|
||||
GL_AUX3
|
||||
GL_CW
|
||||
GL_CCW
|
||||
|
||||
# ErrorCode
|
||||
GL_NO_ERROR
|
||||
GL_INVALID_ENUM
|
||||
GL_INVALID_VALUE
|
||||
GL_INVALID_OPERATION
|
||||
GL_STACK_OVERFLOW
|
||||
GL_STACK_UNDERFLOW
|
||||
GL_OUT_OF_MEMORY
|
||||
|
||||
# GetTarget
|
||||
GL_POLYGON_MODE
|
||||
GL_POLYGON_SMOOTH
|
||||
GL_POLYGON_STIPPLE
|
||||
GL_FRONT_FACE
|
||||
GL_SHADE_MODEL
|
||||
GL_COLOR_MATERIAL_FACE
|
||||
GL_COLOR_MATERIAL_PARAMETER
|
||||
GL_COLOR_MATERIAL
|
||||
GL_DEPTH_RANGE
|
||||
GL_DEPTH_TEST
|
||||
GL_DEPTH_WRITEMASK
|
||||
GL_DEPTH_CLEAR_VALUE
|
||||
GL_DEPTH_FUNC
|
||||
GL_MATRIX_MODE
|
||||
GL_NORMALIZE
|
||||
GL_VIEWPORT
|
||||
GL_MODELVIEW_MATRIX
|
||||
GL_PROJECTION_MATRIX
|
||||
GL_TEXTURE_MATRIX
|
||||
GL_ALPHA_TEST
|
||||
GL_ALPHA_TEST_FUNC
|
||||
GL_ALPHA_TEST_REF
|
||||
GL_DITHER
|
||||
GL_BLEND_DST
|
||||
GL_BLEND_SRC
|
||||
GL_BLEND
|
||||
GL_LOGIC_OP_MODE
|
||||
GL_INDEX_LOGIC_OP
|
||||
GL_COLOR_LOGIC_OP
|
||||
GL_AUX_BUFFERS
|
||||
GL_DRAW_BUFFER
|
||||
GL_READ_BUFFER
|
||||
GL_SCISSOR_BOX
|
||||
GL_SCISSOR_TEST
|
||||
GL_INDEX_CLEAR_VALUE
|
||||
GL_INDEX_WRITEMASK
|
||||
GL_COLOR_CLEAR_VALUE
|
||||
GL_COLOR_WRITEMASK
|
||||
GL_INDEX_MODE
|
||||
GL_RGBA_MODE
|
||||
GL_DOUBLEBUFFER
|
||||
GL_STEREO
|
||||
GL_RENDER_MODE
|
||||
GL_SUBPIXEL_BITS
|
||||
GL_INDEX_BITS
|
||||
GL_RED_BITS
|
||||
GL_GREEN_BITS
|
||||
GL_BLUE_BITS
|
||||
GL_ALPHA_BITS
|
||||
GL_DEPTH_BITS
|
||||
GL_STENCIL_BITS
|
||||
GL_CULL_FACE
|
||||
|
||||
# Ligthing & Material
|
||||
GL_AMBIENT
|
||||
GL_DIFFUSE
|
||||
GL_SPECULAR
|
||||
GL_SHININESS
|
||||
GL_EMISSION
|
||||
GL_POSITION
|
||||
GL_SPOT_DIRECTION
|
||||
GL_AMBIENT_AND_DIFFUSE
|
||||
GL_COLOR_INDEXES
|
||||
GL_LIGHTING
|
||||
GL_LIGHT0
|
||||
GL_LIGHT1
|
||||
GL_LIGHT2
|
||||
GL_LIGHT3
|
||||
GL_LIGHT4
|
||||
GL_LIGHT5
|
||||
GL_LIGHT6
|
||||
GL_LIGHT7
|
||||
GL_LIGHT_MODEL_TWO_SIDE
|
||||
GL_LIGHT_MODEL_LOCAL_VIEWER
|
||||
GL_LIGHT_MODEL_AMBIENT
|
||||
|
||||
# MatrixMode
|
||||
GL_MODELVIEW
|
||||
GL_PROJECTION
|
||||
GL_TEXTURE
|
||||
|
||||
# Lines
|
||||
GL_LINE_SMOOTH
|
||||
|
||||
# PolygonMode
|
||||
GL_POINT
|
||||
GL_LINE
|
||||
GL_FILL
|
||||
|
||||
# ShadingModel
|
||||
GL_FLAT
|
||||
GL_SMOOTH
|
||||
|
||||
# Texture mapping
|
||||
GL_TEXTURE_1D
|
||||
GL_TEXTURE_2D
|
||||
|
||||
# glext.h
|
||||
GL_MULTISAMPLE
|
||||
GL_STATIC_DRAW
|
||||
|
||||
GL_ARRAY_BUFFER
|
||||
GL_ELEMENT_ARRAY_BUFFER
|
||||
|
||||
378
gltools/@src/glfwLib.pxd
Normal file
378
gltools/@src/glfwLib.pxd
Normal file
|
|
@ -0,0 +1,378 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
cdef extern from "GL/glfw3.h":
|
||||
cdef enum:
|
||||
GLFW_VERSION_MAJOR
|
||||
GLFW_VERSION_MINOR
|
||||
GLFW_VERSION_REVISION
|
||||
|
||||
# Key and button state/action definitions
|
||||
GLFW_RELEASE
|
||||
GLFW_PRESS
|
||||
|
||||
# Printable keys
|
||||
GLFW_KEY_SPACE
|
||||
GLFW_KEY_APOSTROPHE
|
||||
GLFW_KEY_COMMA
|
||||
GLFW_KEY_MINUS
|
||||
GLFW_KEY_PERIOD
|
||||
GLFW_KEY_SLASH
|
||||
GLFW_KEY_0
|
||||
GLFW_KEY_1
|
||||
GLFW_KEY_2
|
||||
GLFW_KEY_3
|
||||
GLFW_KEY_4
|
||||
GLFW_KEY_5
|
||||
GLFW_KEY_6
|
||||
GLFW_KEY_7
|
||||
GLFW_KEY_8
|
||||
GLFW_KEY_9
|
||||
GLFW_KEY_SEMICOLON
|
||||
GLFW_KEY_EQUAL
|
||||
GLFW_KEY_A
|
||||
GLFW_KEY_B
|
||||
GLFW_KEY_C
|
||||
GLFW_KEY_D
|
||||
GLFW_KEY_E
|
||||
GLFW_KEY_F
|
||||
GLFW_KEY_G
|
||||
GLFW_KEY_H
|
||||
GLFW_KEY_I
|
||||
GLFW_KEY_J
|
||||
GLFW_KEY_K
|
||||
GLFW_KEY_L
|
||||
GLFW_KEY_M
|
||||
GLFW_KEY_N
|
||||
GLFW_KEY_O
|
||||
GLFW_KEY_P
|
||||
GLFW_KEY_Q
|
||||
GLFW_KEY_R
|
||||
GLFW_KEY_S
|
||||
GLFW_KEY_T
|
||||
GLFW_KEY_U
|
||||
GLFW_KEY_V
|
||||
GLFW_KEY_W
|
||||
GLFW_KEY_X
|
||||
GLFW_KEY_Y
|
||||
GLFW_KEY_Z
|
||||
GLFW_KEY_LEFT_BRACKET
|
||||
GLFW_KEY_BACKSLASH
|
||||
GLFW_KEY_RIGHT_BRACKET
|
||||
GLFW_KEY_GRAVE_ACCENT
|
||||
GLFW_KEY_WORLD_1
|
||||
GLFW_KEY_WORLD_2
|
||||
|
||||
# Function keys
|
||||
GLFW_KEY_ESCAPE
|
||||
GLFW_KEY_ENTER
|
||||
GLFW_KEY_TAB
|
||||
GLFW_KEY_BACKSPACE
|
||||
GLFW_KEY_INSERT
|
||||
GLFW_KEY_DELETE
|
||||
GLFW_KEY_RIGHT
|
||||
GLFW_KEY_LEFT
|
||||
GLFW_KEY_DOWN
|
||||
GLFW_KEY_UP
|
||||
GLFW_KEY_PAGE_UP
|
||||
GLFW_KEY_PAGE_DOWN
|
||||
GLFW_KEY_HOME
|
||||
GLFW_KEY_END
|
||||
GLFW_KEY_CAPS_LOCK
|
||||
GLFW_KEY_SCROLL_LOCK
|
||||
GLFW_KEY_NUM_LOCK
|
||||
GLFW_KEY_PRINT_SCREEN
|
||||
GLFW_KEY_PAUSE
|
||||
GLFW_KEY_F1
|
||||
GLFW_KEY_F2
|
||||
GLFW_KEY_F3
|
||||
GLFW_KEY_F4
|
||||
GLFW_KEY_F5
|
||||
GLFW_KEY_F6
|
||||
GLFW_KEY_F7
|
||||
GLFW_KEY_F8
|
||||
GLFW_KEY_F9
|
||||
GLFW_KEY_F10
|
||||
GLFW_KEY_F11
|
||||
GLFW_KEY_F12
|
||||
GLFW_KEY_F13
|
||||
GLFW_KEY_F14
|
||||
GLFW_KEY_F15
|
||||
GLFW_KEY_F16
|
||||
GLFW_KEY_F17
|
||||
GLFW_KEY_F18
|
||||
GLFW_KEY_F19
|
||||
GLFW_KEY_F20
|
||||
GLFW_KEY_F21
|
||||
GLFW_KEY_F22
|
||||
GLFW_KEY_F23
|
||||
GLFW_KEY_F24
|
||||
GLFW_KEY_F25
|
||||
GLFW_KEY_KP_0
|
||||
GLFW_KEY_KP_1
|
||||
GLFW_KEY_KP_2
|
||||
GLFW_KEY_KP_3
|
||||
GLFW_KEY_KP_4
|
||||
GLFW_KEY_KP_5
|
||||
GLFW_KEY_KP_6
|
||||
GLFW_KEY_KP_7
|
||||
GLFW_KEY_KP_8
|
||||
GLFW_KEY_KP_9
|
||||
GLFW_KEY_KP_DECIMAL
|
||||
GLFW_KEY_KP_DIVIDE
|
||||
GLFW_KEY_KP_MULTIPLY
|
||||
GLFW_KEY_KP_SUBTRACT
|
||||
GLFW_KEY_KP_ADD
|
||||
GLFW_KEY_KP_ENTER
|
||||
GLFW_KEY_KP_EQUAL
|
||||
GLFW_KEY_LEFT_SHIFT
|
||||
GLFW_KEY_LEFT_CONTROL
|
||||
GLFW_KEY_LEFT_ALT
|
||||
GLFW_KEY_LEFT_SUPER
|
||||
GLFW_KEY_RIGHT_SHIFT
|
||||
GLFW_KEY_RIGHT_CONTROL
|
||||
GLFW_KEY_RIGHT_ALT
|
||||
GLFW_KEY_RIGHT_SUPER
|
||||
GLFW_KEY_MENU
|
||||
GLFW_KEY_LAST
|
||||
|
||||
# Mouse button definitions
|
||||
GLFW_MOUSE_BUTTON_1
|
||||
GLFW_MOUSE_BUTTON_2
|
||||
GLFW_MOUSE_BUTTON_3
|
||||
GLFW_MOUSE_BUTTON_4
|
||||
GLFW_MOUSE_BUTTON_5
|
||||
GLFW_MOUSE_BUTTON_6
|
||||
GLFW_MOUSE_BUTTON_7
|
||||
GLFW_MOUSE_BUTTON_8
|
||||
GLFW_MOUSE_BUTTON_LAST
|
||||
|
||||
# Mouse button aliases
|
||||
GLFW_MOUSE_BUTTON_LEFT
|
||||
GLFW_MOUSE_BUTTON_RIGHT
|
||||
GLFW_MOUSE_BUTTON_MIDDLE
|
||||
|
||||
# Joystick identifiers
|
||||
GLFW_JOYSTICK_1
|
||||
GLFW_JOYSTICK_2
|
||||
GLFW_JOYSTICK_3
|
||||
GLFW_JOYSTICK_4
|
||||
GLFW_JOYSTICK_5
|
||||
GLFW_JOYSTICK_6
|
||||
GLFW_JOYSTICK_7
|
||||
GLFW_JOYSTICK_8
|
||||
GLFW_JOYSTICK_9
|
||||
GLFW_JOYSTICK_10
|
||||
GLFW_JOYSTICK_11
|
||||
GLFW_JOYSTICK_12
|
||||
GLFW_JOYSTICK_13
|
||||
GLFW_JOYSTICK_14
|
||||
GLFW_JOYSTICK_15
|
||||
GLFW_JOYSTICK_16
|
||||
GLFW_JOYSTICK_LAST
|
||||
|
||||
# glfwCreateWindow modes
|
||||
GLFW_WINDOWED
|
||||
GLFW_FULLSCREEN
|
||||
|
||||
# glfwGetWindowParam tokens
|
||||
GLFW_ACTIVE
|
||||
GLFW_ICONIFIED
|
||||
GLFW_CLOSE_REQUESTED
|
||||
GLFW_OPENGL_REVISION
|
||||
|
||||
# glfwWindowHint tokens
|
||||
GLFW_RED_BITS
|
||||
GLFW_GREEN_BITS
|
||||
GLFW_BLUE_BITS
|
||||
GLFW_ALPHA_BITS
|
||||
GLFW_DEPTH_BITS
|
||||
GLFW_STENCIL_BITS
|
||||
GLFW_REFRESH_RATE
|
||||
GLFW_ACCUM_RED_BITS
|
||||
GLFW_ACCUM_GREEN_BITS
|
||||
GLFW_ACCUM_BLUE_BITS
|
||||
GLFW_ACCUM_ALPHA_BITS
|
||||
GLFW_AUX_BUFFERS
|
||||
GLFW_STEREO
|
||||
GLFW_FSAA_SAMPLES
|
||||
|
||||
# The following constants are used with both glfwGetWindowParam
|
||||
# and glfwWindowHint
|
||||
GLFW_CLIENT_API
|
||||
GLFW_OPENGL_VERSION_MAJOR
|
||||
GLFW_OPENGL_VERSION_MINOR
|
||||
GLFW_OPENGL_FORWARD_COMPAT
|
||||
GLFW_OPENGL_DEBUG_CONTEXT
|
||||
GLFW_OPENGL_PROFILE
|
||||
GLFW_OPENGL_ROBUSTNESS
|
||||
GLFW_RESIZABLE
|
||||
GLFW_VISIBLE
|
||||
|
||||
# GLFW_CLIENT_API tokens
|
||||
GLFW_OPENGL_API
|
||||
GLFW_OPENGL_ES_API
|
||||
|
||||
# GLFW_OPENGL_ROBUSTNESS mode tokens
|
||||
GLFW_OPENGL_NO_ROBUSTNESS
|
||||
GLFW_OPENGL_NO_RESET_NOTIFICATION
|
||||
GLFW_OPENGL_LOSE_CONTEXT_ON_RESET
|
||||
|
||||
# GLFW_OPENGL_PROFILE bit tokens
|
||||
GLFW_OPENGL_NO_PROFILE
|
||||
GLFW_OPENGL_CORE_PROFILE
|
||||
GLFW_OPENGL_COMPAT_PROFILE
|
||||
|
||||
# glfwGetInputMode/glfwSetInputMode tokens
|
||||
GLFW_CURSOR_MODE
|
||||
GLFW_STICKY_KEYS
|
||||
GLFW_STICKY_MOUSE_BUTTONS
|
||||
GLFW_SYSTEM_KEYS
|
||||
GLFW_KEY_REPEAT
|
||||
|
||||
# GLFW_CURSOR_MODE values
|
||||
GLFW_CURSOR_NORMAL
|
||||
GLFW_CURSOR_HIDDEN
|
||||
GLFW_CURSOR_CAPTURED
|
||||
|
||||
# glfwGetJoystickParam tokens
|
||||
GLFW_PRESENT
|
||||
GLFW_AXES
|
||||
GLFW_BUTTONS
|
||||
|
||||
# glfwGetError/glfwErrorString tokens
|
||||
GLFW_NO_ERROR
|
||||
GLFW_NOT_INITIALIZED
|
||||
GLFW_NO_CURRENT_CONTEXT
|
||||
GLFW_INVALID_ENUM
|
||||
GLFW_INVALID_VALUE
|
||||
GLFW_OUT_OF_MEMORY
|
||||
GLFW_OPENGL_UNAVAILABLE
|
||||
GLFW_VERSION_UNAVAILABLE
|
||||
GLFW_PLATFORM_ERROR
|
||||
GLFW_WINDOW_NOT_ACTIVE
|
||||
GLFW_FORMAT_UNAVAILABLE
|
||||
|
||||
# Gamma ramps
|
||||
GLFW_GAMMA_RAMP_SIZE
|
||||
|
||||
# OpenGL function pointer type
|
||||
ctypedef void (*GLFWglproc)()
|
||||
|
||||
# Window handle type
|
||||
ctypedef void* GLFWwindow
|
||||
|
||||
# Function pointer types
|
||||
ctypedef void (* GLFWerrorfun)(int,char*)
|
||||
ctypedef void (* GLFWwindowsizefun)(GLFWwindow,int,int)
|
||||
ctypedef int (* GLFWwindowclosefun)(GLFWwindow)
|
||||
ctypedef void (* GLFWwindowrefreshfun)(GLFWwindow)
|
||||
ctypedef void (* GLFWwindowfocusfun)(GLFWwindow,int)
|
||||
ctypedef void (* GLFWwindowiconifyfun)(GLFWwindow,int)
|
||||
ctypedef void (* GLFWmousebuttonfun)(GLFWwindow,int,int)
|
||||
ctypedef void (* GLFWcursorposfun)(GLFWwindow,int,int)
|
||||
ctypedef void (* GLFWcursorenterfun)(GLFWwindow,int)
|
||||
ctypedef void (* GLFWscrollfun)(GLFWwindow,double,double)
|
||||
ctypedef void (* GLFWkeyfun)(GLFWwindow,int,int)
|
||||
ctypedef void (* GLFWcharfun)(GLFWwindow,int)
|
||||
|
||||
|
||||
# The video mode structure used by glfwGetVideoModes
|
||||
cdef struct _GLFWvidmode:
|
||||
int width
|
||||
int height
|
||||
int redBits
|
||||
int blueBits
|
||||
int greenBits
|
||||
|
||||
ctypedef _GLFWvidmode GLFWvidmode
|
||||
|
||||
# Gamma ramp
|
||||
cdef struct _GLFWgammaramp:
|
||||
unsigned short red[GLFW_GAMMA_RAMP_SIZE]
|
||||
unsigned short green[GLFW_GAMMA_RAMP_SIZE]
|
||||
unsigned short blue[GLFW_GAMMA_RAMP_SIZE]
|
||||
|
||||
ctypedef _GLFWgammaramp GLFWgammaramp
|
||||
|
||||
# Initialization, termination and version querying
|
||||
int glfwInit()
|
||||
void glfwTerminate()
|
||||
void glfwGetVersion(int* major, int* minor, int* rev)
|
||||
char* glfwGetVersionString()
|
||||
|
||||
# Error handling
|
||||
int glfwGetError()
|
||||
char* glfwErrorString(int error)
|
||||
void glfwSetErrorCallback(GLFWerrorfun cbfun)
|
||||
|
||||
# Video mode functions
|
||||
GLFWvidmode* glfwGetVideoModes(int* count)
|
||||
void glfwGetDesktopMode(GLFWvidmode* mode)
|
||||
|
||||
# Gamma ramp functions
|
||||
void glfwSetGamma(float gamma)
|
||||
void glfwGetGammaRamp(GLFWgammaramp* ramp)
|
||||
void glfwSetGammaRamp(GLFWgammaramp* ramp)
|
||||
|
||||
# Window handling
|
||||
void glfwWindowHint(int target, int hint)
|
||||
GLFWwindow glfwCreateWindow(int width, int height, int mode, char* title, GLFWwindow share)
|
||||
void glfwDestroyWindow(GLFWwindow window)
|
||||
void glfwSetWindowTitle(GLFWwindow window, char* title)
|
||||
void glfwGetWindowSize(GLFWwindow window, int* width, int* height)
|
||||
void glfwSetWindowSize(GLFWwindow window, int width, int height)
|
||||
void glfwGetWindowPos(GLFWwindow window, int* xpos, int* ypos)
|
||||
void glfwSetWindowPos(GLFWwindow window, int xpos, int ypos)
|
||||
void glfwIconifyWindow(GLFWwindow window)
|
||||
void glfwRestoreWindow(GLFWwindow window)
|
||||
void glfwShowWindow(GLFWwindow window)
|
||||
void glfwHideWindow(GLFWwindow window)
|
||||
int glfwGetWindowParam(GLFWwindow window, int param)
|
||||
void glfwSetWindowUserPointer(GLFWwindow window, void* pointer)
|
||||
void* glfwGetWindowUserPointer(GLFWwindow window)
|
||||
void glfwSetWindowSizeCallback(GLFWwindowsizefun cbfun)
|
||||
void glfwSetWindowCloseCallback(GLFWwindowclosefun cbfun)
|
||||
void glfwSetWindowRefreshCallback(GLFWwindowrefreshfun cbfun)
|
||||
void glfwSetWindowFocusCallback(GLFWwindowfocusfun cbfun)
|
||||
void glfwSetWindowIconifyCallback(GLFWwindowiconifyfun cbfun)
|
||||
|
||||
# Event handling
|
||||
void glfwPollEvents()
|
||||
void glfwWaitEvents()
|
||||
|
||||
# Input handling
|
||||
int glfwGetInputMode(GLFWwindow window, int mode)
|
||||
void glfwSetInputMode(GLFWwindow window, int mode, int value)
|
||||
int glfwGetKey(GLFWwindow window, int key)
|
||||
int glfwGetMouseButton(GLFWwindow window, int button)
|
||||
void glfwGetCursorPos(GLFWwindow window, int* xpos, int* ypos)
|
||||
void glfwSetCursorPos(GLFWwindow window, int xpos, int ypos)
|
||||
void glfwGetScrollOffset(GLFWwindow window, double* xoffset, double* yoffset)
|
||||
void glfwSetKeyCallback(GLFWkeyfun cbfun)
|
||||
void glfwSetCharCallback(GLFWcharfun cbfun)
|
||||
void glfwSetMouseButtonCallback(GLFWmousebuttonfun cbfun)
|
||||
void glfwSetCursorPosCallback(GLFWcursorposfun cbfun)
|
||||
void glfwSetCursorEnterCallback(GLFWcursorenterfun cbfun)
|
||||
void glfwSetScrollCallback(GLFWscrollfun cbfun)
|
||||
|
||||
# Joystick input
|
||||
int glfwGetJoystickParam(int joy, int param)
|
||||
int glfwGetJoystickAxes(int joy, float* axes, int numaxes)
|
||||
int glfwGetJoystickButtons(int joy, unsigned char* buttons, int numbuttons)
|
||||
|
||||
# Clipboard
|
||||
void glfwSetClipboardString(GLFWwindow window, char* string)
|
||||
char* glfwGetClipboardString(GLFWwindow window)
|
||||
|
||||
# Time
|
||||
double glfwGetTime()
|
||||
void glfwSetTime(double time)
|
||||
|
||||
# OpenGL support
|
||||
void glfwMakeContextCurrent(GLFWwindow window)
|
||||
GLFWwindow glfwGetCurrentContext()
|
||||
void glfwSwapBuffers(GLFWwindow window)
|
||||
void glfwSwapInterval(int interval)
|
||||
int glfwExtensionSupported(char* extension)
|
||||
GLFWglproc glfwGetProcAddress(char* procname)
|
||||
void glfwCopyContext(GLFWwindow src, GLFWwindow dst, unsigned long mask)
|
||||
41
gltools/@src/imguiLib.pxd
Normal file
41
gltools/@src/imguiLib.pxd
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
cdef extern from "imguiRenderGL.h":
|
||||
bint imguiRenderGLInit()
|
||||
void imguiRenderGLDraw()
|
||||
|
||||
cdef extern from "imgui.h":
|
||||
cdef enum imguiMouseButton:
|
||||
IMGUI_MBUT_LEFT
|
||||
IMGUI_MBUT_RIGHT
|
||||
|
||||
cdef enum imguiTextAlign:
|
||||
IMGUI_ALIGN_LEFT
|
||||
IMGUI_ALIGN_CENTER
|
||||
IMGUI_ALIGN_RIGHT
|
||||
|
||||
unsigned int imguiRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
|
||||
|
||||
bint imguiAnyActive()
|
||||
void imguiBeginFrame(int mx, int my, unsigned char mbut, int scroll)
|
||||
void imguiEndFrame()
|
||||
|
||||
bint imguiBeginScrollArea(char* name, int x, int y, int w, int h, int* scroll)
|
||||
void imguiEndScrollArea()
|
||||
|
||||
void imguiIndent()
|
||||
void imguiUnindent()
|
||||
void imguiSeparator()
|
||||
void imguiSeparatorLine()
|
||||
|
||||
bint imguiButton(char* text, bint enabled)
|
||||
bint imguiItem(char* text, bint enabled)
|
||||
bint imguiCheck(char* text, bint checked, bint enabled)
|
||||
bint imguiCollapse(char* text, char* subtext, bint checked, bint enabled)
|
||||
void imguiLabel(char* text)
|
||||
void imguiValue(char* text)
|
||||
bint imguiSlider(char* text, float* val, float vmin, float vmax, float vinc, bint enabled)
|
||||
|
||||
void imguiDrawText(int x, int y, int align, char* text, unsigned int color)
|
||||
void imguiDrawLine(float x0, float y0, float x1, float y1, float r, unsigned int color)
|
||||
void imguiDrawRoundedRect(float x, float y, float w, float h, float r, unsigned int color)
|
||||
void imguiDrawRect(float x, float y, float w, float h, unsigned int color)
|
||||
|
||||
25
gltools/Makefile
Normal file
25
gltools/Makefile
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#
|
||||
# File: Makefile (for library)
|
||||
#
|
||||
PYTHON=python2
|
||||
|
||||
.PHONY: all docs test install clean
|
||||
|
||||
all:
|
||||
@echo lib Makefile - building python extension
|
||||
$(PYTHON) setup_build.py build_ext --inplace
|
||||
-strip --strip-all gltools.so
|
||||
|
||||
docs: all
|
||||
@echo lib Makefile - building documentation
|
||||
@cd @docs ; $(PYTHON) ../setup_docs.py build_sphinx
|
||||
@cp -rf @docs/build/sphinx/html/* @docs/html/
|
||||
|
||||
install: all
|
||||
@cp gltools.so ~/.local/lib/python2.7/site-packages/
|
||||
@cp gltools.pxd ~/.local/lib/python2.7/site-packages/
|
||||
|
||||
clean:
|
||||
-rm -rf build
|
||||
-rm gltools.cpp
|
||||
-rm gltools.so
|
||||
139
gltools/gltools.pxd
Normal file
139
gltools/gltools.pxd
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This file is part of gltools - See LICENSE.txt
|
||||
#
|
||||
from geotools cimport Point, Transform
|
||||
|
||||
cdef class ColorRGBA:
|
||||
cdef readonly unsigned char red
|
||||
cdef readonly unsigned char green
|
||||
cdef readonly unsigned char blue
|
||||
cdef readonly unsigned char alpha
|
||||
cpdef ColorRGBA copy(self, int red = ?, int green = ?, int blue = ?, alpha = ?)
|
||||
cpdef unsigned toInt(self)
|
||||
cpdef tuple toFloatVector(self)
|
||||
cdef setFloatVector(self, float *vec)
|
||||
|
||||
cdef class Material:
|
||||
cdef public ColorRGBA ambient
|
||||
cdef public ColorRGBA diffuse
|
||||
cdef public ColorRGBA specular
|
||||
cdef public ColorRGBA emissive
|
||||
cdef public float shininess
|
||||
cdef readonly int mode
|
||||
cpdef enable(self)
|
||||
|
||||
cdef class Light:
|
||||
cdef public Material material
|
||||
cdef public Point position
|
||||
cdef public bint directional
|
||||
cdef readonly int index
|
||||
cpdef enable(self)
|
||||
cpdef disable(self)
|
||||
|
||||
cdef class ClientBuffer:
|
||||
cdef void *thisptr
|
||||
cpdef bind(self)
|
||||
cpdef unBind(self)
|
||||
cpdef setDataType(self, int type, int dataType, int dataTypeSize,
|
||||
int stride, size_t pointer)
|
||||
cdef cloadData(self, void *data, ssize_t size, ssize_t offset, int usage)
|
||||
cpdef loadData(self, data, ssize_t size, ssize_t offset = ?, int usage = ?)
|
||||
|
||||
cpdef Init()
|
||||
cpdef double getTime()
|
||||
cpdef SetTime(double time)
|
||||
cpdef SetGamma(float gamma)
|
||||
cpdef tuple GetDesktopSize()
|
||||
|
||||
cdef class Window:
|
||||
cdef void *thisptr
|
||||
cdef public bint running
|
||||
cpdef setTitle(self, title)
|
||||
cpdef tuple getSize(self)
|
||||
cpdef setSize(self, int width, int height)
|
||||
cpdef tuple getPos(self)
|
||||
cpdef setPos(self, int x, int y)
|
||||
cpdef setClipboard(self, content)
|
||||
cpdef getClipboard(self)
|
||||
cpdef iconify(self)
|
||||
cpdef restore(self)
|
||||
cpdef show(self)
|
||||
cpdef hide(self)
|
||||
cpdef close(self)
|
||||
cpdef makeContextCurrent(self)
|
||||
cpdef swapBuffers(self)
|
||||
cpdef mainLoop(self)
|
||||
cpdef onSize(self, int w, int h)
|
||||
cpdef onRefresh(self)
|
||||
cpdef onCursorPos(self, int x, int y)
|
||||
cpdef onMouseButton(self, int button, int action)
|
||||
cpdef onKey(self, int key, int action)
|
||||
cpdef onChar(self, ch)
|
||||
cpdef onFocus(self, int status)
|
||||
cpdef onEnter(self, int status)
|
||||
cpdef onScroll(self, double dx, double dy)
|
||||
cpdef onIconify(self, int status)
|
||||
cpdef bint onClose(self)
|
||||
|
||||
cdef class ShaderProgram:
|
||||
cdef void *thisptr
|
||||
cpdef bint isValid(self)
|
||||
cpdef begin(self)
|
||||
cpdef end(self)
|
||||
cpdef loadUniform1i(self, char *name, int value)
|
||||
cpdef loadUniform1f(self, char *name, float value)
|
||||
cpdef loadUniform4f(self, char *name, float v0, float v1, float v2, float v3)
|
||||
cpdef loadUniformMatrix4vf(self, char *name, float [::1] value, int count = ?)
|
||||
cpdef build(self, vertex_src = ?, fragment_src = ?)
|
||||
|
||||
cpdef BeginText()
|
||||
cpdef float DrawText(size, float x, float y, text)
|
||||
cpdef EndText()
|
||||
|
||||
cdef class UI:
|
||||
cdef int scroll[10]
|
||||
cdef int scrollIdx
|
||||
|
||||
cpdef bint anyActive(self)
|
||||
cpdef flush(self)
|
||||
cpdef beginFrame(self, int mx, int my, char mbut, int scroll)
|
||||
cpdef endFrame(self)
|
||||
cpdef bint beginScrollArea(self, name, int x, int y, int w, int h)
|
||||
cpdef endScrollArea(self)
|
||||
cpdef indent(self)
|
||||
cpdef unindent(self)
|
||||
cpdef separator(self)
|
||||
cpdef separatorLine(self)
|
||||
cpdef bint button(self, text, bint enabled)
|
||||
cpdef bint item(self, text, bint enabled)
|
||||
cpdef bint check(self, text, bint checked, bint enabled)
|
||||
cpdef bint collapse(self, text, char* subtext, bint checked, bint enabled)
|
||||
cpdef label(self, text)
|
||||
cpdef value(self, text)
|
||||
cpdef float slider(self, text, float val, float vmin, float vmax,
|
||||
float vinc, bint enabled)
|
||||
cpdef drawText(self, int x, int y, int align, text, ColorRGBA color)
|
||||
cpdef drawLine(self, float x0, float y0, float x1, float y1, float r, ColorRGBA color)
|
||||
cpdef drawRoundedRect(self, float x, float y, float w, float h, float r, ColorRGBA color)
|
||||
cpdef drawRect(self, float x, float y, float w, float h, ColorRGBA color)
|
||||
|
||||
cpdef InitGLExt()
|
||||
cpdef BlendFunc(unsigned int sfactor, unsigned int dfactor)
|
||||
cpdef Clear(unsigned int mask)
|
||||
cpdef ClearColor(ColorRGBA col)
|
||||
cpdef ClearDepth(double depth)
|
||||
cpdef Color(ColorRGBA col)
|
||||
cpdef Disable(unsigned int cap)
|
||||
cpdef DrawArrays(unsigned int mode, int first, int count)
|
||||
cpdef DrawElements(unsigned int mode, int count, int type, indices)
|
||||
cpdef Enable(unsigned int cap)
|
||||
cpdef LineWidth(float width)
|
||||
cpdef LightModeli(int pname, int param)
|
||||
cpdef LoadIdentity()
|
||||
cpdef LoadMatrixd(Transform tr)
|
||||
cpdef MatrixMode(unsigned int mode)
|
||||
cpdef Ortho(double left, double right, double bottom, double top, double zNear,
|
||||
double zFar)
|
||||
cpdef PolygonMode(unsigned int face, unsigned int mode)
|
||||
cpdef Viewport(int x, int y, int width, int height)
|
||||
37
gltools/gltools.pyx
Normal file
37
gltools/gltools.pyx
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#cython: embedsignature=True
|
||||
#
|
||||
# This file is part of gltools - See LICENSE.txt
|
||||
#
|
||||
from geotools cimport *
|
||||
from GLToolsLib cimport *
|
||||
|
||||
class GLError(Exception):
|
||||
pass
|
||||
|
||||
include "Utilities.pxi"
|
||||
include "Constants.pxi"
|
||||
include "GLFW.pxi"
|
||||
include "Color.pxi"
|
||||
include "GL.pxi"
|
||||
include "ClientBuffer.pxi"
|
||||
include "ShaderProgram.pxi"
|
||||
include "Text.pxi"
|
||||
include "UI.pxi"
|
||||
|
||||
def test2d(double [:, ::1] arr):
|
||||
for row in range(4):
|
||||
for col in range(4):
|
||||
print row, col, arr[row][col]
|
||||
print
|
||||
print
|
||||
|
||||
def test1d(double [:] vec):
|
||||
for col in range(4):
|
||||
print col, vec[col]
|
||||
print
|
||||
|
||||
def test1f(float [:] vec):
|
||||
for col in range(4):
|
||||
print col, vec[col]
|
||||
print
|
||||
36
gltools/setup_build.py
Normal file
36
gltools/setup_build.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#!/usr/bin/python2
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This file is part of gltools - See LICENSE.txt
|
||||
#
|
||||
import sys
|
||||
import os
|
||||
import glob
|
||||
|
||||
from distutils.core import setup
|
||||
from distutils.extension import Extension
|
||||
from Cython.Distutils import build_ext
|
||||
|
||||
try:
|
||||
setup(
|
||||
name = 'gltools',
|
||||
ext_modules=[
|
||||
Extension("gltools",
|
||||
sources=["gltools.pyx", "@src/GLTools.cpp", "@contrib/fontstash.c",
|
||||
"@contrib/imgui.cpp", "@contrib/imguiRenderGL.cpp"],
|
||||
depends = ["gltools.pxd",] + glob.glob("@src/*.pxi") + \
|
||||
glob.glob("@src/*.pxd") + glob.glob("@src/*.h"),
|
||||
include_dirs = ['@src','@contrib'],
|
||||
libraries = ["GL", "glfw"],
|
||||
extra_compile_args = ["-fpermissive"],
|
||||
language="c++"
|
||||
),
|
||||
],
|
||||
|
||||
cmdclass = {'build_ext': build_ext}
|
||||
)
|
||||
except:
|
||||
print('Traceback\n:%s\n' % str(sys.exc_info()[-2]))
|
||||
sys.exit(1)
|
||||
else:
|
||||
print('\n')
|
||||
366
gltools/test.py
Normal file
366
gltools/test.py
Normal file
|
|
@ -0,0 +1,366 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
import array
|
||||
import geotools as geo
|
||||
import gltools as gl
|
||||
|
||||
# cube
|
||||
# v6----- v5
|
||||
# /| /|
|
||||
# v1------v0|
|
||||
# | | | |
|
||||
# | |v7---|-|v4
|
||||
# |/ |/
|
||||
# v2------v3
|
||||
|
||||
vertices = array.array('f',(
|
||||
1, 1, 1, -1, 1, 1, -1,-1, 1, 1,-1, 1, # v0,v1,v2,v3 (front)
|
||||
1, 1, 1, 1,-1, 1, 1,-1,-1, 1, 1,-1, # v0,v3,v4,v5 (right)
|
||||
1, 1, 1, 1, 1,-1, -1, 1,-1, -1, 1, 1, # v0,v5,v6,v1 (top)
|
||||
-1, 1, 1, -1, 1,-1, -1,-1,-1, -1,-1, 1, # v1,v6,v7,v2 (left)
|
||||
-1,-1,-1, 1,-1,-1, 1,-1, 1, -1,-1, 1, # v7,v4,v3,v2 (bottom)
|
||||
1,-1,-1, -1,-1,-1, -1, 1,-1, 1, 1,-1, # v4,v7,v6,v5 (back)
|
||||
))
|
||||
|
||||
normals = array.array('f',(
|
||||
0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, # v0,v1,v2,v3 (front)
|
||||
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, # v0,v3,v4,v5 (right)
|
||||
0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, # v0,v5,v6,v1 (top)
|
||||
-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, # v1,v6,v7,v2 (left)
|
||||
0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, # v7,v4,v3,v2 (bottom)
|
||||
0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, # v4,v7,v6,v5 (back)
|
||||
))
|
||||
|
||||
colors = array.array('f',(
|
||||
1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, # v0,v1,v2,v3 (front)
|
||||
1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, # v0,v3,v4,v5 (right)
|
||||
1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, # v0,v5,v6,v1 (top)
|
||||
1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, # v1,v6,v7,v2 (left)
|
||||
0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, # v7,v4,v3,v2 (bottom)
|
||||
0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, # v4,v7,v6,v5 (back)
|
||||
))
|
||||
|
||||
indices = array.array('B',(
|
||||
0, 1, 2, 2, 3, 0, # front
|
||||
4, 5, 6, 6, 7, 4, # right
|
||||
8, 9,10, 10,11, 8, # top
|
||||
12,13,14, 14,15,12, # left
|
||||
16,17,18, 18,19,16, # bottom
|
||||
20,21,22, 22,23,20, # back
|
||||
))
|
||||
|
||||
GLSL_VERTEX = \
|
||||
"""
|
||||
varying vec3 vN;
|
||||
varying vec3 v;
|
||||
void main(void)
|
||||
{
|
||||
v = vec3(gl_ModelViewMatrix * gl_Vertex);
|
||||
vN = normalize(gl_NormalMatrix * gl_Normal);
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
}
|
||||
"""
|
||||
|
||||
GLSL_FRAG = \
|
||||
"""
|
||||
varying vec3 vN;
|
||||
varying vec3 v;
|
||||
|
||||
#define MAX_LIGHTS 3
|
||||
void main (void)
|
||||
{
|
||||
vec3 N = normalize(vN);
|
||||
vec4 finalColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
for (int i=0;i<MAX_LIGHTS;i++)
|
||||
{
|
||||
vec3 L = normalize(gl_LightSource[i].position.xyz - v);
|
||||
vec3 E = normalize(-v); // we are in Eye Coordinates, so EyePos is (0,0,0)
|
||||
vec3 R = normalize(-reflect(L,N));
|
||||
|
||||
//calculate Ambient Term:
|
||||
vec4 Iamb = gl_FrontLightProduct[i].ambient;
|
||||
//calculate Diffuse Term:
|
||||
vec4 Idiff = gl_FrontLightProduct[i].diffuse * max(dot(N,L), 0.0);
|
||||
Idiff = clamp(Idiff, 0.0, 1.0);
|
||||
|
||||
// calculate Specular Term:
|
||||
vec4 Ispec = gl_FrontLightProduct[i].specular
|
||||
* pow(max(dot(R,E),0.0),0.3*gl_FrontMaterial.shininess);
|
||||
Ispec = clamp(Ispec, 0.0, 1.0);
|
||||
|
||||
finalColor += Iamb + Idiff + Ispec;
|
||||
}
|
||||
|
||||
// write Total Color:
|
||||
gl_FragColor = gl_FrontLightModelProduct.sceneColor + finalColor;
|
||||
}
|
||||
"""
|
||||
|
||||
class MainWindow(gl.Window):
|
||||
def __init__(self, width, height, title):
|
||||
self.initialized = False
|
||||
|
||||
self.cam = geo.Camera()
|
||||
self.near = geo.Point(-2.,-2.,-2.)
|
||||
self.far = geo.Point(2.,2.,2.)
|
||||
|
||||
self.lastPos = 0,0
|
||||
self.currentButton = -1
|
||||
|
||||
gl.Window.__init__(self, width, height, title)
|
||||
|
||||
self.projectionMatrix = geo.Transform()
|
||||
self.modelviewMatrix = geo.Transform()
|
||||
|
||||
def onSetup(self):
|
||||
self.ui = gl.UI()
|
||||
gl.ClearColor(gl.ColorRGBA(38,38,102,255))
|
||||
gl.ClearDepth(1.)
|
||||
|
||||
gl.InitGLExt()
|
||||
|
||||
# Material & lights
|
||||
mat = self.mat = gl.Material(
|
||||
ambient = gl.ColorRGBA(80,80,80,255),
|
||||
diffuse = gl.ColorRGBA(45,45,45,255),
|
||||
specular = gl.ColorRGBA(255,255,255,255),
|
||||
shininess = 100.,
|
||||
)
|
||||
|
||||
lightMat = gl.Material(
|
||||
diffuse = gl.ColorRGBA(255,255,55,255),
|
||||
ambient = gl.ColorRGBA(55,55,25,255),
|
||||
specular = gl.ColorRGBA(255,255,255,255)
|
||||
)
|
||||
|
||||
light0 = self.light0 = gl.Light(
|
||||
0,
|
||||
lightMat,
|
||||
geo.Point(0.,50.,100.),
|
||||
)
|
||||
|
||||
light1 = self.light1 = gl.Light(
|
||||
1,
|
||||
lightMat,
|
||||
geo.Point(50.,0.,-100.),
|
||||
)
|
||||
|
||||
light2 = self.light2 = gl.Light(
|
||||
2,
|
||||
lightMat,
|
||||
geo.Point(0.,-50.,0.),
|
||||
)
|
||||
|
||||
# GLSL
|
||||
glsl = self.program = gl.ShaderProgram()
|
||||
glsl.build(GLSL_VERTEX, GLSL_FRAG)
|
||||
|
||||
# mesh
|
||||
fsize = vertices.itemsize
|
||||
buffer = self.buffer = gl.ClientBuffer()
|
||||
buffer.loadData(None, (len(vertices) + len(normals))*fsize)
|
||||
|
||||
offset = 0
|
||||
size = len(vertices)*fsize
|
||||
buffer.setDataType(gl.VERTEX_ARRAY, gl.FLOAT, 3, 0, 0)
|
||||
buffer.loadData(vertices, size, offset) # copy vertices starting from 0 offest
|
||||
offset += size
|
||||
|
||||
size = len(normals)*fsize
|
||||
buffer.setDataType(gl.NORMAL_ARRAY, gl.FLOAT, 3, 0, offset)
|
||||
buffer.loadData(normals, size, offset) # copy normals after vertices
|
||||
offset += size
|
||||
|
||||
# index buffer
|
||||
idxbuffer = self.idxbuffer = gl.ClientBuffer(gl.ELEMENT_ARRAY_BUFFER)
|
||||
idxbuffer.loadData(indices, len(indices)*indices.itemsize)
|
||||
|
||||
|
||||
def onSize(self, w, h):
|
||||
#print 'onSize ', w, h
|
||||
self.width, self.height = w - 1, h - 1
|
||||
|
||||
if self.width > 1 and self.height > 1:
|
||||
# Adjust frustum to viewport aspect
|
||||
frustum_aspect = float(self.width) / self.height
|
||||
self.cam.setFrustumAspect(frustum_aspect)
|
||||
self.cam.setViewportSize(self.width, self.height)
|
||||
|
||||
self.makeContextCurrent()
|
||||
gl.Viewport(0, 0, self.width, self.height)
|
||||
|
||||
# initialize
|
||||
if not self.initialized:
|
||||
self.onSetup()
|
||||
self.cam.zoomExtents(self.near, self.far)
|
||||
self.initialized = True
|
||||
|
||||
def insideUI(self, x, y):
|
||||
y = self.height - y
|
||||
|
||||
if x >= 10 and x <= 200:
|
||||
if y >= 10 and y <= self.height - 300:
|
||||
return True
|
||||
return False
|
||||
|
||||
def onRefresh(self):
|
||||
#print 'onRefresh'
|
||||
if not self.running:
|
||||
return
|
||||
|
||||
ui = self.ui
|
||||
glsl = self.program
|
||||
x, y = self.lastPos
|
||||
w, h = self.width, self.height
|
||||
|
||||
self.makeContextCurrent()
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
||||
|
||||
gl.Enable(gl.DEPTH_TEST)
|
||||
gl.Enable(gl.MULTISAMPLE)
|
||||
gl.Enable(gl.DITHER)
|
||||
gl.Disable(gl.BLEND)
|
||||
gl.Disable(gl.CULL_FACE)
|
||||
gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL)
|
||||
gl.LightModeli(gl.LIGHT_MODEL_TWO_SIDE, gl.TRUE)
|
||||
|
||||
gl.MatrixMode(gl.PROJECTION)
|
||||
self.projectionMatrix.cameraToClip(self.cam)
|
||||
gl.LoadMatrixd(self.projectionMatrix)
|
||||
|
||||
gl.MatrixMode(gl.MODELVIEW)
|
||||
self.modelviewMatrix.worldToCamera(self.cam)
|
||||
gl.LoadMatrixd(self.modelviewMatrix)
|
||||
|
||||
gl.Enable(gl.LIGHTING)
|
||||
self.light0.enable()
|
||||
self.light1.enable()
|
||||
self.light2.enable()
|
||||
self.mat.enable()
|
||||
|
||||
glsl.begin()
|
||||
self.buffer.bind()
|
||||
self.idxbuffer.bind()
|
||||
gl.DrawElements(gl.TRIANGLES, 36, gl.UNSIGNED_BYTE, 0)
|
||||
self.buffer.unBind()
|
||||
self.idxbuffer.unBind()
|
||||
glsl.end()
|
||||
|
||||
# draw font overlay
|
||||
gl.Disable(gl.DEPTH_TEST)
|
||||
gl.Disable(gl.LIGHTING)
|
||||
gl.Disable(gl.DITHER)
|
||||
gl.Enable(gl.BLEND)
|
||||
gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
|
||||
|
||||
gl.MatrixMode(gl.PROJECTION)
|
||||
gl.LoadIdentity()
|
||||
gl.Ortho(0,self.width,0,self.height,-1,1)
|
||||
gl.MatrixMode(gl.MODELVIEW)
|
||||
gl.LoadIdentity()
|
||||
|
||||
ui.beginFrame(x,h - y,self.currentButton,0)
|
||||
ui.beginScrollArea("Scroll Area", 10, 10, 200, h-300)
|
||||
|
||||
ui.label('Label test')
|
||||
|
||||
ui.value(u'Value æøå')
|
||||
ui.separatorLine()
|
||||
ui.item('Item 1', True)
|
||||
ui.indent()
|
||||
ui.item('Item 2', False)
|
||||
ui.separator()
|
||||
ui.item('Item 3', True)
|
||||
ui.unindent()
|
||||
if ui.button("Button 1", True):
|
||||
print 'Button 1 pressed'
|
||||
|
||||
ui.button("Button 2", False)
|
||||
ui.separator()
|
||||
ui.check("Check 1", True, True)
|
||||
ui.check("Check 2", False, True)
|
||||
ui.check("Check 3", False, False)
|
||||
ui.separatorLine()
|
||||
ui.slider('Slider 1', 5, 0, 10, 1, True)
|
||||
ui.slider('Slider 2', 5, 0, 10, 1, False)
|
||||
ui.separatorLine()
|
||||
ui.collapse('Text line', 'Sub text line', True, True)
|
||||
ui.collapse('Text line', 'Sub text line', False, True)
|
||||
|
||||
ui.endScrollArea()
|
||||
ui.endFrame()
|
||||
ui.flush()
|
||||
|
||||
gl.Enable(gl.DEPTH_TEST)
|
||||
|
||||
self.swapBuffers()
|
||||
|
||||
def onCursorPos(self, x, y):
|
||||
width, height = self.width, self.height
|
||||
lastx,lasty = self.lastPos
|
||||
cam = self.cam
|
||||
|
||||
ui = self.insideUI(x, y)
|
||||
|
||||
if not ui and self.currentButton == gl.MOUSE.LEFT:
|
||||
# rotate view
|
||||
dx = x - lastx
|
||||
dy = y - lasty
|
||||
|
||||
if dx != 0:
|
||||
cam.rotateCamera(0.001*dx, geo.Vector(0.,0.,1.), cam.target)
|
||||
|
||||
if dy != 0:
|
||||
cam.rotateCamera(0.001*dy, cam.X, cam.target)
|
||||
|
||||
elif not ui and self.currentButton == gl.MOUSE.RIGHT:
|
||||
# pan view
|
||||
d = geo.dot(geo.Vector(cam.Loc - cam.target), cam.Z)
|
||||
dolly_vector = cam.getDollyCameraVector(lastx,lasty,x,y,d)
|
||||
cam.Loc += dolly_vector
|
||||
|
||||
#print 'onCursorPos ', x, y
|
||||
self.lastPos = x, y
|
||||
self.onRefresh()
|
||||
|
||||
def onMouseButton(self, button, action):
|
||||
#print 'onMouseButton ', button, action
|
||||
if action == gl.ACTION.PRESS:
|
||||
if button in {gl.MOUSE.LEFT, gl.MOUSE.RIGHT}:
|
||||
self.currentButton = button
|
||||
else:
|
||||
self.currentButton = -1
|
||||
|
||||
self.onRefresh()
|
||||
|
||||
def onKey(self, key, action):
|
||||
#print 'onKey ', key, action
|
||||
if key == gl.KEY.ESCAPE:
|
||||
self.running = False
|
||||
|
||||
def onChar(self, ch):
|
||||
#print 'onChar ', ch
|
||||
if ch == 'f':
|
||||
self.cam.zoomExtents(self.near, self.far)
|
||||
self.onRefresh()
|
||||
|
||||
def onScroll(self, scx, scy):
|
||||
x, y = self.lastPos
|
||||
|
||||
if self.insideUI(x, y):
|
||||
return
|
||||
|
||||
delta = 1e-4*scy
|
||||
dx = delta*self.width
|
||||
dy = delta*self.height
|
||||
|
||||
self.cam.zoomFactor(1. + max(dx,dy), (x, y))
|
||||
self.onRefresh()
|
||||
|
||||
def onClose(self):
|
||||
#print 'onClose'
|
||||
return True
|
||||
|
||||
win = MainWindow(800, 600, title = u'title')
|
||||
win.mainLoop()
|
||||
Loading…
Reference in a new issue