Add ShaderVG, a shader based version of ShivaVG
All FlighGear specific patches applied to ShivaVG are also applied to ShaderVG, if appropriate. For testing only for now, it is not yet fully functional.
This commit is contained in:
parent
c1179f2e3b
commit
6451e505d8
504
simgear/canvas/ShaderVG/COPYING
Normal file
504
simgear/canvas/ShaderVG/COPYING
Normal file
@ -0,0 +1,504 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 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.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
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 and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, 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 library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete 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 distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
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 Library or any portion
|
||||
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
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 Library, 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 Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you 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.
|
||||
|
||||
If distribution of 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 satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be 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.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library 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.
|
||||
|
||||
9. 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 Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
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 with
|
||||
this License.
|
||||
|
||||
11. 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 Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library 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 Library.
|
||||
|
||||
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.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library 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.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser 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 Library
|
||||
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 Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
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
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "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
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. 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 LIBRARY 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
|
||||
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. 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 library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; 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.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
223
simgear/canvas/ShaderVG/README.md
Normal file
223
simgear/canvas/ShaderVG/README.md
Normal file
@ -0,0 +1,223 @@
|
||||
# ShaderVG
|
||||
|
||||
<img src="/examples/test_tiger_shader.gif?raw=true" width="400px">
|
||||
|
||||
_**Note:** This project is based on https://github.com/tqm-dev/ShivaVG-2_
|
||||
|
||||
## Main Features
|
||||
|
||||
- Working on Shader-Based OpenGL
|
||||
- API extensions for GLSL shader integrated to vector/image rendering
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- OpenGL development libraries and headers should be installed.
|
||||
- freeglut must be installed for rendering on window system.
|
||||
- jpeglib needs to be installed for example programs that use images.
|
||||
|
||||
### Compiling
|
||||
|
||||
Clone and enter the repository:
|
||||
```
|
||||
$ git clone https://github.com/tqm-dev/ShaderVG
|
||||
$ cd ShaderVG
|
||||
```
|
||||
|
||||
Under UNIX systems, execute configure and make:
|
||||
```
|
||||
$ sh autogen.sh
|
||||
$ ./configure LIBS="-lGL -lglut -ljpeg"
|
||||
$ make
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
Move to examples directory, execute tests:
|
||||
```
|
||||
$ cd examples
|
||||
$ ./test_tiger_shader
|
||||
```
|
||||
#### test_tiger_shader
|
||||
Well known svg tiger meets GLSL vertex/fragment shading.
|
||||
|
||||
#### test_vgu
|
||||
Constructs some path primitives using the VGU API.
|
||||
|
||||
#### test_tiger
|
||||
The most simple performance test. It draws the well known svg
|
||||
tiger using just simple stroke and fill of solid colors. It
|
||||
consists of 240 paths.
|
||||
|
||||
#### test_dash
|
||||
Shows different stroke dashing modes.
|
||||
|
||||
#### test_linear
|
||||
A rectangle drawn using 3-color linear gradient fill paint
|
||||
|
||||
#### test_radial
|
||||
A rectangle drawn using 3-color radial gradient fill paint
|
||||
|
||||
#### test_interpolate
|
||||
Interpolates between two paths - an apple and a pear.
|
||||
|
||||
#### test_image
|
||||
Images are drawn using VG_DRAW_IMAGE_MULTIPLY image mode to be
|
||||
multiplied with radial gradient fill paint.
|
||||
|
||||
#### test_pattern
|
||||
An image is drawn in multiply mode with an image pattern fill
|
||||
paint.
|
||||
|
||||
## Implementation status
|
||||
|
||||
#### General
|
||||
API | status
|
||||
----------------------- | ---------------------
|
||||
vgGetError | FULLY implemented
|
||||
vgFlush | FULLY implemented
|
||||
vgFinish | FULLY implemented
|
||||
|
||||
#### Getters and setters
|
||||
API | status
|
||||
----------------------- | ---------------------
|
||||
vgSet | FULLY implemented
|
||||
vgSeti | FULLY implemented
|
||||
vgSetfv | FULLY implemented
|
||||
vgSetiv | FULLY implemented
|
||||
vgGetf | FULLY implemented
|
||||
vgGeti | FULLY implemented
|
||||
vgGetVectorSize | FULLY implemented
|
||||
vgGetfv | FULLY implemented
|
||||
vgGetiv | FULLY implemented
|
||||
vgSetParameterf | FULLY implemented
|
||||
vgSetParameteri | FULLY implemented
|
||||
vgSetParameterfv | FULLY implemented
|
||||
vgSetParameteriv | FULLY implemented
|
||||
vgGetParameterf | FULLY implemented
|
||||
vgGetParameteri | FULLY implemented
|
||||
vgGetParameterVectorSize| FULLY implemented
|
||||
vgGetParameterfv | FULLY implemented
|
||||
vgGetParameteriv | FULLY implemented
|
||||
|
||||
#### Matrix Manipulation
|
||||
API | status
|
||||
----------------------- | ---------------------
|
||||
vgLoadIdentity | FULLY implemented
|
||||
vgLoadMatrix | FULLY implemented
|
||||
vgGetMatrix | FULLY implemented
|
||||
vgMultMatrix | FULLY implemented
|
||||
vgTranslate | FULLY implemented
|
||||
vgScale | FULLY implemented
|
||||
vgShear | FULLY implemented
|
||||
vgRotate | FULLY implemented
|
||||
|
||||
#### Masking and Clearing
|
||||
API | status
|
||||
----------------------- | ---------------------
|
||||
vgMask | NOT implemented
|
||||
vgClear | FULLY implemented
|
||||
|
||||
#### Paths
|
||||
API | status
|
||||
----------------------- | ---------------------
|
||||
vgCreatePath | FULLY implemented
|
||||
vgClearPath | FULLY implemented
|
||||
vgDestroyPath | FULLY implemented
|
||||
vgRemovePathCapabilities| FULLY implemented
|
||||
vgGetPathCapabilities | FULLY implemented
|
||||
vgAppendPath | FULLY implemented
|
||||
vgAppendPathData | FULLY implemented
|
||||
vgModifyPathCoords | FULLY implemented
|
||||
vgTransformPath | FULLY implemented
|
||||
vgInterpolatePath | FULLY implemented
|
||||
vgPathLength | NOT implemented
|
||||
vgPointAlongPath | NOT implemented
|
||||
vgPathBounds | FULLY implemented
|
||||
vgPathTransformedBounds | FULLY implemented
|
||||
vgDrawPath | PARTIALLY implemented
|
||||
|
||||
#### Paint
|
||||
API | status
|
||||
----------------------- | ---------------------
|
||||
vgCreatePaint | FULLY implemented
|
||||
vgDestroyPaint | FULLY implemented
|
||||
vgSetPaint | FULLY implemented
|
||||
vgGetPaint | FULLY implemented
|
||||
vgSetColor | FULLY implemented
|
||||
vgGetColor | FULLY implemented
|
||||
vgPaintPattern | FULLY implemented
|
||||
|
||||
#### Images
|
||||
API | status
|
||||
----------------------- | ---------------------
|
||||
vgCreateImage | PARTIALLY implemented
|
||||
vgDestroyImage | FULLY implemented
|
||||
vgClearImage | FULLY implemented
|
||||
vgImageSubData | PARTIALLY implemented
|
||||
vgGetImageSubData | PARTIALLY implemented
|
||||
vgChildImage | NOT implemented
|
||||
vgGetParent | NOT implemented
|
||||
vgCopyImage | FULLY implemented
|
||||
vgDrawImage | PARTIALLY implemented
|
||||
vgSetPixels | NOT implemented yet
|
||||
vgWritePixels | NOT implemented yet
|
||||
vgGetPixels | FULLY implemented
|
||||
vgReadPixels | FULLY implemented
|
||||
vgCopyPixels | NOT implemented yet
|
||||
|
||||
#### Image Filters
|
||||
API | status
|
||||
----------------------- | ---------------------
|
||||
vgColorMatrix | NOT implemented
|
||||
vgConvolve | NOT implemented
|
||||
vgSeparableConvolve | NOT implemented
|
||||
vgGaussianBlur | NOT implemented
|
||||
vgLookup | NOT implemented
|
||||
vgLookupSingle | NOT implemented
|
||||
|
||||
#### Queries
|
||||
API | status
|
||||
----------------------- | ---------------------
|
||||
vgHardwareQuery | NOT implemented
|
||||
vgGetString | FULLY implemented
|
||||
|
||||
#### VGU
|
||||
API | status
|
||||
----------------------- | ---------------------
|
||||
vguLine | FULLY implemented
|
||||
vguPolygon | FULLY implemented
|
||||
vguRect | FULLY implemented
|
||||
vguRoundRect | FULLY implemented
|
||||
vguEllipse | FULLY implemented
|
||||
vguArc | FULLY implemented
|
||||
vguComputeWarpQuadToSquare | NOT implemented
|
||||
vguComputeWarpSquareToQuad | NOT implemented
|
||||
vguComputeWarpQuadToQuad | NOT implemented
|
||||
|
||||
## Extensions
|
||||
|
||||
### Manipulate the OpenVG context as a temporary replacement for EGL:
|
||||
|
||||
- VGboolean vgCreateContextSH(VGint width, VGint height)
|
||||
|
||||
Creates an OpenVG context on top of an existing OpenGL context
|
||||
that should have been manually initialized by the user of the
|
||||
library. Width and height specify the size of the rendering
|
||||
surface. No multi-threading support has been implemented yet.
|
||||
The context is created once per process.
|
||||
|
||||
- void vgResizeSurfaceSH(VGint width, VGint height)
|
||||
|
||||
Should be called whenever the size of the surface changes (e.g.
|
||||
the owner window of the OpenGL context is resized).
|
||||
|
||||
- void vgDestroyContextSH()
|
||||
|
||||
Destroys the OpenVG context associated with the calling process.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the GNU Lesser General Public License v2.1 - see the [LICENSE](https://github.com/tqm-dev/ShaderVG/blob/master/COPYING) file for details
|
||||
|
676
simgear/canvas/ShaderVG/include/vg/openvg.h
Normal file
676
simgear/canvas/ShaderVG/include/vg/openvg.h
Normal file
@ -0,0 +1,676 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _OPENVG_H
|
||||
#define _OPENVG_H
|
||||
|
||||
#define OPENVG_VERSION_1_0_1 1
|
||||
|
||||
/* Type definitions */
|
||||
/* TODO: we can't use config.h in this header so there
|
||||
must be some other technique to assert the proper
|
||||
size of the basic types */
|
||||
|
||||
typedef float VGfloat;
|
||||
typedef char VGbyte;
|
||||
typedef unsigned char VGubyte;
|
||||
typedef short VGshort;
|
||||
typedef int VGint;
|
||||
typedef unsigned int VGuint;
|
||||
typedef unsigned int VGbitfield;
|
||||
|
||||
typedef enum {
|
||||
VG_FALSE = 0,
|
||||
VG_TRUE = 1
|
||||
} VGboolean;
|
||||
|
||||
#define VG_MAXSHORT ((VGshort)((~((unsigned)0)) >> 1))
|
||||
#define VG_MAXINT ((VGint)((~((unsigned)0)) >> 1))
|
||||
|
||||
/* Define handle to be of same length as any pointer */
|
||||
|
||||
typedef void * VGHandle;
|
||||
#define VG_INVALID_HANDLE ((VGHandle)NULL)
|
||||
|
||||
/* Enumerations */
|
||||
|
||||
typedef enum {
|
||||
VG_NO_ERROR = 0,
|
||||
VG_BAD_HANDLE_ERROR = 0x1000,
|
||||
VG_ILLEGAL_ARGUMENT_ERROR = 0x1001,
|
||||
VG_OUT_OF_MEMORY_ERROR = 0x1002,
|
||||
VG_PATH_CAPABILITY_ERROR = 0x1003,
|
||||
VG_UNSUPPORTED_IMAGE_FORMAT_ERROR = 0x1004,
|
||||
VG_UNSUPPORTED_PATH_FORMAT_ERROR = 0x1005,
|
||||
VG_IMAGE_IN_USE_ERROR = 0x1006,
|
||||
VG_NO_CONTEXT_ERROR = 0x1007
|
||||
} VGErrorCode;
|
||||
|
||||
typedef enum {
|
||||
/* Mode settings */
|
||||
VG_MATRIX_MODE = 0x1100,
|
||||
VG_FILL_RULE = 0x1101,
|
||||
VG_IMAGE_QUALITY = 0x1102,
|
||||
VG_RENDERING_QUALITY = 0x1103,
|
||||
VG_BLEND_MODE = 0x1104,
|
||||
VG_IMAGE_MODE = 0x1105,
|
||||
|
||||
/* Scissoring rectangles */
|
||||
VG_SCISSOR_RECTS = 0x1106,
|
||||
|
||||
/* Stroke parameters */
|
||||
VG_STROKE_LINE_WIDTH = 0x1110,
|
||||
VG_STROKE_CAP_STYLE = 0x1111,
|
||||
VG_STROKE_JOIN_STYLE = 0x1112,
|
||||
VG_STROKE_MITER_LIMIT = 0x1113,
|
||||
VG_STROKE_DASH_PATTERN = 0x1114,
|
||||
VG_STROKE_DASH_PHASE = 0x1115,
|
||||
VG_STROKE_DASH_PHASE_RESET = 0x1116,
|
||||
|
||||
/* Edge fill color for VG_TILE_FILL tiling mode */
|
||||
VG_TILE_FILL_COLOR = 0x1120,
|
||||
|
||||
/* Color for vgClear */
|
||||
VG_CLEAR_COLOR = 0x1121,
|
||||
|
||||
/* Enable/disable alpha masking and scissoring */
|
||||
VG_MASKING = 0x1130,
|
||||
VG_SCISSORING = 0x1131,
|
||||
|
||||
/* Pixel layout information */
|
||||
VG_PIXEL_LAYOUT = 0x1140,
|
||||
VG_SCREEN_LAYOUT = 0x1141,
|
||||
|
||||
/* Source format selection for image filters */
|
||||
VG_FILTER_FORMAT_LINEAR = 0x1150,
|
||||
VG_FILTER_FORMAT_PREMULTIPLIED = 0x1151,
|
||||
|
||||
/* Destination write enable mask for image filters */
|
||||
VG_FILTER_CHANNEL_MASK = 0x1152,
|
||||
|
||||
/* Implementation limits (read-only) */
|
||||
VG_MAX_SCISSOR_RECTS = 0x1160,
|
||||
VG_MAX_DASH_COUNT = 0x1161,
|
||||
VG_MAX_KERNEL_SIZE = 0x1162,
|
||||
VG_MAX_SEPARABLE_KERNEL_SIZE = 0x1163,
|
||||
VG_MAX_COLOR_RAMP_STOPS = 0x1164,
|
||||
VG_MAX_IMAGE_WIDTH = 0x1165,
|
||||
VG_MAX_IMAGE_HEIGHT = 0x1166,
|
||||
VG_MAX_IMAGE_PIXELS = 0x1167,
|
||||
VG_MAX_IMAGE_BYTES = 0x1168,
|
||||
VG_MAX_FLOAT = 0x1169,
|
||||
VG_MAX_GAUSSIAN_STD_DEVIATION = 0x116A
|
||||
} VGParamType;
|
||||
|
||||
typedef enum {
|
||||
VG_RENDERING_QUALITY_NONANTIALIASED = 0x1200,
|
||||
VG_RENDERING_QUALITY_FASTER = 0x1201,
|
||||
VG_RENDERING_QUALITY_BETTER = 0x1202 /* Default */
|
||||
} VGRenderingQuality;
|
||||
|
||||
typedef enum {
|
||||
VG_PIXEL_LAYOUT_UNKNOWN = 0x1300,
|
||||
VG_PIXEL_LAYOUT_RGB_VERTICAL = 0x1301,
|
||||
VG_PIXEL_LAYOUT_BGR_VERTICAL = 0x1302,
|
||||
VG_PIXEL_LAYOUT_RGB_HORIZONTAL = 0x1303,
|
||||
VG_PIXEL_LAYOUT_BGR_HORIZONTAL = 0x1304
|
||||
} VGPixelLayout;
|
||||
|
||||
typedef enum {
|
||||
VG_MATRIX_PATH_USER_TO_SURFACE = 0x1400,
|
||||
VG_MATRIX_IMAGE_USER_TO_SURFACE = 0x1401,
|
||||
VG_MATRIX_FILL_PAINT_TO_USER = 0x1402,
|
||||
VG_MATRIX_STROKE_PAINT_TO_USER = 0x1403
|
||||
} VGMatrixMode;
|
||||
|
||||
typedef enum {
|
||||
VG_CLEAR_MASK = 0x1500,
|
||||
VG_FILL_MASK = 0x1501,
|
||||
VG_SET_MASK = 0x1502,
|
||||
VG_UNION_MASK = 0x1503,
|
||||
VG_INTERSECT_MASK = 0x1504,
|
||||
VG_SUBTRACT_MASK = 0x1505
|
||||
} VGMaskOperation;
|
||||
|
||||
#define VG_PATH_FORMAT_STANDARD 0
|
||||
|
||||
typedef enum {
|
||||
VG_PATH_DATATYPE_S_8 = 0,
|
||||
VG_PATH_DATATYPE_S_16 = 1,
|
||||
VG_PATH_DATATYPE_S_32 = 2,
|
||||
VG_PATH_DATATYPE_F = 3
|
||||
} VGPathDatatype;
|
||||
|
||||
typedef enum {
|
||||
VG_ABSOLUTE = 0,
|
||||
VG_RELATIVE = 1
|
||||
} VGPathAbsRel;
|
||||
|
||||
typedef enum {
|
||||
VG_CLOSE_PATH = ( 0 << 1),
|
||||
VG_MOVE_TO = ( 1 << 1),
|
||||
VG_LINE_TO = ( 2 << 1),
|
||||
VG_HLINE_TO = ( 3 << 1),
|
||||
VG_VLINE_TO = ( 4 << 1),
|
||||
VG_QUAD_TO = ( 5 << 1),
|
||||
VG_CUBIC_TO = ( 6 << 1),
|
||||
VG_SQUAD_TO = ( 7 << 1),
|
||||
VG_SCUBIC_TO = ( 8 << 1),
|
||||
VG_SCCWARC_TO = ( 9 << 1),
|
||||
VG_SCWARC_TO = (10 << 1),
|
||||
VG_LCCWARC_TO = (11 << 1),
|
||||
VG_LCWARC_TO = (12 << 1)
|
||||
} VGPathSegment;
|
||||
|
||||
typedef enum {
|
||||
VG_MOVE_TO_ABS = VG_MOVE_TO | VG_ABSOLUTE,
|
||||
VG_MOVE_TO_REL = VG_MOVE_TO | VG_RELATIVE,
|
||||
VG_LINE_TO_ABS = VG_LINE_TO | VG_ABSOLUTE,
|
||||
VG_LINE_TO_REL = VG_LINE_TO | VG_RELATIVE,
|
||||
VG_HLINE_TO_ABS = VG_HLINE_TO | VG_ABSOLUTE,
|
||||
VG_HLINE_TO_REL = VG_HLINE_TO | VG_RELATIVE,
|
||||
VG_VLINE_TO_ABS = VG_VLINE_TO | VG_ABSOLUTE,
|
||||
VG_VLINE_TO_REL = VG_VLINE_TO | VG_RELATIVE,
|
||||
VG_QUAD_TO_ABS = VG_QUAD_TO | VG_ABSOLUTE,
|
||||
VG_QUAD_TO_REL = VG_QUAD_TO | VG_RELATIVE,
|
||||
VG_CUBIC_TO_ABS = VG_CUBIC_TO | VG_ABSOLUTE,
|
||||
VG_CUBIC_TO_REL = VG_CUBIC_TO | VG_RELATIVE,
|
||||
VG_SQUAD_TO_ABS = VG_SQUAD_TO | VG_ABSOLUTE,
|
||||
VG_SQUAD_TO_REL = VG_SQUAD_TO | VG_RELATIVE,
|
||||
VG_SCUBIC_TO_ABS = VG_SCUBIC_TO | VG_ABSOLUTE,
|
||||
VG_SCUBIC_TO_REL = VG_SCUBIC_TO | VG_RELATIVE,
|
||||
VG_SCCWARC_TO_ABS = VG_SCCWARC_TO | VG_ABSOLUTE,
|
||||
VG_SCCWARC_TO_REL = VG_SCCWARC_TO | VG_RELATIVE,
|
||||
VG_SCWARC_TO_ABS = VG_SCWARC_TO | VG_ABSOLUTE,
|
||||
VG_SCWARC_TO_REL = VG_SCWARC_TO | VG_RELATIVE,
|
||||
VG_LCCWARC_TO_ABS = VG_LCCWARC_TO | VG_ABSOLUTE,
|
||||
VG_LCCWARC_TO_REL = VG_LCCWARC_TO | VG_RELATIVE,
|
||||
VG_LCWARC_TO_ABS = VG_LCWARC_TO | VG_ABSOLUTE,
|
||||
VG_LCWARC_TO_REL = VG_LCWARC_TO | VG_RELATIVE
|
||||
} VGPathCommand;
|
||||
|
||||
typedef VGHandle VGPath;
|
||||
|
||||
typedef enum {
|
||||
VG_PATH_CAPABILITY_APPEND_FROM = (1 << 0),
|
||||
VG_PATH_CAPABILITY_APPEND_TO = (1 << 1),
|
||||
VG_PATH_CAPABILITY_MODIFY = (1 << 2),
|
||||
VG_PATH_CAPABILITY_TRANSFORM_FROM = (1 << 3),
|
||||
VG_PATH_CAPABILITY_TRANSFORM_TO = (1 << 4),
|
||||
VG_PATH_CAPABILITY_INTERPOLATE_FROM = (1 << 5),
|
||||
VG_PATH_CAPABILITY_INTERPOLATE_TO = (1 << 6),
|
||||
VG_PATH_CAPABILITY_PATH_LENGTH = (1 << 7),
|
||||
VG_PATH_CAPABILITY_POINT_ALONG_PATH = (1 << 8),
|
||||
VG_PATH_CAPABILITY_TANGENT_ALONG_PATH = (1 << 9),
|
||||
VG_PATH_CAPABILITY_PATH_BOUNDS = (1 << 10),
|
||||
VG_PATH_CAPABILITY_PATH_TRANSFORMED_BOUNDS = (1 << 11),
|
||||
VG_PATH_CAPABILITY_ALL = (1 << 12) - 1
|
||||
} VGPathCapabilities;
|
||||
|
||||
typedef enum {
|
||||
VG_PATH_FORMAT = 0x1600,
|
||||
VG_PATH_DATATYPE = 0x1601,
|
||||
VG_PATH_SCALE = 0x1602,
|
||||
VG_PATH_BIAS = 0x1603,
|
||||
VG_PATH_NUM_SEGMENTS = 0x1604,
|
||||
VG_PATH_NUM_COORDS = 0x1605
|
||||
} VGPathParamType;
|
||||
|
||||
typedef enum {
|
||||
VG_CAP_BUTT = 0x1700,
|
||||
VG_CAP_ROUND = 0x1701,
|
||||
VG_CAP_SQUARE = 0x1702
|
||||
} VGCapStyle;
|
||||
|
||||
typedef enum {
|
||||
VG_JOIN_MITER = 0x1800,
|
||||
VG_JOIN_ROUND = 0x1801,
|
||||
VG_JOIN_BEVEL = 0x1802
|
||||
} VGJoinStyle;
|
||||
|
||||
typedef enum {
|
||||
VG_EVEN_ODD = 0x1900,
|
||||
VG_NON_ZERO = 0x1901
|
||||
} VGFillRule;
|
||||
|
||||
typedef enum {
|
||||
VG_STROKE_PATH = (1 << 0),
|
||||
VG_FILL_PATH = (1 << 1)
|
||||
} VGPaintMode;
|
||||
|
||||
typedef VGHandle VGPaint;
|
||||
|
||||
typedef enum {
|
||||
/* Color paint parameters */
|
||||
VG_PAINT_TYPE = 0x1A00,
|
||||
VG_PAINT_COLOR = 0x1A01,
|
||||
VG_PAINT_COLOR_RAMP_SPREAD_MODE = 0x1A02,
|
||||
VG_PAINT_COLOR_RAMP_PREMULTIPLIED = 0x1A07,
|
||||
VG_PAINT_COLOR_RAMP_STOPS = 0x1A03,
|
||||
|
||||
/* Linear gradient paint parameters */
|
||||
VG_PAINT_LINEAR_GRADIENT = 0x1A04,
|
||||
|
||||
/* Radial gradient paint parameters */
|
||||
VG_PAINT_RADIAL_GRADIENT = 0x1A05,
|
||||
|
||||
/* Pattern paint parameters */
|
||||
VG_PAINT_PATTERN_TILING_MODE = 0x1A06
|
||||
} VGPaintParamType;
|
||||
|
||||
typedef enum {
|
||||
VG_PAINT_TYPE_COLOR = 0x1B00,
|
||||
VG_PAINT_TYPE_LINEAR_GRADIENT = 0x1B01,
|
||||
VG_PAINT_TYPE_RADIAL_GRADIENT = 0x1B02,
|
||||
VG_PAINT_TYPE_PATTERN = 0x1B03
|
||||
} VGPaintType;
|
||||
|
||||
typedef enum {
|
||||
VG_COLOR_RAMP_SPREAD_PAD = 0x1C00,
|
||||
VG_COLOR_RAMP_SPREAD_REPEAT = 0x1C01,
|
||||
VG_COLOR_RAMP_SPREAD_REFLECT = 0x1C02
|
||||
} VGColorRampSpreadMode;
|
||||
|
||||
typedef enum {
|
||||
VG_TILE_FILL = 0x1D00,
|
||||
VG_TILE_PAD = 0x1D01,
|
||||
VG_TILE_REPEAT = 0x1D02,
|
||||
VG_TILE_REFLECT = 0x1D03
|
||||
} VGTilingMode;
|
||||
|
||||
typedef enum {
|
||||
/* RGB{A,X} channel ordering */
|
||||
VG_sRGBX_8888 = 0,
|
||||
VG_sRGBA_8888 = 1,
|
||||
VG_sRGBA_8888_PRE = 2,
|
||||
VG_sRGB_565 = 3,
|
||||
VG_sRGBA_5551 = 4,
|
||||
VG_sRGBA_4444 = 5,
|
||||
VG_sL_8 = 6,
|
||||
VG_lRGBX_8888 = 7,
|
||||
VG_lRGBA_8888 = 8,
|
||||
VG_lRGBA_8888_PRE = 9,
|
||||
VG_lL_8 = 10,
|
||||
VG_A_8 = 11,
|
||||
VG_BW_1 = 12,
|
||||
|
||||
/* {A,X}RGB channel ordering */
|
||||
VG_sXRGB_8888 = 0 | (1 << 6),
|
||||
VG_sARGB_8888 = 1 | (1 << 6),
|
||||
VG_sARGB_8888_PRE = 2 | (1 << 6),
|
||||
VG_sARGB_1555 = 4 | (1 << 6),
|
||||
VG_sARGB_4444 = 5 | (1 << 6),
|
||||
VG_lXRGB_8888 = 7 | (1 << 6),
|
||||
VG_lARGB_8888 = 8 | (1 << 6),
|
||||
VG_lARGB_8888_PRE = 9 | (1 << 6),
|
||||
|
||||
/* BGR{A,X} channel ordering */
|
||||
VG_sBGRX_8888 = 0 | (1 << 7),
|
||||
VG_sBGRA_8888 = 1 | (1 << 7),
|
||||
VG_sBGRA_8888_PRE = 2 | (1 << 7),
|
||||
VG_sBGR_565 = 3 | (1 << 7),
|
||||
VG_sBGRA_5551 = 4 | (1 << 7),
|
||||
VG_sBGRA_4444 = 5 | (1 << 7),
|
||||
VG_lBGRX_8888 = 7 | (1 << 7),
|
||||
VG_lBGRA_8888 = 8 | (1 << 7),
|
||||
VG_lBGRA_8888_PRE = 9 | (1 << 7),
|
||||
|
||||
/* {A,X}BGR channel ordering */
|
||||
VG_sXBGR_8888 = 0 | (1 << 6) | (1 << 7),
|
||||
VG_sABGR_8888 = 1 | (1 << 6) | (1 << 7),
|
||||
VG_sABGR_8888_PRE = 2 | (1 << 6) | (1 << 7),
|
||||
VG_sABGR_1555 = 4 | (1 << 6) | (1 << 7),
|
||||
VG_sABGR_4444 = 5 | (1 << 6) | (1 << 7),
|
||||
VG_lXBGR_8888 = 7 | (1 << 6) | (1 << 7),
|
||||
VG_lABGR_8888 = 8 | (1 << 6) | (1 << 7),
|
||||
VG_lABGR_8888_PRE = 9 | (1 << 6) | (1 << 7)
|
||||
} VGImageFormat;
|
||||
|
||||
typedef VGHandle VGImage;
|
||||
|
||||
typedef enum {
|
||||
VG_IMAGE_QUALITY_NONANTIALIASED = (1 << 0),
|
||||
VG_IMAGE_QUALITY_FASTER = (1 << 1),
|
||||
VG_IMAGE_QUALITY_BETTER = (1 << 2)
|
||||
} VGImageQuality;
|
||||
|
||||
typedef enum {
|
||||
VG_IMAGE_FORMAT = 0x1E00,
|
||||
VG_IMAGE_WIDTH = 0x1E01,
|
||||
VG_IMAGE_HEIGHT = 0x1E02
|
||||
} VGImageParamType;
|
||||
|
||||
typedef enum {
|
||||
VG_DRAW_IMAGE_NORMAL = 0x1F00,
|
||||
VG_DRAW_IMAGE_MULTIPLY = 0x1F01,
|
||||
VG_DRAW_IMAGE_STENCIL = 0x1F02
|
||||
} VGImageMode;
|
||||
|
||||
typedef enum {
|
||||
VG_RED = (1 << 3),
|
||||
VG_GREEN = (1 << 2),
|
||||
VG_BLUE = (1 << 1),
|
||||
VG_ALPHA = (1 << 0)
|
||||
} VGImageChannel;
|
||||
|
||||
typedef enum {
|
||||
VG_BLEND_SRC = 0x2000,
|
||||
VG_BLEND_SRC_OVER = 0x2001,
|
||||
VG_BLEND_DST_OVER = 0x2002,
|
||||
VG_BLEND_SRC_IN = 0x2003,
|
||||
VG_BLEND_DST_IN = 0x2004,
|
||||
VG_BLEND_MULTIPLY = 0x2005,
|
||||
VG_BLEND_SCREEN = 0x2006,
|
||||
VG_BLEND_DARKEN = 0x2007,
|
||||
VG_BLEND_LIGHTEN = 0x2008,
|
||||
VG_BLEND_ADDITIVE = 0x2009,
|
||||
VG_BLEND_SRC_OUT_SH = 0x200A,
|
||||
VG_BLEND_DST_OUT_SH = 0x200B,
|
||||
VG_BLEND_SRC_ATOP_SH = 0x200C,
|
||||
VG_BLEND_DST_ATOP_SH = 0x200D
|
||||
} VGBlendMode;
|
||||
|
||||
typedef enum {
|
||||
VG_IMAGE_FORMAT_QUERY = 0x2100,
|
||||
VG_PATH_DATATYPE_QUERY = 0x2101
|
||||
} VGHardwareQueryType;
|
||||
|
||||
typedef enum {
|
||||
VG_HARDWARE_ACCELERATED = 0x2200,
|
||||
VG_HARDWARE_UNACCELERATED = 0x2201
|
||||
} VGHardwareQueryResult;
|
||||
|
||||
typedef enum {
|
||||
VG_VENDOR = 0x2300,
|
||||
VG_RENDERER = 0x2301,
|
||||
VG_VERSION = 0x2302,
|
||||
VG_EXTENSIONS = 0x2303
|
||||
} VGStringID;
|
||||
|
||||
/* Function Prototypes */
|
||||
|
||||
#if 0 // We are including ShivaVG directly into libSimGearScene and only using
|
||||
// inside the library so there is no need for any dll import/export stuff
|
||||
#if defined(_WIN32) || defined(__VC32__)
|
||||
# if defined(VG_API_EXPORT)
|
||||
# define VG_API_CALL __declspec(dllexport)
|
||||
# else
|
||||
# define VG_API_CALL __declspec(dllimport)
|
||||
# endif
|
||||
#else
|
||||
# define VG_API_CALL extern
|
||||
#endif
|
||||
#else
|
||||
# define VG_API_CALL
|
||||
#endif
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
VG_API_CALL VGErrorCode vgGetError(void);
|
||||
|
||||
VG_API_CALL void vgFlush(void);
|
||||
VG_API_CALL void vgFinish(void);
|
||||
|
||||
/* Getters and Setters */
|
||||
VG_API_CALL void vgSetf (VGParamType type, VGfloat value);
|
||||
VG_API_CALL void vgSeti (VGParamType type, VGint value);
|
||||
VG_API_CALL void vgSetfv(VGParamType type, VGint count,
|
||||
const VGfloat * values);
|
||||
VG_API_CALL void vgSetiv(VGParamType type, VGint count,
|
||||
const VGint * values);
|
||||
|
||||
VG_API_CALL VGfloat vgGetf(VGParamType type);
|
||||
VG_API_CALL VGint vgGeti(VGParamType type);
|
||||
VG_API_CALL VGint vgGetVectorSize(VGParamType type);
|
||||
VG_API_CALL void vgGetfv(VGParamType type, VGint count, VGfloat * values);
|
||||
VG_API_CALL void vgGetiv(VGParamType type, VGint count, VGint * values);
|
||||
|
||||
VG_API_CALL void vgSetParameterf(VGHandle object,
|
||||
VGint paramType,
|
||||
VGfloat value);
|
||||
VG_API_CALL void vgSetParameteri(VGHandle object,
|
||||
VGint paramType,
|
||||
VGint value);
|
||||
VG_API_CALL void vgSetParameterfv(VGHandle object,
|
||||
VGint paramType,
|
||||
VGint count, const VGfloat * values);
|
||||
VG_API_CALL void vgSetParameteriv(VGHandle object,
|
||||
VGint paramType,
|
||||
VGint count, const VGint * values);
|
||||
|
||||
VG_API_CALL VGfloat vgGetParameterf(VGHandle object,
|
||||
VGint paramType);
|
||||
VG_API_CALL VGint vgGetParameteri(VGHandle object,
|
||||
VGint paramType);
|
||||
VG_API_CALL VGint vgGetParameterVectorSize(VGHandle object,
|
||||
VGint paramType);
|
||||
VG_API_CALL void vgGetParameterfv(VGHandle object,
|
||||
VGint paramType,
|
||||
VGint count, VGfloat * values);
|
||||
VG_API_CALL void vgGetParameteriv(VGHandle object,
|
||||
VGint paramType,
|
||||
VGint count, VGint * values);
|
||||
|
||||
/* Matrix Manipulation */
|
||||
VG_API_CALL void vgLoadIdentity(void);
|
||||
VG_API_CALL void vgLoadMatrix(const VGfloat * m);
|
||||
VG_API_CALL void vgGetMatrix(VGfloat * m);
|
||||
VG_API_CALL void vgMultMatrix(const VGfloat * m);
|
||||
VG_API_CALL void vgTranslate(VGfloat tx, VGfloat ty);
|
||||
VG_API_CALL void vgScale(VGfloat sx, VGfloat sy);
|
||||
VG_API_CALL void vgShear(VGfloat shx, VGfloat shy);
|
||||
VG_API_CALL void vgRotate(VGfloat angle);
|
||||
|
||||
/* Masking and Clearing */
|
||||
VG_API_CALL void vgMask(VGImage mask, VGMaskOperation operation,
|
||||
VGint x, VGint y, VGint width, VGint height);
|
||||
VG_API_CALL void vgClear(VGint x, VGint y, VGint width, VGint height);
|
||||
|
||||
/* Paths */
|
||||
VG_API_CALL VGPath vgCreatePath(VGint pathFormat,
|
||||
VGPathDatatype datatype,
|
||||
VGfloat scale, VGfloat bias,
|
||||
VGint segmentCapacityHint,
|
||||
VGint coordCapacityHint,
|
||||
VGbitfield capabilities);
|
||||
VG_API_CALL void vgClearPath(VGPath path, VGbitfield capabilities);
|
||||
VG_API_CALL void vgDestroyPath(VGPath path);
|
||||
VG_API_CALL void vgRemovePathCapabilities(VGPath path,
|
||||
VGbitfield capabilities);
|
||||
VG_API_CALL VGbitfield vgGetPathCapabilities(VGPath path);
|
||||
VG_API_CALL void vgAppendPath(VGPath dstPath, VGPath srcPath);
|
||||
VG_API_CALL void vgAppendPathData(VGPath dstPath,
|
||||
VGint numSegments,
|
||||
const VGubyte * pathSegments,
|
||||
const void * pathData);
|
||||
VG_API_CALL void vgModifyPathCoords(VGPath dstPath, VGint startIndex,
|
||||
VGint numSegments,
|
||||
const void * pathData);
|
||||
VG_API_CALL void vgTransformPath(VGPath dstPath, VGPath srcPath);
|
||||
VG_API_CALL VGboolean vgInterpolatePath(VGPath dstPath,
|
||||
VGPath startPath,
|
||||
VGPath endPath,
|
||||
VGfloat amount);
|
||||
VG_API_CALL VGfloat vgPathLength(VGPath path,
|
||||
VGint startSegment, VGint numSegments);
|
||||
VG_API_CALL void vgPointAlongPath(VGPath path,
|
||||
VGint startSegment, VGint numSegments,
|
||||
VGfloat distance,
|
||||
VGfloat * x, VGfloat * y,
|
||||
VGfloat * tangentX, VGfloat * tangentY);
|
||||
VG_API_CALL void vgPathBounds(VGPath path,
|
||||
VGfloat * minX, VGfloat * minY,
|
||||
VGfloat * width, VGfloat * height);
|
||||
VG_API_CALL void vgPathTransformedBounds(VGPath path,
|
||||
VGfloat * minX, VGfloat * minY,
|
||||
VGfloat * width, VGfloat * height);
|
||||
VG_API_CALL void vgDrawPath(VGPath path, VGbitfield paintModes);
|
||||
|
||||
/* Paint */
|
||||
VG_API_CALL VGPaint vgCreatePaint(void);
|
||||
VG_API_CALL void vgDestroyPaint(VGPaint paint);
|
||||
VG_API_CALL void vgSetPaint(VGPaint paint, VGbitfield paintModes);
|
||||
VG_API_CALL VGPaint vgGetPaint(VGPaintMode paintMode);
|
||||
VG_API_CALL void vgSetColor(VGPaint paint, VGuint rgba);
|
||||
VG_API_CALL VGuint vgGetColor(VGPaint paint);
|
||||
VG_API_CALL void vgPaintPattern(VGPaint paint, VGImage pattern);
|
||||
|
||||
/* Images */
|
||||
VG_API_CALL VGImage vgCreateImage(VGImageFormat format,
|
||||
VGint width, VGint height,
|
||||
VGbitfield allowedQuality);
|
||||
VG_API_CALL void vgDestroyImage(VGImage image);
|
||||
VG_API_CALL void vgClearImage(VGImage image,
|
||||
VGint x, VGint y, VGint width, VGint height);
|
||||
VG_API_CALL void vgImageSubData(VGImage image,
|
||||
const void * data, VGint dataStride,
|
||||
VGImageFormat dataFormat,
|
||||
VGint x, VGint y, VGint width, VGint height);
|
||||
VG_API_CALL void vgGetImageSubData(VGImage image,
|
||||
void * data, VGint dataStride,
|
||||
VGImageFormat dataFormat,
|
||||
VGint x, VGint y,
|
||||
VGint width, VGint height);
|
||||
VG_API_CALL VGImage vgChildImage(VGImage parent,
|
||||
VGint x, VGint y, VGint width, VGint height);
|
||||
VG_API_CALL VGImage vgGetParent(VGImage image);
|
||||
VG_API_CALL void vgCopyImage(VGImage dst, VGint dx, VGint dy,
|
||||
VGImage src, VGint sx, VGint sy,
|
||||
VGint width, VGint height,
|
||||
VGboolean dither);
|
||||
VG_API_CALL void vgDrawImage(VGImage image);
|
||||
VG_API_CALL void vgSetPixels(VGint dx, VGint dy,
|
||||
VGImage src, VGint sx, VGint sy,
|
||||
VGint width, VGint height);
|
||||
VG_API_CALL void vgWritePixels(const void * data, VGint dataStride,
|
||||
VGImageFormat dataFormat,
|
||||
VGint dx, VGint dy,
|
||||
VGint width, VGint height);
|
||||
VG_API_CALL void vgGetPixels(VGImage dst, VGint dx, VGint dy,
|
||||
VGint sx, VGint sy,
|
||||
VGint width, VGint height);
|
||||
VG_API_CALL void vgReadPixels(void * data, VGint dataStride,
|
||||
VGImageFormat dataFormat,
|
||||
VGint sx, VGint sy,
|
||||
VGint width, VGint height);
|
||||
VG_API_CALL void vgCopyPixels(VGint dx, VGint dy,
|
||||
VGint sx, VGint sy,
|
||||
VGint width, VGint height);
|
||||
|
||||
/* Image Filters */
|
||||
VG_API_CALL void vgColorMatrix(VGImage dst, VGImage src,
|
||||
const VGfloat * matrix);
|
||||
VG_API_CALL void vgConvolve(VGImage dst, VGImage src,
|
||||
VGint kernelWidth, VGint kernelHeight,
|
||||
VGint shiftX, VGint shiftY,
|
||||
const VGshort * kernel,
|
||||
VGfloat scale,
|
||||
VGfloat bias,
|
||||
VGTilingMode tilingMode);
|
||||
VG_API_CALL void vgSeparableConvolve(VGImage dst, VGImage src,
|
||||
VGint kernelWidth,
|
||||
VGint kernelHeight,
|
||||
VGint shiftX, VGint shiftY,
|
||||
const VGshort * kernelX,
|
||||
const VGshort * kernelY,
|
||||
VGfloat scale,
|
||||
VGfloat bias,
|
||||
VGTilingMode tilingMode);
|
||||
VG_API_CALL void vgGaussianBlur(VGImage dst, VGImage src,
|
||||
VGfloat stdDeviationX,
|
||||
VGfloat stdDeviationY,
|
||||
VGTilingMode tilingMode);
|
||||
VG_API_CALL void vgLookup(VGImage dst, VGImage src,
|
||||
const VGubyte * redLUT,
|
||||
const VGubyte * greenLUT,
|
||||
const VGubyte * blueLUT,
|
||||
const VGubyte * alphaLUT,
|
||||
VGboolean outputLinear,
|
||||
VGboolean outputPremultiplied);
|
||||
VG_API_CALL void vgLookupSingle(VGImage dst, VGImage src,
|
||||
const VGuint * lookupTable,
|
||||
VGImageChannel sourceChannel,
|
||||
VGboolean outputLinear,
|
||||
VGboolean outputPremultiplied);
|
||||
|
||||
/* Hardware Queries */
|
||||
VG_API_CALL VGHardwareQueryResult vgHardwareQuery(VGHardwareQueryType key,
|
||||
VGint setting);
|
||||
|
||||
/* Renderer and Extension Information */
|
||||
VG_API_CALL const VGubyte * vgGetString(VGStringID name);
|
||||
|
||||
/* Extensions */
|
||||
|
||||
#define OVG_SH_blend_src_out 1
|
||||
#define OVG_SH_blend_dst_out 1
|
||||
#define OVG_SH_blend_src_atop 1
|
||||
#define OVG_SH_blend_dst_atop 1
|
||||
|
||||
VG_API_CALL VGboolean vgCreateContextSH(VGint width, VGint height);
|
||||
VG_API_CALL VGboolean vgHasContextSH();
|
||||
VG_API_CALL void vgResizeSurfaceSH(VGint width, VGint height);
|
||||
VG_API_CALL void vgDestroyContextSH(void);
|
||||
|
||||
/* Extensions for ShaderVG */
|
||||
#define VG_FRAGMENT_SHADER_SH 0
|
||||
#define VG_VERTEX_SHADER_SH 1
|
||||
|
||||
#define VG_IMAGE_UNIT_OFFSET_SH 2
|
||||
|
||||
typedef enum {
|
||||
VG_IMAGE_UNIT_0_SH = VG_IMAGE_UNIT_OFFSET_SH,
|
||||
VG_IMAGE_UNIT_1_SH,
|
||||
VG_IMAGE_UNIT_2_SH,
|
||||
VG_IMAGE_UNIT_3_SH,
|
||||
VG_IMAGE_UNIT_4_SH
|
||||
} VGImageUnitSH;
|
||||
|
||||
VG_API_CALL void vgShaderSourceSH(VGuint shadertype, const VGbyte* string);
|
||||
VG_API_CALL void vgCompileShaderSH(void);
|
||||
VG_API_CALL void vgUniform1fSH(VGint location, VGfloat v0);
|
||||
VG_API_CALL void vgUniform2fSH(VGint location, VGfloat v0, VGfloat v1);
|
||||
VG_API_CALL void vgUniform3fSH(VGint location, VGfloat v0, VGfloat v1, VGfloat v2);
|
||||
VG_API_CALL void vgUniform4fSH(VGint location, VGfloat v0, VGfloat v1, VGfloat v2, VGfloat v3);
|
||||
VG_API_CALL void vgUniform1fvSH(VGint location, VGint count, const VGfloat *value);
|
||||
VG_API_CALL void vgUniform2fvSH(VGint location, VGint count, const VGfloat *value);
|
||||
VG_API_CALL void vgUniform3fvSH(VGint location, VGint count, const VGfloat *value);
|
||||
VG_API_CALL void vgUniform4fvSH(VGint location, VGint count, const VGfloat *value);
|
||||
VG_API_CALL void vgUniform1iSH(VGint location, VGint v0);
|
||||
VG_API_CALL void vgUniform2iSH(VGint location, VGint v0, VGint v1);
|
||||
VG_API_CALL void vgUniform3iSH(VGint location, VGint v0, VGint v1, VGint v2);
|
||||
VG_API_CALL void vgUniform4iSH(VGint location, VGint v0, VGint v1, VGint v2, VGint v3);
|
||||
VG_API_CALL void vgUniform1ivSH(VGint location, VGint count, const VGint *value);
|
||||
VG_API_CALL void vgUniform2ivSH(VGint location, VGint count, const VGint *value);
|
||||
VG_API_CALL void vgUniform3ivSH(VGint location, VGint count, const VGint *value);
|
||||
VG_API_CALL void vgUniform4ivSH(VGint location, VGint count, const VGint *value);
|
||||
VG_API_CALL void vgUniformMatrix2fvSH (VGint location, VGint count, VGboolean transpose, const VGfloat *value);
|
||||
VG_API_CALL void vgUniformMatrix3fvSH (VGint location, VGint count, VGboolean transpose, const VGfloat *value);
|
||||
VG_API_CALL void vgUniformMatrix4fvSH (VGint location, VGint count, VGboolean transpose, const VGfloat *value);
|
||||
VG_API_CALL void vgBindImageSH(VGImage image, VGImageUnitSH unit);
|
||||
VG_API_CALL VGint vgGetUniformLocationSH(const VGbyte *name);
|
||||
VG_API_CALL void vgGetUniformfvSH(VGint location, VGfloat *params);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
#endif /* _OPENVG_H */
|
104
simgear/canvas/ShaderVG/include/vg/vgu.h
Normal file
104
simgear/canvas/ShaderVG/include/vg/vgu.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _VGU_H
|
||||
#define _VGU_H
|
||||
|
||||
#include "openvg.h"
|
||||
|
||||
#define VGU_VERSION_1_0 1
|
||||
#define VGU_VERSION_1_0_1 1
|
||||
|
||||
#ifndef VGU_API_CALL
|
||||
#define VGU_API_CALL VG_API_CALL
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
VGU_NO_ERROR = 0,
|
||||
VGU_BAD_HANDLE_ERROR = 0xF000,
|
||||
VGU_ILLEGAL_ARGUMENT_ERROR = 0xF001,
|
||||
VGU_OUT_OF_MEMORY_ERROR = 0xF002,
|
||||
VGU_PATH_CAPABILITY_ERROR = 0xF003,
|
||||
VGU_BAD_WARP_ERROR = 0xF004
|
||||
} VGUErrorCode;
|
||||
|
||||
typedef enum {
|
||||
VGU_ARC_OPEN = 0xF100,
|
||||
VGU_ARC_CHORD = 0xF101,
|
||||
VGU_ARC_PIE = 0xF102
|
||||
} VGUArcType;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguLine(VGPath path,
|
||||
VGfloat x0, VGfloat y0,
|
||||
VGfloat x1, VGfloat y1);
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguPolygon(VGPath path,
|
||||
const VGfloat * points, VGint count,
|
||||
VGboolean closed);
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguRect(VGPath path,
|
||||
VGfloat x, VGfloat y,
|
||||
VGfloat width, VGfloat height);
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguRoundRect(VGPath path,
|
||||
VGfloat x, VGfloat y,
|
||||
VGfloat width, VGfloat height,
|
||||
VGfloat arcWidth, VGfloat arcHeight);
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguEllipse(VGPath path,
|
||||
VGfloat cx, VGfloat cy,
|
||||
VGfloat width, VGfloat height);
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguArc(VGPath path,
|
||||
VGfloat x, VGfloat y,
|
||||
VGfloat width, VGfloat height,
|
||||
VGfloat startAngle, VGfloat angleExtent,
|
||||
VGUArcType arcType);
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguComputeWarpQuadToSquare(VGfloat sx0, VGfloat sy0,
|
||||
VGfloat sx1, VGfloat sy1,
|
||||
VGfloat sx2, VGfloat sy2,
|
||||
VGfloat sx3, VGfloat sy3,
|
||||
VGfloat * matrix);
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguComputeWarpSquareToQuad(VGfloat dx0, VGfloat dy0,
|
||||
VGfloat dx1, VGfloat dy1,
|
||||
VGfloat dx2, VGfloat dy2,
|
||||
VGfloat dx3, VGfloat dy3,
|
||||
VGfloat * matrix);
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguComputeWarpQuadToQuad(VGfloat dx0, VGfloat dy0,
|
||||
VGfloat dx1, VGfloat dy1,
|
||||
VGfloat dx2, VGfloat dy2,
|
||||
VGfloat dx3, VGfloat dy3,
|
||||
VGfloat sx0, VGfloat sy0,
|
||||
VGfloat sx1, VGfloat sy1,
|
||||
VGfloat sx2, VGfloat sy2,
|
||||
VGfloat sx3, VGfloat sy3,
|
||||
VGfloat * matrix);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* #ifndef _VGU_H */
|
23
simgear/canvas/ShaderVG/src/CMakeLists.txt
Normal file
23
simgear/canvas/ShaderVG/src/CMakeLists.txt
Normal file
@ -0,0 +1,23 @@
|
||||
include(SimGearComponent)
|
||||
|
||||
set(HEADERS
|
||||
../include/vg/openvg.h
|
||||
../include/vg/vgu.h
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
shaders.c
|
||||
shArrays.c
|
||||
shContext.c
|
||||
shExtensions.c
|
||||
shGeometry.c
|
||||
shImage.c
|
||||
shPaint.c
|
||||
shParams.c
|
||||
shPath.c
|
||||
shPipeline.c
|
||||
shVectors.c
|
||||
shVgu.c
|
||||
)
|
||||
|
||||
simgear_scene_component(ShivaVG canvas/ShivaVG "${SOURCES}" "${HEADERS}")
|
31
simgear/canvas/ShaderVG/src/Makefile.am
Normal file
31
simgear/canvas/ShaderVG/src/Makefile.am
Normal file
@ -0,0 +1,31 @@
|
||||
lib_LTLIBRARIES = libOpenVG.la
|
||||
libOpenVG_la_CFLAGS = -pedantic -I$(top_builddir)/include/vg
|
||||
libOpenVG_la_SOURCES =\
|
||||
shDefs.h\
|
||||
shExtensions.h\
|
||||
shArrayBase.h\
|
||||
shArrays.h\
|
||||
shVectors.h\
|
||||
shPath.h\
|
||||
shImage.h\
|
||||
shPaint.h\
|
||||
shGeometry.h\
|
||||
shContext.h\
|
||||
shaders.h\
|
||||
shExtensions.c\
|
||||
shArrays.c\
|
||||
shVectors.c\
|
||||
shPath.c\
|
||||
shImage.c\
|
||||
shPaint.c\
|
||||
shGeometry.c\
|
||||
shPipeline.c\
|
||||
shParams.c\
|
||||
shContext.c\
|
||||
shaders.c\
|
||||
shVgu.c
|
||||
|
||||
VG_includedir = $(includedir)/vg
|
||||
VG_include_HEADERS =\
|
||||
$(top_builddir)/include/vg/openvg.h\
|
||||
$(top_builddir)/include/vg/vgu.h
|
370
simgear/canvas/ShaderVG/src/shArrayBase.h
Normal file
370
simgear/canvas/ShaderVG/src/shArrayBase.h
Normal file
@ -0,0 +1,370 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------
|
||||
* The base for any type of array. According to appropriate
|
||||
* macro definitions, specific array types will be generated
|
||||
* and their manipulation functions respectively.
|
||||
*
|
||||
* This code assumes the following are defined:
|
||||
* _ITEM_T: the type of the items in the array
|
||||
* _ARRAY_T: the name of the structure
|
||||
* _FUNC_T: the prefix to prepend to each function
|
||||
*
|
||||
* And at least one of these:
|
||||
* _ARRAY_DECLARE: generate structure declaration
|
||||
* _ARRAY_DEFINE: generate function definitions
|
||||
*-----------------------------------------------------------*/
|
||||
|
||||
#ifndef __SHARRAYBASE_H
|
||||
#define __SHARRAYBASE_H
|
||||
|
||||
#include "shDefs.h"
|
||||
|
||||
#define VAL(x,y) x ## y
|
||||
#define JN(x,y) VAL(x,y)
|
||||
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------
|
||||
* The rest is not #ifndef protected to allow
|
||||
* for various array type definitions.
|
||||
*--------------------------------------------*/
|
||||
|
||||
|
||||
#ifdef _ARRAY_DECLARE
|
||||
typedef struct
|
||||
{
|
||||
_ITEM_T *items;
|
||||
SHint32 capacity;
|
||||
SHint32 size;
|
||||
SHint outofmemory;
|
||||
|
||||
} _ARRAY_T;
|
||||
#endif
|
||||
|
||||
|
||||
void JN(_ARRAY_T,_ctor) (_ARRAY_T *a)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
a->items = (_ITEM_T*)malloc(sizeof(_ITEM_T));
|
||||
|
||||
if (!a->items) {
|
||||
a->outofmemory = 1;
|
||||
a->capacity = 0;
|
||||
a->size = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
a->outofmemory = 0;
|
||||
a->capacity = 1;
|
||||
a->size = 0;
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
void JN(_ARRAY_T,_dtor) (_ARRAY_T *a)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
if (a->items) {
|
||||
free(a->items);
|
||||
a->items = NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
void JN(_FUNC_T,Clear) (_ARRAY_T *a)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
a->size = 0;
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
/*--------------------------------------------------------
|
||||
* Set the capacity of the array. In case of reallocation
|
||||
* the items are not preserved.
|
||||
*--------------------------------------------------------*/
|
||||
|
||||
int JN(_FUNC_T,Realloc) (_ARRAY_T *a, SHint newsize)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
_ITEM_T *newitems = 0;
|
||||
|
||||
SH_ASSERT(newsize > 0);
|
||||
if (newsize == a->capacity)
|
||||
return 1;
|
||||
|
||||
newitems = (_ITEM_T*)malloc(newsize * sizeof(_ITEM_T));
|
||||
|
||||
if (!newitems) {
|
||||
a->outofmemory = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a->items)
|
||||
free(a->items);
|
||||
|
||||
a->outofmemory = 0;
|
||||
a->items = newitems;
|
||||
a->capacity = newsize;
|
||||
a->size = 0;
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Asserts the capacity is at least [newsize]. In case
|
||||
* of reallocation items are not preserved.
|
||||
*------------------------------------------------------*/
|
||||
|
||||
int JN(_FUNC_T,Reserve) (_ARRAY_T *a, SHint newsize)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
_ITEM_T *newitems = 0;
|
||||
|
||||
SH_ASSERT(newsize >= 0);
|
||||
if (newsize <= a->capacity)
|
||||
return 1;
|
||||
|
||||
newitems = (_ITEM_T*)malloc(newsize * sizeof(_ITEM_T));
|
||||
|
||||
if (!newitems) {
|
||||
a->outofmemory = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a->items)
|
||||
free(a->items);
|
||||
|
||||
a->outofmemory = 0;
|
||||
a->items = newitems;
|
||||
a->capacity = newsize;
|
||||
a->size = 0;
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Asserts the capacity is at least [newsize]. In case
|
||||
* of reallocation items are copied.
|
||||
*------------------------------------------------------*/
|
||||
|
||||
int JN(_FUNC_T,ReserveAndCopy) (_ARRAY_T *a, SHint newsize)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
_ITEM_T *newitems = 0;
|
||||
|
||||
SH_ASSERT(newsize >= 0);
|
||||
if (newsize <= a->capacity)
|
||||
return 1;
|
||||
|
||||
newitems = (_ITEM_T*)realloc(a->items, newsize * sizeof(_ITEM_T));
|
||||
|
||||
if (!newitems) {
|
||||
a->outofmemory = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
a->outofmemory = 0;
|
||||
a->items = newitems;
|
||||
a->capacity = newsize;
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
int JN(_FUNC_T,PushBack) (_ARRAY_T *a, _ITEM_T item)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
if (a->capacity == 0) {
|
||||
JN(_FUNC_T,Realloc)(a, 1);
|
||||
if (a->outofmemory)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a->size + 1 > a->capacity)
|
||||
JN(_FUNC_T,ReserveAndCopy)(a, a->capacity*2);
|
||||
|
||||
if (a->outofmemory)
|
||||
return 0;
|
||||
|
||||
a->items[a->size++] = item;
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
int JN(_FUNC_T,PushBackP) (_ARRAY_T *a, _ITEM_T *item)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
if (a->capacity == 0) {
|
||||
JN(_FUNC_T,Realloc)(a, 1);
|
||||
if (a->outofmemory)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a->size + 1 > a->capacity)
|
||||
JN(_FUNC_T,ReserveAndCopy)(a, a->capacity*2);
|
||||
|
||||
if (a->outofmemory)
|
||||
return 0;
|
||||
|
||||
a->items[a->size++] = *item;
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
void JN(_FUNC_T,PopBack) (_ARRAY_T *a)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
SH_ASSERT(a->size);
|
||||
--a->size;
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
_ITEM_T JN(_FUNC_T,Front) (_ARRAY_T *a)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
SH_ASSERT(a->size);
|
||||
return a->items[0];
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
_ITEM_T* JN(_FUNC_T,FrontP) (_ARRAY_T *a)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
SH_ASSERT(a->size);
|
||||
return &a->items[0];
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
_ITEM_T JN(_FUNC_T,Back) (_ARRAY_T *a)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
SH_ASSERT(a->size);
|
||||
return a->items[a->size - 1];
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
_ITEM_T* JN(_FUNC_T,BackP) (_ARRAY_T *a)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
SH_ASSERT(a->size);
|
||||
return &a->items[a->size - 1];
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
_ITEM_T JN(_FUNC_T,At) (_ARRAY_T *a, SHint index)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
SH_ASSERT(index >= 0);
|
||||
SH_ASSERT(index < a->size);
|
||||
return a->items[index];
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
_ITEM_T* JN(_FUNC_T,AtP) (_ARRAY_T *a, SHint index)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
SH_ASSERT(index >= 0);
|
||||
SH_ASSERT(index < a->size);
|
||||
return &a->items[index];
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
SHint JN(_FUNC_T,Find) (_ARRAY_T *a, _ITEM_T item)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<a->size; ++i) {
|
||||
#ifdef _COMPARE_T
|
||||
if (_COMPARE_T(a->items[i], item))
|
||||
return i;
|
||||
#else
|
||||
if (a->items[i] == item)
|
||||
return i;
|
||||
#endif
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
void JN(_FUNC_T,RemoveAt) (_ARRAY_T *a, SHint index)
|
||||
#ifdef _ARRAY_DEFINE
|
||||
{
|
||||
int i;
|
||||
SH_ASSERT(index >= 0);
|
||||
SH_ASSERT(index < a->size);
|
||||
for (i=index; i<a->size-1; ++i)
|
||||
a->items[i] = a->items[i+1];
|
||||
a->size--;
|
||||
}
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
#undef _ITEM_T
|
||||
#undef _ARRAY_T
|
||||
#undef _FUNC_T
|
||||
#undef _COMPARE_T
|
||||
#undef _ARRAY_DEFINE
|
||||
#undef _ARRAY_DECLARE
|
50
simgear/canvas/ShaderVG/src/shArrays.c
Normal file
50
simgear/canvas/ShaderVG/src/shArrays.c
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/*--------------------------------------------
|
||||
* Definitions of all the arrays used
|
||||
*--------------------------------------------*/
|
||||
|
||||
#include "shArrays.h"
|
||||
|
||||
#define _ITEM_T SHint
|
||||
#define _ARRAY_T SHIntArray
|
||||
#define _FUNC_T shIntArray
|
||||
#define _ARRAY_DEFINE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
#define _ITEM_T SHuint8
|
||||
#define _ARRAY_T SHUint8Array
|
||||
#define _FUNC_T shUint8Array
|
||||
#define _ARRAY_DEFINE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
#define _ITEM_T SHfloat
|
||||
#define _ARRAY_T SHFloatArray
|
||||
#define _FUNC_T shFloatArray
|
||||
#define _ARRAY_DEFINE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
#define _ITEM_T SHRectangle
|
||||
#define _ARRAY_T SHRectArray
|
||||
#define _FUNC_T shRectArray
|
||||
#define _COMPARE_T(x,y) 1
|
||||
#define _ARRAY_DEFINE
|
||||
#include "shArrayBase.h"
|
55
simgear/canvas/ShaderVG/src/shArrays.h
Normal file
55
simgear/canvas/ShaderVG/src/shArrays.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/*--------------------------------------------
|
||||
* Declarations of all the arrays used
|
||||
*--------------------------------------------*/
|
||||
|
||||
#ifndef __SHARRAYS_H
|
||||
#define __SHARRAYS_H
|
||||
|
||||
#include "shVectors.h"
|
||||
|
||||
|
||||
#define _ITEM_T SHint
|
||||
#define _ARRAY_T SHIntArray
|
||||
#define _FUNC_T shIntArray
|
||||
#define _ARRAY_DECLARE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
#define _ITEM_T SHuint8
|
||||
#define _ARRAY_T SHUint8Array
|
||||
#define _FUNC_T shUint8Array
|
||||
#define _ARRAY_DECLARE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
#define _ITEM_T SHfloat
|
||||
#define _ARRAY_T SHFloatArray
|
||||
#define _FUNC_T shFloatArray
|
||||
#define _ARRAY_DECLARE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
#define _ITEM_T SHRectangle
|
||||
#define _ARRAY_T SHRectArray
|
||||
#define _FUNC_T shRectArray
|
||||
#define _ARRAY_DECLARE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
#endif
|
51
simgear/canvas/ShaderVG/src/shConfig.h
Normal file
51
simgear/canvas/ShaderVG/src/shConfig.h
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
#ifndef __SHCONFIG_H
|
||||
#define __SHCONFIG_H
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Identify the operating system
|
||||
////////////////////////////////////////////////////////////
|
||||
#if defined(_WIN32) || defined(__WIN32__)
|
||||
|
||||
// Windows
|
||||
#define VG_API_WINDOWS
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#elif defined(linux) || defined(__linux)
|
||||
|
||||
// Linux
|
||||
#define VG_API_LINUX
|
||||
|
||||
#elif defined(__APPLE__) || defined(MACOSX) || defined(macintosh) || defined(Macintosh)
|
||||
|
||||
// MacOS
|
||||
#define VG_API_MACOSX
|
||||
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
|
||||
// FreeBSD
|
||||
#define VG_API_FREEBSD
|
||||
|
||||
#elif defined(__OpenBSD__)
|
||||
|
||||
// FreeBSD
|
||||
#define VG_API_OPENBSD
|
||||
|
||||
#else
|
||||
|
||||
// Unsupported system
|
||||
#error This operating system is not supported by SFML library
|
||||
|
||||
#endif
|
||||
|
||||
// We currently do not support using images (inside paths). If we were going to
|
||||
// use it loading and unloading needs to happen within OpenSceneGraph to handle
|
||||
// synchronization correctly in multithreading mode.
|
||||
#define SH_NO_IMAGE
|
||||
|
||||
#endif // __SHCONFIG_H
|
504
simgear/canvas/ShaderVG/src/shContext.c
Normal file
504
simgear/canvas/ShaderVG/src/shContext.c
Normal file
@ -0,0 +1,504 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#define VG_API_EXPORT
|
||||
#include "vg/openvg.h"
|
||||
#include "shContext.h"
|
||||
#include "shaders.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*-----------------------------------------------------
|
||||
* Simple functions to create a VG context instance
|
||||
* on top of an existing OpenGL context.
|
||||
* TODO: There is no mechanics yet to asure the OpenGL
|
||||
* context exists and to choose which context / window
|
||||
* to bind to.
|
||||
*-----------------------------------------------------*/
|
||||
|
||||
static VGContext *g_context = NULL;
|
||||
|
||||
VG_API_CALL VGboolean vgCreateContextSH(VGint width, VGint height)
|
||||
{
|
||||
/* return if already created */
|
||||
if (g_context) return VG_TRUE;
|
||||
|
||||
/* create new context */
|
||||
SH_NEWOBJ(VGContext, g_context);
|
||||
if (!g_context) return VG_FALSE;
|
||||
|
||||
/* init surface info */
|
||||
g_context->surfaceWidth = width;
|
||||
g_context->surfaceHeight = height;
|
||||
|
||||
/* setup GL projection */
|
||||
/* We handle viewport and projection ourselves...
|
||||
glViewport(0,0,width,height); */
|
||||
|
||||
/* Setup shader for rendering*/
|
||||
g_context->userShaderVertex = NULL;
|
||||
g_context->userShaderFragment = NULL;
|
||||
shInitPiplelineShaders();
|
||||
|
||||
/* Setup shaders for making color ramp */
|
||||
shInitRampShaders();
|
||||
|
||||
return VG_TRUE;
|
||||
}
|
||||
|
||||
VG_API_CALL VGboolean vgHasContextSH()
|
||||
{
|
||||
return g_context != NULL;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgResizeSurfaceSH(VGint width, VGint height)
|
||||
{
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
/* update surface info */
|
||||
context->surfaceWidth = width;
|
||||
context->surfaceHeight = height;
|
||||
|
||||
/* setup GL projection */
|
||||
/* We handle viewport and projection ourselves...
|
||||
glViewport(0,0,width,height); */
|
||||
|
||||
/* Setup projection matrix */
|
||||
//float mat[16];
|
||||
//float volume = fmax(width, height) / 2;
|
||||
//shCalcOrtho2D(mat, 0, width, 0, height, -volume, volume);
|
||||
glUseProgram(context->progDraw);
|
||||
//glUniformMatrix4fv(context->locationDraw.projection, 1, GL_FALSE, mat);
|
||||
GL_CEHCK_ERROR;
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
VG_API_CALL void vgDestroyContextSH()
|
||||
{
|
||||
/* return if already released */
|
||||
if (!g_context) return;
|
||||
|
||||
/* delete context object */
|
||||
SH_DELETEOBJ(VGContext, g_context);
|
||||
g_context = NULL;
|
||||
}
|
||||
|
||||
VGContext* shGetContext()
|
||||
{
|
||||
SH_ASSERT(g_context);
|
||||
return g_context;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------
|
||||
* VGContext constructor
|
||||
*-----------------------------------------------------*/
|
||||
|
||||
void shLoadExtensions(void *c);
|
||||
|
||||
void VGContext_ctor(VGContext *c)
|
||||
{
|
||||
/* Surface info */
|
||||
c->surfaceWidth = 0;
|
||||
c->surfaceHeight = 0;
|
||||
|
||||
/* GetString info */
|
||||
strncpy(c->vendor, "Takuma Hayashi", sizeof(c->vendor));
|
||||
strncpy(c->renderer, "ShaderVG", sizeof(c->renderer));
|
||||
strncpy(c->version, "1.0.0", sizeof(c->version));
|
||||
strncpy(c->extensions, "", sizeof(c->extensions));
|
||||
|
||||
/* Mode settings */
|
||||
c->matrixMode = VG_MATRIX_PATH_USER_TO_SURFACE;
|
||||
c->fillRule = VG_EVEN_ODD;
|
||||
c->imageQuality = VG_IMAGE_QUALITY_FASTER;
|
||||
c->renderingQuality = VG_RENDERING_QUALITY_BETTER;
|
||||
c->blendMode = VG_BLEND_SRC_OVER;
|
||||
c->imageMode = VG_DRAW_IMAGE_NORMAL;
|
||||
|
||||
/* Scissor rectangles */
|
||||
SH_INITOBJ(SHRectArray, c->scissor);
|
||||
c->scissoring = VG_FALSE;
|
||||
c->masking = VG_FALSE;
|
||||
|
||||
/* Stroke parameters */
|
||||
c->strokeLineWidth = 1.0f;
|
||||
c->strokeCapStyle = VG_CAP_BUTT;
|
||||
c->strokeJoinStyle = VG_JOIN_MITER;
|
||||
c->strokeMiterLimit = 4.0f;
|
||||
c->strokeDashPhase = 0.0f;
|
||||
c->strokeDashPhaseReset = VG_FALSE;
|
||||
SH_INITOBJ(SHFloatArray, c->strokeDashPattern);
|
||||
|
||||
/* Edge fill color for vgConvolve and pattern paint */
|
||||
CSET(c->tileFillColor, 0,0,0,0);
|
||||
|
||||
/* Color for vgClear */
|
||||
CSET(c->clearColor, 0,0,0,0);
|
||||
|
||||
/* Color components layout inside pixel */
|
||||
c->pixelLayout = VG_PIXEL_LAYOUT_UNKNOWN;
|
||||
|
||||
/* Source format for image filters */
|
||||
c->filterFormatLinear = VG_FALSE;
|
||||
c->filterFormatPremultiplied = VG_FALSE;
|
||||
c->filterChannelMask = VG_RED|VG_GREEN|VG_BLUE|VG_ALPHA;
|
||||
|
||||
/* Matrices */
|
||||
SH_INITOBJ(SHMatrix3x3, c->pathTransform);
|
||||
SH_INITOBJ(SHMatrix3x3, c->imageTransform);
|
||||
SH_INITOBJ(SHMatrix3x3, c->fillTransform);
|
||||
SH_INITOBJ(SHMatrix3x3, c->strokeTransform);
|
||||
|
||||
/* Paints */
|
||||
c->fillPaint = NULL;
|
||||
c->strokePaint = NULL;
|
||||
SH_INITOBJ(SHPaint, c->defaultPaint);
|
||||
|
||||
/* Error */
|
||||
c->error = VG_NO_ERROR;
|
||||
|
||||
/* Resources */
|
||||
SH_INITOBJ(SHPathArray, c->paths);
|
||||
SH_INITOBJ(SHPaintArray, c->paints);
|
||||
SH_INITOBJ(SHImageArray, c->images);
|
||||
|
||||
shLoadExtensions(c);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------
|
||||
* VGContext constructor
|
||||
*-----------------------------------------------------*/
|
||||
|
||||
void VGContext_dtor(VGContext *c)
|
||||
{
|
||||
int i;
|
||||
|
||||
SH_DEINITOBJ(SHRectArray, c->scissor);
|
||||
SH_DEINITOBJ(SHFloatArray, c->strokeDashPattern);
|
||||
|
||||
/* Destroy resources */
|
||||
for (i=0; i<c->paths.size; ++i)
|
||||
SH_DELETEOBJ(SHPath, c->paths.items[i]);
|
||||
|
||||
for (i=0; i<c->paints.size; ++i)
|
||||
SH_DELETEOBJ(SHPaint, c->paints.items[i]);
|
||||
|
||||
for (i=0; i<c->images.size; ++i)
|
||||
SH_DELETEOBJ(SHImage, c->images.items[i]);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
* Tries to find resources in this context
|
||||
*--------------------------------------------------*/
|
||||
|
||||
SHint shIsValidPath(VGContext *c, VGHandle h)
|
||||
{
|
||||
int index = shPathArrayFind(&c->paths, (SHPath*)h);
|
||||
return (index == -1) ? 0 : 1;
|
||||
}
|
||||
|
||||
SHint shIsValidPaint(VGContext *c, VGHandle h)
|
||||
{
|
||||
int index = shPaintArrayFind(&c->paints, (SHPaint*)h);
|
||||
return (index == -1) ? 0 : 1;
|
||||
}
|
||||
|
||||
SHint shIsValidImage(VGContext *c, VGHandle h)
|
||||
{
|
||||
int index = shImageArrayFind(&c->images, (SHImage*)h);
|
||||
return (index == -1) ? 0 : 1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
* Tries to find a resources in this context and
|
||||
* return its type or invalid flag.
|
||||
*--------------------------------------------------*/
|
||||
|
||||
SHResourceType shGetResourceType(VGContext *c, VGHandle h)
|
||||
{
|
||||
if (shIsValidPath(c, h))
|
||||
return SH_RESOURCE_PATH;
|
||||
|
||||
else if (shIsValidPaint(c, h))
|
||||
return SH_RESOURCE_PAINT;
|
||||
|
||||
else if (shIsValidImage(c, h))
|
||||
return SH_RESOURCE_IMAGE;
|
||||
|
||||
else
|
||||
return SH_RESOURCE_INVALID;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------
|
||||
* Sets the specified error on the given context if
|
||||
* there is no pending error yet
|
||||
*-----------------------------------------------------*/
|
||||
|
||||
void shSetError(VGContext *c, VGErrorCode e)
|
||||
{
|
||||
if (c->error == VG_NO_ERROR)
|
||||
c->error = e;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
* Returns the oldest error pending on the current
|
||||
* context and clears its error code
|
||||
*--------------------------------------------------*/
|
||||
|
||||
VG_API_CALL VGErrorCode vgGetError(void)
|
||||
{
|
||||
VGErrorCode error;
|
||||
VG_GETCONTEXT(VG_NO_CONTEXT_ERROR);
|
||||
error = context->error;
|
||||
context->error = VG_NO_ERROR;
|
||||
VG_RETURN(error);
|
||||
}
|
||||
|
||||
VG_API_CALL void vgFlush(void)
|
||||
{
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
glFlush();
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
VG_API_CALL void vgFinish(void)
|
||||
{
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
glFinish();
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
VG_API_CALL void vgMask(VGImage mask, VGMaskOperation operation,
|
||||
VGint x, VGint y, VGint width, VGint height)
|
||||
{
|
||||
}
|
||||
|
||||
VG_API_CALL void vgClear(VGint x, VGint y, VGint width, VGint height)
|
||||
{
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
/* Clip to window */
|
||||
if (x < 0) x = 0;
|
||||
if (y < 0) y = 0;
|
||||
if (width > context->surfaceWidth) width = context->surfaceWidth;
|
||||
if (height > context->surfaceHeight) height = context->surfaceHeight;
|
||||
|
||||
/* Check if scissoring needed */
|
||||
if (x > 0 || y > 0 ||
|
||||
width < context->surfaceWidth ||
|
||||
height < context->surfaceHeight) {
|
||||
|
||||
glScissor(x, y, width, height);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
/* Clear GL color buffer */
|
||||
/* TODO: what about stencil and depth? when do we clear that?
|
||||
we would need some kind of special "begin" function at
|
||||
beginning of each drawing or clear the planes prior to each
|
||||
drawing where it takes places */
|
||||
glClearColor(context->clearColor.r,
|
||||
context->clearColor.g,
|
||||
context->clearColor.b,
|
||||
context->clearColor.a);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT |
|
||||
GL_STENCIL_BUFFER_BIT |
|
||||
GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Returns the matrix currently selected via VG_MATRIX_MODE
|
||||
*-----------------------------------------------------------*/
|
||||
|
||||
SHMatrix3x3* shCurrentMatrix(VGContext *c)
|
||||
{
|
||||
switch(c->matrixMode) {
|
||||
case VG_MATRIX_PATH_USER_TO_SURFACE:
|
||||
return &c->pathTransform;
|
||||
case VG_MATRIX_IMAGE_USER_TO_SURFACE:
|
||||
return &c->imageTransform;
|
||||
case VG_MATRIX_FILL_PAINT_TO_USER:
|
||||
return &c->fillTransform;
|
||||
default:
|
||||
return &c->strokeTransform;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------
|
||||
* Sets the current matrix to identity
|
||||
*--------------------------------------*/
|
||||
|
||||
VG_API_CALL void vgLoadIdentity(void)
|
||||
{
|
||||
SHMatrix3x3 *m;
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
m = shCurrentMatrix(context);
|
||||
IDMAT((*m));
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------
|
||||
* Loads values into the current matrix from the given array.
|
||||
* Matrix affinity is preserved if an affine matrix is loaded.
|
||||
*-------------------------------------------------------------*/
|
||||
|
||||
VG_API_CALL void vgLoadMatrix(const VGfloat * mm)
|
||||
{
|
||||
SHMatrix3x3 *m;
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
VG_RETURN_ERR_IF(!mm, VG_ILLEGAL_ARGUMENT_ERROR, VG_NO_RETVAL);
|
||||
/* TODO: check matrix array alignment */
|
||||
|
||||
m = shCurrentMatrix(context);
|
||||
|
||||
if (context->matrixMode == VG_MATRIX_IMAGE_USER_TO_SURFACE) {
|
||||
|
||||
SETMAT((*m),
|
||||
mm[0], mm[3], mm[6],
|
||||
mm[1], mm[4], mm[7],
|
||||
mm[2], mm[5], mm[8]);
|
||||
}else{
|
||||
|
||||
SETMAT((*m),
|
||||
mm[0], mm[3], mm[6],
|
||||
mm[1], mm[4], mm[7],
|
||||
0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
* Outputs the values of the current matrix into the given array
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
VG_API_CALL void vgGetMatrix(VGfloat * mm)
|
||||
{
|
||||
SHMatrix3x3 *m; int i,j,k=0;
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
VG_RETURN_ERR_IF(!mm, VG_ILLEGAL_ARGUMENT_ERROR, VG_NO_RETVAL);
|
||||
/* TODO: check matrix array alignment */
|
||||
|
||||
m = shCurrentMatrix(context);
|
||||
|
||||
for (i=0; i<3; ++i)
|
||||
for (j=0; j<3; ++j)
|
||||
mm[k++] = m->m[j][i];
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------
|
||||
* Right-multiplies the current matrix with the one specified
|
||||
* in the given array. Matrix affinity is preserved if an
|
||||
* affine matrix is begin multiplied.
|
||||
*-------------------------------------------------------------*/
|
||||
|
||||
VG_API_CALL void vgMultMatrix(const VGfloat * mm)
|
||||
{
|
||||
SHMatrix3x3 *m, mul, temp;
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
VG_RETURN_ERR_IF(!mm, VG_ILLEGAL_ARGUMENT_ERROR, VG_NO_RETVAL);
|
||||
/* TODO: check matrix array alignment */
|
||||
|
||||
m = shCurrentMatrix(context);
|
||||
|
||||
if (context->matrixMode == VG_MATRIX_IMAGE_USER_TO_SURFACE) {
|
||||
|
||||
SETMAT(mul,
|
||||
mm[0], mm[3], mm[6],
|
||||
mm[1], mm[4], mm[7],
|
||||
mm[2], mm[5], mm[8]);
|
||||
}else{
|
||||
|
||||
SETMAT(mul,
|
||||
mm[0], mm[3], mm[6],
|
||||
mm[1], mm[4], mm[7],
|
||||
0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
MULMATMAT((*m), mul, temp);
|
||||
SETMATMAT((*m), temp);
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
VG_API_CALL void vgTranslate(VGfloat tx, VGfloat ty)
|
||||
{
|
||||
SHMatrix3x3 *m;
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
m = shCurrentMatrix(context);
|
||||
TRANSLATEMATR((*m), tx, ty);
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
VG_API_CALL void vgScale(VGfloat sx, VGfloat sy)
|
||||
{
|
||||
SHMatrix3x3 *m;
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
m = shCurrentMatrix(context);
|
||||
SCALEMATR((*m), sx, sy);
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
VG_API_CALL void vgShear(VGfloat shx, VGfloat shy)
|
||||
{
|
||||
SHMatrix3x3 *m;
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
m = shCurrentMatrix(context);
|
||||
SHEARMATR((*m), shx, shy);
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
VG_API_CALL void vgRotate(VGfloat angle)
|
||||
{
|
||||
SHfloat a;
|
||||
SHMatrix3x3 *m;
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
a = SH_DEG2RAD(angle);
|
||||
m = shCurrentMatrix(context);
|
||||
ROTATEMATR((*m), a);
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
VG_API_CALL VGHardwareQueryResult vgHardwareQuery(VGHardwareQueryType key,
|
||||
VGint setting)
|
||||
{
|
||||
return VG_HARDWARE_UNACCELERATED;
|
||||
}
|
196
simgear/canvas/ShaderVG/src/shContext.h
Normal file
196
simgear/canvas/ShaderVG/src/shContext.h
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SHCONTEXT_H
|
||||
#define __SHCONTEXT_H
|
||||
|
||||
#include "shDefs.h"
|
||||
#include "shVectors.h"
|
||||
#include "shArrays.h"
|
||||
#include "shPath.h"
|
||||
#include "shPaint.h"
|
||||
#include "shImage.h"
|
||||
|
||||
/*------------------------------------------------
|
||||
* VGContext object
|
||||
*------------------------------------------------*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SH_RESOURCE_INVALID = 0,
|
||||
SH_RESOURCE_PATH = 1,
|
||||
SH_RESOURCE_PAINT = 2,
|
||||
SH_RESOURCE_IMAGE = 3
|
||||
} SHResourceType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Surface info (since no EGL yet) */
|
||||
SHint surfaceWidth;
|
||||
SHint surfaceHeight;
|
||||
|
||||
/* GetString info */
|
||||
char vendor[256];
|
||||
char renderer[256];
|
||||
char version[256];
|
||||
char extensions[256];
|
||||
|
||||
/* Mode settings */
|
||||
VGMatrixMode matrixMode;
|
||||
VGFillRule fillRule;
|
||||
VGImageQuality imageQuality;
|
||||
VGRenderingQuality renderingQuality;
|
||||
VGBlendMode blendMode;
|
||||
VGImageMode imageMode;
|
||||
|
||||
/* Scissor rectangles */
|
||||
SHRectArray scissor;
|
||||
VGboolean scissoring;
|
||||
VGboolean masking;
|
||||
|
||||
/* Stroke parameters */
|
||||
SHfloat strokeLineWidth;
|
||||
VGCapStyle strokeCapStyle;
|
||||
VGJoinStyle strokeJoinStyle;
|
||||
SHfloat strokeMiterLimit;
|
||||
SHFloatArray strokeDashPattern;
|
||||
SHfloat strokeDashPhase;
|
||||
VGboolean strokeDashPhaseReset;
|
||||
|
||||
/* Edge fill color for vgConvolve and pattern paint */
|
||||
SHColor tileFillColor;
|
||||
|
||||
/* Color for vgClear */
|
||||
SHColor clearColor;
|
||||
|
||||
/* Color components layout inside pixel */
|
||||
VGPixelLayout pixelLayout;
|
||||
|
||||
/* Source format for image filters */
|
||||
VGboolean filterFormatLinear;
|
||||
VGboolean filterFormatPremultiplied;
|
||||
VGbitfield filterChannelMask;
|
||||
|
||||
/* Matrices */
|
||||
SHMatrix3x3 pathTransform;
|
||||
SHMatrix3x3 imageTransform;
|
||||
SHMatrix3x3 fillTransform;
|
||||
SHMatrix3x3 strokeTransform;
|
||||
|
||||
/* Paints */
|
||||
SHPaint* fillPaint;
|
||||
SHPaint* strokePaint;
|
||||
SHPaint defaultPaint;
|
||||
|
||||
VGErrorCode error;
|
||||
|
||||
/* Resources */
|
||||
SHPathArray paths;
|
||||
SHPaintArray paints;
|
||||
SHImageArray images;
|
||||
|
||||
/* Pointers to extensions */
|
||||
|
||||
/* GL locations */
|
||||
struct {
|
||||
GLint pos ;
|
||||
GLint textureUV ;
|
||||
GLint model ;
|
||||
GLint projection ;
|
||||
GLint paintInverted ;
|
||||
GLint drawMode ;
|
||||
GLint imageSampler ;
|
||||
GLint imageMode ;
|
||||
GLint paintType ;
|
||||
GLint rampSampler ;
|
||||
GLint patternSampler ;
|
||||
GLint userSampler ;
|
||||
GLint paintParams ;
|
||||
GLint paintColor ;
|
||||
GLint scaleFactorBias;
|
||||
} locationDraw;
|
||||
|
||||
struct {
|
||||
GLuint step;
|
||||
GLuint stepColor;
|
||||
} locationColorRamp;
|
||||
|
||||
/* GL programs */
|
||||
GLuint progDraw;
|
||||
GLuint progColorRamp;
|
||||
|
||||
/* GL shaders */
|
||||
const void* userShaderVertex;
|
||||
const void* userShaderFragment;
|
||||
GLint vs;
|
||||
GLint fs;
|
||||
|
||||
} VGContext;
|
||||
|
||||
void VGContext_ctor(VGContext *c);
|
||||
void VGContext_dtor(VGContext *c);
|
||||
void shSetError(VGContext *c, VGErrorCode e);
|
||||
SHint shIsValidPath(VGContext *c, VGHandle h);
|
||||
SHint shIsValidPaint(VGContext *c, VGHandle h);
|
||||
SHint shIsValidImage(VGContext *c, VGHandle h);
|
||||
SHResourceType shGetResourceType(VGContext *c, VGHandle h);
|
||||
VGContext* shGetContext();
|
||||
|
||||
/*----------------------------------------------------
|
||||
* TODO: Add mutex locking/unlocking to these macros
|
||||
* to assure sequentiallity in multithreading.
|
||||
*----------------------------------------------------*/
|
||||
|
||||
#define VG_NO_RETVAL
|
||||
|
||||
#define VG_GETCONTEXT(RETVAL) \
|
||||
VGContext *context = shGetContext(); \
|
||||
if (!context) return RETVAL;
|
||||
|
||||
#define VG_RETURN(RETVAL) \
|
||||
{ return RETVAL; }
|
||||
|
||||
#define VG_RETURN_ERR(ERRORCODE, RETVAL) \
|
||||
{ shSetError(context,ERRORCODE); return RETVAL; }
|
||||
|
||||
#define VG_RETURN_ERR_IF(COND, ERRORCODE, RETVAL) \
|
||||
{ if (COND) {shSetError(context,ERRORCODE); return RETVAL;} }
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Same macros but no mutex handling - used by sub-functions
|
||||
*-----------------------------------------------------------*/
|
||||
|
||||
#define SH_NO_RETVAL
|
||||
|
||||
#define SH_GETCONTEXT(RETVAL) \
|
||||
VGContext *context = shGetContext(); \
|
||||
if (!context) return RETVAL;
|
||||
|
||||
#define SH_RETURN(RETVAL) \
|
||||
{ return RETVAL; }
|
||||
|
||||
#define SH_RETURN_ERR(ERRORCODE, RETVAL) \
|
||||
{ shSetError(context,ERRORCODE); return RETVAL; }
|
||||
|
||||
#define SH_RETURN_ERR_IF(COND, ERRORCODE, RETVAL) \
|
||||
{ if (COND) {shSetError(context,ERRORCODE); return RETVAL;} }
|
||||
|
||||
|
||||
#endif /* __SHCONTEXT_H */
|
189
simgear/canvas/ShaderVG/src/shDefs.h
Normal file
189
simgear/canvas/ShaderVG/src/shDefs.h
Normal file
@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SHDEFS_H
|
||||
#define __SHDEFS_H
|
||||
|
||||
/* Standard headers */
|
||||
|
||||
#include "shConfig.h"
|
||||
|
||||
#ifdef VG_API_WINDOWS
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#if !defined(VG_API_MACOSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
/* Disable VGHandle-pointer conversion warnings since we
|
||||
do deal with it by defining VGHandle properly */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable:4311)
|
||||
# pragma warning(disable:4312)
|
||||
#endif
|
||||
|
||||
/* Type definitions */
|
||||
#if HAVE_INTTYPES_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#else
|
||||
|
||||
#define int8_t char
|
||||
#define uint8_t unsigned char
|
||||
#define int16_t short
|
||||
#define uint16_t unsigned short
|
||||
#define int32_t int
|
||||
#define uint32_t unsigned int
|
||||
#define int64_t long long
|
||||
#define uint64_t unsigned long long
|
||||
|
||||
#endif
|
||||
|
||||
typedef int8_t SHint8;
|
||||
typedef uint8_t SHuint8;
|
||||
typedef int16_t SHint16;
|
||||
typedef uint16_t SHuint16;
|
||||
typedef int32_t SHint32;
|
||||
typedef uint32_t SHuint32;
|
||||
typedef float SHfloat32;
|
||||
|
||||
#define SHint SHint32
|
||||
#define SHuint SHuint32
|
||||
#define SHfloat SHfloat32
|
||||
|
||||
/* Maximum / minimum values */
|
||||
|
||||
#define SH_MAX_INT (0x7fffffff)
|
||||
#define SH_MIN_INT (-0x7fffffff-1)
|
||||
|
||||
#define SH_MANTISSA_BITS 23
|
||||
#define SH_EXPONENT_BITS 8
|
||||
|
||||
/* all 1s in exponent yields NaN in IEEE 754 so we take
|
||||
1 less then maximum representable with exponent bits */
|
||||
#define SH_MAX_EXPONENT ((1 << SH_EXPONENT_BITS) - 2)
|
||||
/* maximum representable with mantissa bits */
|
||||
#define SH_MAX_MANTISSA ((1 << SH_MANTISSA_BITS) - 1)
|
||||
/* compose into IEEE754 floating point bit value */
|
||||
#define SH_MAX_FLOAT_BITS (SH_MAX_EXPONENT << SH_MANTISSA_BITS) | SH_MAX_MANTISSA
|
||||
|
||||
typedef union {
|
||||
float f;
|
||||
unsigned int i;
|
||||
} SHfloatint;
|
||||
|
||||
SHfloat getMaxFloat();
|
||||
|
||||
/* Portable function definitions */
|
||||
|
||||
#define SH_SQRT (float)sqrt
|
||||
#define SH_COS (float)cos
|
||||
#define SH_SIN (float)sin
|
||||
#define SH_ACOS (float)acos
|
||||
#define SH_ASIN (float)asin
|
||||
#define SH_ATAN (float)atan
|
||||
#define SH_FLOOR (float)floor
|
||||
#define SH_CEIL (float)ceil
|
||||
#define SH_ASSERT assert
|
||||
|
||||
#if defined(__isnan) || (defined(__APPLE__) && (__GNUC__ == 3))
|
||||
# define SH_ISNAN __isnan
|
||||
#elif defined(_isnan) || defined(WIN32)
|
||||
# define SH_ISNAN _isnan
|
||||
#else
|
||||
# define SH_ISNAN isnan
|
||||
#endif
|
||||
|
||||
|
||||
/* Helper macros */
|
||||
|
||||
#define PI 3.141592654f
|
||||
#define SH_DEG2RAD(a) (a * PI / 180.0f)
|
||||
#define SH_RAD2DEG(a) (a * 180.0f / PI)
|
||||
#define SH_ABS(a) ((a < 0.0f) ? -a : a)
|
||||
#define SH_MAX(a,b) ((a > b) ? a : b)
|
||||
#define SH_MIN(a,b) ((a < b) ? a : b)
|
||||
#define SH_NEARZERO(a) (a >= -0.0001 && a < 0.0001)
|
||||
#define SH_SWAP(a,b) {SHfloat t=a; a=b; b=t;}
|
||||
#define SH_CLAMP(a,min,max) {if (a<min) a=min; if (a>max) a=max; }
|
||||
|
||||
#define SH_NEWOBJ(type,obj) { obj = (type*)malloc(sizeof(type)); if(obj) type ## _ctor(obj); }
|
||||
#define SH_INITOBJ(type,obj){ type ## _ctor(&obj); }
|
||||
#define SH_DEINITOBJ(type,obj) { type ## _dtor(&obj); }
|
||||
#define SH_DELETEOBJ(type,obj) { if(obj) type ## _dtor(obj); free(obj); }
|
||||
|
||||
/* Implementation limits */
|
||||
|
||||
#define SH_MAX_SCISSOR_RECTS 1
|
||||
#define SH_MAX_DASH_COUNT VG_MAXINT
|
||||
#define SH_MAX_IMAGE_WIDTH VG_MAXINT
|
||||
#define SH_MAX_IMAGE_HEIGHT VG_MAXINT
|
||||
#define SH_MAX_IMAGE_PIXELS VG_MAXINT
|
||||
#define SH_MAX_IMAGE_BYTES VG_MAXINT
|
||||
#define SH_MAX_COLOR_RAMP_STOPS 256
|
||||
|
||||
#define SH_MAX_VERTICES 999999999
|
||||
#define SH_MAX_RECURSE_DEPTH 16
|
||||
|
||||
#define SH_GRADIENT_TEX_WIDTH 1024
|
||||
#define SH_GRADIENT_TEX_HEIGHT 1
|
||||
#define SH_GRADIENT_TEX_COORDSIZE 4096 /* 1024 * RGBA */
|
||||
|
||||
/* OpenGL headers */
|
||||
|
||||
#if defined(VG_API_LINUX) || defined(VG_API_FREEBSD) || defined(VG_API_OPENBSD)
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
#elif defined(VG_API_MACOSX)
|
||||
#include <OpenGL/gl.h>
|
||||
#elif defined(VG_API_WINDOWS)
|
||||
#include <GL/gl.h>
|
||||
#else
|
||||
#define GL_GLEXT_LEGACY /* don't include glext.h */
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
|
||||
#include "shExtensions.h"
|
||||
|
||||
#define GL_GET_ERROR printf("glGetError() -> %d line:%d file:%s\r\n", glGetError(), __LINE__, __FILE__)
|
||||
#define GL_CEHCK_ERROR \
|
||||
{ \
|
||||
GLint err = glGetError(); \
|
||||
if(err){\
|
||||
printf("glGetError() -> %d \r\n", err);\
|
||||
assert(0);\
|
||||
}\
|
||||
}
|
||||
|
||||
// GL_TEXTURE0 :imageSampler
|
||||
// GL_TEXTURE1 :rampSampler or patternSampler
|
||||
// GL_TEXTURE2 :User defined
|
||||
#define SH_TEXTURE_USER_TOP GL_TEXTURE2
|
||||
|
||||
#endif /* __SHDEFS_H */
|
136
simgear/canvas/ShaderVG/src/shExtensions.c
Normal file
136
simgear/canvas/ShaderVG/src/shExtensions.c
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#define VG_API_EXPORT
|
||||
#include "shExtensions.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <GL/glcorearb.h>
|
||||
|
||||
/*-----------------------------------------------------
|
||||
* OpenGL core profile
|
||||
*-----------------------------------------------------*/
|
||||
#if defined(_WIN32)
|
||||
PFNGLUNIFORM1IPROC glUniform1i;
|
||||
PFNGLUNIFORM2FVPROC glUniform2fv;
|
||||
PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv;
|
||||
PFNGLUNIFORM2FPROC glUniform2f;
|
||||
PFNGLUNIFORM4FVPROC glUniform4fv;
|
||||
PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
|
||||
PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
|
||||
PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
|
||||
PFNGLUSEPROGRAMPROC glUseProgram;
|
||||
PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
|
||||
PFNGLCREATESHADERPROC glCreateShader;
|
||||
PFNGLSHADERSOURCEPROC glShaderSource;
|
||||
PFNGLCOMPILESHADERPROC glCompileShader;
|
||||
PFNGLGETSHADERIVPROC glGetShaderiv;
|
||||
PFNGLATTACHSHADERPROC glAttachShader;
|
||||
PFNGLLINKPROGRAMPROC glLinkProgram;
|
||||
PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
|
||||
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
|
||||
PFNGLDELETESHADERPROC glDeleteShader;
|
||||
PFNGLDELETEPROGRAMPROC glDeleteProgram;
|
||||
PFNGLUNIFORM1FPROC glUniform1f;
|
||||
PFNGLUNIFORM3FPROC glUniform3f;
|
||||
PFNGLUNIFORM4FPROC glUniform4f;
|
||||
PFNGLUNIFORM1FVPROC glUniform1fv;
|
||||
PFNGLUNIFORM3FVPROC glUniform3fv;
|
||||
PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv;
|
||||
PFNGLGETUNIFORMFVPROC glGetUniformfv;
|
||||
PFNGLCREATEPROGRAMPROC glCreateProgram;
|
||||
PFNGLACTIVETEXTUREPROC glActiveTexture;
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------
|
||||
* Extensions check
|
||||
*-----------------------------------------------------*/
|
||||
static int checkExtension(const char *extensions, const char *name)
|
||||
{
|
||||
int nlen = (int)strlen(name);
|
||||
int elen = (int)strlen(extensions);
|
||||
const char *e = extensions;
|
||||
if(nlen <= 0) return 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
/* Try to find sub-string */
|
||||
e = strstr(e, name);
|
||||
if (e == NULL) return 0;
|
||||
/* Check if last */
|
||||
if (e == extensions + elen - nlen)
|
||||
return 1;
|
||||
/* Check if space follows (avoid same names with a suffix) */
|
||||
if (*(e + nlen) == ' ')
|
||||
return 1;
|
||||
|
||||
e += nlen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef void (*PFVOID)();
|
||||
|
||||
PFVOID shGetProcAddress(const char *name)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return (PFVOID)wglGetProcAddress(name);
|
||||
#else
|
||||
return (PFVOID)NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void shLoadExtensions(void *c)
|
||||
{
|
||||
if(shGetProcAddress == NULL) return;
|
||||
|
||||
#if defined(_WIN32)
|
||||
glUniform1i = shGetProcAddress("glUniform1i");
|
||||
glUniform2fv = shGetProcAddress("glUniform2fv");
|
||||
glUniformMatrix3fv = shGetProcAddress("glUniformMatrix3fv");
|
||||
glUniform2f = shGetProcAddress("glUniform2f");
|
||||
glUniform4fv = shGetProcAddress("glUniform4fv");
|
||||
glEnableVertexAttribArray = shGetProcAddress("glEnableVertexAttribArray");
|
||||
glVertexAttribPointer = shGetProcAddress("glVertexAttribPointer");
|
||||
glDisableVertexAttribArray = shGetProcAddress("glDisableVertexAttribArray");
|
||||
glUseProgram = shGetProcAddress("glUseProgram");
|
||||
glUniformMatrix4fv = shGetProcAddress("glUniformMatrix4fv");
|
||||
glCreateShader = shGetProcAddress("glCreateShader");
|
||||
glShaderSource = shGetProcAddress("glShaderSource");
|
||||
glCompileShader = shGetProcAddress("glCompileShader");
|
||||
glGetShaderiv = shGetProcAddress("glGetShaderiv");
|
||||
glAttachShader = shGetProcAddress("glAttachShader");
|
||||
glLinkProgram = shGetProcAddress("glLinkProgram");
|
||||
glGetAttribLocation = shGetProcAddress("glGetAttribLocation");
|
||||
glGetUniformLocation = shGetProcAddress("glGetUniformLocation");
|
||||
glDeleteShader = shGetProcAddress("glDeleteShader");
|
||||
glDeleteProgram = shGetProcAddress("glDeleteProgram");
|
||||
glUniform1f = shGetProcAddress("glUniform1f");
|
||||
glUniform3f = shGetProcAddress("glUniform3f");
|
||||
glUniform4f = shGetProcAddress("glUniform4f");
|
||||
glUniform1fv = shGetProcAddress("glUniform1fv");
|
||||
glUniform3fv = shGetProcAddress("glUniform3fv");
|
||||
glUniformMatrix2fv = shGetProcAddress("glUniformMatrix2fv");
|
||||
glGetUniformfv = shGetProcAddress("glGetUniformfv");
|
||||
glCreateProgram = shGetProcAddress("glCreateProgram");
|
||||
glActiveTexture = shGetProcAddress("glActiveTexture");
|
||||
#endif
|
||||
}
|
25
simgear/canvas/ShaderVG/src/shExtensions.h
Normal file
25
simgear/canvas/ShaderVG/src/shExtensions.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SHEXTENSIONS_H
|
||||
#define __SHEXTENSIONS_H
|
||||
|
||||
|
||||
#endif
|
937
simgear/canvas/ShaderVG/src/shGeometry.c
Normal file
937
simgear/canvas/ShaderVG/src/shGeometry.c
Normal file
@ -0,0 +1,937 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#define VG_API_EXPORT
|
||||
#include "vg/openvg.h"
|
||||
#include "shContext.h"
|
||||
#include "shGeometry.h"
|
||||
|
||||
|
||||
static int shAddVertex(SHPath *p, SHVertex *v, SHint *contourStart)
|
||||
{
|
||||
/* Assert contour was open */
|
||||
SH_ASSERT((*contourStart) >= 0);
|
||||
|
||||
/* Check vertex limit */
|
||||
if (p->vertices.size >= SH_MAX_VERTICES) return 0;
|
||||
|
||||
/* Add vertex to subdivision */
|
||||
shVertexArrayPushBackP(&p->vertices, v);
|
||||
|
||||
/* Increment contour size. Its stored in
|
||||
the flags of first contour vertex */
|
||||
p->vertices.items[*contourStart].flags++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void shSubrecurseQuad(SHPath *p, SHQuad *quad, SHint *contourStart)
|
||||
{
|
||||
SHVertex v;
|
||||
SHVector2 mid, dif, c1, c2, c3;
|
||||
SHQuad quads[SH_MAX_RECURSE_DEPTH];
|
||||
SHQuad *q, *qleft, *qright;
|
||||
SHint qindex=0;
|
||||
quads[0] = *quad;
|
||||
|
||||
while (qindex >= 0) {
|
||||
|
||||
q = &quads[qindex];
|
||||
|
||||
/* Calculate distance of control point from its
|
||||
counterpart on the line between end points */
|
||||
SET2V(mid, q->p1); ADD2V(mid, q->p3); DIV2(mid, 2);
|
||||
SET2V(dif, q->p2); SUB2V(dif, mid); ABS2(dif);
|
||||
|
||||
/* Cancel if the curve is flat enough */
|
||||
if (dif.x + dif.y <= 1.0f || qindex == SH_MAX_RECURSE_DEPTH-1) {
|
||||
|
||||
/* Add subdivision point */
|
||||
v.point = q->p3; v.flags = 0;
|
||||
if (qindex == 0) return; /* Skip last point */
|
||||
if (!shAddVertex(p, &v, contourStart)) return;
|
||||
--qindex;
|
||||
|
||||
}else{
|
||||
|
||||
/* Left recursion goes on top of stack! */
|
||||
qright = q; qleft = &quads[++qindex];
|
||||
|
||||
/* Subdivide into 2 sub-curves */
|
||||
SET2V(c1, q->p1); ADD2V(c1, q->p2); DIV2(c1, 2);
|
||||
SET2V(c3, q->p2); ADD2V(c3, q->p3); DIV2(c3, 2);
|
||||
SET2V(c2, c1); ADD2V(c2, c3); DIV2(c2, 2);
|
||||
|
||||
/* Add left recursion onto stack */
|
||||
qleft->p1 = q->p1;
|
||||
qleft->p2 = c1;
|
||||
qleft->p3 = c2;
|
||||
|
||||
/* Add right recursion onto stack */
|
||||
qright->p1 = c2;
|
||||
qright->p2 = c3;
|
||||
qright->p3 = q->p3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void shSubrecurseCubic(SHPath *p, SHCubic *cubic, SHint *contourStart)
|
||||
{
|
||||
SHVertex v;
|
||||
SHfloat dx1, dy1, dx2, dy2;
|
||||
SHVector2 mm, c1, c2, c3, c4, c5;
|
||||
SHCubic cubics[SH_MAX_RECURSE_DEPTH];
|
||||
SHCubic *c, *cleft, *cright;
|
||||
SHint cindex = 0;
|
||||
cubics[0] = *cubic;
|
||||
|
||||
while (cindex >= 0) {
|
||||
|
||||
c = &cubics[cindex];
|
||||
|
||||
/* Calculate distance of control points from their
|
||||
counterparts on the line between end points */
|
||||
dx1 = 3.0f*c->p2.x - 2.0f*c->p1.x - c->p4.x; dx1 *= dx1;
|
||||
dy1 = 3.0f*c->p2.y - 2.0f*c->p1.y - c->p4.y; dy1 *= dy1;
|
||||
dx2 = 3.0f*c->p3.x - 2.0f*c->p4.x - c->p1.x; dx2 *= dx2;
|
||||
dy2 = 3.0f*c->p3.y - 2.0f*c->p4.y - c->p1.y; dy2 *= dy2;
|
||||
if (dx1 < dx2) dx1 = dx2;
|
||||
if (dy1 < dy2) dy1 = dy2;
|
||||
|
||||
/* Cancel if the curve is flat enough */
|
||||
if (dx1+dy1 <= 1.0 || cindex == SH_MAX_RECURSE_DEPTH-1) {
|
||||
|
||||
/* Add subdivision point */
|
||||
v.point = c->p4; v.flags = 0;
|
||||
if (cindex == 0) return; /* Skip last point */
|
||||
if (!shAddVertex(p, &v, contourStart)) return;
|
||||
--cindex;
|
||||
|
||||
}else{
|
||||
|
||||
/* Left recursion goes on top of stack! */
|
||||
cright = c; cleft = &cubics[++cindex];
|
||||
|
||||
/* Subdivide into 2 sub-curves */
|
||||
SET2V(c1, c->p1); ADD2V(c1, c->p2); DIV2(c1, 2);
|
||||
SET2V(mm, c->p2); ADD2V(mm, c->p3); DIV2(mm, 2);
|
||||
SET2V(c5, c->p3); ADD2V(c5, c->p4); DIV2(c5, 2);
|
||||
|
||||
SET2V(c2, c1); ADD2V(c2, mm); DIV2(c2, 2);
|
||||
SET2V(c4, mm); ADD2V(c4, c5); DIV2(c4, 2);
|
||||
|
||||
SET2V(c3, c2); ADD2V(c3, c4); DIV2(c3, 2);
|
||||
|
||||
/* Add left recursion to stack */
|
||||
cleft->p1 = c->p1;
|
||||
cleft->p2 = c1;
|
||||
cleft->p3 = c2;
|
||||
cleft->p4 = c3;
|
||||
|
||||
/* Add right recursion to stack */
|
||||
cright->p1 = c3;
|
||||
cright->p2 = c4;
|
||||
cright->p3 = c5;
|
||||
cright->p4 = c->p4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void shSubrecurseArc(SHPath *p, SHArc *arc,
|
||||
SHVector2 *c,SHVector2 *ux, SHVector2 *uy,
|
||||
SHint *contourStart)
|
||||
{
|
||||
SHVertex v;
|
||||
SHfloat am, cosa, sina, dx, dy;
|
||||
SHVector2 uux, uuy, c1, m;
|
||||
SHArc arcs[SH_MAX_RECURSE_DEPTH];
|
||||
SHArc *a, *aleft, *aright;
|
||||
SHint aindex=0;
|
||||
arcs[0] = *arc;
|
||||
|
||||
while (aindex >= 0) {
|
||||
|
||||
a = &arcs[aindex];
|
||||
|
||||
/* Middle angle and its cos/sin */
|
||||
am = (a->a1 + a->a2)/2;
|
||||
cosa = SH_COS(am);
|
||||
sina = SH_SIN(am);
|
||||
|
||||
/* New point */
|
||||
SET2V(uux, (*ux)); MUL2(uux, cosa);
|
||||
SET2V(uuy, (*uy)); MUL2(uuy, sina);
|
||||
SET2V(c1, (*c)); ADD2V(c1, uux); ADD2V(c1, uuy);
|
||||
|
||||
/* Check distance from linear midpoint */
|
||||
SET2V(m, a->p1); ADD2V(m, a->p2); DIV2(m, 2);
|
||||
dx = c1.x - m.x; dy = c1.y - m.y;
|
||||
if (dx < 0.0f) dx = -dx;
|
||||
if (dy < 0.0f) dy = -dy;
|
||||
|
||||
/* Stop if flat enough */
|
||||
if (dx+dy <= 1.0f || aindex == SH_MAX_RECURSE_DEPTH-1) {
|
||||
|
||||
/* Add middle subdivision point */
|
||||
v.point = c1; v.flags = 0;
|
||||
if (!shAddVertex(p, &v, contourStart)) return;
|
||||
if (aindex == 0) return; /* Skip very last point */
|
||||
|
||||
/* Add end subdivision point */
|
||||
v.point = a->p2; v.flags = 0;
|
||||
if (!shAddVertex(p, &v, contourStart)) return;
|
||||
--aindex;
|
||||
|
||||
}else{
|
||||
|
||||
/* Left subdivision goes on top of stack! */
|
||||
aright = a; aleft = &arcs[++aindex];
|
||||
|
||||
/* Add left recursion to stack */
|
||||
aleft->p1 = a->p1;
|
||||
aleft->a1 = a->a1;
|
||||
aleft->p2 = c1;
|
||||
aleft->a2 = am;
|
||||
|
||||
/* Add right recursion to stack */
|
||||
aright->p1 = c1;
|
||||
aright->a1 = am;
|
||||
aright->p2 = a->p2;
|
||||
aright->a2 = a->a2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void shSubdivideSegment(SHPath *p, VGPathSegment segment,
|
||||
VGPathCommand originalCommand,
|
||||
SHfloat *data, void *userData)
|
||||
{
|
||||
SHVertex v;
|
||||
SHint *contourStart = ((SHint**)userData)[0];
|
||||
SHint *surfaceSpace = ((SHint**)userData)[1];
|
||||
SHQuad quad; SHCubic cubic; SHArc arc;
|
||||
SHVector2 c, ux, uy;
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
switch (segment)
|
||||
{
|
||||
case VG_MOVE_TO:
|
||||
|
||||
/* Set contour start here */
|
||||
(*contourStart) = p->vertices.size;
|
||||
|
||||
/* First contour vertex */
|
||||
v.point.x = data[2];
|
||||
v.point.y = data[3];
|
||||
v.flags = 0;
|
||||
if (*surfaceSpace)
|
||||
TRANSFORM2(v.point, context->pathTransform);
|
||||
break;
|
||||
|
||||
case VG_CLOSE_PATH:
|
||||
|
||||
/* Last contour vertex */
|
||||
v.point.x = data[2];
|
||||
v.point.y = data[3];
|
||||
v.flags = SH_VERTEX_FLAG_SEGEND | SH_VERTEX_FLAG_CLOSE;
|
||||
if (*surfaceSpace)
|
||||
TRANSFORM2(v.point, context->pathTransform);
|
||||
break;
|
||||
|
||||
case VG_LINE_TO:
|
||||
|
||||
/* Last segment vertex */
|
||||
v.point.x = data[2];
|
||||
v.point.y = data[3];
|
||||
v.flags = SH_VERTEX_FLAG_SEGEND;
|
||||
if (*surfaceSpace)
|
||||
TRANSFORM2(v.point, context->pathTransform);
|
||||
break;
|
||||
|
||||
case VG_QUAD_TO:
|
||||
|
||||
/* Recurse subdivision */
|
||||
SET2(quad.p1, data[0], data[1]);
|
||||
SET2(quad.p2, data[2], data[3]);
|
||||
SET2(quad.p3, data[4], data[5]);
|
||||
if (*surfaceSpace) {
|
||||
TRANSFORM2(quad.p1, context->pathTransform);
|
||||
TRANSFORM2(quad.p2, context->pathTransform);
|
||||
TRANSFORM2(quad.p3, context->pathTransform); }
|
||||
shSubrecurseQuad(p, &quad, contourStart);
|
||||
|
||||
/* Last segment vertex */
|
||||
v.point.x = data[4];
|
||||
v.point.y = data[5];
|
||||
v.flags = SH_VERTEX_FLAG_SEGEND;
|
||||
if (*surfaceSpace)
|
||||
TRANSFORM2(v.point, context->pathTransform);
|
||||
break;
|
||||
|
||||
case VG_CUBIC_TO:
|
||||
|
||||
/* Recurse subdivision */
|
||||
SET2(cubic.p1, data[0], data[1]);
|
||||
SET2(cubic.p2, data[2], data[3]);
|
||||
SET2(cubic.p3, data[4], data[5]);
|
||||
SET2(cubic.p4, data[6], data[7]);
|
||||
if (*surfaceSpace) {
|
||||
TRANSFORM2(cubic.p1, context->pathTransform);
|
||||
TRANSFORM2(cubic.p2, context->pathTransform);
|
||||
TRANSFORM2(cubic.p3, context->pathTransform);
|
||||
TRANSFORM2(cubic.p4, context->pathTransform); }
|
||||
shSubrecurseCubic(p, &cubic, contourStart);
|
||||
|
||||
/* Last segment vertex */
|
||||
v.point.x = data[6];
|
||||
v.point.y = data[7];
|
||||
v.flags = SH_VERTEX_FLAG_SEGEND;
|
||||
if (*surfaceSpace)
|
||||
TRANSFORM2(v.point, context->pathTransform);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
SH_ASSERT(segment==VG_SCWARC_TO || segment==VG_SCCWARC_TO ||
|
||||
segment==VG_LCWARC_TO || segment==VG_LCCWARC_TO);
|
||||
|
||||
/* Recurse subdivision */
|
||||
SET2(arc.p1, data[0], data[1]);
|
||||
SET2(arc.p2, data[10], data[11]);
|
||||
arc.a1 = data[8]; arc.a2 = data[9];
|
||||
SET2(c, data[2], data[3]);
|
||||
SET2(ux, data[4], data[5]);
|
||||
SET2(uy, data[6], data[7]);
|
||||
if (*surfaceSpace) {
|
||||
TRANSFORM2(arc.p1, context->pathTransform);
|
||||
TRANSFORM2(arc.p2, context->pathTransform);
|
||||
TRANSFORM2(c, context->pathTransform);
|
||||
TRANSFORM2DIR(ux, context->pathTransform);
|
||||
TRANSFORM2DIR(uy, context->pathTransform); }
|
||||
shSubrecurseArc(p, &arc, &c, &ux, &uy, contourStart);
|
||||
|
||||
/* Last segment vertex */
|
||||
v.point.x = data[10];
|
||||
v.point.y = data[11];
|
||||
v.flags = SH_VERTEX_FLAG_SEGEND;
|
||||
if (*surfaceSpace) {
|
||||
TRANSFORM2(v.point, context->pathTransform); }
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add subdivision vertex */
|
||||
shAddVertex(p, &v, contourStart);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
* Processes path data by simplfying it and sending
|
||||
* each segment to subdivision callback function
|
||||
*--------------------------------------------------*/
|
||||
|
||||
void shFlattenPath(SHPath *p, SHint surfaceSpace)
|
||||
{
|
||||
SHint contourStart = -1;
|
||||
//SHint surfSpace = surfaceSpace;
|
||||
SHint *userData[2];
|
||||
SHint processFlags =
|
||||
SH_PROCESS_SIMPLIFY_LINES |
|
||||
SH_PROCESS_SIMPLIFY_CURVES |
|
||||
SH_PROCESS_CENTRALIZE_ARCS |
|
||||
SH_PROCESS_REPAIR_ENDS;
|
||||
|
||||
userData[0] = &contourStart;
|
||||
userData[1] = &surfaceSpace;
|
||||
|
||||
shVertexArrayClear(&p->vertices);
|
||||
shProcessPathData(p, processFlags, shSubdivideSegment, userData);
|
||||
}
|
||||
|
||||
/*-------------------------------------------
|
||||
* Adds a rectangle to the path's stroke.
|
||||
*-------------------------------------------*/
|
||||
|
||||
static void shPushStrokeQuad(SHPath *p, SHVector2 *p1, SHVector2 *p2,
|
||||
SHVector2 *p3, SHVector2 *p4)
|
||||
{
|
||||
shVector2ArrayPushBackP(&p->stroke, p1);
|
||||
shVector2ArrayPushBackP(&p->stroke, p2);
|
||||
shVector2ArrayPushBackP(&p->stroke, p3);
|
||||
shVector2ArrayPushBackP(&p->stroke, p3);
|
||||
shVector2ArrayPushBackP(&p->stroke, p4);
|
||||
shVector2ArrayPushBackP(&p->stroke, p1);
|
||||
}
|
||||
|
||||
/*-------------------------------------------
|
||||
* Adds a triangle to the path's stroke.
|
||||
*-------------------------------------------*/
|
||||
|
||||
static void shPushStrokeTri(SHPath *p, SHVector2 *p1,
|
||||
SHVector2 *p2, SHVector2 *p3)
|
||||
{
|
||||
shVector2ArrayPushBackP(&p->stroke, p1);
|
||||
shVector2ArrayPushBackP(&p->stroke, p2);
|
||||
shVector2ArrayPushBackP(&p->stroke, p3);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Adds a miter join to the path's stroke at the given
|
||||
* turn point [c], with the end of the previous segment
|
||||
* outset [o1] and the beginning of the next segment
|
||||
* outset [o2], transiting from tangent [d1] to [d2].
|
||||
*-----------------------------------------------------------*/
|
||||
|
||||
static void shStrokeJoinMiter(SHPath *p, SHVector2 *c,
|
||||
SHVector2 *o1, SHVector2 *d1,
|
||||
SHVector2 *o2, SHVector2 *d2)
|
||||
{
|
||||
/* Init miter top to first point in case lines are colinear */
|
||||
SHVector2 x; SET2V(x,(*o1));
|
||||
|
||||
/* Find intersection of two outer turn edges
|
||||
(lines defined by origin and direction) */
|
||||
shLineLineXsection(o1, d1, o2, d2, &x);
|
||||
|
||||
/* Add a "diamond" quad with top on intersected point
|
||||
and bottom on center of turn (on the line) */
|
||||
shPushStrokeQuad(p, &x, o1, c, o2);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Adds a round join to the path's stroke at the given
|
||||
* turn point [c], with the end of the previous segment
|
||||
* outset [pstart] and the beginning of the next segment
|
||||
* outset [pend], transiting from perpendicular vector
|
||||
* [tstart] to [tend].
|
||||
*-----------------------------------------------------------*/
|
||||
|
||||
static void shStrokeJoinRound(SHPath *p, SHVector2 *c,
|
||||
SHVector2 *pstart, SHVector2 *tstart,
|
||||
SHVector2 *pend, SHVector2 *tend)
|
||||
{
|
||||
SHVector2 p1, p2;
|
||||
SHfloat a, ang, cosa, sina;
|
||||
|
||||
/* Find angle between lines */
|
||||
ang = ANGLE2((*tstart),(*tend));
|
||||
|
||||
/* Begin with start point */
|
||||
SET2V(p1,(*pstart));
|
||||
for (a=0.0f; a<ang; a+=PI/12) {
|
||||
|
||||
/* Rotate perpendicular vector around and
|
||||
find next offset point from center */
|
||||
cosa = SH_COS(-a);
|
||||
sina = SH_SIN(-a);
|
||||
SET2(p2, tstart->x*cosa - tstart->y*sina,
|
||||
tstart->x*sina + tstart->y*cosa);
|
||||
ADD2V(p2, (*c));
|
||||
|
||||
/* Add triangle, save previous */
|
||||
shPushStrokeTri(p, &p1, &p2, c);
|
||||
SET2V(p1, p2);
|
||||
}
|
||||
|
||||
/* Add last triangle */
|
||||
shPushStrokeTri(p, &p1, pend, c);
|
||||
}
|
||||
|
||||
static void shStrokeCapRound(SHPath *p, SHVector2 *c, SHVector2 *t, SHint start)
|
||||
{
|
||||
SHint a;
|
||||
SHfloat ang, cosa, sina;
|
||||
SHVector2 p1, p2;
|
||||
SHint steps = 12;
|
||||
SHVector2 tt;
|
||||
|
||||
/* Revert perpendicular vector if start cap */
|
||||
SET2V(tt, (*t));
|
||||
if (start) MUL2(tt, -1);
|
||||
|
||||
/* Find start point */
|
||||
SET2V(p1, (*c));
|
||||
ADD2V(p1, tt);
|
||||
|
||||
for (a = 1; a<=steps; ++a) {
|
||||
|
||||
/* Rotate perpendicular vector around and
|
||||
find next offset point from center */
|
||||
ang = (SHfloat)a * PI / steps;
|
||||
cosa = SH_COS(-ang);
|
||||
sina = SH_SIN(-ang);
|
||||
SET2(p2, tt.x*cosa - tt.y*sina,
|
||||
tt.x*sina + tt.y*cosa);
|
||||
ADD2V(p2, (*c));
|
||||
|
||||
/* Add triangle, save previous */
|
||||
shPushStrokeTri(p, &p1, &p2, c);
|
||||
SET2V(p1, p2);
|
||||
}
|
||||
}
|
||||
|
||||
static void shStrokeCapSquare(SHPath *p, SHVector2 *c, SHVector2 *t, SHint start)
|
||||
{
|
||||
SHVector2 tt, p1, p2, p3, p4;
|
||||
|
||||
/* Revert perpendicular vector if start cap */
|
||||
SET2V(tt, (*t));
|
||||
if (start) MUL2(tt, -1);
|
||||
|
||||
/* Find four corners of the quad */
|
||||
SET2V(p1, (*c));
|
||||
ADD2V(p1, tt);
|
||||
|
||||
SET2V(p2, p1);
|
||||
ADD2(p2, tt.y, -tt.x);
|
||||
|
||||
SET2V(p3, p2);
|
||||
ADD2(p3, -2*tt.x, -2*tt.y);
|
||||
|
||||
SET2V(p4, p3);
|
||||
ADD2(p4, -tt.y, tt.x);
|
||||
|
||||
shPushStrokeQuad(p, &p1, &p2, &p3, &p4);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Generates stroke of a path according to VGContext state.
|
||||
* Produces quads for every linear subdivision segment or
|
||||
* dash "on" segment, handles line caps and joins.
|
||||
*-----------------------------------------------------------*/
|
||||
|
||||
void shStrokePath(VGContext* c, SHPath *p)
|
||||
{
|
||||
/* Line width and vertex count */
|
||||
SHfloat w = c->strokeLineWidth / 2;
|
||||
SHfloat mlimit = c->strokeMiterLimit;
|
||||
SHint vertsize = p->vertices.size;
|
||||
|
||||
/* Contour state */
|
||||
SHint contourStart = 0;
|
||||
SHint contourLength = 0;
|
||||
SHint start = 0;
|
||||
SHint end = 0;
|
||||
SHint loop = 0;
|
||||
SHint close = 0;
|
||||
SHint segend = 0;
|
||||
|
||||
/* Current vertices */
|
||||
SHint i1=0, i2=0;
|
||||
SHVertex *v1, *v2;
|
||||
SHVector2 *p1, *p2;
|
||||
SHVector2 d, t, dprev, tprev;
|
||||
SHfloat norm, cross, mlength;
|
||||
|
||||
/* Stroke edge points */
|
||||
SHVector2 l1, r1, l2, r2, lprev, rprev;
|
||||
|
||||
/* Dash state */
|
||||
SHint dashIndex = 0;
|
||||
SHfloat dashLength = 0.0f, strokeLength = 0.0f;
|
||||
SHint dashSize = c->strokeDashPattern.size;
|
||||
SHfloat *dashPattern = c->strokeDashPattern.items;
|
||||
SHint dashOn = 1;
|
||||
|
||||
/* Dash edge points */
|
||||
SHVector2 dash1, dash2;
|
||||
SHVector2 dashL1, dashR1;
|
||||
SHVector2 dashL2, dashR2;
|
||||
SHfloat nextDashLength, dashOffset;
|
||||
|
||||
/* Discard odd dash segment */
|
||||
dashSize -= dashSize % 2;
|
||||
|
||||
/* Init previous so compiler doesn't warn
|
||||
for uninitialized usage */
|
||||
SET2(tprev, 0,0); SET2(dprev, 0,0);
|
||||
SET2(lprev, 0,0); SET2(rprev, 0,0);
|
||||
|
||||
|
||||
/* Walk over subdivision vertices */
|
||||
for (i1=0; i1<vertsize; ++i1) {
|
||||
|
||||
if (loop) {
|
||||
/* Start new contour if exists */
|
||||
if (contourStart < vertsize)
|
||||
i1 = contourStart;
|
||||
else break;
|
||||
}
|
||||
|
||||
start = end = loop = close = segend = 0;
|
||||
i2 = i1 + 1;
|
||||
|
||||
if (i1 == contourStart) {
|
||||
/* Contour has started. Get length */
|
||||
contourLength = p->vertices.items[i1].flags;
|
||||
start = 1;
|
||||
}
|
||||
|
||||
if (contourLength <= 1) {
|
||||
/* Discard empty contours. */
|
||||
contourStart = i1 + 1;
|
||||
loop = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
v1 = &p->vertices.items[i1];
|
||||
v2 = &p->vertices.items[i2];
|
||||
|
||||
if (i2 == contourStart + contourLength-1) {
|
||||
/* Contour has ended. Check close */
|
||||
close = v2->flags & SH_VERTEX_FLAG_CLOSE;
|
||||
end = 1;
|
||||
}
|
||||
|
||||
if (i1 == contourStart + contourLength-1) {
|
||||
/* Loop back to first edge. Check close */
|
||||
close = v1->flags & SH_VERTEX_FLAG_CLOSE;
|
||||
i2 = contourStart+1;
|
||||
contourStart = i1 + 1;
|
||||
i1 = i2 - 1;
|
||||
loop = 1;
|
||||
}
|
||||
|
||||
if (!start && !loop) {
|
||||
/* We are inside a contour. Check segment end. */
|
||||
segend = (v1->flags & SH_VERTEX_FLAG_SEGEND);
|
||||
}
|
||||
|
||||
if (dashSize > 0 && start &&
|
||||
(contourStart == 0 || c->strokeDashPhaseReset)) {
|
||||
|
||||
/* Reset pattern phase at contour start */
|
||||
dashLength = -c->strokeDashPhase;
|
||||
strokeLength = 0.0f;
|
||||
dashIndex = 0;
|
||||
dashOn = 1;
|
||||
|
||||
if (dashLength < 0.0f) {
|
||||
/* Consume dash segments forward to reach stroke start */
|
||||
while (dashLength + dashPattern[dashIndex] <= 0.0f) {
|
||||
dashLength += dashPattern[dashIndex];
|
||||
dashIndex = (dashIndex + 1) % dashSize;
|
||||
dashOn = !dashOn; }
|
||||
|
||||
}else if (dashLength > 0.0f) {
|
||||
/* Consume dash segments backward to return to stroke start */
|
||||
dashIndex = dashSize;
|
||||
while (dashLength > 0.0f) {
|
||||
dashIndex = dashIndex ? (dashIndex-1) : (dashSize-1);
|
||||
dashLength -= dashPattern[dashIndex];
|
||||
dashOn = !dashOn; }
|
||||
}
|
||||
}
|
||||
|
||||
/* Subdiv segment vertices and points */
|
||||
v1 = &p->vertices.items[i1];
|
||||
v2 = &p->vertices.items[i2];
|
||||
p1 = &v1->point;
|
||||
p2 = &v2->point;
|
||||
|
||||
/* Direction vector */
|
||||
SET2(d, p2->x-p1->x, p2->y-p1->y);
|
||||
norm = NORM2(d);
|
||||
if (norm == 0.0f) d = dprev;
|
||||
else DIV2(d, norm);
|
||||
|
||||
/* Perpendicular vector */
|
||||
SET2(t, -d.y, d.x);
|
||||
MUL2(t, w);
|
||||
cross = CROSS2(t,tprev);
|
||||
|
||||
/* Left and right edge points */
|
||||
SET2V(l1, (*p1)); ADD2V(l1, t);
|
||||
SET2V(r1, (*p1)); SUB2V(r1, t);
|
||||
SET2V(l2, (*p2)); ADD2V(l2, t);
|
||||
SET2V(r2, (*p2)); SUB2V(r2, t);
|
||||
|
||||
/* Check if join needed */
|
||||
if ((segend || (loop && close)) && dashOn) {
|
||||
|
||||
switch (c->strokeJoinStyle) {
|
||||
case VG_JOIN_ROUND:
|
||||
|
||||
/* Add a round join to stroke */
|
||||
if (cross >= 0.0f)
|
||||
shStrokeJoinRound(p, p1, &lprev, &tprev, &l1, &t);
|
||||
else{
|
||||
SHVector2 _t, _tprev;
|
||||
SET2(_t, -t.x, -t.y);
|
||||
SET2(_tprev, -tprev.x, -tprev.y);
|
||||
shStrokeJoinRound(p, p1, &r1, &_t, &rprev, &_tprev);
|
||||
}
|
||||
|
||||
break;
|
||||
case VG_JOIN_MITER:
|
||||
|
||||
/* Add a miter join to stroke */
|
||||
mlength = 1/SH_COS((ANGLE2(t, tprev))/2);
|
||||
if (mlength <= mlimit) {
|
||||
if (cross > 0.0f)
|
||||
shStrokeJoinMiter(p, p1, &lprev, &dprev, &l1, &d);
|
||||
else if (cross < 0.0f)
|
||||
shStrokeJoinMiter(p, p1, &rprev, &dprev, &r1, &d);
|
||||
break;
|
||||
}/* Else fall down to bevel */
|
||||
|
||||
case VG_JOIN_BEVEL:
|
||||
|
||||
/* Add a bevel join to stroke */
|
||||
if (cross > 0.0f)
|
||||
shPushStrokeTri(p, &l1, &lprev, p1);
|
||||
else if (cross < 0.0f)
|
||||
shPushStrokeTri(p, &r1, &rprev, p1);
|
||||
|
||||
break;
|
||||
}
|
||||
}else if (!start && !loop && dashOn) {
|
||||
|
||||
/* Fill gap with previous (= bevel join) */
|
||||
if (cross > 0.0f)
|
||||
shPushStrokeTri(p, &l1, &lprev, p1);
|
||||
else if (cross < 0.0f)
|
||||
shPushStrokeTri(p, &r1, &rprev, p1);
|
||||
}
|
||||
|
||||
|
||||
/* Apply cap to start of a non-closed contour or
|
||||
if we are dashing and dash segment is on */
|
||||
if ((dashSize == 0 && loop && !close) ||
|
||||
(dashSize > 0 && start && dashOn)) {
|
||||
switch (c->strokeCapStyle) {
|
||||
case VG_CAP_ROUND:
|
||||
shStrokeCapRound(p, p1, &t, 1); break;
|
||||
case VG_CAP_SQUARE:
|
||||
shStrokeCapSquare(p, p1, &t, 1); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if (loop)
|
||||
continue;
|
||||
|
||||
/* Handle dashing */
|
||||
if (dashSize > 0) {
|
||||
|
||||
/* Start with beginning of subdiv segment */
|
||||
SET2V(dash1, (*p1)); SET2V(dashL1, l1); SET2V(dashR1, r1);
|
||||
|
||||
do {
|
||||
/* Interpolate point on the current subdiv segment */
|
||||
nextDashLength = dashLength + dashPattern[dashIndex];
|
||||
dashOffset = (nextDashLength - strokeLength) / norm;
|
||||
if (dashOffset > 1.0f) dashOffset = 1;
|
||||
SET2V(dash2, (*p2)); SUB2V(dash2, (*p1));
|
||||
MUL2(dash2, dashOffset); ADD2V(dash2, (*p1));
|
||||
|
||||
/* Left and right edge points */
|
||||
SET2V(dashL2, dash2); ADD2V(dashL2, t);
|
||||
SET2V(dashR2, dash2); SUB2V(dashR2, t);
|
||||
|
||||
/* Add quad for this dash segment */
|
||||
if (dashOn) shPushStrokeQuad(p, &dashL2, &dashL1, &dashR1, &dashR2);
|
||||
|
||||
/* Move to next dash segment if inside this subdiv segment */
|
||||
if (nextDashLength <= strokeLength + norm) {
|
||||
dashIndex = (dashIndex + 1) % dashSize;
|
||||
dashLength = nextDashLength;
|
||||
dashOn = !dashOn;
|
||||
SET2V(dash1, dash2);
|
||||
SET2V(dashL1, dashL2);
|
||||
SET2V(dashR1, dashR2);
|
||||
|
||||
/* Apply cap to dash segment */
|
||||
switch (c->strokeCapStyle) {
|
||||
case VG_CAP_ROUND:
|
||||
shStrokeCapRound(p, &dash1, &t, dashOn); break;
|
||||
case VG_CAP_SQUARE:
|
||||
shStrokeCapSquare(p, &dash1, &t, dashOn); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Consume dash segments until subdiv end met */
|
||||
} while (nextDashLength < strokeLength + norm);
|
||||
|
||||
}else{
|
||||
|
||||
/* Add quad for this line segment */
|
||||
shPushStrokeQuad(p, &l2, &l1, &r1, &r2);
|
||||
}
|
||||
|
||||
|
||||
/* Apply cap to end of a non-closed contour or
|
||||
if we are dashing and dash segment is on */
|
||||
if ((dashSize == 0 && end && !close) ||
|
||||
(dashSize > 0 && end && dashOn)) {
|
||||
switch (c->strokeCapStyle) {
|
||||
case VG_CAP_ROUND:
|
||||
shStrokeCapRound(p, p2, &t, 0); break;
|
||||
case VG_CAP_SQUARE:
|
||||
shStrokeCapSquare(p, p2, &t, 0); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save previous edge */
|
||||
strokeLength += norm;
|
||||
SET2V(lprev, l2);
|
||||
SET2V(rprev, r2);
|
||||
dprev = d;
|
||||
tprev = t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------
|
||||
* Transforms the tessellation vertices using the given matrix
|
||||
*-------------------------------------------------------------*/
|
||||
|
||||
void shTransformVertices(SHMatrix3x3 *m, SHPath *p)
|
||||
{
|
||||
SHVector2 *v;
|
||||
int i = 0;
|
||||
|
||||
for (i = p->vertices.size-1; i>=0; --i) {
|
||||
v = (&p->vertices.items[i].point);
|
||||
TRANSFORM2((*v), (*m)); }
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------
|
||||
* Finds the tight bounding box of path's tesselation
|
||||
* vertices. Depends on whether the path had been
|
||||
* tesselated in user or surface space.
|
||||
*--------------------------------------------------------*/
|
||||
|
||||
void shFindBoundbox(SHPath *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (p->vertices.size == 0) {
|
||||
SET2(p->min, 0,0);
|
||||
SET2(p->max, 0,0);
|
||||
return;
|
||||
}
|
||||
|
||||
p->min.x = p->max.x = p->vertices.items[0].point.x;
|
||||
p->min.y = p->max.y = p->vertices.items[0].point.y;
|
||||
|
||||
for (i=0; i<p->vertices.size; ++i) {
|
||||
|
||||
SHVector2 *v = &p->vertices.items[i].point;
|
||||
if (v->x < p->min.x) p->min.x = v->x;
|
||||
if (v->x > p->max.x) p->max.x = v->x;
|
||||
if (v->y < p->min.y) p->min.y = v->y;
|
||||
if (v->y > p->max.y) p->max.y = v->y;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------
|
||||
* Outputs a tight bounding box of a path in path's own
|
||||
* coordinate system.
|
||||
*--------------------------------------------------------*/
|
||||
|
||||
VG_API_CALL void vgPathBounds(VGPath path,
|
||||
VGfloat * minX, VGfloat * minY,
|
||||
VGfloat * width, VGfloat * height)
|
||||
{
|
||||
SHPath *p = NULL;
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
VG_RETURN_ERR_IF(!shIsValidPath(context, path),
|
||||
VG_BAD_HANDLE_ERROR, VG_NO_RETVAL);
|
||||
|
||||
VG_RETURN_ERR_IF(minX == NULL || minY == NULL ||
|
||||
width == NULL || height == NULL,
|
||||
VG_ILLEGAL_ARGUMENT_ERROR, VG_NO_RETVAL);
|
||||
|
||||
/* TODO: check output pointer alignment */
|
||||
|
||||
p = (SHPath*)path;
|
||||
VG_RETURN_ERR_IF(!(p->caps & VG_PATH_CAPABILITY_PATH_BOUNDS),
|
||||
VG_PATH_CAPABILITY_ERROR, VG_NO_RETVAL);
|
||||
|
||||
/* Update path geometry */
|
||||
shFlattenPath(p, 0);
|
||||
shFindBoundbox(p);
|
||||
|
||||
/* Output bounds */
|
||||
*minX = p->min.x;
|
||||
*minY = p->min.y;
|
||||
*width = p->max.x - p->min.x;
|
||||
*height = p->max.y - p->min.y;
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------
|
||||
* Outputs a bounding box of a path defined by its control
|
||||
* points that is guaranteed to enclose the path geometry
|
||||
* after applying the current path-user-to-surface transform
|
||||
*------------------------------------------------------------*/
|
||||
|
||||
VG_API_CALL void vgPathTransformedBounds(VGPath path,
|
||||
VGfloat * minX, VGfloat * minY,
|
||||
VGfloat * width, VGfloat * height)
|
||||
{
|
||||
SHPath *p = NULL;
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
VG_RETURN_ERR_IF(!shIsValidPath(context, path),
|
||||
VG_BAD_HANDLE_ERROR, VG_NO_RETVAL);
|
||||
|
||||
VG_RETURN_ERR_IF(minX == NULL || minY == NULL ||
|
||||
width == NULL || height == NULL,
|
||||
VG_ILLEGAL_ARGUMENT_ERROR, VG_NO_RETVAL);
|
||||
|
||||
/* TODO: check output pointer alignment */
|
||||
|
||||
p = (SHPath*)path;
|
||||
VG_RETURN_ERR_IF(!(p->caps & VG_PATH_CAPABILITY_PATH_BOUNDS),
|
||||
VG_PATH_CAPABILITY_ERROR, VG_NO_RETVAL);
|
||||
|
||||
/* Update path geometry */
|
||||
shFlattenPath(p, 1);
|
||||
shFindBoundbox(p);
|
||||
|
||||
/* Output bounds */
|
||||
*minX = p->min.x;
|
||||
*minY = p->min.y;
|
||||
*width = p->max.x - p->min.x;
|
||||
*height = p->max.y - p->min.y;
|
||||
|
||||
/* Invalidate subdivision for rendering */
|
||||
p->cacheDataValid = VG_FALSE;
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
VG_API_CALL VGfloat vgPathLength(VGPath path,
|
||||
VGint startSegment, VGint numSegments)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgPointAlongPath(VGPath path,
|
||||
VGint startSegment, VGint numSegments,
|
||||
VGfloat distance,
|
||||
VGfloat * x, VGfloat * y,
|
||||
VGfloat * tangentX, VGfloat * tangentY)
|
||||
{
|
||||
}
|
33
simgear/canvas/ShaderVG/src/shGeometry.h
Normal file
33
simgear/canvas/ShaderVG/src/shGeometry.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SH_GEOMETRY_H
|
||||
|
||||
#include "shDefs.h"
|
||||
#include "shContext.h"
|
||||
#include "shVectors.h"
|
||||
#include "shPath.h"
|
||||
|
||||
void shFlattenPath(SHPath *p, SHint surfaceSpace);
|
||||
void shStrokePath(VGContext* c, SHPath *p);
|
||||
void shTransformVertices(SHMatrix3x3 *m, SHPath *p);
|
||||
void shFindBoundbox(SHPath *p);
|
||||
|
||||
#endif /* __SH_GEOMETRY_H */
|
1294
simgear/canvas/ShaderVG/src/shImage.c
Normal file
1294
simgear/canvas/ShaderVG/src/shImage.c
Normal file
File diff suppressed because it is too large
Load Diff
154
simgear/canvas/ShaderVG/src/shImage.h
Normal file
154
simgear/canvas/ShaderVG/src/shImage.h
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SHIMAGE_H
|
||||
#define __SHIMAGE_H
|
||||
|
||||
#include "shDefs.h"
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* ColorFormat holds the data necessary to pack/unpack color
|
||||
* components from a pixel of each supported image format
|
||||
*-----------------------------------------------------------*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
VGImageFormat vgformat;
|
||||
SHuint8 bytes;
|
||||
|
||||
SHuint32 rmask;
|
||||
SHuint8 rshift;
|
||||
SHuint8 rmax;
|
||||
|
||||
SHuint32 gmask;
|
||||
SHuint8 gshift;
|
||||
SHuint8 gmax;
|
||||
|
||||
SHuint32 bmask;
|
||||
SHuint8 bshift;
|
||||
SHuint8 bmax;
|
||||
|
||||
SHuint32 amask;
|
||||
SHuint8 ashift;
|
||||
SHuint8 amax;
|
||||
|
||||
GLenum glintformat;
|
||||
GLenum glformat;
|
||||
GLenum gltype;
|
||||
|
||||
} SHImageFormatDesc;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SHfloat r,g,b,a;
|
||||
|
||||
} SHColor;
|
||||
|
||||
void SHColor_ctor(SHColor *c);
|
||||
void SHColor_dtor(SHColor *c);
|
||||
|
||||
#define _ITEM_T SHColor
|
||||
#define _ARRAY_T SHColorArray
|
||||
#define _FUNC_T shColorArray
|
||||
#define _ARRAY_DECLARE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SHuint8 *data;
|
||||
SHint width;
|
||||
SHint height;
|
||||
SHImageFormatDesc fd;
|
||||
|
||||
SHint texwidth;
|
||||
SHint texheight;
|
||||
SHfloat texwidthK;
|
||||
SHfloat texheightK;
|
||||
GLuint texture;
|
||||
|
||||
} SHImage;
|
||||
|
||||
void SHImage_ctor(SHImage *i);
|
||||
void SHImage_dtor(SHImage *i);
|
||||
|
||||
#define _ITEM_T SHImage*
|
||||
#define _ARRAY_T SHImageArray
|
||||
#define _FUNC_T shImageArray
|
||||
#define _ARRAY_DECLARE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
/*-------------------------------------------------------
|
||||
* Color operators
|
||||
*-------------------------------------------------------*/
|
||||
|
||||
#define CSET(c, rr,gg,bb,aa) { c.r=rr; c.g=gg; c.b=bb; c.a=aa; }
|
||||
#define CSETC(c1, c2) { c1.r=c2.r; c1.g=c2.g; c1.b=c2.b; c1.a=c2.a; }
|
||||
|
||||
#define CSUB(c1, rr,gg,bb,aa) { c.r-=rr; c.g-=gg; c.b-=bb; c.a-=aa; }
|
||||
#define CSUBC(c1, c2) { c1.r-=c2.r; c1.g-=c2.g; c1.b-=c2.b; c1.a-=c2.a; }
|
||||
#define CSUBCTO(c1, c2, c3) { c3.r=c1.r-c2.r; c3.g=c1.g-c2.g; c3.b=c1.b-c2.b; c3.a=c1.a-c2.a; }
|
||||
|
||||
#define CADD(c1, rr,gg,bb,aa) { c.r+=rr; c.g+=gg; c.b+=bb; c.a+=aa; }
|
||||
#define CADDC(c1, c2) { c1.r+=c2.r; c1.g+=c2.g; c1.b+=c2.b; c1.a+=c2.a; }
|
||||
#define CADDTO(c1, c2, c3) { c3.r=c1.r+c2.r; c3.g=c1.g+c2.g; c3.b=c1.b+c2.b; c3.a=c1.a+c2.a; }
|
||||
#define CADDCK(c1, c2, k) { c1.r+=k*c2.r; c1.g+=k*c2.g; c1.b+=k*c2.b; c1.a+=k*c2.a; }
|
||||
|
||||
#define CMUL(c, s) { c.r*=s; c.g*=s; c.b*=s; c.a*=s; }
|
||||
#define CDIV(c, s) { c.r/=s; c.g/=s; c.b/=s; c.a/=s; }
|
||||
|
||||
#define CPREMUL(c) { c.r*=c.a; c.g*=c.a; c.b*=c.a; }
|
||||
#define CUNPREMUL(c) { c.r/=c.a; c.g/=c.a; c.b/=c.a; }
|
||||
|
||||
/*-------------------------------------------------------
|
||||
* Color-to-memory functions
|
||||
*-------------------------------------------------------*/
|
||||
|
||||
#define CSTORE_RGBA1D_8(c, rgba, x) { \
|
||||
rgba[x*4+0] = (SHuint8)SH_FLOOR(c.r * 255); \
|
||||
rgba[x*4+1] = (SHuint8)SH_FLOOR(c.g * 255); \
|
||||
rgba[x*4+2] = (SHuint8)SH_FLOOR(c.b * 255); \
|
||||
rgba[x*4+3] = (SHuint8)SH_FLOOR(c.a * 255); }
|
||||
|
||||
#define CSTORE_RGBA1D_F(c, rgba, x) { \
|
||||
rgba[x*4+0] = c.r; \
|
||||
rgba[x*4+1] = c.g; \
|
||||
rgba[x*4+2] = c.b; \
|
||||
rgba[x*4+3] = c.a; }
|
||||
|
||||
#define CSTORE_RGBA2D_8(c, rgba, x, y, width) { \
|
||||
rgba[y*width*4+x*4+0] = (SHuint8)SH_FLOOR(c.r * 255); \
|
||||
rgba[y*width*4+x*4+1] = (SHuint8)SH_FLOOR(c.g * 255); \
|
||||
rgba[y*width*4+x*4+2] = (SHuint8)SH_FLOOR(c.b * 255); \
|
||||
rgba[y*width*4+x*4+3] = (SHuint8)SH_FLOOR(c.a * 255); }
|
||||
|
||||
#define CSTORE_RGBA2D_F(c, rgba, x, y, width) { \
|
||||
rgba[y*width*4+x*4+0] = c.r; \
|
||||
rgba[y*width*4+x*4+1] = c.g; \
|
||||
rgba[y*width*4+x*4+2] = c.b; \
|
||||
rgba[y*width*4+x*4+3] = c.a; }
|
||||
|
||||
#define INT2COLCOORD(i, max) ( (SHfloat)i / (SHfloat)max )
|
||||
#define COL2INTCOORD(c, max) ( (SHuint)SH_FLOOR(c * (SHfloat)max + 0.5f) )
|
||||
|
||||
void shStoreColor(SHColor *c, void *data, SHImageFormatDesc *f);
|
||||
void shLoadColor(SHColor *c, const void *data, SHImageFormatDesc *f);
|
||||
|
||||
|
||||
#endif /* __SHIMAGE_H */
|
518
simgear/canvas/ShaderVG/src/shPaint.c
Normal file
518
simgear/canvas/ShaderVG/src/shPaint.c
Normal file
@ -0,0 +1,518 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#define VG_API_EXPORT
|
||||
#include "vg/openvg.h"
|
||||
#include "shContext.h"
|
||||
#include "shPaint.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define _ITEM_T SHStop
|
||||
#define _ARRAY_T SHStopArray
|
||||
#define _FUNC_T shStopArray
|
||||
#define _COMPARE_T(s1,s2) 0
|
||||
#define _ARRAY_DEFINE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
#define _ITEM_T SHPaint*
|
||||
#define _ARRAY_T SHPaintArray
|
||||
#define _FUNC_T shPaintArray
|
||||
#define _ARRAY_DEFINE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
// We currently do not use gradients which need textures, so disable them to
|
||||
// prevent freeing resources outside the correct OpenGL thread/context.
|
||||
#define SH_NO_PAINT_TEXTURE
|
||||
|
||||
void SHPaint_ctor(SHPaint *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
p->type = VG_PAINT_TYPE_COLOR;
|
||||
CSET(p->color, 0,0,0,1);
|
||||
SH_INITOBJ(SHStopArray, p->instops);
|
||||
SH_INITOBJ(SHStopArray, p->stops);
|
||||
p->premultiplied = VG_FALSE;
|
||||
p->spreadMode = VG_COLOR_RAMP_SPREAD_PAD;
|
||||
p->tilingMode = VG_TILE_FILL;
|
||||
for (i=0; i<4; ++i) p->linearGradient[i] = 0.0f;
|
||||
for (i=0; i<5; ++i) p->radialGradient[i] = 0.0f;
|
||||
p->pattern = VG_INVALID_HANDLE;
|
||||
|
||||
#ifndef SH_NO_PAINT_TEXTURE
|
||||
glGenTextures(1, &p->texture);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glBindTexture(GL_TEXTURE_2D, p->texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SH_GRADIENT_TEX_WIDTH, SH_GRADIENT_TEX_HEIGHT, 0,
|
||||
GL_RGBA, GL_FLOAT, NULL);
|
||||
GL_CEHCK_ERROR;
|
||||
#else
|
||||
p->texture = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SHPaint_dtor(SHPaint *p)
|
||||
{
|
||||
SH_DEINITOBJ(SHStopArray, p->instops);
|
||||
SH_DEINITOBJ(SHStopArray, p->stops);
|
||||
|
||||
#ifndef SH_NO_PAINT_TEXTURE
|
||||
if (glIsTexture(p->texture))
|
||||
glDeleteTextures(1, &p->texture);
|
||||
#endif
|
||||
}
|
||||
|
||||
VG_API_CALL VGPaint vgCreatePaint(void)
|
||||
{
|
||||
SHPaint *p = NULL;
|
||||
VG_GETCONTEXT(VG_INVALID_HANDLE);
|
||||
|
||||
/* Create new paint object */
|
||||
SH_NEWOBJ(SHPaint, p);
|
||||
VG_RETURN_ERR_IF(!p, VG_OUT_OF_MEMORY_ERROR,
|
||||
VG_INVALID_HANDLE);
|
||||
|
||||
/* Add to resource list */
|
||||
shPaintArrayPushBack(&context->paints, p);
|
||||
|
||||
VG_RETURN((VGPaint)p);
|
||||
}
|
||||
|
||||
VG_API_CALL void vgDestroyPaint(VGPaint paint)
|
||||
{
|
||||
SHint index;
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
/* Check if handle valid */
|
||||
index = shPaintArrayFind(&context->paints, (SHPaint*)paint);
|
||||
VG_RETURN_ERR_IF(index == -1, VG_BAD_HANDLE_ERROR, VG_NO_RETVAL);
|
||||
|
||||
/* Delete object and remove resource */
|
||||
SH_DELETEOBJ(SHPaint, (SHPaint*)paint);
|
||||
shPaintArrayRemoveAt(&context->paints, index);
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
VG_API_CALL void vgSetPaint(VGPaint paint, VGbitfield paintModes)
|
||||
{
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
/* Check if handle valid */
|
||||
VG_RETURN_ERR_IF(!shIsValidPaint(context, paint) &&
|
||||
paint != VG_INVALID_HANDLE,
|
||||
VG_BAD_HANDLE_ERROR, VG_NO_RETVAL);
|
||||
|
||||
/* Check for invalid mode */
|
||||
VG_RETURN_ERR_IF(paintModes & ~(VG_STROKE_PATH | VG_FILL_PATH),
|
||||
VG_ILLEGAL_ARGUMENT_ERROR, VG_NO_RETVAL);
|
||||
|
||||
/* Set stroke / fill */
|
||||
if (paintModes & VG_STROKE_PATH)
|
||||
context->strokePaint = (SHPaint*)paint;
|
||||
if (paintModes & VG_FILL_PATH)
|
||||
context->fillPaint = (SHPaint*)paint;
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
VG_API_CALL void vgPaintPattern(VGPaint paint, VGImage pattern)
|
||||
{
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
/* Check if handle valid */
|
||||
VG_RETURN_ERR_IF(!shIsValidPaint(context, paint),
|
||||
VG_BAD_HANDLE_ERROR, VG_NO_RETVAL);
|
||||
|
||||
/* Check if pattern image valid */
|
||||
VG_RETURN_ERR_IF(!shIsValidImage(context, pattern),
|
||||
VG_BAD_HANDLE_ERROR, VG_NO_RETVAL);
|
||||
|
||||
/* TODO: Check if pattern image is current rendering target */
|
||||
|
||||
/* Set pattern image */
|
||||
((SHPaint*)paint)->pattern = pattern;
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
void shUpdateColorRampTexture(SHPaint *p)
|
||||
{
|
||||
#ifndef SH_NO_PAINT_TEXTURE
|
||||
SHint s=0;
|
||||
SHStop *stop1, *stop2;
|
||||
SHfloat rgba[SH_GRADIENT_TEX_COORDSIZE];
|
||||
SHint x1=0, x2=0, dx, x;
|
||||
SHColor dc, c;
|
||||
SHfloat k;
|
||||
|
||||
/* Write first pixel color */
|
||||
stop1 = &p->stops.items[0];
|
||||
CSTORE_RGBA1D_F(stop1->color, rgba, x1);
|
||||
|
||||
/* Walk stops */
|
||||
for (s=1; s<p->stops.size; ++s, x1=x2, stop1=stop2) {
|
||||
|
||||
/* Pick next stop */
|
||||
stop2 = &p->stops.items[s];
|
||||
x2 = (SHint)(stop2->offset * (SH_GRADIENT_TEX_WIDTH-1));
|
||||
|
||||
SH_ASSERT(x1 >= 0 && x1 < SH_GRADIENT_TEX_WIDTH &&
|
||||
x2 >= 0 && x2 < SH_GRADIENT_TEX_WIDTH &&
|
||||
x1 <= x2);
|
||||
|
||||
dx = x2 - x1;
|
||||
CSUBCTO(stop2->color, stop1->color, dc);
|
||||
|
||||
/* Interpolate inbetween */
|
||||
for (x=x1+1; x<=x2; ++x) {
|
||||
|
||||
k = (SHfloat)(x-x1)/dx;
|
||||
CSETC(c, stop1->color);
|
||||
CADDCK(c, dc, k);
|
||||
CSTORE_RGBA1D_F(c, rgba, x);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update texture image */
|
||||
glBindTexture(GL_TEXTURE_2D, p->texture);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
for(int i = 0; i < SH_GRADIENT_TEX_HEIGHT ; i++)
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i, SH_GRADIENT_TEX_WIDTH, 1, GL_RGBA, GL_FLOAT, rgba);
|
||||
|
||||
GL_CEHCK_ERROR;
|
||||
#else
|
||||
printf("ShaderVG: gradients not supported!");
|
||||
#endif
|
||||
}
|
||||
|
||||
void shValidateInputStops(SHPaint *p)
|
||||
{
|
||||
SHStop *instop, stop = {0, {0,0,0,0}};
|
||||
SHfloat lastOffset=0.0f;
|
||||
int i;
|
||||
|
||||
shStopArrayClear(&p->stops);
|
||||
shStopArrayReserve(&p->stops, p->instops.size);
|
||||
|
||||
/* Assure input stops are properly defined */
|
||||
for (i=0; i<p->instops.size; ++i) {
|
||||
|
||||
/* Copy stop color */
|
||||
instop = &p->instops.items[i];
|
||||
stop.color = instop->color;
|
||||
|
||||
/* Offset must be in [0,1] */
|
||||
if (instop->offset < 0.0f || instop->offset > 1.0f)
|
||||
continue;
|
||||
|
||||
/* Discard whole sequence if not in ascending order */
|
||||
if (instop->offset < lastOffset)
|
||||
{shStopArrayClear(&p->stops); break;}
|
||||
|
||||
/* Add stop at offset 0 with same color if first not at 0 */
|
||||
if (p->stops.size == 0 && instop->offset != 0.0f) {
|
||||
stop.offset = 0.0f;
|
||||
shStopArrayPushBackP(&p->stops, &stop);}
|
||||
|
||||
/* Add current stop to array */
|
||||
stop.offset = instop->offset;
|
||||
shStopArrayPushBackP(&p->stops, &stop);
|
||||
|
||||
/* Save last offset */
|
||||
lastOffset = instop->offset;
|
||||
}
|
||||
|
||||
/* Add stop at offset 1 with same color if last not at 1 */
|
||||
if (p->stops.size > 0 && lastOffset != 1.0f) {
|
||||
stop.offset = 1.0f;
|
||||
shStopArrayPushBackP(&p->stops, &stop);
|
||||
}
|
||||
|
||||
/* Add 2 default stops if no valid found */
|
||||
if (p->stops.size == 0) {
|
||||
/* First opaque black */
|
||||
stop.offset = 0.0f;
|
||||
CSET(stop.color, 0,0,0,1);
|
||||
shStopArrayPushBackP(&p->stops, &stop);
|
||||
/* Last opaque white */
|
||||
stop.offset = 1.0f;
|
||||
CSET(stop.color, 1,1,1,1);
|
||||
shStopArrayPushBackP(&p->stops, &stop);
|
||||
}
|
||||
|
||||
/* Update texture */
|
||||
shUpdateColorRampTexture(p);
|
||||
}
|
||||
|
||||
void shGenerateStops(SHPaint *p, SHfloat minOffset, SHfloat maxOffset,
|
||||
SHStopArray *outStops)
|
||||
{
|
||||
SHStop *s1,*s2;
|
||||
SHint i1,i2;
|
||||
SHfloat o=0.0f;
|
||||
SHfloat ostep=0.0f;
|
||||
SHint istep=1;
|
||||
SHint istart=0;
|
||||
SHint iend=p->stops.size-1;
|
||||
SHint minDone=0;
|
||||
SHint maxDone=0;
|
||||
SHStop outStop;
|
||||
|
||||
/* Start below zero? */
|
||||
if (minOffset < 0.0f) {
|
||||
if (p->spreadMode == VG_COLOR_RAMP_SPREAD_PAD) {
|
||||
/* Add min offset stop */
|
||||
outStop = p->stops.items[0];
|
||||
outStop.offset = minOffset;
|
||||
shStopArrayPushBackP(outStops, &outStop);
|
||||
/* Add max offset stop and exit */
|
||||
if (maxOffset < 0.0f) {
|
||||
outStop.offset = maxOffset;
|
||||
shStopArrayPushBackP(outStops, &outStop);
|
||||
return; }
|
||||
}else{
|
||||
/* Pad starting offset to nearest factor of 2 */
|
||||
SHint ioff = (SHint)SH_FLOOR(minOffset);
|
||||
o = (SHfloat)(ioff - (ioff & 1));
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct stops until max offset reached */
|
||||
for (i1=istart, i2=istart+istep; maxDone!=1;
|
||||
i1+=istep, i2+=istep, o+=ostep) {
|
||||
|
||||
/* All stops consumed? */
|
||||
if (i1==iend) { switch(p->spreadMode) {
|
||||
|
||||
case VG_COLOR_RAMP_SPREAD_PAD:
|
||||
/* Pick last stop */
|
||||
outStop = p->stops.items[i1];
|
||||
if (!minDone) {
|
||||
/* Add min offset stop with last color */
|
||||
outStop.offset = minOffset;
|
||||
shStopArrayPushBackP(outStops, &outStop); }
|
||||
/* Add max offset stop with last color */
|
||||
outStop.offset = maxOffset;
|
||||
shStopArrayPushBackP(outStops, &outStop);
|
||||
return;
|
||||
|
||||
case VG_COLOR_RAMP_SPREAD_REPEAT:
|
||||
/* Reset iteration */
|
||||
i1=istart; i2=istart+istep;
|
||||
/* Add stop1 if past min offset */
|
||||
if (minDone) {
|
||||
outStop = p->stops.items[0];
|
||||
outStop.offset = o;
|
||||
shStopArrayPushBackP(outStops, &outStop); }
|
||||
break;
|
||||
|
||||
case VG_COLOR_RAMP_SPREAD_REFLECT:
|
||||
/* Reflect iteration direction */
|
||||
istep = -istep;
|
||||
i2 = i1 + istep;
|
||||
iend = (istep==1) ? p->stops.size-1 : 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* 2 stops and their offset distance */
|
||||
s1 = &p->stops.items[i1];
|
||||
s2 = &p->stops.items[i2];
|
||||
ostep = s2->offset - s1->offset;
|
||||
ostep = SH_ABS(ostep);
|
||||
|
||||
/* Add stop1 if reached min offset */
|
||||
if (!minDone && o+ostep > minOffset) {
|
||||
minDone = 1;
|
||||
outStop = *s1;
|
||||
outStop.offset = o;
|
||||
shStopArrayPushBackP(outStops, &outStop);
|
||||
}
|
||||
|
||||
/* Mark done if reached max offset */
|
||||
if (o+ostep > maxOffset)
|
||||
maxDone = 1;
|
||||
|
||||
/* Add stop2 if past min offset */
|
||||
if (minDone) {
|
||||
outStop = *s2;
|
||||
outStop.offset = o+ostep;
|
||||
shStopArrayPushBackP(outStops, &outStop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void shSetGradientTexGLState(SHPaint *p)
|
||||
{
|
||||
#ifndef SH_NO_PAINT_TEXTURE
|
||||
glBindTexture(GL_TEXTURE_2D, p->texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
switch (p->spreadMode) {
|
||||
case VG_COLOR_RAMP_SPREAD_PAD:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); break;
|
||||
case VG_COLOR_RAMP_SPREAD_REPEAT:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); break;
|
||||
case VG_COLOR_RAMP_SPREAD_REFLECT:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); break;
|
||||
}
|
||||
#else
|
||||
printf("ShaderVG: gradients not supported!");
|
||||
#endif
|
||||
}
|
||||
|
||||
void shSetPatternTexGLState(SHPaint *p, VGContext *c)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, ((SHImage*)p->pattern)->texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
switch(p->tilingMode) {
|
||||
case VG_TILE_FILL:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR,
|
||||
(GLfloat*)&c->tileFillColor);
|
||||
break;
|
||||
case VG_TILE_PAD:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
break;
|
||||
case VG_TILE_REPEAT:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
break;
|
||||
case VG_TILE_REFLECT:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int shLoadLinearGradientMesh(SHPaint *p, VGPaintMode mode, VGMatrixMode matrixMode)
|
||||
{
|
||||
SHMatrix3x3 *m = 0;
|
||||
SHMatrix3x3 mu2p;
|
||||
GLfloat u2p[9];
|
||||
|
||||
/* Pick paint transform matrix */
|
||||
SH_GETCONTEXT(0);
|
||||
if (mode == VG_FILL_PATH)
|
||||
m = &context->fillTransform;
|
||||
else if (mode == VG_STROKE_PATH)
|
||||
m = &context->strokeTransform;
|
||||
|
||||
/* Back to paint space */
|
||||
shInvertMatrix(m, &mu2p);
|
||||
shMatrixToVG(&mu2p, (SHfloat*)u2p);
|
||||
|
||||
/* Setup shader */
|
||||
glUniform1i(context->locationDraw.paintType, VG_PAINT_TYPE_LINEAR_GRADIENT);
|
||||
glUniform2fv(context->locationDraw.paintParams, 2, p->linearGradient);
|
||||
glUniformMatrix3fv(context->locationDraw.paintInverted, 1, GL_FALSE, u2p);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
shSetGradientTexGLState(p);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glUniform1i(context->locationDraw.rampSampler, 1);
|
||||
GL_CEHCK_ERROR;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int shLoadRadialGradientMesh(SHPaint *p, VGPaintMode mode, VGMatrixMode matrixMode)
|
||||
{
|
||||
SHMatrix3x3 *m = 0;
|
||||
SHMatrix3x3 mu2p;
|
||||
GLfloat u2p[9];
|
||||
|
||||
/* Pick paint transform matrix */
|
||||
SH_GETCONTEXT(0);
|
||||
if (mode == VG_FILL_PATH)
|
||||
m = &context->fillTransform;
|
||||
else if (mode == VG_STROKE_PATH)
|
||||
m = &context->strokeTransform;
|
||||
|
||||
/* Back to paint space */
|
||||
shInvertMatrix(m, &mu2p);
|
||||
shMatrixToVG(&mu2p, (SHfloat*)u2p);
|
||||
|
||||
/* Setup shader */
|
||||
glUniform1i(context->locationDraw.paintType, VG_PAINT_TYPE_RADIAL_GRADIENT);
|
||||
glUniform2fv(context->locationDraw.paintParams, 3, p->radialGradient);
|
||||
glUniformMatrix3fv(context->locationDraw.paintInverted, 1, GL_FALSE, u2p);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
shSetGradientTexGLState(p);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glUniform1i(context->locationDraw.rampSampler, 1);
|
||||
GL_CEHCK_ERROR;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int shLoadPatternMesh(SHPaint *p, VGPaintMode mode, VGMatrixMode matrixMode)
|
||||
{
|
||||
SHImage *i = (SHImage*)p->pattern;
|
||||
SHMatrix3x3 *m = 0;
|
||||
SHMatrix3x3 mu2p;
|
||||
GLfloat u2p[9];
|
||||
|
||||
/* Pick paint transform matrix */
|
||||
SH_GETCONTEXT(0);
|
||||
if (mode == VG_FILL_PATH)
|
||||
m = &context->fillTransform;
|
||||
else if (mode == VG_STROKE_PATH)
|
||||
m = &context->strokeTransform;
|
||||
|
||||
/* Back to paint space */
|
||||
shInvertMatrix(m, &mu2p);
|
||||
shMatrixToVG(&mu2p, (SHfloat*)u2p);
|
||||
|
||||
/* Setup shader */
|
||||
glUniform1i(context->locationDraw.paintType, VG_PAINT_TYPE_PATTERN);
|
||||
glUniform2f(context->locationDraw.paintParams, (GLfloat)i->width, (GLfloat)i->height);
|
||||
glUniformMatrix3fv(context->locationDraw.paintInverted, 1, GL_FALSE, u2p);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
shSetPatternTexGLState(p, context);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glUniform1i(context->locationDraw.patternSampler, 1);
|
||||
GL_CEHCK_ERROR;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int shLoadOneColorMesh(SHPaint *p)
|
||||
{
|
||||
static GLfloat id[9] = {
|
||||
1.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f };
|
||||
SH_GETCONTEXT(0);
|
||||
|
||||
/* Setup shader */
|
||||
glUniform1i(context->locationDraw.paintType, VG_PAINT_TYPE_COLOR);
|
||||
glUniform4fv(context->locationDraw.paintColor, 1, (GLfloat*)&p->color);
|
||||
glUniformMatrix3fv(context->locationDraw.paintInverted, 1, GL_FALSE, id);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
76
simgear/canvas/ShaderVG/src/shPaint.h
Normal file
76
simgear/canvas/ShaderVG/src/shPaint.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SHPAINT_H
|
||||
#define __SHPAINT_H
|
||||
|
||||
#include "shDefs.h"
|
||||
#include "shArrays.h"
|
||||
#include "shImage.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float offset;
|
||||
SHColor color;
|
||||
|
||||
} SHStop;
|
||||
|
||||
#define _ITEM_T SHStop
|
||||
#define _ARRAY_T SHStopArray
|
||||
#define _FUNC_T shStopArray
|
||||
#define _ARRAY_DECLARE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
VGPaintType type;
|
||||
SHColor color;
|
||||
SHColorArray colors;
|
||||
SHStopArray instops;
|
||||
SHStopArray stops;
|
||||
VGboolean premultiplied;
|
||||
VGColorRampSpreadMode spreadMode;
|
||||
VGTilingMode tilingMode;
|
||||
SHfloat linearGradient[4];
|
||||
SHfloat radialGradient[5];
|
||||
GLuint texture;
|
||||
VGImage pattern;
|
||||
|
||||
} SHPaint;
|
||||
|
||||
void SHPaint_ctor(SHPaint *p);
|
||||
void SHPaint_dtor(SHPaint *p);
|
||||
|
||||
#define _ITEM_T SHPaint*
|
||||
#define _ARRAY_T SHPaintArray
|
||||
#define _FUNC_T shPaintArray
|
||||
#define _ARRAY_DECLARE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
void shValidateInputStops(SHPaint *p);
|
||||
void shSetGradientTexGLState(SHPaint *p);
|
||||
|
||||
int shLoadLinearGradientMesh(SHPaint *p, VGPaintMode mode, VGMatrixMode matrixMode);
|
||||
int shLoadRadialGradientMesh(SHPaint *p, VGPaintMode mode, VGMatrixMode matrixMode);
|
||||
int shLoadPatternMesh(SHPaint *p, VGPaintMode mode, VGMatrixMode matrixMode);
|
||||
int shLoadOneColorMesh(SHPaint *p);
|
||||
|
||||
|
||||
#endif /* __SHPAINT_H */
|
1403
simgear/canvas/ShaderVG/src/shParams.c
Normal file
1403
simgear/canvas/ShaderVG/src/shParams.c
Normal file
File diff suppressed because it is too large
Load Diff
1305
simgear/canvas/ShaderVG/src/shPath.c
Normal file
1305
simgear/canvas/ShaderVG/src/shPath.c
Normal file
File diff suppressed because it is too large
Load Diff
142
simgear/canvas/ShaderVG/src/shPath.h
Normal file
142
simgear/canvas/ShaderVG/src/shPath.h
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SHPATH_H
|
||||
#define __SHPATH_H
|
||||
|
||||
#include "shVectors.h"
|
||||
#include "shArrays.h"
|
||||
|
||||
/* Helper structures for subdivision */
|
||||
typedef struct {
|
||||
SHVector2 p1;
|
||||
SHVector2 p2;
|
||||
SHVector2 p3;
|
||||
} SHQuad;
|
||||
|
||||
typedef struct {
|
||||
SHVector2 p1;
|
||||
SHVector2 p2;
|
||||
SHVector2 p3;
|
||||
SHVector2 p4;
|
||||
} SHCubic;
|
||||
|
||||
typedef struct {
|
||||
SHVector2 p1;
|
||||
SHVector2 p2;
|
||||
SHfloat a1;
|
||||
SHfloat a2;
|
||||
} SHArc;
|
||||
|
||||
/* SHVertex */
|
||||
typedef struct
|
||||
{
|
||||
SHVector2 point;
|
||||
SHVector2 tangent;
|
||||
SHfloat length;
|
||||
SHuint flags;
|
||||
|
||||
} SHVertex;
|
||||
|
||||
/* Vertex flags for contour definition */
|
||||
#define SH_VERTEX_FLAG_CLOSE (1 << 0)
|
||||
#define SH_VERTEX_FLAG_SEGEND (1 << 1)
|
||||
#define SH_SEGMENT_TYPE_COUNT 13
|
||||
|
||||
/* Vertex array */
|
||||
#define _ITEM_T SHVertex
|
||||
#define _ARRAY_T SHVertexArray
|
||||
#define _FUNC_T shVertexArray
|
||||
#define _ARRAY_DECLARE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
|
||||
/* SHPath */
|
||||
typedef struct SHPath
|
||||
{
|
||||
/* Properties */
|
||||
VGint format;
|
||||
SHfloat scale;
|
||||
SHfloat bias;
|
||||
SHint segHint;
|
||||
SHint dataHint;
|
||||
VGbitfield caps;
|
||||
VGPathDatatype datatype;
|
||||
|
||||
/* Raw data */
|
||||
SHuint8 *segs;
|
||||
void *data;
|
||||
SHint segCount;
|
||||
SHint dataCount;
|
||||
|
||||
/* Subdivision */
|
||||
SHVertexArray vertices;
|
||||
SHVector2 min, max;
|
||||
|
||||
/* Additional stroke geometry (dash vertices if
|
||||
path dashed or triangle vertices if width > 1 */
|
||||
SHVector2Array stroke;
|
||||
|
||||
/* Cache */
|
||||
VGboolean cacheDataValid;
|
||||
|
||||
VGboolean cacheTransformInit;
|
||||
SHMatrix3x3 cacheTransform;
|
||||
|
||||
VGboolean cacheStrokeInit;
|
||||
VGboolean cacheStrokeTessValid;
|
||||
SHfloat cacheStrokeLineWidth;
|
||||
VGCapStyle cacheStrokeCapStyle;
|
||||
VGJoinStyle cacheStrokeJoinStyle;
|
||||
SHfloat cacheStrokeMiterLimit;
|
||||
SHfloat cacheStrokeDashPhase;
|
||||
VGboolean cacheStrokeDashPhaseReset;
|
||||
|
||||
} SHPath;
|
||||
|
||||
void SHPath_ctor(SHPath *p);
|
||||
void SHPath_dtor(SHPath *p);
|
||||
|
||||
|
||||
/* Processing normalization flags */
|
||||
#define SH_PROCESS_SIMPLIFY_LINES (1 << 0)
|
||||
#define SH_PROCESS_SIMPLIFY_CURVES (1 << 1)
|
||||
#define SH_PROCESS_CENTRALIZE_ARCS (1 << 2)
|
||||
#define SH_PROCESS_REPAIR_ENDS (1 << 3)
|
||||
|
||||
/* Segment callback function type */
|
||||
typedef void (*SegmentFunc) (SHPath *p, VGPathSegment segment,
|
||||
VGPathCommand originalCommand,
|
||||
SHfloat *data, void *userData);
|
||||
|
||||
/* Processes raw path data into normalized segments */
|
||||
void shProcessPathData(SHPath *p, int flags,
|
||||
SegmentFunc callback,
|
||||
void *userData);
|
||||
|
||||
|
||||
/* Pointer-to-path array */
|
||||
#define _ITEM_T SHPath*
|
||||
#define _ARRAY_T SHPathArray
|
||||
#define _FUNC_T shPathArray
|
||||
#define _ARRAY_DECLARE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
#endif /* __SHPATH_H */
|
522
simgear/canvas/ShaderVG/src/shPipeline.c
Normal file
522
simgear/canvas/ShaderVG/src/shPipeline.c
Normal file
@ -0,0 +1,522 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#define VG_API_EXPORT
|
||||
#include "vg/openvg.h"
|
||||
#include "shDefs.h"
|
||||
#include "shExtensions.h"
|
||||
#include "shContext.h"
|
||||
#include "shPath.h"
|
||||
#include "shImage.h"
|
||||
#include "shGeometry.h"
|
||||
#include "shPaint.h"
|
||||
|
||||
void shPremultiplyFramebuffer()
|
||||
{
|
||||
/* Multiply target color with its own alpha */
|
||||
glBlendFunc(GL_ZERO, GL_DST_ALPHA);
|
||||
}
|
||||
|
||||
void shUnpremultiplyFramebuffer()
|
||||
{
|
||||
/* TODO: hmmmm..... any idea? */
|
||||
}
|
||||
|
||||
void updateBlendingStateGL(VGContext *c, int alphaIsOne)
|
||||
{
|
||||
/* Most common drawing mode (SRC_OVER with alpha=1)
|
||||
as well as SRC is optimized by turning OpenGL
|
||||
blending off. In other cases its turned on. */
|
||||
|
||||
switch (c->blendMode)
|
||||
{
|
||||
case VG_BLEND_SRC:
|
||||
glBlendFunc(GL_ONE, GL_ZERO);
|
||||
glDisable(GL_BLEND); break;
|
||||
|
||||
case VG_BLEND_SRC_IN:
|
||||
glBlendFunc(GL_DST_ALPHA, GL_ZERO);
|
||||
glEnable(GL_BLEND); break;
|
||||
|
||||
case VG_BLEND_DST_IN:
|
||||
glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
|
||||
glEnable(GL_BLEND); break;
|
||||
|
||||
case VG_BLEND_SRC_OUT_SH:
|
||||
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO);
|
||||
glEnable(GL_BLEND); break;
|
||||
|
||||
case VG_BLEND_DST_OUT_SH:
|
||||
glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND); break;
|
||||
|
||||
case VG_BLEND_SRC_ATOP_SH:
|
||||
glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND); break;
|
||||
|
||||
case VG_BLEND_DST_ATOP_SH:
|
||||
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA);
|
||||
glEnable(GL_BLEND); break;
|
||||
|
||||
case VG_BLEND_DST_OVER:
|
||||
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
|
||||
glEnable(GL_BLEND); break;
|
||||
|
||||
case VG_BLEND_SRC_OVER: default:
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
if (alphaIsOne) {
|
||||
glDisable(GL_BLEND);
|
||||
} else {
|
||||
glEnable(GL_BLEND);
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Draws the triangles representing the stroke of a path.
|
||||
*-----------------------------------------------------------*/
|
||||
|
||||
static void shDrawStroke(SHPath *p)
|
||||
{
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
glEnableVertexAttribArray(context->locationDraw.pos);
|
||||
glVertexAttribPointer(context->locationDraw.pos, 2, GL_FLOAT, GL_FALSE, 0, p->stroke.items);
|
||||
glDrawArrays(GL_TRIANGLES, 0, p->stroke.size);
|
||||
glDisableVertexAttribArray(context->locationDraw.pos);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Draws the subdivided vertices in the OpenGL mode given
|
||||
* (this could be VG_TRIANGLE_FAN or VG_LINE_STRIP).
|
||||
*-----------------------------------------------------------*/
|
||||
|
||||
static void shDrawVertices(SHPath *p, GLenum mode)
|
||||
{
|
||||
int start = 0;
|
||||
int size = 0;
|
||||
|
||||
/* We separate vertex arrays by contours to properly
|
||||
handle the fill modes */
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
glEnableVertexAttribArray(context->locationDraw.pos);
|
||||
glVertexAttribPointer(context->locationDraw.pos, 2, GL_FLOAT, GL_FALSE, sizeof(SHVertex), p->vertices.items);
|
||||
|
||||
while (start < p->vertices.size) {
|
||||
size = p->vertices.items[start].flags;
|
||||
glDrawArrays(mode, start, size);
|
||||
start += size;
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(context->locationDraw.pos);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* Constructs & draws colored OpenGL primitives that cover the
|
||||
* given bounding box to represent the currently selected
|
||||
* stroke or fill paint
|
||||
*--------------------------------------------------------------*/
|
||||
|
||||
static void shDrawPaintMesh(VGContext *c, SHVector2 *min, SHVector2 *max,
|
||||
VGPaintMode mode, GLenum texUnit)
|
||||
{
|
||||
SHPaint *p = 0;
|
||||
SHVector2 pmin, pmax;
|
||||
SHfloat K = 1.0f;
|
||||
|
||||
/* Pick the right paint */
|
||||
if (mode == VG_FILL_PATH) {
|
||||
p = (c->fillPaint ? c->fillPaint : &c->defaultPaint);
|
||||
}else if (mode == VG_STROKE_PATH) {
|
||||
p = (c->strokePaint ? c->strokePaint : &c->defaultPaint);
|
||||
K = SH_CEIL(c->strokeMiterLimit * c->strokeLineWidth) + 1.0f;
|
||||
}
|
||||
|
||||
/* We want to be sure to cover every pixel of this path so better
|
||||
take a pixel more than leave some out (multisampling is tricky). */
|
||||
SET2V(pmin, (*min)); SUB2(pmin, K,K);
|
||||
SET2V(pmax, (*max)); ADD2(pmax, K,K);
|
||||
|
||||
/* Construct appropriate OpenGL primitives so as
|
||||
to fill the stencil mask with select paint */
|
||||
|
||||
switch (p->type) {
|
||||
case VG_PAINT_TYPE_LINEAR_GRADIENT:
|
||||
shLoadLinearGradientMesh(p, mode, VG_MATRIX_PATH_USER_TO_SURFACE);
|
||||
break;
|
||||
|
||||
case VG_PAINT_TYPE_RADIAL_GRADIENT:
|
||||
shLoadRadialGradientMesh(p, mode, VG_MATRIX_PATH_USER_TO_SURFACE);
|
||||
break;
|
||||
|
||||
case VG_PAINT_TYPE_PATTERN:
|
||||
if (p->pattern != VG_INVALID_HANDLE) {
|
||||
shLoadPatternMesh(p, mode, VG_MATRIX_PATH_USER_TO_SURFACE);
|
||||
break;
|
||||
}/* else behave as a color paint */
|
||||
|
||||
case VG_PAINT_TYPE_COLOR:
|
||||
shLoadOneColorMesh(p);
|
||||
break;
|
||||
}
|
||||
|
||||
GLfloat v[] = { pmin.x, pmin.y,
|
||||
pmax.x, pmin.y,
|
||||
pmin.x, pmax.y,
|
||||
pmax.x, pmax.y };
|
||||
glEnableVertexAttribArray(c->locationDraw.pos);
|
||||
glVertexAttribPointer(c->locationDraw.pos, 2, GL_FLOAT, GL_FALSE, 0, v);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDisableVertexAttribArray(c->locationDraw.pos);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VGboolean shIsTessCacheValid (VGContext *c, SHPath *p)
|
||||
{
|
||||
SHfloat nX, nY;
|
||||
SHVector2 X, Y;
|
||||
SHMatrix3x3 mi; //, mchange;
|
||||
VGboolean valid = VG_TRUE;
|
||||
|
||||
if (p->cacheDataValid == VG_FALSE) {
|
||||
valid = VG_FALSE;
|
||||
}
|
||||
else if (p->cacheTransformInit == VG_FALSE) {
|
||||
valid = VG_FALSE;
|
||||
}
|
||||
else if (shInvertMatrix( &p->cacheTransform, &mi ) == VG_FALSE) {
|
||||
valid = VG_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO: Compare change matrix for any scale or shear */
|
||||
// MULMATMAT( c->pathTransform, mi, mchange );
|
||||
SET2( X, mi.m[0][0], mi.m[1][0] );
|
||||
SET2( Y, mi.m[0][1], mi.m[1][1] );
|
||||
nX = NORM2( X ); nY = NORM2( Y );
|
||||
if (nX > 1.01f || nX < 0.99 ||
|
||||
nY > 1.01f || nY < 0.99)
|
||||
valid = VG_FALSE;
|
||||
}
|
||||
|
||||
if (valid == VG_FALSE)
|
||||
{
|
||||
/* Update cache */
|
||||
p->cacheDataValid = VG_TRUE;
|
||||
p->cacheTransformInit = VG_TRUE;
|
||||
p->cacheTransform = c->pathTransform;
|
||||
p->cacheStrokeTessValid = VG_FALSE;
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
VGboolean shIsStrokeCacheValid (VGContext *c, SHPath *p)
|
||||
{
|
||||
VGboolean valid = VG_TRUE;
|
||||
|
||||
if (p->cacheStrokeInit == VG_FALSE) {
|
||||
valid = VG_FALSE;
|
||||
}
|
||||
else if (p->cacheStrokeTessValid == VG_FALSE) {
|
||||
valid = VG_FALSE;
|
||||
}
|
||||
else if (c->strokeDashPattern.size > 0) {
|
||||
valid = VG_FALSE;
|
||||
}
|
||||
else if (p->cacheStrokeLineWidth != c->strokeLineWidth ||
|
||||
p->cacheStrokeCapStyle != c->strokeCapStyle ||
|
||||
p->cacheStrokeJoinStyle != c->strokeJoinStyle ||
|
||||
p->cacheStrokeMiterLimit != c->strokeMiterLimit) {
|
||||
valid = VG_FALSE;
|
||||
}
|
||||
|
||||
if (valid == VG_FALSE)
|
||||
{
|
||||
/* Update cache */
|
||||
p->cacheStrokeInit = VG_TRUE;
|
||||
p->cacheStrokeTessValid = VG_TRUE;
|
||||
p->cacheStrokeLineWidth = c->strokeLineWidth;
|
||||
p->cacheStrokeCapStyle = c->strokeCapStyle;
|
||||
p->cacheStrokeJoinStyle = c->strokeJoinStyle;
|
||||
p->cacheStrokeMiterLimit = c->strokeMiterLimit;
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Tessellates / strokes the path and draws it according to
|
||||
* VGContext state.
|
||||
*-----------------------------------------------------------*/
|
||||
|
||||
VG_API_CALL void vgDrawPath(VGPath path, VGbitfield paintModes)
|
||||
{
|
||||
SHPath *p;
|
||||
SHMatrix3x3 mi;
|
||||
SHfloat mgl[16];
|
||||
SHPaint *fill, *stroke;
|
||||
SHRectangle *rect;
|
||||
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
VG_RETURN_ERR_IF(!shIsValidPath(context, path),
|
||||
VG_BAD_HANDLE_ERROR, VG_NO_RETVAL);
|
||||
|
||||
VG_RETURN_ERR_IF(paintModes & (~(VG_STROKE_PATH | VG_FILL_PATH)),
|
||||
VG_ILLEGAL_ARGUMENT_ERROR, VG_NO_RETVAL);
|
||||
|
||||
/* Check whether scissoring is enabled and scissor
|
||||
rectangle is valid */
|
||||
if (context->scissoring == VG_TRUE) {
|
||||
rect = &context->scissor.items[0];
|
||||
if (context->scissor.size == 0) VG_RETURN( VG_NO_RETVAL );
|
||||
if (rect->w <= 0.0f || rect->h <= 0.0f) VG_RETURN( VG_NO_RETVAL );
|
||||
glScissor( (GLint)rect->x, (GLint)rect->y, (GLint)rect->w, (GLint)rect->h );
|
||||
glEnable( GL_SCISSOR_TEST );
|
||||
}
|
||||
|
||||
p = (SHPath*)path;
|
||||
|
||||
/* If user-to-surface matrix invertible tessellate in
|
||||
surface space for better path resolution */
|
||||
if (shIsTessCacheValid( context, p ) == VG_FALSE)
|
||||
{
|
||||
if (shInvertMatrix(&context->pathTransform, &mi)) {
|
||||
shFlattenPath(p, 1);
|
||||
shTransformVertices(&mi, p);
|
||||
}else shFlattenPath(p, 0);
|
||||
shFindBoundbox(p);
|
||||
}
|
||||
|
||||
/* Pick paint if available or default*/
|
||||
fill = (context->fillPaint ? context->fillPaint : &context->defaultPaint);
|
||||
stroke = (context->strokePaint ? context->strokePaint : &context->defaultPaint);
|
||||
|
||||
/* Apply transformation */
|
||||
shMatrixToGL(&context->pathTransform, mgl);
|
||||
glUseProgram(context->progDraw);
|
||||
glUniformMatrix4fv(context->locationDraw.model, 1, GL_FALSE, mgl);
|
||||
glUniform1i(context->locationDraw.drawMode, 0); /* drawMode: path */
|
||||
GL_CEHCK_ERROR;
|
||||
|
||||
if (paintModes & VG_FILL_PATH) {
|
||||
|
||||
/* Tesselate into stencil */
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
if( context->fillRule == VG_EVEN_ODD )
|
||||
{
|
||||
glStencilFunc(GL_ALWAYS, 0, 0);
|
||||
glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
|
||||
}
|
||||
else
|
||||
{
|
||||
// pseudo non-zero fill rule. Fill everything at least covered once, don't
|
||||
// care for possible decrements.
|
||||
// TODO implement real non-zero fill-rule
|
||||
glStencilFunc(GL_ALWAYS, 1, 1);
|
||||
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
||||
}
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
shDrawVertices(p, GL_TRIANGLE_FAN);
|
||||
|
||||
/* Setup blending */
|
||||
updateBlendingStateGL(context,
|
||||
fill->type == VG_PAINT_TYPE_COLOR &&
|
||||
fill->color.a == 1.0f);
|
||||
|
||||
/* Draw paint where stencil odd */
|
||||
glStencilFunc(GL_EQUAL, 1, 1);
|
||||
glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
shDrawPaintMesh(context, &p->min, &p->max, VG_FILL_PATH, GL_TEXTURE0);
|
||||
|
||||
/* Reset state */
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
// glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
if ((paintModes & VG_STROKE_PATH) &&
|
||||
context->strokeLineWidth > 0.0f) {
|
||||
#if 0
|
||||
if (1) {/*context->strokeLineWidth > 1.0f) {*/
|
||||
#endif
|
||||
if (shIsStrokeCacheValid( context, p ) == VG_FALSE)
|
||||
{
|
||||
/* Generate stroke triangles in user space */
|
||||
shVector2ArrayClear(&p->stroke);
|
||||
shStrokePath(context, p);
|
||||
}
|
||||
|
||||
/* Stroke into stencil */
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilFunc(GL_NOTEQUAL, 1, 1);
|
||||
glStencilOp(GL_KEEP, GL_INCR, GL_INCR);
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
shDrawStroke(p);
|
||||
|
||||
/* Setup blending */
|
||||
updateBlendingStateGL(context,
|
||||
stroke->type == VG_PAINT_TYPE_COLOR &&
|
||||
stroke->color.a == 1.0f);
|
||||
|
||||
/* Draw paint where stencil odd */
|
||||
glStencilFunc(GL_EQUAL, 1, 1);
|
||||
glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
shDrawPaintMesh(context, &p->min, &p->max, VG_STROKE_PATH, GL_TEXTURE0);
|
||||
|
||||
/* Reset state */
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
// glDisable(GL_BLEND);
|
||||
#if 0
|
||||
}else{
|
||||
|
||||
/* Simulate thin stroke by alpha */
|
||||
SHColor c = stroke->color;
|
||||
if (context->strokeLineWidth < 1.0f)
|
||||
c.a *= context->strokeLineWidth;
|
||||
|
||||
/* Draw contour as a line */
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
shDrawVertices(p, GL_LINE_STRIP);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (context->scissoring == VG_TRUE)
|
||||
glDisable( GL_SCISSOR_TEST );
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
||||
|
||||
VG_API_CALL void vgDrawImage(VGImage image)
|
||||
{
|
||||
SHImage *i;
|
||||
SHfloat mgl[16];
|
||||
SHPaint *fill;
|
||||
SHVector2 min, max;
|
||||
SHRectangle *rect;
|
||||
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
VG_RETURN_ERR_IF(!shIsValidImage(context, image),
|
||||
VG_BAD_HANDLE_ERROR, VG_NO_RETVAL);
|
||||
|
||||
/* TODO: check if image is current render target */
|
||||
|
||||
/* Check whether scissoring is enabled and scissor
|
||||
rectangle is valid */
|
||||
if (context->scissoring == VG_TRUE) {
|
||||
rect = &context->scissor.items[0];
|
||||
if (context->scissor.size == 0) VG_RETURN( VG_NO_RETVAL );
|
||||
if (rect->w <= 0.0f || rect->h <= 0.0f) VG_RETURN( VG_NO_RETVAL );
|
||||
glScissor( (GLint)rect->x, (GLint)rect->y, (GLint)rect->w, (GLint)rect->h );
|
||||
glEnable( GL_SCISSOR_TEST );
|
||||
}
|
||||
|
||||
/* Apply image-user-to-surface transformation */
|
||||
i = (SHImage*)image;
|
||||
shMatrixToGL(&context->imageTransform, mgl);
|
||||
glUseProgram(context->progDraw);
|
||||
glUniformMatrix4fv(context->locationDraw.model, 1, GL_FALSE, mgl);
|
||||
glUniform1i(context->locationDraw.drawMode, 1); /* drawMode: image */
|
||||
GL_CEHCK_ERROR;
|
||||
|
||||
/* Clamp to edge for proper filtering, modulate for multiply mode */
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, i->texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
/* Adjust antialiasing to settings */
|
||||
if (context->imageQuality == VG_IMAGE_QUALITY_NONANTIALIASED) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}else{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
glEnableVertexAttribArray(context->locationDraw.textureUV);
|
||||
GLfloat uv[] = { 0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
0.0f, 1.0f,
|
||||
1.0f, 1.0f };
|
||||
glVertexAttribPointer(context->locationDraw.textureUV, 2, GL_FLOAT, GL_FALSE, 0, uv);
|
||||
glUniform1i(context->locationDraw.imageSampler, 0);
|
||||
GL_CEHCK_ERROR;
|
||||
|
||||
/* Pick fill paint */
|
||||
fill = (context->fillPaint ? context->fillPaint : &context->defaultPaint);
|
||||
|
||||
/* Setup blending */
|
||||
updateBlendingStateGL(context, 0);
|
||||
|
||||
/* Draw textured quad */
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
if (context->imageMode == VG_DRAW_IMAGE_MULTIPLY){
|
||||
/* Multiply each colors */
|
||||
glUniform1i(context->locationDraw.imageMode, VG_DRAW_IMAGE_MULTIPLY );
|
||||
switch(fill->type){
|
||||
case VG_PAINT_TYPE_RADIAL_GRADIENT:
|
||||
shLoadRadialGradientMesh(fill, VG_FILL_PATH, VG_MATRIX_IMAGE_USER_TO_SURFACE);
|
||||
break;
|
||||
case VG_PAINT_TYPE_LINEAR_GRADIENT:
|
||||
shLoadLinearGradientMesh(fill, VG_FILL_PATH, VG_MATRIX_IMAGE_USER_TO_SURFACE);
|
||||
break;
|
||||
case VG_PAINT_TYPE_PATTERN:
|
||||
shLoadPatternMesh(fill, VG_FILL_PATH, VG_MATRIX_IMAGE_USER_TO_SURFACE);
|
||||
break;
|
||||
default:
|
||||
case VG_PAINT_TYPE_COLOR:
|
||||
shLoadOneColorMesh(fill);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
glUniform1i(context->locationDraw.imageMode, VG_DRAW_IMAGE_NORMAL );
|
||||
}
|
||||
|
||||
GLfloat v[] = { 0.0f, 0.0f,
|
||||
i->width, 0.0f,
|
||||
0.0f, i->height,
|
||||
i->width, i->height };
|
||||
glVertexAttribPointer(context->locationDraw.pos, 2, GL_FLOAT, GL_FALSE, 0, v);
|
||||
glEnableVertexAttribArray(context->locationDraw.pos);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDisableVertexAttribArray(context->locationDraw.pos);
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
GL_CEHCK_ERROR;
|
||||
|
||||
glDisableVertexAttribArray(context->locationDraw.textureUV);
|
||||
|
||||
if (context->scissoring == VG_TRUE)
|
||||
glDisable( GL_SCISSOR_TEST );
|
||||
|
||||
VG_RETURN(VG_NO_RETVAL);
|
||||
}
|
184
simgear/canvas/ShaderVG/src/shVectors.c
Normal file
184
simgear/canvas/ShaderVG/src/shVectors.c
Normal file
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shVectors.h"
|
||||
|
||||
#define _ITEM_T SHVector2
|
||||
#define _ARRAY_T SHVector2Array
|
||||
#define _FUNC_T shVector2Array
|
||||
#define _COMPARE_T(v1,v2) EQ2V(v1,v2)
|
||||
#define _ARRAY_DEFINE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
void SHVector2_ctor(SHVector2 *v) {
|
||||
v->x=0.0f; v->y=0.0f;
|
||||
}
|
||||
|
||||
void SHVector2_dtor(SHVector2 *v) {
|
||||
}
|
||||
|
||||
void SHVector3_ctor(SHVector3 *v) {
|
||||
v->x=0.0f; v->y=0.0f; v->z=0.0f;
|
||||
}
|
||||
|
||||
void SHVector3_dtor(SHVector3 *v) {
|
||||
}
|
||||
|
||||
void SHVector4_ctor(SHVector4 *v) {
|
||||
v->x=0.0f; v->y=0.0f; v->z=0.0f; v->w=0.0f;
|
||||
}
|
||||
|
||||
void SHVector4_dtor(SHVector4 *v) {
|
||||
}
|
||||
|
||||
void SHRectangle_ctor(SHRectangle *r) {
|
||||
r->x=0.0f; r->y=0.0f; r->w=0.0f; r->h=0.0f;
|
||||
}
|
||||
|
||||
void SHRectangle_dtor(SHRectangle *r) {
|
||||
}
|
||||
|
||||
void shRectangleSet(SHRectangle *r, SHfloat x,
|
||||
SHfloat y, SHfloat w, SHfloat h)
|
||||
{
|
||||
r->x=x; r->y=y; r->w=w; r->h=h;
|
||||
}
|
||||
|
||||
void SHMatrix3x3_ctor(SHMatrix3x3 *mt)
|
||||
{
|
||||
IDMAT((*mt));
|
||||
}
|
||||
|
||||
void SHMatrix3x3_dtor(SHMatrix3x3 *mt)
|
||||
{
|
||||
}
|
||||
|
||||
void shMatrixToGL(SHMatrix3x3 *m, SHfloat mgl[16])
|
||||
{
|
||||
/* When 2D vectors are specified OpenGL defaults Z to 0.0f so we
|
||||
have to shift the third column of our 3x3 matrix to right */
|
||||
mgl[0] = m->m[0][0]; mgl[4] = m->m[0][1]; mgl[8] = 0.0f; mgl[12] = m->m[0][2];
|
||||
mgl[1] = m->m[1][0]; mgl[5] = m->m[1][1]; mgl[9] = 0.0f; mgl[13] = m->m[1][2];
|
||||
mgl[2] = 0.0f; mgl[6] = 0.0f ; mgl[10] = 1.0f; mgl[14] = 0.0f;
|
||||
mgl[3] = m->m[2][0]; mgl[7] = m->m[2][1]; mgl[11] = 0.0f; mgl[15] = m->m[2][2];
|
||||
}
|
||||
|
||||
int shInvertMatrix(SHMatrix3x3 *m, SHMatrix3x3 *mout)
|
||||
{
|
||||
/* Calculate determinant */
|
||||
SHfloat D0 = m->m[1][1]*m->m[2][2] - m->m[2][1]*m->m[1][2];
|
||||
SHfloat D1 = m->m[2][0]*m->m[1][2] - m->m[1][0]*m->m[2][2];
|
||||
SHfloat D2 = m->m[1][0]*m->m[2][1] - m->m[2][0]*m->m[1][1];
|
||||
SHfloat D = m->m[0][0]*D0 + m->m[0][1]*D1 + m->m[0][2]*D2;
|
||||
|
||||
/* Check if singular */
|
||||
if( D == 0.0f ) return 0;
|
||||
D = 1.0f / D;
|
||||
|
||||
/* Calculate inverse */
|
||||
mout->m[0][0] = D * D0;
|
||||
mout->m[1][0] = D * D1;
|
||||
mout->m[2][0] = D * D2;
|
||||
mout->m[0][1] = D * (m->m[2][1]*m->m[0][2] - m->m[0][1]*m->m[2][2]);
|
||||
mout->m[1][1] = D * (m->m[0][0]*m->m[2][2] - m->m[2][0]*m->m[0][2]);
|
||||
mout->m[2][1] = D * (m->m[2][0]*m->m[0][1] - m->m[0][0]*m->m[2][1]);
|
||||
mout->m[0][2] = D * (m->m[0][1]*m->m[1][2] - m->m[1][1]*m->m[0][2]);
|
||||
mout->m[1][2] = D * (m->m[1][0]*m->m[0][2] - m->m[0][0]*m->m[1][2]);
|
||||
mout->m[2][2] = D * (m->m[0][0]*m->m[1][1] - m->m[1][0]*m->m[0][1]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
SHfloat shVectorOrientation(SHVector2 *v) {
|
||||
SHfloat norm = (SHfloat)NORM2((*v));
|
||||
SHfloat cosa = v->x/norm;
|
||||
SHfloat sina = v->y/norm;
|
||||
return (SHfloat)(sina>=0 ? SH_ACOS(cosa) : 2*PI-SH_ACOS(cosa));
|
||||
}
|
||||
|
||||
int shLineLineXsection(SHVector2 *o1, SHVector2 *v1,
|
||||
SHVector2 *o2, SHVector2 *v2,
|
||||
SHVector2 *xsection)
|
||||
{
|
||||
SHfloat rightU = o2->x - o1->x;
|
||||
SHfloat rightD = o2->y - o1->y;
|
||||
|
||||
SHfloat D = v1->x * (-v2->y) - v1->y * (-v2->x);
|
||||
SHfloat DX = rightU * (-v2->y) - rightD * (-v2->x);
|
||||
/*SHfloat DY = v1.x * rightD - v1.y * rightU;*/
|
||||
|
||||
SHfloat t1 = DX / D;
|
||||
|
||||
if (D == 0.0f)
|
||||
return 0;
|
||||
|
||||
xsection->x = o1->x + t1*v1->x;
|
||||
xsection->y = o1->y + t1*v1->y;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void shCalcOrtho2D(float* mat, float left, float right, float bottom, float top, float near, float far)
|
||||
{
|
||||
/* http://en.wikipedia.org/wiki/Orthographic_projection */
|
||||
const float zNear = near;
|
||||
const float zFar = far;
|
||||
const float inv_z = 1.0f / (zFar - zNear);
|
||||
const float inv_y = 1.0f / (top - bottom);
|
||||
const float inv_x = 1.0f / (right - left);
|
||||
|
||||
/* first column */
|
||||
*mat++ = (2.0f*inv_x);
|
||||
*mat++ = (0.0f);
|
||||
*mat++ = (0.0f);
|
||||
*mat++ = (0.0f);
|
||||
|
||||
/* second */
|
||||
*mat++ = (0.0f);
|
||||
*mat++ = (2.0*inv_y);
|
||||
*mat++ = (0.0f);
|
||||
*mat++ = (0.0f);
|
||||
|
||||
/* third */
|
||||
*mat++ = (0.0f);
|
||||
*mat++ = (0.0f);
|
||||
*mat++ = (-2.0f*inv_z);
|
||||
*mat++ = (0.0f);
|
||||
|
||||
/* fourth */
|
||||
*mat++ = (-(right + left)*inv_x);
|
||||
*mat++ = (-(top + bottom)*inv_y);
|
||||
*mat++ = (-(zFar + zNear)*inv_z);
|
||||
*mat++ = (1.0f);
|
||||
}
|
||||
|
||||
void shMatrixToVG(SHMatrix3x3 *m, SHfloat mvg[9])
|
||||
{
|
||||
mvg[0] = m->m[0][0]; mvg[3] = m->m[0][1]; mvg[6] = m->m[0][2];
|
||||
mvg[1] = m->m[1][0]; mvg[4] = m->m[1][1]; mvg[7] = m->m[1][2];
|
||||
mvg[2] = m->m[2][0]; mvg[5] = m->m[2][1]; mvg[8] = m->m[2][2];
|
||||
}
|
||||
|
||||
void shIdMatrixGL(SHfloat mgl[16])
|
||||
{
|
||||
mgl[0] = 1.0f; mgl[4] = 0.0f; mgl[8] = 0.0f; mgl[12] = 0.0f;
|
||||
mgl[1] = 0.0f; mgl[5] = 1.0f; mgl[9] = 0.0f; mgl[13] = 0.0f;
|
||||
mgl[2] = 0.0f; mgl[6] = 0.0f; mgl[10] = 1.0f; mgl[14] = 0.0f;
|
||||
mgl[3] = 0.0f; mgl[7] = 0.0f; mgl[11] = 0.0f; mgl[15] = 1.0f;
|
||||
}
|
278
simgear/canvas/ShaderVG/src/shVectors.h
Normal file
278
simgear/canvas/ShaderVG/src/shVectors.h
Normal file
@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SHVECTORS_H
|
||||
#define __SHVECTORS_H
|
||||
|
||||
#include "shDefs.h"
|
||||
|
||||
/* Vector structures
|
||||
*--------------------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
SHfloat x,y;
|
||||
} SHVector2;
|
||||
|
||||
void SHVector2_ctor(SHVector2 *v);
|
||||
void SHVector2_dtor(SHVector2 *v);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SHfloat x,y,z;
|
||||
} SHVector3;
|
||||
|
||||
void SHVector3_ctor(SHVector3 *v);
|
||||
void SHVector3_dtor(SHVector3 *v);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SHfloat x,y,z,w;
|
||||
} SHVector4;
|
||||
|
||||
void SHVector4_ctor(SHVector4 *v);
|
||||
void SHVector4_dtor(SHVector4 *v);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SHfloat x,y,w,h;
|
||||
} SHRectangle;
|
||||
|
||||
void SHRectangle_ctor(SHRectangle *r);
|
||||
void SHRectangle_dtor(SHRectangle *r);
|
||||
void shRectangleSet(SHRectangle *r, SHfloat x,
|
||||
SHfloat y, SHfloat w, SHfloat h);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SHfloat m[3][3];
|
||||
} SHMatrix3x3;
|
||||
|
||||
void SHMatrix3x3_ctor(SHMatrix3x3 *m);
|
||||
void SHMatrix3x3_dtor(SHMatrix3x3 *m);
|
||||
|
||||
/*------------------------------------------------------------
|
||||
* Vector Arrays
|
||||
*------------------------------------------------------------*/
|
||||
|
||||
#define _ITEM_T SHVector2
|
||||
#define _ARRAY_T SHVector2Array
|
||||
#define _FUNC_T shVector2Array
|
||||
#define _ARRAY_DECLARE
|
||||
#include "shArrayBase.h"
|
||||
|
||||
/*--------------------------------------------------------
|
||||
* Macros for typical vector operations. The only way to
|
||||
* inline in C is to actually write a macro
|
||||
*--------------------------------------------------------- */
|
||||
|
||||
#define SET2(v,xs,ys) { v.x=xs; v.y=ys; }
|
||||
#define SET3(v,xs,ys,zs) { v.x=xs; v.y=ys; v.z=zs; }
|
||||
#define SET4(v,xs,ys,zs,ws) { v.x=xs; v.y=ys; v.z=zs; v.w=ws; }
|
||||
|
||||
#define SET2V(v1,v2) { v1.x=v2.x; v1.y=v2.y; }
|
||||
#define SET3V(v1,v2) { v1.x=v2.x; v1.y=v2.y; v1.z=v2.z; }
|
||||
#define SET4V(v1,v2) { v1.x=v2.x; v1.y=v2.y; v1.z=v2.z; v1.w=v2.w; }
|
||||
|
||||
#define EQ2(v,xx,yy) ( v.x==xx && v.y==yy )
|
||||
#define EQ3(v,xx,yy,zz) ( v.x==xx && v.y==yy && v.z==zz )
|
||||
#define EQ4(v,xx,yy,zz,ww) ( v.x==xx && v.y==yy && v.z==zz && v.w==ww )
|
||||
|
||||
#define ISZERO2(v) ( v.x==0.0f && v.y==0.0f )
|
||||
#define ISZERO3(v) ( v.x==0.0f && v.y==0.0f && v.z==0.0f)
|
||||
#define ISZERO4(v) ( v.x==0.0f && v.y==0.0f && v.z==0.0f && v.w==0.0f )
|
||||
|
||||
#define EQ2V(v1,v2) ( v1.x==v2.x && v1.y==v2.y )
|
||||
#define EQ3V(v1,v2) ( v1.x==v2.x && v1.y==v2.y && v1.z==v2.z )
|
||||
#define EQ4V(v1,v2) ( v1.x==v2.x && v1.y==v2.y && v1.z==v2.z && v1.w==v2.w )
|
||||
|
||||
#define ADD2(v,xx,yy) { v.x+=xx; v.y+=yy; }
|
||||
#define ADD3(v,xx,yy,zz) { v.x+=xx; v.y+=yy; v.z+=zz; }
|
||||
#define ADD4(v,xx,yy,zz,ww) { v.x+=xx; v.y+=yy; v.z+=zz; v.w+=ww; }
|
||||
|
||||
#define ADD2V(v1,v2) { v1.x+=v2.x; v1.y+=v2.y; }
|
||||
#define ADD3V(v1,v2) { v1.x+=v2.x; v1.y+=v2.y; v1.z+=v2.z; }
|
||||
#define ADD4V(v1,v2) { v1.x+=v2.x; v1.y+=v2.y; v1.z+=v2.z; v1.w+=v2.w; }
|
||||
|
||||
#define SUB2(v,xx,yy) { v.x-=xx; v.y-=yy; }
|
||||
#define SUB3(v,xx,yy,zz) { v.x-=xx; v.y-=yy; v.z-=zz; }
|
||||
#define SUB4(v,xx,yy,zz,ww) { v.x-=xx; v.y-=yy; v.z-=zz; v.w-=v2.w; }
|
||||
|
||||
#define SUB2V(v1,v2) { v1.x-=v2.x; v1.y-=v2.y; }
|
||||
#define SUB3V(v1,v2) { v1.x-=v2.x; v1.y-=v2.y; v1.z-=v2.z; }
|
||||
#define SUB4V(v1,v2) { v1.x-=v2.x; v1.y-=v2.y; v1.z-=v2.z; v1.w-=v2.w; }
|
||||
|
||||
#define MUL2(v,f) { v.x*=f; v.y*=f; }
|
||||
#define MUL3(v,f) { v.x*=f; v.y*=f; v.z*=z; }
|
||||
#define MUL4(v,f) { v.x*=f; v.y*=f; v.z*=z; v.w*=w; }
|
||||
|
||||
#define DIV2(v,f) { v.x/=f; v.y/=f; }
|
||||
#define DIV3(v,f) { v.x/=f; v.y/=f; v.z/=z; }
|
||||
#define DIV4(v,f) { v.x/=f; v.y/=f; v.z/=z; v.w/=w; }
|
||||
|
||||
#define ABS2(v) { v.x=SH_ABS(v.x); v.y=SH_ABS(v.y); }
|
||||
#define ABS3(v) { v.x=SH_ABS(v.x); v.y=SH_ABS(v.y); v.z=SH_ABS(v.z); }
|
||||
#define ABS4(v) { v.x=SH_ABS(v.x); v.y=SH_ABS(v.y); v.z=SH_ABS(v.z); v.w=SH_ABS(v.w); }
|
||||
|
||||
#define NORMSQ2(v) (v.x*v.x + v.y*v.y)
|
||||
#define NORMSQ3(v) (v.x*v.x + v.y*v.y + v.z*v.z)
|
||||
#define NORMSQ4(v) (v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w)
|
||||
|
||||
#define NORM2(v) SH_SQRT(NORMSQ2(v))
|
||||
#define NORM3(v) SH_SQRT(NORMSQ3(v))
|
||||
#define NORM4(v) SH_SQRT(NORMSQ4(v))
|
||||
|
||||
#define NORMALIZE2(v) { SHfloat n=NORM2(v); v.x/=n; v.y/=n; }
|
||||
#define NORMALIZE3(v) { SHfloat n=NORM3(v); v.x/=n; v.y/=n; v.z/=n; }
|
||||
#define NORMALIZE4(v) { SHfloat n=NORM4(v); v.x/=n; v.y/=n; v.z/=n; v.w/=w; }
|
||||
|
||||
#define DOT2(v1,v2) (v1.x*v2.x + v1.y*v2.y)
|
||||
#define DOT3(v1,v2) (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z)
|
||||
#define DOT4(v1,v2) (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z + v1.w*v2.w)
|
||||
|
||||
#define CROSS2(v1,v2) (v1.x*v2.y - v2.x*v1.y)
|
||||
|
||||
#define ANGLE2(v1,v2) (SH_ACOS( DOT2(v1,v2) / (NORM2(v1)*NORM2(v2)) ))
|
||||
#define ANGLE2N(v1,v2) (SH_ACOS( DOT2(v1,v2) ))
|
||||
|
||||
#define OFFSET2V(v, o, s) { v.x += o.x*s; v.y += o.y*s; }
|
||||
#define OFFSET3V(v, o, s) { v.x += o.x*s; v.y += o.y*s; v.z += o.z*s; }
|
||||
#define OFFSET4V(v, o, s) { v.x += o.x*s; v.y += o.y*s; v.z += o.z*s; v.w += o.w*s; }
|
||||
|
||||
/*-----------------------------------------------------
|
||||
* Macros for matrix operations
|
||||
*-----------------------------------------------------*/
|
||||
|
||||
#define SETMAT(mat, m00, m01, m02, m10, m11, m12, m20, m21, m22) { \
|
||||
mat.m[0][0] = m00; mat.m[0][1] = m01; mat.m[0][2] = m02; \
|
||||
mat.m[1][0] = m10; mat.m[1][1] = m11; mat.m[1][2] = m12; \
|
||||
mat.m[2][0] = m20; mat.m[2][1] = m21; mat.m[2][2] = m22; }
|
||||
|
||||
#define SETMATMAT(m1, m2) { \
|
||||
int i,j; \
|
||||
for(i=0;i<3;i++) \
|
||||
for(j=0;j<3;j++) \
|
||||
m1.m[i][j] = m2.m[i][j]; }
|
||||
|
||||
#define MULMATS(mat, s) { \
|
||||
int i,j; \
|
||||
for(i=0;i<3;i++) \
|
||||
for(j=0;j<3;j++) \
|
||||
mat.m[i][j] *= s; }
|
||||
|
||||
#define DIVMATS(mat, s) { \
|
||||
int i,j; \
|
||||
for(i=0;i<3;i++) \
|
||||
for(j=0;j<3;j++) \
|
||||
mat.m[i][j] /= s; }
|
||||
|
||||
#define MULMATMAT(m1, m2, mout) { \
|
||||
int i,j; \
|
||||
for(i=0;i<3;i++) \
|
||||
for(j=0;j<3;j++) \
|
||||
mout.m[i][j] = \
|
||||
m1.m[i][0] * m2.m[0][j] + \
|
||||
m1.m[i][1] * m2.m[1][j] + \
|
||||
m1.m[i][2] * m2.m[2][j]; }
|
||||
|
||||
#define IDMAT(mat) SETMAT(mat, 1,0,0, 0,1,0, 0,0,1)
|
||||
|
||||
#define TRANSLATEMATL(mat, tx, ty) { \
|
||||
SHMatrix3x3 trans,temp; \
|
||||
SETMAT(trans, 1,0,tx, 0,1,ty, 0,0,1); \
|
||||
MULMATMAT(trans, mat, temp); \
|
||||
SETMATMAT(mat, temp); }
|
||||
|
||||
#define TRANSLATEMATR(mat, tx, ty) { \
|
||||
SHMatrix3x3 trans,temp; \
|
||||
SETMAT(trans, 1,0,tx, 0,1,ty, 0,0,1); \
|
||||
MULMATMAT(mat, trans, temp); \
|
||||
SETMATMAT(mat, temp); }
|
||||
|
||||
#define SCALEMATL(mat, sx, sy) { \
|
||||
SHMatrix3x3 scale, temp; \
|
||||
SETMAT(scale, sx,0,0, 0,sy,0, 0,0,1); \
|
||||
MULMATMAT(scale, mat, temp); \
|
||||
SETMATMAT(mat, temp); }
|
||||
|
||||
#define SCALEMATR(mat, sx, sy) { \
|
||||
SHMatrix3x3 scale, temp; \
|
||||
SETMAT(scale, sx,0,0, 0,sy,0, 0,0,1); \
|
||||
MULMATMAT(mat, scale, temp); \
|
||||
SETMATMAT(mat, temp); }
|
||||
|
||||
#define SHEARMATL(mat, shx, shy) {\
|
||||
SHMatrix3x3 shear, temp;\
|
||||
SETMAT(shear, 1,shx,0, shy,1,0, 0,0,1); \
|
||||
MULMATMAT(shear, mat, temp); \
|
||||
SETMATMAT(mat, temp); }
|
||||
|
||||
#define SHEARMATR(mat, shx, shy) {\
|
||||
SHMatrix3x3 shear, temp;\
|
||||
SETMAT(shear, 1,shx,0, shy,1,0, 0,0,1); \
|
||||
MULMATMAT(mat, shear, temp); \
|
||||
SETMATMAT(mat, temp); }
|
||||
|
||||
#define ROTATEMATL(mat, a) { \
|
||||
SHfloat cosa=SH_COS(a), sina=SH_SIN(a); \
|
||||
SHMatrix3x3 rot, temp; \
|
||||
SETMAT(rot, cosa,-sina,0, sina,cosa,0, 0,0,1); \
|
||||
MULMATMAT(rot, mat, temp); \
|
||||
SETMATMAT(mat, temp); }
|
||||
|
||||
#define ROTATEMATR(mat, a) { \
|
||||
SHfloat cosa=SH_COS(a), sina=SH_SIN(a); \
|
||||
SHMatrix3x3 rot, temp; \
|
||||
SETMAT(rot, cosa,-sina,0, sina,cosa,0, 0,0,1); \
|
||||
MULMATMAT(mat, rot, temp); \
|
||||
SETMATMAT(mat, temp); }
|
||||
|
||||
#define TRANSFORM2TO(v, mat, vout) { \
|
||||
vout.x = v.x*mat.m[0][0] + v.y*mat.m[0][1] + 1*mat.m[0][2]; \
|
||||
vout.y = v.x*mat.m[1][0] + v.y*mat.m[1][1] + 1*mat.m[1][2]; }
|
||||
|
||||
#define TRANSFORM2(v, mat) { \
|
||||
SHVector2 temp; TRANSFORM2TO(v, mat, temp); v = temp; }
|
||||
|
||||
#define TRANSFORM2DIRTO(v, mat, vout) { \
|
||||
vout.x = v.x*mat.m[0][0] + v.y*mat.m[0][1]; \
|
||||
vout.y = v.x*mat.m[1][0] + v.y*mat.m[1][1]; }
|
||||
|
||||
#define TRANSFORM2DIR(v, mat) { \
|
||||
SHVector2 temp; TRANSFORM2DIRTO(v, mat, temp); v = temp; }
|
||||
|
||||
|
||||
/*--------------------------------------------------------
|
||||
* Additional functions
|
||||
*--------------------------------------------------------- */
|
||||
|
||||
void shMatrixToGL(SHMatrix3x3 *m, SHfloat mgl[16]);
|
||||
|
||||
SHint shInvertMatrix(SHMatrix3x3 *m, SHMatrix3x3 *mout);
|
||||
|
||||
SHfloat shVectorOrientation(SHVector2 *v);
|
||||
|
||||
int shLineLineXsection(SHVector2 *o1, SHVector2 *v1,
|
||||
SHVector2 *o2, SHVector2 *v2,
|
||||
SHVector2 *xsection);
|
||||
void shCalcOrtho2D(float* mat, float left, float right, float bottom, float top, float near, float far);
|
||||
void shMatrixToVG(SHMatrix3x3 *m, SHfloat mvg[9]);
|
||||
void shIdMatrixGL(SHfloat mgl[16]);
|
||||
|
||||
#endif/* __SHVECTORS_H */
|
426
simgear/canvas/ShaderVG/src/shVgu.c
Normal file
426
simgear/canvas/ShaderVG/src/shVgu.c
Normal file
@ -0,0 +1,426 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Ivan Leben
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#define VG_API_EXPORT
|
||||
#include "vg/openvg.h"
|
||||
#include "vg/vgu.h"
|
||||
#include "shDefs.h"
|
||||
#include "shContext.h"
|
||||
#include <math.h>
|
||||
|
||||
static VGUErrorCode shAppend(VGPath path, SHint commSize, const VGubyte *comm,
|
||||
SHint dataSize, const VGfloat *data)
|
||||
{
|
||||
VGErrorCode err = VG_NO_ERROR;
|
||||
VGPathDatatype type = vgGetParameterf(path, VG_PATH_DATATYPE);
|
||||
VGfloat scale = vgGetParameterf(path, VG_PATH_SCALE);
|
||||
VGfloat bias = vgGetParameterf(path, VG_PATH_BIAS);
|
||||
SH_ASSERT(dataSize <= 26);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case VG_PATH_DATATYPE_S_8: {
|
||||
|
||||
SHint8 data8[26]; int i;
|
||||
for (i=0; i<dataSize; ++i)
|
||||
data8[i] = (SHint8)SH_FLOOR((data[i] - bias) / scale + 0.5f);
|
||||
vgAppendPathData(path, commSize, comm, data8);
|
||||
|
||||
break;}
|
||||
case VG_PATH_DATATYPE_S_16: {
|
||||
|
||||
SHint16 data16[26]; int i;
|
||||
for (i=0; i<dataSize; ++i)
|
||||
data16[i] = (SHint16)SH_FLOOR((data[i] - bias) / scale + 0.5f);
|
||||
vgAppendPathData(path, commSize, comm, data16);
|
||||
|
||||
break;}
|
||||
case VG_PATH_DATATYPE_S_32: {
|
||||
|
||||
SHint32 data32[26]; int i;
|
||||
for (i=0; i<dataSize; ++i)
|
||||
data32[i] = (SHint32)SH_FLOOR((data[i] - bias) / scale + 0.5f);
|
||||
vgAppendPathData(path, commSize, comm, data32);
|
||||
|
||||
break;}
|
||||
default: {
|
||||
|
||||
VGfloat dataF[26]; int i;
|
||||
for (i=0; i<dataSize; ++i)
|
||||
dataF[i] = (data[i] - bias) / scale;
|
||||
vgAppendPathData(path, commSize, comm, dataF);
|
||||
|
||||
break;}
|
||||
}
|
||||
|
||||
err = vgGetError();
|
||||
if (err == VG_PATH_CAPABILITY_ERROR)
|
||||
return VGU_PATH_CAPABILITY_ERROR;
|
||||
else if (err == VG_BAD_HANDLE_ERROR)
|
||||
return VGU_BAD_HANDLE_ERROR;
|
||||
else if (err == VG_OUT_OF_MEMORY_ERROR)
|
||||
return VGU_OUT_OF_MEMORY_ERROR;
|
||||
|
||||
return VGU_NO_ERROR;
|
||||
}
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguLine(VGPath path,
|
||||
VGfloat x0, VGfloat y0,
|
||||
VGfloat x1, VGfloat y1)
|
||||
{
|
||||
VGUErrorCode err = VGU_NO_ERROR;
|
||||
const VGubyte comm[] = {VG_MOVE_TO_ABS, VG_LINE_TO_ABS};
|
||||
|
||||
VGfloat data[4];
|
||||
data[0] = x0; data[1] = y0;
|
||||
data[2] = x1; data[3] = y1;
|
||||
|
||||
err = shAppend(path, 2, comm, 4, data);
|
||||
return err;
|
||||
}
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguPolygon(VGPath path,
|
||||
const VGfloat * points, VGint count,
|
||||
VGboolean closed)
|
||||
{
|
||||
VGint i;
|
||||
VGubyte *comm = NULL;
|
||||
VGUErrorCode err = VGU_NO_ERROR;
|
||||
|
||||
if (points == NULL || count <= 0)
|
||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
||||
/* TODO: check points array alignment */
|
||||
|
||||
comm = (VGubyte*)malloc( (count+1) * sizeof(VGubyte) );
|
||||
if (comm == NULL) return VGU_OUT_OF_MEMORY_ERROR;
|
||||
|
||||
comm[0] = VG_MOVE_TO_ABS;
|
||||
for (i=1; i<count; ++i)
|
||||
comm[i] = VG_LINE_TO_ABS;
|
||||
comm[count] = VG_CLOSE_PATH;
|
||||
|
||||
if (closed) err = shAppend(path, count+1, comm, count*2, points);
|
||||
else err = shAppend(path, count, comm, count*2, points);
|
||||
|
||||
free(comm);
|
||||
return err;
|
||||
}
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguRect(VGPath path,
|
||||
VGfloat x, VGfloat y,
|
||||
VGfloat width, VGfloat height)
|
||||
{
|
||||
VGUErrorCode err = VGU_NO_ERROR;
|
||||
|
||||
VGubyte comm[5] = {
|
||||
VG_MOVE_TO_ABS, VG_HLINE_TO_REL,
|
||||
VG_VLINE_TO_REL, VG_HLINE_TO_REL,
|
||||
VG_CLOSE_PATH };
|
||||
|
||||
VGfloat data[5];
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
||||
|
||||
data[0] = x; data[1] = y;
|
||||
data[2] = width; data[3] = height;
|
||||
data[4] = -width;
|
||||
|
||||
err = shAppend(path, 5, comm, 5, data);
|
||||
return err;
|
||||
}
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguRoundRect(VGPath path,
|
||||
VGfloat x, VGfloat y,
|
||||
VGfloat width, VGfloat height,
|
||||
VGfloat arcWidth, VGfloat arcHeight)
|
||||
{
|
||||
VGUErrorCode err = VGU_NO_ERROR;
|
||||
|
||||
VGubyte comm[10] = {
|
||||
VG_MOVE_TO_ABS,
|
||||
VG_HLINE_TO_REL, VG_SCCWARC_TO_REL,
|
||||
VG_VLINE_TO_REL, VG_SCCWARC_TO_REL,
|
||||
VG_HLINE_TO_REL, VG_SCCWARC_TO_REL,
|
||||
VG_VLINE_TO_REL, VG_SCCWARC_TO_REL,
|
||||
VG_CLOSE_PATH };
|
||||
|
||||
VGfloat data[26];
|
||||
VGfloat rx, ry;
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
||||
|
||||
SH_CLAMP(arcWidth, 0.0f, width);
|
||||
SH_CLAMP(arcHeight, 0.0f, height);
|
||||
rx = arcWidth/2;
|
||||
ry = arcHeight/2;
|
||||
|
||||
data[0] = x + rx; data[1] = y;
|
||||
|
||||
data[2] = width - arcWidth;
|
||||
data[3] = rx; data[4] = ry; data[5] = 0;
|
||||
data[6] = rx; data[7] = ry;
|
||||
|
||||
data[8] = height - arcHeight;
|
||||
data[9] = rx; data[10] = ry; data[11] = 0;
|
||||
data[12] = -rx; data[13] = ry;
|
||||
|
||||
data[14] = -(width - arcWidth);
|
||||
data[15] = rx; data[16] = ry; data[17] = 0;
|
||||
data[18] = -rx; data[19] = -ry;
|
||||
|
||||
data[20] = -(height - arcHeight);
|
||||
data[21] = rx; data[22] = ry; data[23] = 0;
|
||||
data[24] = rx; data[25] = -ry;
|
||||
|
||||
err = shAppend(path, 10, comm, 26, data);
|
||||
return err;
|
||||
}
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguEllipse(VGPath path,
|
||||
VGfloat cx, VGfloat cy,
|
||||
VGfloat width, VGfloat height)
|
||||
{
|
||||
VGUErrorCode err = VGU_NO_ERROR;
|
||||
|
||||
const VGubyte comm[] = {
|
||||
VG_MOVE_TO_ABS, VG_SCCWARC_TO_REL,
|
||||
VG_SCCWARC_TO_REL, VG_CLOSE_PATH};
|
||||
|
||||
VGfloat data[12];
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
||||
|
||||
data[0] = cx + width/2; data[1] = cy;
|
||||
|
||||
data[2] = width/2; data[3] = height/2; data[4] = 0;
|
||||
data[5] = -width; data[6] = 0;
|
||||
|
||||
data[7] = width/2; data[8] = height/2; data[9] = 0;
|
||||
data[10] = width; data[11] = 0;
|
||||
|
||||
err = shAppend(path, 4, comm, 12, data);
|
||||
return err;
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguArc(VGPath path,
|
||||
VGfloat x, VGfloat y,
|
||||
VGfloat width, VGfloat height,
|
||||
VGfloat startAngle, VGfloat angleExtent,
|
||||
VGUArcType arcType)
|
||||
{
|
||||
VGUErrorCode err = VGU_NO_ERROR;
|
||||
|
||||
VGubyte commStart[1] = {VG_MOVE_TO_ABS};
|
||||
VGfloat dataStart[2];
|
||||
|
||||
VGubyte commArcCCW[1] = {VG_SCCWARC_TO_ABS};
|
||||
VGubyte commArcCW[1] = {VG_SCWARC_TO_ABS};
|
||||
VGfloat dataArc[5];
|
||||
|
||||
VGubyte commEndPie[2] = {VG_LINE_TO_ABS, VG_CLOSE_PATH};
|
||||
VGfloat dataEndPie[2];
|
||||
|
||||
VGubyte commEndChord[1] = {VG_CLOSE_PATH};
|
||||
VGfloat dataEndChord[1] = {0.0f};
|
||||
|
||||
VGfloat alast, a = 0.0f;
|
||||
VGfloat rx = width/2, ry = height/2;
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
||||
|
||||
if (arcType != VGU_ARC_OPEN &&
|
||||
arcType != VGU_ARC_CHORD &&
|
||||
arcType != VGU_ARC_PIE)
|
||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
||||
|
||||
startAngle = SH_DEG2RAD(startAngle);
|
||||
angleExtent = SH_DEG2RAD(angleExtent);
|
||||
alast = startAngle + angleExtent;
|
||||
|
||||
dataStart[0] = x + SH_COS(startAngle) * rx;
|
||||
dataStart[1] = y + SH_SIN(startAngle) * ry;
|
||||
err = shAppend(path, 1, commStart, 2, dataStart);
|
||||
if (err != VGU_NO_ERROR) return err;
|
||||
|
||||
dataArc[0] = rx;
|
||||
dataArc[1] = ry;
|
||||
dataArc[2] = 0.0f;
|
||||
|
||||
if (angleExtent > 0) {
|
||||
|
||||
a = startAngle + PI;
|
||||
while (a < alast) {
|
||||
dataArc[3] = x + SH_COS(a) * rx;
|
||||
dataArc[4] = y + SH_SIN(a) * ry;
|
||||
err = shAppend(path, 1, commArcCCW, 5, dataArc);
|
||||
if (err != VGU_NO_ERROR) return err;
|
||||
a += PI; }
|
||||
|
||||
dataArc[3] = x + SH_COS(alast) * rx;
|
||||
dataArc[4] = y + SH_SIN(alast) * ry;
|
||||
err = shAppend(path, 1, commArcCCW, 5, dataArc);
|
||||
if (err != VGU_NO_ERROR) return err;
|
||||
|
||||
}else{
|
||||
|
||||
a = startAngle - PI;
|
||||
while (a > alast) {
|
||||
dataArc[3] = x + SH_COS(a) * rx;
|
||||
dataArc[4] = y + SH_SIN(a) * ry;
|
||||
err = shAppend(path, 1, commArcCW, 5, dataArc);
|
||||
if (err != VGU_NO_ERROR) return err;
|
||||
a -= PI; }
|
||||
|
||||
dataArc[3] = x + SH_COS(alast) * rx;
|
||||
dataArc[4] = y + SH_SIN(alast) * ry;
|
||||
err = shAppend(path, 1, commArcCW, 5, dataArc);
|
||||
if (err != VGU_NO_ERROR) return err;
|
||||
}
|
||||
|
||||
|
||||
if (arcType == VGU_ARC_PIE) {
|
||||
dataEndPie[0] = x; dataEndPie[1] = y;
|
||||
err = shAppend(path, 2, commEndPie, 2, dataEndPie);
|
||||
}else if (arcType == VGU_ARC_CHORD) {
|
||||
err = shAppend(path, 1, commEndChord, 0, dataEndChord);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguComputeWarpQuadToSquare(VGfloat sx0, VGfloat sy0,
|
||||
VGfloat sx1, VGfloat sy1,
|
||||
VGfloat sx2, VGfloat sy2,
|
||||
VGfloat sx3, VGfloat sy3,
|
||||
VGfloat * matrix)
|
||||
{
|
||||
/* Basic idea taken from the reference implementation */
|
||||
VGfloat mat[3][3];
|
||||
VGfloat det, det00, det01, det02;
|
||||
|
||||
if( !matrix )
|
||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
||||
|
||||
if( vguComputeWarpSquareToQuad( sx0, sy0, sx1, sy1, sx2, sy2, sx3, sy3,
|
||||
(VGfloat*)mat )
|
||||
== VGU_BAD_WARP_ERROR )
|
||||
return VGU_BAD_WARP_ERROR;
|
||||
|
||||
// Invert the matrix...
|
||||
det00 = mat[1][1]*mat[2][2] - mat[2][1]*mat[1][2];
|
||||
det01 = mat[2][0]*mat[1][2] - mat[1][0]*mat[2][2];
|
||||
det02 = mat[1][0]*mat[2][1] - mat[2][0]*mat[1][1];
|
||||
|
||||
det = mat[0][0]*det00 + mat[0][1]*det01 + mat[0][2]*det02;
|
||||
if( det == 0.0f )
|
||||
return VGU_BAD_WARP_ERROR;
|
||||
|
||||
det = 1 / det;
|
||||
|
||||
matrix[0] = det * det00;
|
||||
matrix[3] = det * det01;
|
||||
matrix[6] = det * det02;
|
||||
matrix[1] = det * (mat[2][1]*mat[0][2] - mat[0][1]*mat[2][2]);
|
||||
matrix[4] = det * (mat[0][0]*mat[2][2] - mat[2][0]*mat[0][2]);
|
||||
matrix[7] = det * (mat[2][0]*mat[0][1] - mat[0][0]*mat[2][1]);
|
||||
matrix[2] = det * (mat[0][1]*mat[1][2] - mat[1][1]*mat[0][2]);
|
||||
matrix[5] = det * (mat[1][0]*mat[0][2] - mat[0][0]*mat[1][2]);
|
||||
matrix[8] = det * (mat[0][0]*mat[1][1] - mat[1][0]*mat[0][1]);
|
||||
|
||||
return VGU_NO_ERROR;
|
||||
}
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguComputeWarpSquareToQuad(VGfloat dx0, VGfloat dy0,
|
||||
VGfloat dx1, VGfloat dy1,
|
||||
VGfloat dx2, VGfloat dy2,
|
||||
VGfloat dx3, VGfloat dy3,
|
||||
VGfloat * matrix)
|
||||
{
|
||||
/* Taken from https://github.com/mvr/shivavg (who has taken it from the
|
||||
reference implementation) */
|
||||
|
||||
VGfloat diffx1 = dx1 - dx3;
|
||||
VGfloat diffy1 = dy1 - dy3;
|
||||
VGfloat diffx2 = dx2 - dx3;
|
||||
VGfloat diffy2 = dy2 - dy3;
|
||||
|
||||
VGfloat det = diffx1*diffy2 - diffx2*diffy1;
|
||||
|
||||
VGfloat sumx = dx0 - dx1 + dx3 - dx2;
|
||||
VGfloat sumy = dy0 - dy1 + dy3 - dy2;
|
||||
|
||||
VGfloat g, h, oodet;
|
||||
|
||||
if(!matrix)
|
||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
||||
|
||||
if(det == 0.0f)
|
||||
return VGU_BAD_WARP_ERROR;
|
||||
|
||||
if(sumx == 0.0f && sumy == 0.0f)
|
||||
{
|
||||
/* Affine mapping */
|
||||
matrix[0] = dx1 - dx0;
|
||||
matrix[1] = dy1 - dy0;
|
||||
matrix[2] = 0.0f;
|
||||
matrix[3] = dx3 - dx1;
|
||||
matrix[4] = dy3 - dy1;
|
||||
matrix[5] = 0.0f;
|
||||
matrix[6] = dx0;
|
||||
matrix[7] = dy0;
|
||||
matrix[8] = 1.0f;
|
||||
return VGU_NO_ERROR;
|
||||
}
|
||||
|
||||
oodet = 1.0f / det;
|
||||
g = (sumx*diffy2 - diffx2*sumy) * oodet;
|
||||
h = (diffx1*sumy - sumx*diffy1) * oodet;
|
||||
|
||||
matrix[0] = dx1-dx0+g*dx1;
|
||||
matrix[1] = dy1-dy0+g*dy1;
|
||||
matrix[2] = g;
|
||||
matrix[3] = dx2-dx0+h*dx2;
|
||||
matrix[4] = dy2-dy0+h*dy2;
|
||||
matrix[5] = h;
|
||||
matrix[6] = dx0;
|
||||
matrix[7] = dy0;
|
||||
matrix[8] = 1.0f;
|
||||
|
||||
return VGU_NO_ERROR;
|
||||
}
|
||||
|
||||
VGU_API_CALL VGUErrorCode vguComputeWarpQuadToQuad(VGfloat dx0, VGfloat dy0,
|
||||
VGfloat dx1, VGfloat dy1,
|
||||
VGfloat dx2, VGfloat dy2,
|
||||
VGfloat dx3, VGfloat dy3,
|
||||
VGfloat sx0, VGfloat sy0,
|
||||
VGfloat sx1, VGfloat sy1,
|
||||
VGfloat sx2, VGfloat sy2,
|
||||
VGfloat sx3, VGfloat sy3,
|
||||
VGfloat * matrix)
|
||||
{
|
||||
return VGU_NO_ERROR;
|
||||
}
|
494
simgear/canvas/ShaderVG/src/shaders.c
Normal file
494
simgear/canvas/ShaderVG/src/shaders.c
Normal file
@ -0,0 +1,494 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Takuma Hayashi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "vg/openvg.h"
|
||||
#include "shContext.h"
|
||||
#include "shDefs.h"
|
||||
#include "shaders.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static const char* vgShaderVertexPipeline = R"glsl(
|
||||
#version 330
|
||||
|
||||
/*** Input *******************/
|
||||
in vec2 pos;
|
||||
in vec2 textureUV;
|
||||
uniform mat4 sh_Model;
|
||||
uniform mat4 sh_Ortho;
|
||||
uniform mat3 paintInverted;
|
||||
|
||||
/*** Output ******************/
|
||||
out vec2 texImageCoord;
|
||||
out vec2 paintCoord;
|
||||
|
||||
/*** Grobal variables ********************/
|
||||
vec4 sh_Vertex;
|
||||
|
||||
/*** Functions ****************************************/
|
||||
|
||||
// User defined shader
|
||||
void shMain(void);
|
||||
|
||||
/*** Main thread **************************************************/
|
||||
void main() {
|
||||
|
||||
/* Stage 3: Transformation */
|
||||
sh_Vertex = vec4(pos, 0, 1);
|
||||
|
||||
/* Extended Stage: User defined shader that affects gl_Position */
|
||||
shMain();
|
||||
|
||||
/* 2D pos in texture space */
|
||||
texImageCoord = textureUV;
|
||||
|
||||
/* 2D pos in paint space (Back to paint space) */
|
||||
paintCoord = (paintInverted * vec3(pos, 1)).xy;
|
||||
|
||||
}
|
||||
)glsl";
|
||||
|
||||
static const char* vgShaderVertexUserDefault = R"glsl(
|
||||
void shMain(){ gl_Position = sh_Ortho * sh_Model * sh_Vertex; }
|
||||
)glsl";
|
||||
|
||||
static const char* vgShaderFragmentPipeline = R"glsl(
|
||||
|
||||
#version 330
|
||||
|
||||
/*** Enum constans ************************************/
|
||||
|
||||
#define PAINT_TYPE_COLOR 0x1B00
|
||||
#define PAINT_TYPE_LINEAR_GRADIENT 0x1B01
|
||||
#define PAINT_TYPE_RADIAL_GRADIENT 0x1B02
|
||||
#define PAINT_TYPE_PATTERN 0x1B03
|
||||
|
||||
#define DRAW_IMAGE_NORMAL 0x1F00
|
||||
#define DRAW_IMAGE_MULTIPLY 0x1F01
|
||||
|
||||
#define DRAW_MODE_PATH 0
|
||||
#define DRAW_MODE_IMAGE 1
|
||||
|
||||
/*** Interpolated *************************************/
|
||||
|
||||
in vec2 texImageCoord;
|
||||
in vec2 paintCoord;
|
||||
|
||||
/*** Input ********************************************/
|
||||
|
||||
// Basic rendering Mode
|
||||
uniform int drawMode;
|
||||
// Image
|
||||
uniform sampler2D imageSampler;
|
||||
uniform int imageMode;
|
||||
// Paint
|
||||
uniform int paintType;
|
||||
uniform vec4 paintColor;
|
||||
uniform vec2 paintParams[3];
|
||||
// Gradient
|
||||
uniform sampler2D rampSampler;
|
||||
// Pattern
|
||||
uniform sampler2D patternSampler;
|
||||
// Color transform
|
||||
uniform vec4 scaleFactorBias[2];
|
||||
|
||||
/*** Output *******************************************/
|
||||
|
||||
//out vec4 fragColor;
|
||||
|
||||
/*** Built-in variables for shMain *******************************************/
|
||||
|
||||
vec4 sh_Color;
|
||||
|
||||
/*** Functions ****************************************/
|
||||
|
||||
// 9.3.1 Linear Gradients
|
||||
float linearGradient(vec2 fragCoord, vec2 p0, vec2 p1){
|
||||
|
||||
float x = fragCoord.x;
|
||||
float y = fragCoord.y;
|
||||
float x0 = p0.x;
|
||||
float y0 = p0.y;
|
||||
float x1 = p1.x;
|
||||
float y1 = p1.y;
|
||||
float dx = x1 - x0;
|
||||
float dy = y1 - y0;
|
||||
|
||||
return
|
||||
( dx * (x - x0) + dy * (y - y0) )
|
||||
/ ( dx*dx + dy*dy );
|
||||
}
|
||||
|
||||
// 9.3.2 Radial Gradients
|
||||
float radialGradient(vec2 fragCoord, vec2 centerCoord, vec2 focalCoord, float r){
|
||||
|
||||
float x = fragCoord.x;
|
||||
float y = fragCoord.y;
|
||||
float cx = centerCoord.x;
|
||||
float cy = centerCoord.y;
|
||||
float fx = focalCoord.x;
|
||||
float fy = focalCoord.y;
|
||||
float dx = x - fx;
|
||||
float dy = y - fy;
|
||||
float dfx = fx - cx;
|
||||
float dfy = fy - cy;
|
||||
|
||||
return
|
||||
( (dx * dfx + dy * dfy) + sqrt(r*r*(dx*dx + dy*dy) - pow(dx*dfy - dy*dfx, 2.0)) )
|
||||
/ ( r*r - (dfx*dfx + dfy*dfy) );
|
||||
}
|
||||
|
||||
// User defined shader
|
||||
void shMain(void);
|
||||
|
||||
/*** Main thread *************************************/
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col;
|
||||
|
||||
/* Stage 6: Paint Generation */
|
||||
switch(paintType){
|
||||
case PAINT_TYPE_LINEAR_GRADIENT:
|
||||
{
|
||||
vec2 x0 = paintParams[0];
|
||||
vec2 x1 = paintParams[1];
|
||||
float factor = linearGradient(paintCoord, x0, x1);
|
||||
col = texture(rampSampler, vec2(factor, 0.5));
|
||||
}
|
||||
break;
|
||||
case PAINT_TYPE_RADIAL_GRADIENT:
|
||||
{
|
||||
vec2 center = paintParams[0];
|
||||
vec2 focal = paintParams[1];
|
||||
float radius = paintParams[2].x;
|
||||
float factor = radialGradient(paintCoord, center, focal, radius);
|
||||
col = texture(rampSampler, vec2(factor, 0.5));
|
||||
}
|
||||
break;
|
||||
case PAINT_TYPE_PATTERN:
|
||||
{
|
||||
float width = paintParams[0].x;
|
||||
float height = paintParams[0].y;
|
||||
vec2 texCoord = vec2(paintCoord.x / width, paintCoord.y / height);
|
||||
col = texture(patternSampler, texCoord);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case PAINT_TYPE_COLOR:
|
||||
col = paintColor;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Stage 7: Image Interpolation */
|
||||
if(drawMode == DRAW_MODE_IMAGE) {
|
||||
col = texture(imageSampler, texImageCoord)
|
||||
* (imageMode == DRAW_IMAGE_MULTIPLY ? col : vec4(1.0, 1.0, 1.0, 1.0));
|
||||
}
|
||||
|
||||
/* Stage 8: Color Transformation, Blending, and Antialiasing */
|
||||
sh_Color = col * scaleFactorBias[0] + scaleFactorBias[1] ;
|
||||
|
||||
/* Extended Stage: User defined shader that affects gl_FragColor */
|
||||
shMain();
|
||||
}
|
||||
)glsl";
|
||||
|
||||
static const char* vgShaderFragmentUserDefault = R"glsl(
|
||||
void shMain(){ gl_FragColor = sh_Color; };
|
||||
)glsl";
|
||||
|
||||
static const char* vgShaderVertexColorRamp = R"glsl(
|
||||
#version 330
|
||||
|
||||
in vec2 step;
|
||||
in vec4 stepColor;
|
||||
out vec4 interpolateColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(step.xy, 0, 1);
|
||||
interpolateColor = stepColor;
|
||||
}
|
||||
)glsl";
|
||||
|
||||
static const char* vgShaderFragmentColorRamp = R"glsl(
|
||||
#version 330
|
||||
|
||||
in vec4 interpolateColor;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = interpolateColor;
|
||||
}
|
||||
)glsl";
|
||||
|
||||
void shInitPiplelineShaders(void) {
|
||||
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
GLint compileStatus;
|
||||
const char* extendedStage;
|
||||
const char* buf[2];
|
||||
GLint size[2];
|
||||
|
||||
context->vs = glCreateShader(GL_VERTEX_SHADER);
|
||||
if(context->userShaderVertex){
|
||||
extendedStage = (const char*)context->userShaderVertex;
|
||||
} else {
|
||||
extendedStage = vgShaderVertexUserDefault;
|
||||
}
|
||||
buf[0] = vgShaderVertexPipeline;
|
||||
buf[1] = extendedStage;
|
||||
size[0] = strlen(vgShaderVertexPipeline);
|
||||
size[1] = strlen(extendedStage);
|
||||
glShaderSource(context->vs, 2, buf, size);
|
||||
glCompileShader(context->vs);
|
||||
glGetShaderiv(context->vs, GL_COMPILE_STATUS, &compileStatus);
|
||||
printf("Shader compile status :%d line:%d\n", compileStatus, __LINE__);
|
||||
GL_CEHCK_ERROR;
|
||||
|
||||
context->fs = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
if(context->userShaderFragment){
|
||||
extendedStage = (const char*)context->userShaderFragment;
|
||||
} else {
|
||||
extendedStage = vgShaderFragmentUserDefault;
|
||||
}
|
||||
buf[0] = vgShaderFragmentPipeline;
|
||||
buf[1] = extendedStage;
|
||||
size[0] = strlen(vgShaderFragmentPipeline);
|
||||
size[1] = strlen(extendedStage);
|
||||
glShaderSource(context->fs, 2, buf, size);
|
||||
glCompileShader(context->fs);
|
||||
glGetShaderiv(context->fs, GL_COMPILE_STATUS, &compileStatus);
|
||||
printf("Shader compile status :%d line:%d\n", compileStatus, __LINE__);
|
||||
GL_CEHCK_ERROR;
|
||||
|
||||
context->progDraw = glCreateProgram();
|
||||
glAttachShader(context->progDraw, context->vs);
|
||||
glAttachShader(context->progDraw, context->fs);
|
||||
glLinkProgram(context->progDraw);
|
||||
GL_CEHCK_ERROR;
|
||||
|
||||
context->locationDraw.pos = glGetAttribLocation(context->progDraw, "pos");
|
||||
context->locationDraw.textureUV = glGetAttribLocation(context->progDraw, "textureUV");
|
||||
context->locationDraw.model = glGetUniformLocation(context->progDraw, "sh_Model");
|
||||
context->locationDraw.projection = glGetUniformLocation(context->progDraw, "sh_Ortho");
|
||||
context->locationDraw.paintInverted = glGetUniformLocation(context->progDraw, "paintInverted");
|
||||
context->locationDraw.drawMode = glGetUniformLocation(context->progDraw, "drawMode");
|
||||
context->locationDraw.imageSampler = glGetUniformLocation(context->progDraw, "imageSampler");
|
||||
context->locationDraw.imageMode = glGetUniformLocation(context->progDraw, "imageMode");
|
||||
context->locationDraw.paintType = glGetUniformLocation(context->progDraw, "paintType");
|
||||
context->locationDraw.rampSampler = glGetUniformLocation(context->progDraw, "rampSampler");
|
||||
context->locationDraw.patternSampler = glGetUniformLocation(context->progDraw, "patternSampler");
|
||||
context->locationDraw.paintParams = glGetUniformLocation(context->progDraw, "paintParams");
|
||||
context->locationDraw.paintColor = glGetUniformLocation(context->progDraw, "paintColor");
|
||||
context->locationDraw.scaleFactorBias= glGetUniformLocation(context->progDraw, "scaleFactorBias");
|
||||
GL_CEHCK_ERROR;
|
||||
|
||||
// TODO: Support color transform to remove this from here
|
||||
glUseProgram(context->progDraw);
|
||||
GLfloat factor_bias[8] = {1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0};
|
||||
glUniform4fv(context->locationDraw.scaleFactorBias, 2, factor_bias);
|
||||
GL_CEHCK_ERROR;
|
||||
|
||||
/* Initialize uniform variables */
|
||||
float mat[16];
|
||||
float volume = fmax(context->surfaceWidth, context->surfaceHeight) / 2;
|
||||
shCalcOrtho2D(mat, 0, context->surfaceWidth , 0, context->surfaceHeight, -volume, volume);
|
||||
glUniformMatrix4fv(context->locationDraw.projection, 1, GL_FALSE, mat);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
void shDeinitPiplelineShaders(void){
|
||||
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
glDeleteShader(context->vs);
|
||||
glDeleteShader(context->fs);
|
||||
glDeleteProgram(context->progDraw);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
void shInitRampShaders(void) {
|
||||
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
GLint compileStatus;
|
||||
|
||||
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vs, 1, &vgShaderVertexColorRamp, NULL);
|
||||
glCompileShader(vs);
|
||||
glGetShaderiv(vs, GL_COMPILE_STATUS, &compileStatus);
|
||||
printf("Shader compile status :%d line:%d\n", compileStatus, __LINE__);
|
||||
GL_CEHCK_ERROR;
|
||||
|
||||
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fs, 1, &vgShaderFragmentColorRamp, NULL);
|
||||
glCompileShader(fs);
|
||||
glGetShaderiv(fs, GL_COMPILE_STATUS, &compileStatus);
|
||||
printf("Shader compile status :%d line:%d\n", compileStatus, __LINE__);
|
||||
GL_CEHCK_ERROR;
|
||||
|
||||
context->progColorRamp = glCreateProgram();
|
||||
glAttachShader(context->progColorRamp, vs);
|
||||
glAttachShader(context->progColorRamp, fs);
|
||||
glLinkProgram(context->progColorRamp);
|
||||
glDeleteShader(vs);
|
||||
glDeleteShader(fs);
|
||||
GL_CEHCK_ERROR;
|
||||
|
||||
context->locationColorRamp.step = glGetAttribLocation(context->progColorRamp, "step");
|
||||
context->locationColorRamp.stepColor = glGetAttribLocation(context->progColorRamp, "stepColor");
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
void shDeinitRampShaders(void){
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
glDeleteProgram(context->progColorRamp);
|
||||
}
|
||||
|
||||
VG_API_CALL void vgShaderSourceSH(VGuint shadertype, const VGbyte* string){
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
|
||||
switch(shadertype) {
|
||||
case VG_FRAGMENT_SHADER_SH:
|
||||
context->userShaderFragment = (const void*)string;
|
||||
break;
|
||||
case VG_VERTEX_SHADER_SH:
|
||||
context->userShaderVertex = (const void*)string;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VG_API_CALL void vgCompileShaderSH(void){
|
||||
shDeinitPiplelineShaders();
|
||||
shInitPiplelineShaders();
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniform1fSH(VGint location, VGfloat v0){
|
||||
glUniform1f(location, v0);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniform2fSH(VGint location, VGfloat v0, VGfloat v1){
|
||||
glUniform2f(location, v0, v1);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniform3fSH(VGint location, VGfloat v0, VGfloat v1, VGfloat v2){
|
||||
glUniform3f(location, v0, v1, v2);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniform4fSH(VGint location, VGfloat v0, VGfloat v1, VGfloat v2, VGfloat v3){
|
||||
glUniform4f(location, v0, v1, v2, v3);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniform1fvSH(VGint location, VGint count, const VGfloat *value){
|
||||
glUniform1fv(location, count, value);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniform2fvSH(VGint location, VGint count, const VGfloat *value){
|
||||
glUniform2fv(location, count, value);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniform3fvSH(VGint location, VGint count, const VGfloat *value){
|
||||
glUniform3fv(location, count, value);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniform4fvSH(VGint location, VGint count, const VGfloat *value){
|
||||
glUniform4fv(location, count, value);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniformMatrix2fvSH(VGint location, VGint count, VGboolean transpose, const VGfloat *value){
|
||||
glUniformMatrix2fv(location, count, transpose, value);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniformMatrix3fvSH(VGint location, VGint count, VGboolean transpose, const VGfloat *value){
|
||||
glUniformMatrix3fv(location, count, transpose, value);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniformMatrix4fvSH(VGint location, VGint count, VGboolean transpose, const VGfloat *value){
|
||||
glUniformMatrix4fv(location, count, transpose, value);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL VGint vgGetUniformLocationSH(const VGbyte *name){
|
||||
VG_GETCONTEXT(-1);
|
||||
VGint retval = glGetUniformLocation(context->progDraw, name);
|
||||
GL_CEHCK_ERROR;
|
||||
return retval;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgGetUniformfvSH(VGint location, VGfloat *params){
|
||||
VG_GETCONTEXT(VG_NO_RETVAL);
|
||||
glGetUniformfv(context->progDraw, location, params);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniform1iSH (VGint location, VGint v0){
|
||||
glUniform1i (location, v0);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniform2iSH (VGint location, VGint v0, VGint v1){
|
||||
glUniform2i (location, v0, v1);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniform3iSH (VGint location, VGint v0, VGint v1, VGint v2){
|
||||
glUniform3i (location, v0, v1, v2);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniform4iSH (VGint location, VGint v0, VGint v1, VGint v2, VGint v3){
|
||||
glUniform4i (location, v0, v1, v2, v3);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniform1ivSH (VGint location, VGint count, const VGint *value){
|
||||
glUniform1iv (location, count, value);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniform2ivSH (VGint location, VGint count, const VGint *value){
|
||||
glUniform2iv (location, count, value);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniform3ivSH (VGint location, VGint count, const VGint *value){
|
||||
glUniform3iv (location, count, value);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
VG_API_CALL void vgUniform4ivSH (VGint location, VGint count, const VGint *value){
|
||||
glUniform4iv (location, count, value);
|
||||
GL_CEHCK_ERROR;
|
||||
}
|
||||
|
||||
|
30
simgear/canvas/ShaderVG/src/shaders.h
Normal file
30
simgear/canvas/ShaderVG/src/shaders.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Takuma Hayashi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library in the file COPYING;
|
||||
* if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SHADERS_H
|
||||
#define __SHADERS_H
|
||||
|
||||
void shInitPiplelineShaders(void);
|
||||
void shDeinitPiplelineShaders(void);
|
||||
|
||||
void shInitRampShaders(void);
|
||||
void shDeinitRampShaders(void);
|
||||
|
||||
#endif /* __SHADERS_H */
|
Loading…
Reference in New Issue
Block a user