Compare commits

..

7 Commits

Author SHA1 Message Date
Frederic Bouvier
fe2fb8e6ae Fix issue #392: mktime takes a localtime as input. Assumption that if HAVE_DAYLIGHT is missing imply that mktime takes a gmt time is wrong (sg_time.cxx, line 482) 2011-08-06 16:28:34 +02:00
Frederic Bouvier
4793166abf Fix a typo 2011-08-06 16:28:21 +02:00
ThorstenB
4494eb061e Improved CMake support for libsvn
Added missing CMake defines for SVN_CLIENT.
Don't detect libsvn without APR.
When installed, enable libsvn support by default (same as for automake).
When enabled, provide libsvn include dir to libtsync.
gitignore temporary CMake files
2011-08-04 22:40:21 +02:00
ThorstenB
8ed9e01c63 Ove Kåven: Fix property refcounting for particles 2011-08-01 19:53:59 +02:00
ThorstenB
55fc86741b #232: resurrect the "point sprites for runway lights" switch
Automatic GL/OSG feature detection still not working, since we don't have
a "context" - but at least the manual switch works (on start-up only).
2011-07-31 14:18:35 +02:00
ThorstenB
9c0cafb82c Fix locale setting for Windows 2011-07-19 22:01:37 +02:00
ThorstenB
ede50bec49 Clean solution for locale problem.
Changing and reverting the locale isn't thread-safe. Instead, setup the
environment to ensure the active locale sticks to default "C" locale at
any time.
2011-07-19 22:01:23 +02:00
729 changed files with 26531 additions and 77318 deletions

20
.gitignore vendored
View File

@@ -1,9 +1,20 @@
.*
*~
Makefile
Makefile.in
.deps
autom4te.cache
config.guess
config.log
config.status
config.sub
configure
depcomp
install-sh
missing
aclocal.m4
INSTALL
SimGear.spec
*.o
lib*.a
.*.swp
cmake_install.cmake
CMakeFiles
CMakeCache.txt
@@ -12,5 +23,4 @@ CPackSourceConfig.cmake
cmake_uninstall.cmake
CTestTestfile.cmake
install_manifest.txt
build*
Build

View File

@@ -1,4 +0,0 @@
if (NOT SYSTEM_EXPAT)
add_subdirectory(expat)
endif()

View File

@@ -1,33 +0,0 @@
configure_file (
"${PROJECT_SOURCE_DIR}/3rdparty/expat/expat_config_cmake.in"
"${PROJECT_BINARY_DIR}/3rdparty/expat/expat_config.h"
)
set(expat_sources
asciitab.h
hashtable.h
iasciitab.h
latin1tab.h
nametab.h
utf8tab.h
xmldef.h
xmlparse.h
xmlrole.h
xmltok.h
xmltok_impl.h
hashtable.c
xmlparse.c
xmlrole.c
xmltok.c
internal.h
ascii.h
sg_expat.h
sg_expat_external.h
)
foreach(s ${expat_sources})
set_property(GLOBAL
APPEND PROPERTY LOCAL_EXPAT_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/${s}")
endforeach()

View File

@@ -1,22 +0,0 @@
Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
and Clark Cooper
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,92 +0,0 @@
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file COPYING for copying permission.
*/
#define ASCII_A 0x41
#define ASCII_B 0x42
#define ASCII_C 0x43
#define ASCII_D 0x44
#define ASCII_E 0x45
#define ASCII_F 0x46
#define ASCII_G 0x47
#define ASCII_H 0x48
#define ASCII_I 0x49
#define ASCII_J 0x4A
#define ASCII_K 0x4B
#define ASCII_L 0x4C
#define ASCII_M 0x4D
#define ASCII_N 0x4E
#define ASCII_O 0x4F
#define ASCII_P 0x50
#define ASCII_Q 0x51
#define ASCII_R 0x52
#define ASCII_S 0x53
#define ASCII_T 0x54
#define ASCII_U 0x55
#define ASCII_V 0x56
#define ASCII_W 0x57
#define ASCII_X 0x58
#define ASCII_Y 0x59
#define ASCII_Z 0x5A
#define ASCII_a 0x61
#define ASCII_b 0x62
#define ASCII_c 0x63
#define ASCII_d 0x64
#define ASCII_e 0x65
#define ASCII_f 0x66
#define ASCII_g 0x67
#define ASCII_h 0x68
#define ASCII_i 0x69
#define ASCII_j 0x6A
#define ASCII_k 0x6B
#define ASCII_l 0x6C
#define ASCII_m 0x6D
#define ASCII_n 0x6E
#define ASCII_o 0x6F
#define ASCII_p 0x70
#define ASCII_q 0x71
#define ASCII_r 0x72
#define ASCII_s 0x73
#define ASCII_t 0x74
#define ASCII_u 0x75
#define ASCII_v 0x76
#define ASCII_w 0x77
#define ASCII_x 0x78
#define ASCII_y 0x79
#define ASCII_z 0x7A
#define ASCII_0 0x30
#define ASCII_1 0x31
#define ASCII_2 0x32
#define ASCII_3 0x33
#define ASCII_4 0x34
#define ASCII_5 0x35
#define ASCII_6 0x36
#define ASCII_7 0x37
#define ASCII_8 0x38
#define ASCII_9 0x39
#define ASCII_TAB 0x09
#define ASCII_SPACE 0x20
#define ASCII_EXCL 0x21
#define ASCII_QUOT 0x22
#define ASCII_AMP 0x26
#define ASCII_APOS 0x27
#define ASCII_MINUS 0x2D
#define ASCII_PERIOD 0x2E
#define ASCII_COLON 0x3A
#define ASCII_SEMI 0x3B
#define ASCII_LT 0x3C
#define ASCII_EQUALS 0x3D
#define ASCII_GT 0x3E
#define ASCII_LSQB 0x5B
#define ASCII_RSQB 0x5D
#define ASCII_UNDERSCORE 0x5F
#define ASCII_LPAREN 0x28
#define ASCII_RPAREN 0x29
#define ASCII_FF 0x0C
#define ASCII_SLASH 0x2F
#define ASCII_HASH 0x23
#define ASCII_PIPE 0x7C
#define ASCII_COMMA 0x2C

View File

@@ -1,41 +0,0 @@
#ifndef EXPAT_CONFIG_H
#define EXPAT_CONFIG_H
#cmakedefine HAVE_WINDOWS_H
#ifdef HAVE_WINDOWS_H
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#endif
/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
#define BYTEORDER 1234
/* Define to 1 if you have the `bcopy' function. */
#cmakedefine HAVE_BCOPY
/* Define to 1 if you have the `memmove' function. */
#define HAVE_MEMMOVE
/* Define to 1 if you have a working `mmap' system call. */
#cmakedefine HAVE_MMAP
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H
/* whether byteorder is bigendian */
#undef WORDS_BIGENDIAN
/* Define to specify how much context to retain around the current parse
point. */
#define XML_CONTEXT_BYTES 1024
/* Define to make parameter entity parsing functionality available. */
#define XML_DTD
/* Define to make XML Namespaces functionality available. */
#define XML_NS
#endif /* ifndef EXPAT_CONFIG_H */

View File

@@ -1,73 +0,0 @@
/* internal.h
Internal definitions used by Expat. This is not needed to compile
client code.
The following calling convention macros are defined for frequently
called functions:
FASTCALL - Used for those internal functions that have a simple
body and a low number of arguments and local variables.
PTRCALL - Used for functions called though function pointers.
PTRFASTCALL - Like PTRCALL, but for low number of arguments.
inline - Used for selected internal functions for which inlining
may improve performance on some platforms.
Note: Use of these macros is based on judgement, not hard rules,
and therefore subject to change.
*/
#if defined(__GNUC__) && defined(__i386__) && !defined(__MINGW32__)
/* We'll use this version by default only where we know it helps.
regparm() generates warnings on Solaris boxes. See SF bug #692878.
Instability reported with egcs on a RedHat Linux 7.3.
Let's comment out:
#define FASTCALL __attribute__((stdcall, regparm(3)))
and let's try this:
*/
#define FASTCALL __attribute__((regparm(3)))
#define PTRFASTCALL __attribute__((regparm(3)))
#endif
/* Using __fastcall seems to have an unexpected negative effect under
MS VC++, especially for function pointers, so we won't use it for
now on that platform. It may be reconsidered for a future release
if it can be made more effective.
Likely reason: __fastcall on Windows is like stdcall, therefore
the compiler cannot perform stack optimizations for call clusters.
*/
/* Make sure all of these are defined if they aren't already. */
#ifndef FASTCALL
#define FASTCALL
#endif
#ifndef PTRCALL
#define PTRCALL
#endif
#ifndef PTRFASTCALL
#define PTRFASTCALL
#endif
#ifndef XML_MIN_SIZE
#if !defined(__cplusplus) && !defined(inline)
#ifdef __GNUC__
#define inline __inline
#endif /* __GNUC__ */
#endif
#endif /* XML_MIN_SIZE */
#ifdef __cplusplus
#define inline inline
#else
#ifndef inline
#define inline
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,115 +0,0 @@
/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
See the file COPYING for copying permission.
*/
#ifndef Expat_External_INCLUDED
#define Expat_External_INCLUDED 1
/* External API definitions */
#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
#define XML_USE_MSC_EXTENSIONS 1
#endif
/* Expat tries very hard to make the API boundary very specifically
defined. There are two macros defined to control this boundary;
each of these can be defined before including this header to
achieve some different behavior, but doing so it not recommended or
tested frequently.
XMLCALL - The calling convention to use for all calls across the
"library boundary." This will default to cdecl, and
try really hard to tell the compiler that's what we
want.
XMLIMPORT - Whatever magic is needed to note that a function is
to be imported from a dynamically loaded library
(.dll, .so, or .sl, depending on your platform).
The XMLCALL macro was added in Expat 1.95.7. The only one which is
expected to be directly useful in client code is XMLCALL.
Note that on at least some Unix versions, the Expat library must be
compiled with the cdecl calling convention as the default since
system headers may assume the cdecl convention.
*/
#ifndef XMLCALL
#if defined(_MSC_VER)
#define XMLCALL __cdecl
#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)
#define XMLCALL __attribute__((cdecl))
#else
/* For any platform which uses this definition and supports more than
one calling convention, we need to extend this definition to
declare the convention used on that platform, if it's possible to
do so.
If this is the case for your platform, please file a bug report
with information on how to identify your platform via the C
pre-processor and how to specify the same calling convention as the
platform's malloc() implementation.
*/
#define XMLCALL
#endif
#endif /* not defined XMLCALL */
#if !defined(XML_STATIC) && !defined(XMLIMPORT)
#ifndef XML_BUILDING_EXPAT
/* using Expat from an application */
#ifdef XML_USE_MSC_EXTENSIONS
#define XMLIMPORT __declspec(dllimport)
#endif
#endif
#endif /* not defined XML_STATIC */
/* If we didn't define it above, define it away: */
#ifndef XMLIMPORT
#define XMLIMPORT
#endif
#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
#ifdef __cplusplus
extern "C" {
#endif
#ifdef XML_UNICODE_WCHAR_T
#define XML_UNICODE
#endif
#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
#ifdef XML_UNICODE_WCHAR_T
typedef wchar_t XML_Char;
typedef wchar_t XML_LChar;
#else
typedef unsigned short XML_Char;
typedef char XML_LChar;
#endif /* XML_UNICODE_WCHAR_T */
#else /* Information is UTF-8 encoded. */
typedef char XML_Char;
typedef char XML_LChar;
#endif /* XML_UNICODE */
#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
typedef __int64 XML_Index;
typedef unsigned __int64 XML_Size;
#else
typedef long long XML_Index;
typedef unsigned long long XML_Size;
#endif
#else
typedef long XML_Index;
typedef unsigned long XML_Size;
#endif /* XML_LARGE_SIZE */
#ifdef __cplusplus
}
#endif
#endif /* not Expat_External_INCLUDED */

File diff suppressed because it is too large Load Diff

1336
3rdparty/expat/xmlrole.c vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,316 +0,0 @@
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file COPYING for copying permission.
*/
#ifndef XmlTok_INCLUDED
#define XmlTok_INCLUDED 1
#ifdef __cplusplus
extern "C" {
#endif
/* The following token may be returned by XmlContentTok */
#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be
start of illegal ]]> sequence */
/* The following tokens may be returned by both XmlPrologTok and
XmlContentTok.
*/
#define XML_TOK_NONE -4 /* The string to be scanned is empty */
#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
might be part of CRLF sequence */
#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
#define XML_TOK_PARTIAL -1 /* only part of a token */
#define XML_TOK_INVALID 0
/* The following tokens are returned by XmlContentTok; some are also
returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok.
*/
#define XML_TOK_START_TAG_WITH_ATTS 1
#define XML_TOK_START_TAG_NO_ATTS 2
#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
#define XML_TOK_END_TAG 5
#define XML_TOK_DATA_CHARS 6
#define XML_TOK_DATA_NEWLINE 7
#define XML_TOK_CDATA_SECT_OPEN 8
#define XML_TOK_ENTITY_REF 9
#define XML_TOK_CHAR_REF 10 /* numeric character reference */
/* The following tokens may be returned by both XmlPrologTok and
XmlContentTok.
*/
#define XML_TOK_PI 11 /* processing instruction */
#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
#define XML_TOK_COMMENT 13
#define XML_TOK_BOM 14 /* Byte order mark */
/* The following tokens are returned only by XmlPrologTok */
#define XML_TOK_PROLOG_S 15
#define XML_TOK_DECL_OPEN 16 /* <!foo */
#define XML_TOK_DECL_CLOSE 17 /* > */
#define XML_TOK_NAME 18
#define XML_TOK_NMTOKEN 19
#define XML_TOK_POUND_NAME 20 /* #name */
#define XML_TOK_OR 21 /* | */
#define XML_TOK_PERCENT 22
#define XML_TOK_OPEN_PAREN 23
#define XML_TOK_CLOSE_PAREN 24
#define XML_TOK_OPEN_BRACKET 25
#define XML_TOK_CLOSE_BRACKET 26
#define XML_TOK_LITERAL 27
#define XML_TOK_PARAM_ENTITY_REF 28
#define XML_TOK_INSTANCE_START 29
/* The following occur only in element type declarations */
#define XML_TOK_NAME_QUESTION 30 /* name? */
#define XML_TOK_NAME_ASTERISK 31 /* name* */
#define XML_TOK_NAME_PLUS 32 /* name+ */
#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
#define XML_TOK_COMMA 38
/* The following token is returned only by XmlAttributeValueTok */
#define XML_TOK_ATTRIBUTE_VALUE_S 39
/* The following token is returned only by XmlCdataSectionTok */
#define XML_TOK_CDATA_SECT_CLOSE 40
/* With namespace processing this is returned by XmlPrologTok for a
name with a colon.
*/
#define XML_TOK_PREFIXED_NAME 41
#ifdef XML_DTD
#define XML_TOK_IGNORE_SECT 42
#endif /* XML_DTD */
#ifdef XML_DTD
#define XML_N_STATES 4
#else /* not XML_DTD */
#define XML_N_STATES 3
#endif /* not XML_DTD */
#define XML_PROLOG_STATE 0
#define XML_CONTENT_STATE 1
#define XML_CDATA_SECTION_STATE 2
#ifdef XML_DTD
#define XML_IGNORE_SECTION_STATE 3
#endif /* XML_DTD */
#define XML_N_LITERAL_TYPES 2
#define XML_ATTRIBUTE_VALUE_LITERAL 0
#define XML_ENTITY_VALUE_LITERAL 1
/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
#define XML_UTF8_ENCODE_MAX 4
/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
#define XML_UTF16_ENCODE_MAX 2
typedef struct position {
/* first line and first column are 0 not 1 */
XML_Size lineNumber;
XML_Size columnNumber;
} POSITION;
typedef struct {
const char *name;
const char *valuePtr;
const char *valueEnd;
char normalized;
} ATTRIBUTE;
struct encoding;
typedef struct encoding ENCODING;
typedef int (PTRCALL *SCANNER)(const ENCODING *,
const char *,
const char *,
const char **);
struct encoding {
SCANNER scanners[XML_N_STATES];
SCANNER literalScanners[XML_N_LITERAL_TYPES];
int (PTRCALL *sameName)(const ENCODING *,
const char *,
const char *);
int (PTRCALL *nameMatchesAscii)(const ENCODING *,
const char *,
const char *,
const char *);
int (PTRFASTCALL *nameLength)(const ENCODING *, const char *);
const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
int (PTRCALL *getAtts)(const ENCODING *enc,
const char *ptr,
int attsMax,
ATTRIBUTE *atts);
int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
int (PTRCALL *predefinedEntityName)(const ENCODING *,
const char *,
const char *);
void (PTRCALL *updatePosition)(const ENCODING *,
const char *ptr,
const char *end,
POSITION *);
int (PTRCALL *isPublicId)(const ENCODING *enc,
const char *ptr,
const char *end,
const char **badPtr);
void (PTRCALL *utf8Convert)(const ENCODING *enc,
const char **fromP,
const char *fromLim,
char **toP,
const char *toLim);
void (PTRCALL *utf16Convert)(const ENCODING *enc,
const char **fromP,
const char *fromLim,
unsigned short **toP,
const unsigned short *toLim);
int minBytesPerChar;
char isUtf8;
char isUtf16;
};
/* Scan the string starting at ptr until the end of the next complete
token, but do not scan past eptr. Return an integer giving the
type of token.
Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
Return XML_TOK_PARTIAL when the string does not contain a complete
token; nextTokPtr will not be set.
Return XML_TOK_INVALID when the string does not start a valid
token; nextTokPtr will be set to point to the character which made
the token invalid.
Otherwise the string starts with a valid token; nextTokPtr will be
set to point to the character following the end of that token.
Each data character counts as a single token, but adjacent data
characters may be returned together. Similarly for characters in
the prolog outside literals, comments and processing instructions.
*/
#define XmlTok(enc, state, ptr, end, nextTokPtr) \
(((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
#define XmlContentTok(enc, ptr, end, nextTokPtr) \
XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
#ifdef XML_DTD
#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
#endif /* XML_DTD */
/* This is used for performing a 2nd-level tokenization on the content
of a literal that has already been returned by XmlTok.
*/
#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
(((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
(((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
#define XmlNameLength(enc, ptr) \
(((enc)->nameLength)(enc, ptr))
#define XmlSkipS(enc, ptr) \
(((enc)->skipS)(enc, ptr))
#define XmlGetAttributes(enc, ptr, attsMax, atts) \
(((enc)->getAtts)(enc, ptr, attsMax, atts))
#define XmlCharRefNumber(enc, ptr) \
(((enc)->charRefNumber)(enc, ptr))
#define XmlPredefinedEntityName(enc, ptr, end) \
(((enc)->predefinedEntityName)(enc, ptr, end))
#define XmlUpdatePosition(enc, ptr, end, pos) \
(((enc)->updatePosition)(enc, ptr, end, pos))
#define XmlIsPublicId(enc, ptr, end, badPtr) \
(((enc)->isPublicId)(enc, ptr, end, badPtr))
#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
(((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
(((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
typedef struct {
ENCODING initEnc;
const ENCODING **encPtr;
} INIT_ENCODING;
int XmlParseXmlDecl(int isGeneralTextEntity,
const ENCODING *enc,
const char *ptr,
const char *end,
const char **badPtr,
const char **versionPtr,
const char **versionEndPtr,
const char **encodingNamePtr,
const ENCODING **namedEncodingPtr,
int *standalonePtr);
int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
const ENCODING *XmlGetUtf8InternalEncoding(void);
const ENCODING *XmlGetUtf16InternalEncoding(void);
int FASTCALL XmlUtf8Encode(int charNumber, char *buf);
int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf);
int XmlSizeOfUnknownEncoding(void);
typedef int (XMLCALL *CONVERTER) (void *userData, const char *p);
ENCODING *
XmlInitUnknownEncoding(void *mem,
int *table,
CONVERTER convert,
void *userData);
int XmlParseXmlDeclNS(int isGeneralTextEntity,
const ENCODING *enc,
const char *ptr,
const char *end,
const char **badPtr,
const char **versionPtr,
const char **versionEndPtr,
const char **encodingNamePtr,
const ENCODING **namedEncodingPtr,
int *standalonePtr);
int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
const ENCODING *XmlGetUtf8InternalEncodingNS(void);
const ENCODING *XmlGetUtf16InternalEncodingNS(void);
ENCODING *
XmlInitUnknownEncodingNS(void *mem,
int *table,
CONVERTER convert,
void *userData);
#ifdef __cplusplus
}
#endif
#endif /* not XmlTok_INCLUDED */

View File

@@ -1,115 +0,0 @@
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file COPYING for copying permission.
*/
/* This file is included! */
#ifdef XML_TOK_NS_C
const ENCODING *
NS(XmlGetUtf8InternalEncoding)(void)
{
return &ns(internal_utf8_encoding).enc;
}
const ENCODING *
NS(XmlGetUtf16InternalEncoding)(void)
{
#if BYTEORDER == 1234
return &ns(internal_little2_encoding).enc;
#elif BYTEORDER == 4321
return &ns(internal_big2_encoding).enc;
#else
const short n = 1;
return (*(const char *)&n
? &ns(internal_little2_encoding).enc
: &ns(internal_big2_encoding).enc);
#endif
}
static const ENCODING * const NS(encodings)[] = {
&ns(latin1_encoding).enc,
&ns(ascii_encoding).enc,
&ns(utf8_encoding).enc,
&ns(big2_encoding).enc,
&ns(big2_encoding).enc,
&ns(little2_encoding).enc,
&ns(utf8_encoding).enc /* NO_ENC */
};
static int PTRCALL
NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr)
{
return initScan(NS(encodings), (const INIT_ENCODING *)enc,
XML_PROLOG_STATE, ptr, end, nextTokPtr);
}
static int PTRCALL
NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr)
{
return initScan(NS(encodings), (const INIT_ENCODING *)enc,
XML_CONTENT_STATE, ptr, end, nextTokPtr);
}
int
NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
const char *name)
{
int i = getEncodingIndex(name);
if (i == UNKNOWN_ENC)
return 0;
SET_INIT_ENC_INDEX(p, i);
p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);
p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);
p->initEnc.updatePosition = initUpdatePosition;
p->encPtr = encPtr;
*encPtr = &(p->initEnc);
return 1;
}
static const ENCODING *
NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
{
#define ENCODING_MAX 128
char buf[ENCODING_MAX];
char *p = buf;
int i;
XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
if (ptr != end)
return 0;
*p = 0;
if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2)
return enc;
i = getEncodingIndex(buf);
if (i == UNKNOWN_ENC)
return 0;
return NS(encodings)[i];
}
int
NS(XmlParseXmlDecl)(int isGeneralTextEntity,
const ENCODING *enc,
const char *ptr,
const char *end,
const char **badPtr,
const char **versionPtr,
const char **versionEndPtr,
const char **encodingName,
const ENCODING **encoding,
int *standalone)
{
return doParseXmlDecl(NS(findEncoding),
isGeneralTextEntity,
enc,
ptr,
end,
badPtr,
versionPtr,
versionEndPtr,
encodingName,
encoding,
standalone);
}
#endif /* XML_TOK_NS_C */

View File

@@ -1,8 +1,8 @@
cmake_minimum_required (VERSION 2.6.4)
cmake_minimum_required (VERSION 2.6)
include (CheckFunctionExists)
include (CheckIncludeFile)
include (CheckCXXSourceCompiles)
include (CheckCXXCompilerFlag)
include (CPack)
project(SimGear)
@@ -10,128 +10,28 @@ project(SimGear)
file(READ version versionFile)
string(STRIP ${versionFile} SIMGEAR_VERSION)
set(FIND_LIBRARY_USE_LIB64_PATHS ON)
# use simgear version also as the SO version (if building SOs)
SET(SIMGEAR_SOVERSION ${SIMGEAR_VERSION})
# Warning when build is not an out-of-source build.
string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" InSourceBuild)
if(InSourceBuild)
message(WARNING "Avoid building inside the source tree!")
message(WARNING "Create a separate build directory instead (i.e. 'sgbuild') and call CMake from there: ")
message(WARNING " mkdir ../sgbuild && cd ../sgbuild && cmake ${CMAKE_SOURCE_DIR}")
endif(InSourceBuild)
#packaging
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING")
SET(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Simulation support libraries for FlightGear and related projects")
SET(CPACK_PACKAGE_VENDOR "The FlightGear project")
SET(CPACK_GENERATOR "TBZ2")
SET(CPACK_INSTALL_CMAKE_PROJECTS ${CMAKE_CURRENT_BINARY_DIR};SimGear;ALL;/)
# split version string into components, note CMAKE_MATCH_0 is the entire regexp match
string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" CPACK_PACKAGE_VERSION ${SIMGEAR_VERSION} )
set(CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1})
set(CPACK_PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2})
set(CPACK_PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3})
message(STATUS "version is ${CPACK_PACKAGE_VERSION_MAJOR} dot ${CPACK_PACKAGE_VERSION_MINOR} dot ${CPACK_PACKAGE_VERSION_PATCH}")
set(CPACK_SOURCE_GENERATOR TBZ2)
set(CPACK_SOURCE_PACKAGE_FILE_NAME "simgear-${SIMGEAR_VERSION}" CACHE INTERNAL "tarball basename")
set(CPACK_SOURCE_IGNORE_FILES
"^${PROJECT_SOURCE_DIR}/.git;\\\\.gitignore;Makefile.am;~$;${CPACK_SOURCE_IGNORE_FILES}")
message(STATUS "ignoring: ${CPACK_SOURCE_IGNORE_FILES}")
include (CPack)
# We have some custom .cmake scripts not in the official distribution.
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules;${CMAKE_MODULE_PATH}")
# Change the default build type to something fast
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
FORCE)
endif(NOT CMAKE_BUILD_TYPE)
option(SIMGEAR_SHARED "Set to ON to build SimGear as a shared library/framework" OFF)
option(SIMGEAR_HEADLESS "Set to ON to build SimGear with GUI/graphics support" OFF)
option(JPEG_FACTORY "Enable JPEG-factory support" OFF)
option(ENABLE_LIBSVN "Set to ON to build SimGear with libsvnclient support" ON)
# Determine name of library installation directory, i.e. "lib" vs "lib64", which
# differs between all Debian-based vs all other Linux distros.
# See cmake bug #11964, http://cmake.org/gitweb?p=cmake.git;a=commit;h=126c993d
# GNUInstallDirs requires CMake >= 2.8.5, use own file for older cmake
if(${CMAKE_VERSION} VERSION_GREATER 2.8.4)
include(GNUInstallDirs)
else(${CMAKE_VERSION} VERSION_GREATER 2.8.4)
include(OldGNUInstallDirs)
endif(${CMAKE_VERSION} VERSION_GREATER 2.8.4)
message(STATUS "Library installation directory: ${CMAKE_INSTALL_LIBDIR}")
#####################################################################################
# Configure library search paths
#####################################################################################
if(NOT "${CMAKE_LIBRARY_ARCHITECTURE}" STREQUAL "")
# Workaround for Ubuntu/Debian which introduced the "multiarch" library
# directory structure, which is unsupported by CMake < 2.8.10, so we need to
# add paths manually
# see http://www.cmake.org/Bug/view.php?id=12049 and
# http://www.cmake.org/Bug/view.php?id=12037
list(APPEND ADDITIONAL_LIBRARY_PATHS
/usr/local/lib/${CMAKE_LIBRARY_ARCHITECTURE}
/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}
/lib/${CMAKE_LIBRARY_ARCHITECTURE})
message(STATUS "additional library directories: ${ADDITIONAL_LIBRARY_PATHS}")
endif()
#####################################################################################
if (NOT MSVC)
option(SIMGEAR_SHARED "Set to ON to build SimGear as a shared library/framework" OFF)
option(SYSTEM_EXPAT "Set to ON to build SimGear using the system libExpat" OFF)
else()
# Building SimGear DLLs is currently not supported for MSVC.
set(SIMGEAR_SHARED OFF)
# Using a system expat is currently not supported for MSVC - it would require shared simgear (DLL).
set(SYSTEM_EXPAT OFF)
endif()
option(SIMGEAR_HEADLESS "Set to ON to build SimGear without GUI/graphics support" OFF)
option(JPEG_FACTORY "Enable JPEG-factory support" OFF)
option(ENABLE_RTI "Set to ON to build SimGear with RTI support" OFF)
option(ENABLE_TESTS "Set to OFF to disable building SimGear's test applications" ON)
option(ENABLE_SOUND "Set to OFF to disable building SimGear's sound support" ON)
option(ENABLE_PKGUTIL "Set to ON to build the sg_pkgutil application (default)" ON)
if (MSVC)
GET_FILENAME_COMPONENT(PARENT_DIR ${PROJECT_BINARY_DIR} PATH)
if (CMAKE_CL_64)
SET(TEST_3RDPARTY_DIR "${PARENT_DIR}/3rdparty.x64")
else (CMAKE_CL_64)
SET(TEST_3RDPARTY_DIR "${PARENT_DIR}/3rdparty")
endif (CMAKE_CL_64)
if (EXISTS ${TEST_3RDPARTY_DIR})
set(MSVC_3RDPARTY_ROOT ${PARENT_DIR} CACHE PATH "Location where the third-party dependencies are extracted")
else (EXISTS ${TEST_3RDPARTY_DIR})
set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
endif (EXISTS ${TEST_3RDPARTY_DIR})
else (MSVC)
set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
endif (MSVC)
set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
if (MSVC AND MSVC_3RDPARTY_ROOT)
message(STATUS "3rdparty files located in ${MSVC_3RDPARTY_ROOT}")
set( OSG_MSVC "msvc" )
if (${MSVC_VERSION} EQUAL 1700)
set( OSG_MSVC ${OSG_MSVC}110 )
elseif (${MSVC_VERSION} EQUAL 1600)
if (${MSVC_VERSION} EQUAL 1600)
set( OSG_MSVC ${OSG_MSVC}100 )
else (${MSVC_VERSION} EQUAL 1700)
else (${MSVC_VERSION} EQUAL 1600)
set( OSG_MSVC ${OSG_MSVC}90 )
endif (${MSVC_VERSION} EQUAL 1700)
endif (${MSVC_VERSION} EQUAL 1600)
if (CMAKE_CL_64)
set( OSG_MSVC ${OSG_MSVC}-64 )
set( MSVC_3RDPARTY_DIR 3rdParty.x64 )
@@ -139,143 +39,65 @@ if (MSVC AND MSVC_3RDPARTY_ROOT)
set( MSVC_3RDPARTY_DIR 3rdParty )
endif (CMAKE_CL_64)
set (CMAKE_LIBRARY_PATH ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenScenegraph/lib ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenRTI/lib )
set (CMAKE_INCLUDE_PATH ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenScenegraph/include ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenRTI/include)
find_path(BOOST_ROOT boost/version.hpp
${MSVC_3RDPARTY_ROOT}/boost
${MSVC_3RDPARTY_ROOT}/boost_1_52_0
${MSVC_3RDPARTY_ROOT}/boost_1_51_0
${MSVC_3RDPARTY_ROOT}/boost_1_50_0
${MSVC_3RDPARTY_ROOT}/boost_1_49_0
${MSVC_3RDPARTY_ROOT}/boost_1_48_0
${MSVC_3RDPARTY_ROOT}/boost_1_47_0
${MSVC_3RDPARTY_ROOT}/boost_1_46_1
${MSVC_3RDPARTY_ROOT}/boost_1_46_0
${MSVC_3RDPARTY_ROOT}/boost_1_45_0
${MSVC_3RDPARTY_ROOT}/boost_1_44_0
)
# set (BOOST_ROOT ${MSVC_3RDPARTY_ROOT}/boost_1_44_0)
message(STATUS "BOOST_ROOT is ${BOOST_ROOT}")
set (CMAKE_LIBRARY_PATH ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenScenegraph/lib )
set (CMAKE_INCLUDE_PATH ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenScenegraph/include)
set (BOOST_ROOT ${MSVC_3RDPARTY_ROOT}/boost_1_44_0)
set (OPENAL_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include)
set (OPENAL_LIBRARY_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib)
set (ALUT_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include)
set (OPENAL_LIBRARY_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib)
endif (MSVC AND MSVC_3RDPARTY_ROOT)
if(APPLE)
find_library(CORE_SERVICES_LIBRARY CoreServices)
endif()
find_package(Boost REQUIRED)
set (BOOST_CXX_FLAGS "-DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DBOOST_BIMAP_DISABLE_SERIALIZATION")
if(SIMGEAR_HEADLESS)
message(STATUS "SimGear mode: HEADLESS")
set(ENABLE_SOUND 0)
else()
message(STATUS "SimGear mode: NORMAL")
find_package(OpenGL REQUIRED)
if (ENABLE_SOUND)
find_package(OpenAL REQUIRED)
message(STATUS "Sound support: ENABLED")
endif(ENABLE_SOUND)
find_package(OpenSceneGraph 3.0.0 REQUIRED osgText osgSim osgDB osgParticle osgGA osgUtil)
endif(SIMGEAR_HEADLESS)
if(JPEG_FACTORY)
message(STATUS "JPEG-factory: ENABLED")
find_package(JPEG REQUIRED)
include_directories(${JPEG_INCLUDE_DIR})
else()
message(STATUS "JPEG-factory: DISABLED")
endif(JPEG_FACTORY)
find_package(ZLIB REQUIRED)
find_package(Threads REQUIRED)
if (SYSTEM_EXPAT)
message(STATUS "Requested to use system Expat library, forcing SIMGEAR_SHARED to true")
set(SIMGEAR_SHARED ON)
find_package(EXPAT REQUIRED)
if (${SIMGEAR_HEADLESS})
message(STATUS "headlesss mode")
set(NO_OPENSCENEGRAPH_INTERFACE 1)
else()
message(STATUS "Using built-in expat code")
# XML_STATIC is important to avoid sg_expat_external.h
# declaring symbols as declspec(import)
add_definitions(-DHAVE_EXPAT_CONFIG_H -DXML_STATIC)
set(EXPAT_INCLUDE_DIRS
${PROJECT_SOURCE_DIR}/3rdparty/expat
${PROJECT_BINARY_DIR}/3rdparty/expat)
endif(SYSTEM_EXPAT)
find_package(OpenGL REQUIRED)
find_package(OpenAL REQUIRED)
find_package(ALUT REQUIRED)
find_package(OpenSceneGraph 2.8.1 REQUIRED osgText osgSim osgDB osgParticle osgUtil)
endif()
include_directories(${EXPAT_INCLUDE_DIRS})
if(JPEG_FACTORY)
message(STATUS "JPEG-factory enabled")
find_package(JPEG REQUIRED)
include_directories(${JPEG_INCLUDE_DIR})
endif()
if(ENABLE_LIBSVN)
find_package(SvnClient)
if(LIBSVN_FOUND)
message(STATUS "libsvn found, enabling in SimGear")
set(HAVE_SVN_CLIENT_H 1)
set(HAVE_LIBSVN_CLIENT_1 1)
else()
message(STATUS "Missing libsvn, unable to enable SVN in SimGear")
endif(LIBSVN_FOUND)
endif(ENABLE_LIBSVN)
check_include_file(inttypes.h HAVE_INTTYPES_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H)
check_include_file(sys/timeb.h HAVE_SYS_TIMEB_H)
check_include_file(unistd.h HAVE_UNISTD_H)
check_include_file(windows.h HAVE_WINDOWS_H)
if(HAVE_INTTYPES_H)
# ShivaVG needs inttypes.h
add_definitions(-DHAVE_INTTYPES_H)
endif()
if(ENABLE_RTI)
# See if we have any rti library variant installed
message(STATUS "RTI: ENABLED")
find_package(RTI)
else()
message(STATUS "RTI: DISABLED")
endif(ENABLE_RTI)
# See if we have any rti library variant installed
find_package(RTI)
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
check_function_exists(ftime HAVE_FTIME)
check_function_exists(timegm HAVE_TIMEGM)
check_function_exists(rint HAVE_RINT)
check_function_exists(mkdtemp HAVE_MKDTEMP)
check_function_exists(bcopy HAVE_BCOPY)
check_function_exists(mmap HAVE_MMAP)
if(HAVE_UNISTD_H)
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH})
check_cxx_source_compiles(
"#include <unistd.h>
#if !defined(_POSIX_TIMERS) || (0 >= _POSIX_TIMERS)
#error clock_gettime is not supported
#endif
int main() { return 0; }
"
HAVE_CLOCK_GETTIME)
endif(HAVE_UNISTD_H)
set(RT_LIBRARY "")
if(HAVE_CLOCK_GETTIME)
check_library_exists(rt clock_gettime "" HAVE_RT)
if(HAVE_RT)
set(RT_LIBRARY rt)
endif(HAVE_RT)
endif(HAVE_CLOCK_GETTIME)
set(DL_LIBRARY "")
check_cxx_source_compiles(
"#include <dlfcn.h>
int main(void) {
return 0;
}
"
HAVE_DLFCN_H)
if(HAVE_DLFCN_H)
check_library_exists(dl dlerror "" HAVE_DL)
set(DL_LIBRARY "dl")
endif()
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "add a postfix, usually 'd' on windows")
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "add a postfix, usually d on windows")
SET(CMAKE_RELEASE_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
SET(CMAKE_RELWITHDEBINFO_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
SET(CMAKE_MINSIZEREL_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
SET(CMAKE_RELWITHDEBINFO_POSTFIX "rd" CACHE STRING "add a postfix, usually empty on windows")
SET(CMAKE_MINSIZEREL_POSTFIX "s" CACHE STRING "add a postfix, usually empty on windows")
# isnan might not be real symbol, so can't check using function_exists
check_cxx_source_compiles(
@@ -283,74 +105,35 @@ check_cxx_source_compiles(
void f() { isnan(0.0);} "
HAVE_ISNAN)
check_cxx_source_compiles(
"#include <cmath>
void f() { std::isnan(0.0);} "
HAVE_STD_ISNAN)
if(CMAKE_COMPILER_IS_GNUCXX)
set(WARNING_FLAGS_CXX "-Wall")
set(WARNING_FLAGS_C "-Wall")
# certain GCC versions don't provide the atomic builds, and hence
# require is to provide them in SGAtomic.cxx
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH})
check_cxx_source_compiles(
"int main() { unsigned mValue; return __sync_add_and_fetch(&mValue, 1); }"
GCC_ATOMIC_BUILTINS_FOUND)
set(WARNING_FLAGS -Wall)
endif(CMAKE_COMPILER_IS_GNUCXX)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(WARNING_FLAGS_CXX "-Wall -Wno-overloaded-virtual")
set(WARNING_FLAGS_C "-Wall")
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# boost goes haywire wrt static asserts
check_cxx_compiler_flag(-Wno-unused-local-typedefs HAS_NOWARN_UNUSED_TYPEDEFS)
if(HAS_NOWARN_UNUSED_TYPEDEFS)
set(WARNING_FLAGS_CXX " ${WARNING_FLAGS_CXX} -Wno-unused-local-typedefs")
endif()
endif()
if(WIN32)
if(MINGW)
add_definitions(-D_WIN32_WINNT=0x501)
endif()
if(MSVC)
# turn off various warnings
# foreach(warning 4244 4251 4267 4275 4290 4786 4305 4996)
# SET(WARNING_FLAGS "${WARNING_FLAGS} /wd${warning}")
# endforeach(warning)
set(MSVC_FLAGS "-DWIN32 -DNOMINMAX -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D__CRT_NONSTDC_NO_WARNINGS /wd4996 /wd4250 -Dstrdup=_strdup")
if (${MSVC_VERSION} GREATER 1599)
set( MSVC_LD_FLAGS "/FORCE:MULTIPLE" )
endif (${MSVC_VERSION} GREATER 1599)
set(MSVC_FLAGS "-DWIN32 -DNOMINMAX -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D__CRT_NONSTDC_NO_WARNINGS")
endif(MSVC)
# assumed on Windows
set(HAVE_GETLOCALTIME 1)
set( WINSOCK_LIBRARY "ws2_32.lib" )
set( RT_LIBRARY "winmm" )
endif(WIN32)
endif(WIN32)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS_C} ${MSVC_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS_CXX} ${MSVC_FLAGS} ${BOOST_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MSVC_LD_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} ${MSVC_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} ${MSVC_FLAGS} ${BOOST_CXX_FLAGS}")
include_directories(${PROJECT_SOURCE_DIR})
include_directories(${PROJECT_SOURCE_DIR}/simgear/canvas/ShivaVG/include)
include_directories(${PROJECT_BINARY_DIR}/simgear)
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIR}
${OPENAL_INCLUDE_DIR}
)
${Boost_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR}
${ALUT_INCLUDE_DIR} ${OPENAL_INCLUDE_DIR} )
add_definitions(-DHAVE_CONFIG_H)
@@ -360,34 +143,8 @@ configure_file (
"${PROJECT_SOURCE_DIR}/simgear/simgear_config_cmake.h.in"
"${PROJECT_BINARY_DIR}/simgear/simgear_config.h"
)
if(ENABLE_TESTS)
# enable CTest / make test target
message(STATUS "Tests: ENABLED")
include (Dart)
enable_testing()
else()
message(STATUS "Tests: DISABLED")
endif(ENABLE_TESTS)
# always set TEST_LIBS as it is also used by other tools/applications
set(TEST_LIBS_INTERNAL_CORE
${CMAKE_THREAD_LIBS_INIT}
${ZLIB_LIBRARY}
${WINSOCK_LIBRARY}
${RT_LIBRARY}
${DL_LIBRARY}
${CORE_SERVICES_LIBRARY})
set(TEST_LIBS SimGearCore ${TEST_LIBS_INTERNAL_CORE})
if(NOT SIMGEAR_HEADLESS)
set(TEST_LIBS SimGearScene ${OPENGL_LIBRARIES} ${TEST_LIBS})
endif()
install (FILES ${PROJECT_BINARY_DIR}/simgear/simgear_config.h DESTINATION include/simgear/)
add_subdirectory(3rdparty)
add_subdirectory(simgear)
#-----------------------------------------------------------------------------
@@ -399,5 +156,5 @@ CONFIGURE_FILE(
IMMEDIATE @ONLY)
ADD_CUSTOM_TARGET(uninstall
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")

View File

@@ -0,0 +1,67 @@
# Locate ALUT
# This module defines
# ALUT_LIBRARY
# ALUT_FOUND, if false, do not try to link to ALUT
# ALUT_INCLUDE_DIR, where to find the headers
#
# $ALUTDIR is an environment variable that would
# correspond to the ./configure --prefix=$ALUTDIR
# used in building ALUT.
#
# Created by James Turner. This was influenced by the FindOpenAL.cmake module.
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distributed this file outside of CMake, substitute the full
# License text for the above reference.)
# Per my request, CMake should search for frameworks first in
# the following order:
# ~/Library/Frameworks/OpenAL.framework/Headers
# /Library/Frameworks/OpenAL.framework/Headers
# /System/Library/Frameworks/OpenAL.framework/Headers
#
# On OS X, this will prefer the Framework version (if found) over others.
# People will have to manually change the cache values of
# OPENAL_LIBRARY to override this selection or set the CMake environment
# CMAKE_INCLUDE_PATH to modify the search paths.
FIND_PATH(ALUT_INCLUDE_DIR alut.h
HINTS
$ENV{ALUTDIR}
PATH_SUFFIXES include/AL include/ALUT include
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/opt
)
FIND_LIBRARY(ALUT_LIBRARY
NAMES ALUT alut
HINTS
$ENV{ALUTDIR}
PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/opt
)
SET(ALUT_FOUND "NO")
IF(ALUT_LIBRARY AND ALUT_INCLUDE_DIR)
SET(ALUT_FOUND "YES")
ENDIF(ALUT_LIBRARY AND ALUT_INCLUDE_DIR)

View File

@@ -0,0 +1,51 @@
# Find Subversion client libraries, and dependencies
# including APR (Apache Portable Runtime)
include (CheckFunctionExists)
include (CheckIncludeFile)
find_program(HAVE_APR_CONFIG apr-1-config)
if(HAVE_APR_CONFIG)
execute_process(COMMAND apr-1-config --cppflags --includes
OUTPUT_VARIABLE APR_CFLAGS
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND apr-1-config --link-ld
OUTPUT_VARIABLE RAW_APR_LIBS
OUTPUT_STRIP_TRAILING_WHITESPACE)
# clean up some vars, or other CMake pieces complain
string(STRIP ${RAW_APR_LIBS} APR_LIBS)
else(HAVE_APR_CONFIG)
message(STATUS "apr-1-config not found, implement manual search for APR")
endif(HAVE_APR_CONFIG)
if(HAVE_APR_CONFIG)
find_path(LIBSVN_INCLUDE_DIR svn_client.h
HINTS
$ENV{LIBSVN_DIR}
PATH_SUFFIXES include/subversion-1
PATHS
/usr/local
/usr
/opt
)
check_library_exists(svn_client-1 svn_client_checkout "" HAVE_LIB_SVNCLIENT)
check_library_exists(svn_subr-1 svn_cmdline_init "" HAVE_LIB_SVNSUBR)
check_library_exists(svn_ra-1 svn_ra_initialize "" HAVE_LIB_SVNRA)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG
HAVE_LIB_SVNSUBR
HAVE_LIB_SVNCLIENT
HAVE_LIB_SVNRA
LIBSVN_INCLUDE_DIR)
if(LIBSVN_FOUND)
set(LIBSVN_LIBRARIES "svn_client-1" "svn_subr-1" "svn_ra-1" ${APR_LIBS})
endif(LIBSVN_FOUND)
endif(HAVE_APR_CONFIG)

View File

@@ -1,182 +0,0 @@
# - Define GNU standard installation directories
# Provides install directory variables as defined for GNU software:
# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
# Inclusion of this module defines the following variables:
# CMAKE_INSTALL_<dir> - destination for files of a given type
# CMAKE_INSTALL_FULL_<dir> - corresponding absolute path
# where <dir> is one of:
# BINDIR - user executables (bin)
# SBINDIR - system admin executables (sbin)
# LIBEXECDIR - program executables (libexec)
# SYSCONFDIR - read-only single-machine data (etc)
# SHAREDSTATEDIR - modifiable architecture-independent data (com)
# LOCALSTATEDIR - modifiable single-machine data (var)
# LIBDIR - object code libraries (lib or lib64)
# INCLUDEDIR - C header files (include)
# OLDINCLUDEDIR - C header files for non-gcc (/usr/include)
# DATAROOTDIR - read-only architecture-independent data root (share)
# DATADIR - read-only architecture-independent data (DATAROOTDIR)
# INFODIR - info documentation (DATAROOTDIR/info)
# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale)
# MANDIR - man documentation (DATAROOTDIR/man)
# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME)
# Each CMAKE_INSTALL_<dir> value may be passed to the DESTINATION options of
# install() commands for the corresponding file type. If the includer does
# not define a value the above-shown default will be used and the value will
# appear in the cache for editing by the user.
# Each CMAKE_INSTALL_FULL_<dir> value contains an absolute path constructed
# from the corresponding destination by prepending (if necessary) the value
# of CMAKE_INSTALL_PREFIX.
#=============================================================================
# Copyright 2011 Nikita Krupen'ko <krnekit@gmail.com>
# Copyright 2011 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
# Installation directories
#
if(NOT DEFINED CMAKE_INSTALL_BINDIR)
set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)")
endif()
if(NOT DEFINED CMAKE_INSTALL_SBINDIR)
set(CMAKE_INSTALL_SBINDIR "sbin" CACHE PATH "system admin executables (sbin)")
endif()
if(NOT DEFINED CMAKE_INSTALL_LIBEXECDIR)
set(CMAKE_INSTALL_LIBEXECDIR "libexec" CACHE PATH "program executables (libexec)")
endif()
if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR)
set(CMAKE_INSTALL_SYSCONFDIR "etc" CACHE PATH "read-only single-machine data (etc)")
endif()
if(NOT DEFINED CMAKE_INSTALL_SHAREDSTATEDIR)
set(CMAKE_INSTALL_SHAREDSTATEDIR "com" CACHE PATH "modifiable architecture-independent data (com)")
endif()
if(NOT DEFINED CMAKE_INSTALL_LOCALSTATEDIR)
set(CMAKE_INSTALL_LOCALSTATEDIR "var" CACHE PATH "modifiable single-machine data (var)")
endif()
if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
set(_LIBDIR_DEFAULT "lib")
# Override this default 'lib' with 'lib64' iff:
# - we are on Linux system but NOT cross-compiling
# - we are NOT on debian
# - we are on a 64 bits system
# reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf
# Note that the future of multi-arch handling may be even
# more complicated than that: http://wiki.debian.org/Multiarch
if(CMAKE_SYSTEM_NAME MATCHES "Linux"
AND NOT CMAKE_CROSSCOMPILING
AND NOT EXISTS "/etc/debian_version")
if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
message(AUTHOR_WARNING
"Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
"Please enable at least one language before including GNUInstallDirs.")
else()
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(_LIBDIR_DEFAULT "lib64")
endif()
endif()
endif()
set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
endif()
if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)")
endif()
if(NOT DEFINED CMAKE_INSTALL_OLDINCLUDEDIR)
set(CMAKE_INSTALL_OLDINCLUDEDIR "/usr/include" CACHE PATH "C header files for non-gcc (/usr/include)")
endif()
if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR)
set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)")
endif()
#-----------------------------------------------------------------------------
# Values whose defaults are relative to DATAROOTDIR. Store empty values in
# the cache and store the defaults in local variables if the cache values are
# not set explicitly. This auto-updates the defaults as DATAROOTDIR changes.
if(NOT CMAKE_INSTALL_DATADIR)
set(CMAKE_INSTALL_DATADIR "" CACHE PATH "read-only architecture-independent data (DATAROOTDIR)")
set(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}")
endif()
if(NOT CMAKE_INSTALL_INFODIR)
set(CMAKE_INSTALL_INFODIR "" CACHE PATH "info documentation (DATAROOTDIR/info)")
set(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info")
endif()
if(NOT CMAKE_INSTALL_LOCALEDIR)
set(CMAKE_INSTALL_LOCALEDIR "" CACHE PATH "locale-dependent data (DATAROOTDIR/locale)")
set(CMAKE_INSTALL_LOCALEDIR "${CMAKE_INSTALL_DATAROOTDIR}/locale")
endif()
if(NOT CMAKE_INSTALL_MANDIR)
set(CMAKE_INSTALL_MANDIR "" CACHE PATH "man documentation (DATAROOTDIR/man)")
set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man")
endif()
if(NOT CMAKE_INSTALL_DOCDIR)
set(CMAKE_INSTALL_DOCDIR "" CACHE PATH "documentation root (DATAROOTDIR/doc/PROJECT_NAME)")
set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}")
endif()
#-----------------------------------------------------------------------------
mark_as_advanced(
CMAKE_INSTALL_BINDIR
CMAKE_INSTALL_SBINDIR
CMAKE_INSTALL_LIBEXECDIR
CMAKE_INSTALL_SYSCONFDIR
CMAKE_INSTALL_SHAREDSTATEDIR
CMAKE_INSTALL_LOCALSTATEDIR
CMAKE_INSTALL_LIBDIR
CMAKE_INSTALL_INCLUDEDIR
CMAKE_INSTALL_OLDINCLUDEDIR
CMAKE_INSTALL_DATAROOTDIR
CMAKE_INSTALL_DATADIR
CMAKE_INSTALL_INFODIR
CMAKE_INSTALL_LOCALEDIR
CMAKE_INSTALL_MANDIR
CMAKE_INSTALL_DOCDIR
)
# Result directories
#
foreach(dir
BINDIR
SBINDIR
LIBEXECDIR
SYSCONFDIR
SHAREDSTATEDIR
LOCALSTATEDIR
LIBDIR
INCLUDEDIR
OLDINCLUDEDIR
DATAROOTDIR
DATADIR
INFODIR
LOCALEDIR
MANDIR
DOCDIR
)
if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}})
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
else()
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}")
endif()
endforeach()

View File

@@ -1,29 +1,23 @@
macro(simgear_component_common name includePath sourcesList sources headers)
set(fc${sourcesList} ${name})
set(fh${sourcesList} ${name})
foreach(s ${sources})
set_property(GLOBAL
APPEND PROPERTY ${sourcesList} "${CMAKE_CURRENT_SOURCE_DIR}/${s}")
set(fc${sourcesList} "${fc${sourcesList}}#${CMAKE_CURRENT_SOURCE_DIR}/${s}")
endforeach()
macro(simgear_component name includePath sources headers)
foreach(h ${headers})
set_property(GLOBAL
APPEND PROPERTY PUBLIC_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${h}")
set(fh${sourcesList} "${fh${sourcesList}}#${CMAKE_CURRENT_SOURCE_DIR}/${h}")
endforeach()
if (SIMGEAR_SHARED)
foreach(s ${sources})
set_property(GLOBAL
APPEND PROPERTY ALL_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${s}")
endforeach()
set_property(GLOBAL APPEND PROPERTY FG_GROUPS_${sourcesList}_C "${fc${sourcesList}}@")
set_property(GLOBAL APPEND PROPERTY FG_GROUPS_${sourcesList}_H "${fh${sourcesList}}@")
foreach(h ${headers})
set_property(GLOBAL
APPEND PROPERTY PUBLIC_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${h}")
endforeach()
else()
set(libName "sg${name}")
add_library(${libName} STATIC ${sources} )
install (TARGETS ${libName} ARCHIVE DESTINATION lib${LIB_SUFFIX})
install (FILES ${headers} DESTINATION include/simgear/${includePath})
endif()
install (FILES ${headers} DESTINATION include/simgear/${includePath})
endmacro()
function(simgear_component name includePath sources headers)
simgear_component_common(${name} ${includePath} CORE_SOURCES "${sources}" "${headers}")
endfunction()
function(simgear_scene_component name includePath sources headers)
simgear_component_common(${name} ${includePath} SCENE_SOURCES "${sources}" "${headers}")
endfunction()

View File

@@ -2,7 +2,7 @@
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -464,7 +464,7 @@ convey the exclusion of warranty; and each file should have at least the
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.

View File

@@ -22,7 +22,7 @@ PROJECT_NAME = SimGear
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = 2.11.0
PROJECT_NUMBER = 2.2.0
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
@@ -56,7 +56,7 @@ EXTRACT_PRIVATE = NO
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = YES
EXTRACT_STATIC = NO
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
# undocumented members of documented classes, files or namespaces.

56
INSTALL
View File

@@ -1,56 +0,0 @@
How to build SimGear
====================
SimGear uses the CMake build system to generate a platform-specific
build environment. CMake reads the CMakeLists.txt files that you'll
find throughout the source directories, checks for installed
dependencies and then generates the appropriate build system.
If you don't already have CMake installed on your system you can grab
it from http://www.cmake.org, use version 2.6.4 or later.
Under unices (i.e. Linux, Solaris, Free-BSD, HP-Ux, OSX) use the cmake
or ccmake command-line utils. Preferably, create an out-of-source
build directory and run cmake or ccmake from there. The advantage to
this approach is that the temporary files created by CMake won't
clutter the source directory, and also makes it possible to have
multiple independent build targets by creating multiple build
directories. In a directory alongside the SimGear source directory
use:
mkdir sgbuild
cd sgbuild
cmake ../simgear -DCMAKE_BUILD_TYPE=Release
make
sudo make install
Build Dependencies
==================
SimGear depends on a number of 3rd party libraries, the most notable
being:
* OpenSceneGraph (OSG) - see README.OSG
* zlib compression library - see README.zlib
* Open Audio Library (OpenAL) - see README.OpenAL
* Subversion Client Library (optional dependency)
Further information
===================
* README.cmake
for more detailed CMake instructions
* README.msvc
in the FlightGear source package for more Windows-specific instructions
* FlightGear Wiki
http://wiki.flightgear.org/Building_Flightgear
* FlightGear Forums
For help on building see: http://www.flightgear.org/forums
=> Support/Compiling
* FlightGear Mailing lists
http://wiki.flightgear.org/index.php/Mailing_list

18
Makefile.am Normal file
View File

@@ -0,0 +1,18 @@
EXTRA_DIST = \
acinclude.m4 \
autogen.sh \
DoxygenMain.cxx \
README.zlib \
README.plib \
README.OpenAL \
README.OSG \
projects
SUBDIRS = simgear
#
# Rule to build RPM distribution package
#
rpm: dist
rpm -ta $(PACKAGE)-$(VERSION).tar.gz

16
README
View File

@@ -1,15 +1 @@
SimGear - Simulator Construction Tools
======================================
http://www.flightgear.org
SimGear is a set of open-source libraries designed to be used as building
blocks for quickly assembling 3d simulations, games, and visualization
applications.
SimGear is developed by the FlightGear project and also provides the base
for the FlightGear Flight Simulator.
Source code for SimGear is released under the GNU Library General Public
License (LGPL) - see COPYING for license details.
See INSTALL file for help on building SimGear.
[ Nothing here at this time. ]

View File

@@ -1,9 +1,10 @@
[This file is mirrored in both the FlightGear and SimGear packages.]
You *must* have OpenSceneGraph (OSG) installed to build this version of
You *must* have OpenSceneGraph (OSG) installed to build this version of
FlightGear.
Notice that this version of SimGear/FlightGear requires at least OSG 3.0.0.
Notice that FlightGear 1.9.0 requires at least version 2.7.8. Using earlier
versions of OSG will yield serious rendering bugs.
You can get the latest version of OSG from:
@@ -21,6 +22,6 @@ ccmake .
[ While running ccmake: press 'c' to configure, press 'c' once more, and
then press 'g' to generate and exit ]
make
make
sudo make install

View File

@@ -18,3 +18,12 @@ ccmake .
then press 'g' to generate and exit ]
The alut library is also required, but comes separately in the package
freelut-1.1.0.tar.gz. This package can be downloaded from the same page
(http://connect.creativelabs.com/openal/default.aspx). Download and run:
tar xzvf freelut-1.1.0.tar.gz
cd freealut-1.1.0
./configure
make
sudo make install

View File

@@ -1,161 +0,0 @@
Getting started with CMake
==========================
(These instructions apply to Unix-like systems, including Cygwin and Mac. To
build using Visual Studio or some other IDE supported by CMake, most of the
information below still applies. Otherwise see
http://wiki.flightgear.org/Building_Flightgear for Windows specific build
instructions.)
Always compile in a separate directory to the code. For example, if the
code (eg, from Git) is at /home/curt/projects/simgear, you might create
/home/curt/projects/sgbuild. Change into the new directory, and run
cmake ../simgear
To generate standard Unix Makefiles in sgbuild.
Probably you want to specify an install prefix:
cmake ../simgear -DCMAKE_INSTALL_PREFIX=/usr
Note the install prefix is automatically searched for required libraries
and header files, so if you install OpenSceneGraph to the same prefix,
most configuration options are unnecessary.
If for some reason you have a dependency (or several) at a different prefix,
you can specify one or more via CMAKE_PREFIX_PATH:
cmake ../simgear -DCMAKE_PREFIX_PATH="/opt/local;/opt/fgfs"
(note the use of semi-colons to specify multiple prefix paths)
Standard prefixes are searched automatically (/usr, /usr/local, /opt/local)
Most dependencies also expose an environment variable to specify their
installation directory explicitly eg OSG_DIR. Any of the methods
described above will work, but specifying an INSTALL_PREFIX or PREFIX_PATH is
usually simpler.
By default, we select a release build. To create a debug build, use
cmake ../simgear -DCMAKE_BUILD_TYPE=Debug
(or MinSizeRel, or RelWithDbg)
Debug builds will automatically use corresponding debug builds of required
libraries, if they are available. For example you can install debug builds of
OpenSceneGraph, and a debug SimGear build will use them.
(Debug builds of libraries have the 'd' suffix by default - Release builds
have no additional suffix)
Note most IDE projects (eg Xcode and Visual Studio) support building all the
build types from the same project, so you can omit the CMAKE_BUILD_TYPE option
when running cmake, and simply pick the build configuration as normal in the
IDE.
It's common to have several build directories with different build
configurations, eg
/home/curt/projects/simgear (the git clone)
/home/curt/projects/sgdebug
/home/curt/projects/sgrelease
/home/curt/projects/sg-with-svn-osg
To set an optional feature, do
cmake ../simgear -DFEATURE_NAME=ON
(or 'OFF' to disable )
To see the variables that can be configured / are currently defined, you can
run one of the GUI front ends, or the following command:
cmake ../simgear -L
Add 'A' to see all the options (including advanced options), or 'H' to see
the help for each option (similar to running configure --help under autoconf):
cmake ../simgear -LH
Build Targets
=============
For a Unix makefile build, 'make dist', 'make uninstall' and 'make test' are
all available and should work as expected. 'make clean' is also as normal,
but there is *no* 'make distclean' target. The equivalent is to completely
remove your build directory, and start with a fresh one.
Adding new files to the build
Add source files to the SOURCES list, and headers to the HEADERS list. Note
technically you only need to add source files, but omitting headers confuses
project generation and distribution / packaging targets.
For target conditional files, you can append to the SOURCES or HEADERS lists
inside an if() test, for example:
if(APPLE)
list(APPEND SOURCES extraFile1.cxx extraFile2.cxx)
endif()
Setting include directories
In any CMakeList.txt, you can do the following:
include_directories(${PROJECT_SOURCE_DIR}/some/path)
For example, this can be done in particular subdirectory, or at the project
root, or an intermediate level.
Setting target specific compile flags, includes or defines
Use set_target_property(), for example
set_target_property(fgfs PROPERTIES
COMPILE_DEFINITIONS FOO BAR=1)
You can set a property on an individual source file:
set_property(SOURCE myfile.cxx PROPERTY COMPILE_FLAGS "-Wno-unsigned-compare")
Detecting Features / Libraries
For most standard libraries (Gtk, wxWidget, Python, GDAL, Qt, libXml, Boost),
cmake provides a standard helper. To see the available modules, run:
cmake --help-module-list
In the root CMakeLists file, use a statement like:
find_package(OpenGL REQUIRED)
Each package helper sets various variables such aaa_FOUND, aaa_INCLUDE_DIR,
and aaa_LIBRARY. Depending on the complexity of the package, these variables
might have different names (eg, OPENSCENEGRAPH_LIBRARIES).
If there's no standard helper for a library you need, find a similar one, copy
it to CMakeModules/FindABC.cmake, and modify the code to fit. Generally this
is pretty straightforward. The built-in modules reside in the Cmake 'share'
directory, eg /usr/share/cmake/modules on Unix systems.
Note libraries support by pkg-config can be handled directly, with no need
to create a custom FindABC helper.
Adding a new executable target
add_executable(myexecutable ${SOURCES} ${HEADERS})
target_link_libraries(myexecutable .... libraries ... )
install(TARGETS myexecutable RUNTIME DESTINATION bin)
(If the executable should not be installed, omit the final line above)
If you add an additional line
add_test(testname ${EXECUTABLE_OUTPUT_PATH}/myexecutable)
Then running 'make test' will run your executable as a unit test. The
executable should return either a success or failure result code.

32
README.plib Normal file
View File

@@ -0,0 +1,32 @@
[This file is mirrored in both the FlightGear and SimGear packages.]
You *must* have plib version 1.8.5 or later installed on your system
to build FlightGear!" Flight Gear is no longer compatible with the
earlier versions of the library.
You can get the latest version of plib from:
http://plib.sourceforge.net
Build notes:
You should be able to just run "./configure" to configure the package
and use all of plib's defaults. Then run "make" followed by "make
install". By default, plib installs itself into /usr so if you don't
like this, be sure to specify an alternate prefix such as --prefix=/usr/local
As of this writing (2007-11-18), many linux distributions are shipped with a
working version of plib, so chances are that this library is already
installed. It should be noted, that currently plib version no longer compiles
using recent versions of gcc (confirmed on version gcc 4.1.2, as shipped with
SuSe 10.2). As a workaround, it is possible to either use plib SVN. Run the
following commands:
svn co https://plib.svn.sourceforge.net/svnroot/plib/trunk plib
cd plib
./autogen.sh
./configure
make
make install

1
TODO Normal file
View File

@@ -0,0 +1 @@
03/25/2001 - Resolve location of Sky dome implimentation documentation.

706
acinclude.m4 Normal file
View File

@@ -0,0 +1,706 @@
dnl
dnl originally from ncftp 2.3.0
dnl added wi_EXTRA_PDIR and wi_ANSI_C
dnl $Id$
dnl
AC_DEFUN([wi_EXTRA_IDIR], [
incdir="$1"
if test -r $incdir ; then
already=""
for CPPflag in $CPPFLAGS ; do
if test "_$CPPflag" = "_-I${incdir}" ; then
already=yes
break
fi
done
if test -n "$already" ; then
echo " + already had -I$incdir" 1>&AS_MESSAGE_LOG_FD
else
if test "$CPPFLAGS" = "" ; then
CPPFLAGS="-I$incdir"
else
CPPFLAGS="$CPPFLAGS -I$incdir"
fi
echo " + added -I$incdir" 1>&AS_MESSAGE_LOG_FD
fi
else
echo " + IDIR is not accessible: '$myincdir'" 1>&AS_MESSAGE_LOG_FD
fi
])
dnl
dnl
dnl
dnl
AC_DEFUN([wi_EXTRA_LDIR], [
mylibdir="$1"
if test -r $mylibdir ; then
already=""
for LDflag in $LDFLAGS ; do
if test "_$LDflag" = "_-L${mylibdir}" ; then
already=yes
break
fi
done
if test -n "$already" ; then
echo " + already had -L$mylibdir" 1>&AS_MESSAGE_LOG_FD
else
if test "$LDFLAGS" = "" ; then
LDFLAGS="-L$mylibdir"
else
LDFLAGS="$LDFLAGS -L$mylibdir"
fi
echo " + added -L$mylibdir" 1>&AS_MESSAGE_LOG_FD
fi
else
echo " + LDIR is not accessible: '$mylibdir'" 1>&AS_MESSAGE_LOG_FD
fi
])
dnl
dnl __FP__
dnl
dnl
AC_DEFUN([wi_EXTRA_PDIR], [
progdir="$1"
if test -r $progdir ; then
case ":$PATH:" in
*:${progdir}:*)
echo " + already had $progdir in \$PATH" 1>&AS_MESSAGE_LOG_FD
;;
*)
if test "$PATH" = "" ; then
PATH="$progdir"
else
PATH="$PATH:$progdir"
fi
echo " + appended $progdir to \$PATH" 1>&AS_MESSAGE_LOG_FD
;;
esac
else
echo " + PDIR is not accessible: '$progdir'" 1>&AS_MESSAGE_LOG_FD
fi
])
dnl
dnl
dnl If you want to also look for include and lib subdirectories in the
dnl $HOME tree, you supply "yes" as the first argument to this macro.
dnl
dnl If you want to look for subdirectories in include/lib directories,
dnl you pass the names in argument 3, otherwise pass a dash.
dnl
AC_DEFUN([wi_EXTRA_DIRS], [echo "checking for extra include and lib directories..." 1>&6
ifelse([$1], yes, [dnl
b1=`cd .. ; pwd`
b2=`cd ../.. ; pwd`
exdirs="$HOME $j $b1 $b2 $prefix $2"
],[dnl
exdirs="$prefix $2"
])
subexdirs="$3"
if test "$subexdirs" = "" ; then
subexdirs="-"
fi
for subexdir in $subexdirs ; do
if test "$subexdir" = "-" ; then
subexdir=""
else
subexdir="/$subexdir"
fi
for exdir in $exdirs ; do
if test "$exdir" != "/usr" || test "$subexdir" != ""; then
incdir="${exdir}/include${subexdir}"
wi_EXTRA_IDIR($incdir)
dnl On 64-bit machines, if lib64/ exists and is not identical to lib/
dnl then it should be listed here, listed ahead of lib/.
mylibdir64="${exdir}/lib64${subexdir}"
mylibdir32="${exdir}/lib${subexdir}"
if test "x86_64" = $(uname -m) \
-a ! ${mylibdir64} -ef ${mylibdir32} ; then
wi_EXTRA_LDIR($mylibdir64)
fi
wi_EXTRA_LDIR($mylibdir32)
progdir="${exdir}/bin${subexdir}"
wi_EXTRA_PDIR($progdir)
fi
done
done
])
dnl
dnl
dnl
AC_DEFUN([wi_HPUX_CFLAGS],
[AC_MSG_CHECKING(if HP-UX ansi C compiler flags are needed)
AC_REQUIRE([AC_PROG_CC])
os=`uname -s | tr '[A-Z]' '[a-z]'`
ac_cv_hpux_flags=no
if test "$os" = hp-ux ; then
if test "$ac_cv_prog_gcc" = yes ; then
if test "$CFLAGS" != "" ; then
# Shouldn't be in there.
CFLAGS=`echo "$CFLAGS" | sed 's/-Aa//g'`
fi
else
# If you're not using gcc, then you better have a cc/c89
# that is usable. If you have the barebones compiler, it
# won't work. The good compiler uses -Aa for the ANSI
# compatible stuff.
x=`echo $CFLAGS | grep 'Aa' 2>/dev/null`
if test "$x" = "" ; then
CFLAGS="$CFLAGS -Aa"
fi
ac_cv_hpux_flags=yes
fi
# Also add _HPUX_SOURCE to get the extended namespace.
x=`echo $CFLAGS | grep '_HPUX_SOURCE' 2>/dev/null`
if test "$x" = "" ; then
CFLAGS="$CFLAGS -D_HPUX_SOURCE"
fi
fi
AC_MSG_RESULT($ac_cv_hpux_flags)
])
dnl
dnl
dnl
AC_DEFUN([wi_CFLAGS], [AC_REQUIRE([AC_PROG_CC])
wi_HPUX_CFLAGS
if test "$CFLAGS" = "" ; then
CFLAGS="-O"
elif test "$ac_cv_prog_gcc" = "yes" ; then
case "$CFLAGS" in
*"-g -O"*)
#echo "using -g as default gcc CFLAGS" 1>&6
CFLAGS=`echo $CFLAGS | sed 's/-g\ -O/-O/'`
;;
*"-O -g"*)
# Leave the -g, but remove all -O options.
#echo "using -g as default gcc CFLAGS" 1>&6
CFLAGS=`echo $CFLAGS | sed 's/-O\ -g/-O/'`
;;
esac
fi
])
dnl
dnl
dnl
AC_DEFUN([wi_PROTOTYPES], [
AC_MSG_CHECKING(if the compiler supports function prototypes)
AC_TRY_COMPILE(,[extern void exit(int status);],[wi_cv_prototypes=yes
AC_DEFINE(PROTOTYPES)],wi_cv_prototypes=no)
AC_MSG_RESULT($wi_cv_prototypes)
])
dnl
dnl
dnl
AC_DEFUN([wi_ANSI_C], [
AC_MSG_CHECKING(ANSI-style function definitions)
AC_TRY_COMPILE(,[int blubb(int x) { return 0; }],[wi_cv_ansi_funcs=yes
AC_DEFINE(ANSI_FUNCS)],wi_cv_ansi_funcs=no)
AC_MSG_RESULT($wi_cv_ansi_funcs)
])
dnl
dnl
dnl
AC_DEFUN([wi_HEADER_SYS_SELECT_H], [
# See if <sys/select.h> is includable after <sys/time.h>
if test "$ac_cv_header_sys_time_h" = no ; then
AC_CHECK_HEADERS(sys/time.h sys/select.h)
else
AC_CHECK_HEADERS(sys/select.h)
fi
if test "$ac_cv_header_sys_select_h" = yes ; then
AC_MSG_CHECKING([if <sys/select.h> is compatible with <sys/time.h>])
selecth=yes
if test "$ac_cv_header_sys_time_h" = yes ; then
AC_TRY_COMPILE([#include <sys/time.h>
#include <sys/select.h>],[
fd_set a;
struct timeval tmval;
tmval.tv_sec = 0;],selecth=yes,selecth=no)
if test "$selecth" = yes ; then
AC_DEFINE(CAN_USE_SYS_SELECT_H)
fi
fi
AC_MSG_RESULT($selecth)
fi
])
dnl
dnl
dnl
AC_DEFUN([wi_LIB_RESOLV], [
# See if we could access two well-known sites without help of any special
# libraries, like resolv.
AC_TRY_RUN([
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
main()
{
struct hostent *hp1, *hp2;
int result;
hp1 = gethostbyname("gatekeeper.dec.com");
hp2 = gethostbyname("ftp.ncsa.uiuc.edu");
result = ((hp1 != (struct hostent *) 0) && (hp2 != (struct hostent *) 0));
exit(! result);
}],look_for_resolv=no,look_for_resolv=yes,look_for_resolv=yes)
AC_MSG_CHECKING([if we need to look for -lresolv])
AC_MSG_RESULT($look_for_resolv)
if test "$look_for_resolv" = yes ; then
AC_CHECK_LIB(resolv,main)
else
ac_cv_lib_resolv=no
fi
])
dnl
dnl
dnl
AC_DEFUN([wi_LIB_NSL], [
AC_MSG_CHECKING(if we can use -lnsl)
ac_save_LIBS="$LIBS";
LIBS="$LIBS -lnsl";
AC_CACHE_VAL(r_cv_use_libnsl, [
AC_TRY_RUN(
main() { if (getpwuid(getuid())) exit(0); exit(-1); },
nc_cv_use_libnsl=yes, nc_cv_use_libnsl=no, nc_cv_use_libnsl=no)
])
if test "$nc_cv_use_libnsl" = "no"; then LIBS="$ac_save_LIBS"; fi
AC_MSG_RESULT($nc_cv_use_libnsl)
])dnl
dnl
dnl
dnl
AC_DEFUN([nc_PATH_PROG_ZCAT], [
AC_PATH_PROG(GZCAT,gzcat)
AC_PATH_PROG(ZCAT,zcat)
if test "x$GZCAT" = x ; then
if test "x$ZCAT" != x ; then
# See if zcat is really gzcat. gzcat has a --version option, regular
# zcat does not.
AC_MSG_CHECKING(if zcat is really gzcat in disguise)
if $ZCAT --version 2> /dev/null ; then
AC_DEFINE_UNQUOTED(GZCAT, "$ZCAT")
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
fi
else
AC_DEFINE_UNQUOTED(GZCAT, "$GZCAT")
fi
if test "x$ZCAT" != x ; then
AC_DEFINE_UNQUOTED(ZCAT, "$ZCAT")
fi
])
dnl
dnl
dnl
AC_DEFUN([wi_SYSV_EXTRA_DIRS], [
# Use System V because their curses extensions are required. This must
# be done early so we use the -I and -L in the library checks also.
# This is mostly a Solaris/SunOS hack. Note that doing this will also
# use all of the other System V libraries and headers.
AC_MSG_CHECKING(for alternative System V libraries)
if test -f /usr/5include/curses.h ; then
CPPFLAGS="$CPPFLAGS -I/usr/5include"
LDFLAGS="$LDFLAGS -L/usr/5lib"
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
])
dnl
dnl
dnl
AC_DEFUN([wi_DEFINE_UNAME], [
# Get first 127 chars of all uname information. Some folks have
# way too much stuff there, so grab only the first 127.
unam=`uname -a 2>/dev/null | cut -c1-127`
if test "$unam" != "" ; then
AC_DEFINE_UNQUOTED(UNAME, "$unam")
fi
])
dnl
dnl
dnl
AC_DEFUN([wi_READLINE_WITH_NCURSES], [
# Readline and Ncurses could both define "backspace".
# Warn about this if we have both things in our definitions list.
if test "$ac_cv_lib_readline" = yes && test "$ac_cv_lib_ncurses" = yes ; then
AC_MSG_CHECKING(if readline and ncurses will link together)
j="$LIBS"
LIBS="-lreadline -lncurses"
AC_TRY_LINK(,[
readline("prompt");
endwin();
],k=yes,k=no)
if test "$k" = no ; then
AC_MSG_RESULT(no)
# Remove '-lreadline' from LIBS.
LIBS=`echo $j | sed s/-lreadline//g`
ac_cv_lib_readline=no
AC_WARN([The versions of GNU readline and ncurses you have installed on this system
can't be used together, because they use the same symbol, backspace. If
possible, recompile one of the libraries with -Dbackspace=back_space, then
re-run configure.])
else
AC_MSG_RESULT(yes)
LIBS="$j"
fi
fi
])
dnl
dnl
dnl
dnl AC_EXT_DAYLIGHT
dnl Check for an external variable daylight. Stolen from w3c-libwww.
AC_DEFUN([AC_EXT_DAYLIGHT],
[ AC_MSG_CHECKING(int daylight variable)
AC_TRY_COMPILE([#include <time.h>], [return daylight;],
have_daylight=yes,
have_daylight=no)
AC_MSG_RESULT($have_daylight)
])dnl
dnl AC_EXT_TIMEZONE
dnl Check for an external variable timezone. Stolen from tcl-8.0.
AC_DEFUN([AC_EXT_TIMEZONE],
[
#
# Its important to include time.h in this check, as some systems (like convex)
# have timezone functions, etc.
#
have_timezone=no
AC_MSG_CHECKING([long timezone variable])
AC_TRY_COMPILE([#include <time.h>],
[extern long timezone;
timezone += 1;
exit (0);],
[have_timezone=yes
AC_MSG_RESULT(yes)],
AC_MSG_RESULT(no))
#
# On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
#
if test "$have_timezone" = no; then
AC_MSG_CHECKING([time_t timezone variable])
AC_TRY_COMPILE([#include <time.h>],
[extern time_t timezone;
timezone += 1;
exit (0);],
[have_timezone=yes
AC_MSG_RESULT(yes)],
AC_MSG_RESULT(no))
fi
])dnl
## AC_BZ_SET_COMPILER: Addition by Theodore Papadopoulo
## Patch by Jim McKelvey: change sed -e 's/ /@/g' to sed -e 's/ /@/'
AC_DEFUN([AC_SG_SET_COMPILER],
[cxxwith=`echo $1 | sed -e 's/ /@/'`
case "$cxxwith" in
*:*@*) # Full initialization syntax
CXX=`echo "$cxxwith" | sed -n -e 's/.*:\(.*\)@.*/\1/p'`
CXXFLAGS=`echo "$cxxwith" | sed -n -e 's/.*:.*@\(.*\)/\1/p'`
;;
*:*) # Simple initialization syntax
CXX=`echo "$cxxwith" | sed -n -e 's/.*:\(.*\)/\1/p'`
CXXFLAGS=$3
;;
*) # Default values
CXX=$2
CXXFLAGS=$3
CC="$2 --c"
## CFLAGS=
;;
esac])
pushdef([AC_PROG_INSTALL],
[
dnl our own version, testing for a -p flag
popdef([AC_PROG_INSTALL])
dnl as AC_PROG_INSTALL works as it works we first have
dnl to save if the user didn't specify INSTALL, as the
dnl autoconf one overwrites INSTALL and we have no chance to find
dnl out afterwards
AC_PROG_INSTALL
# OK, user hasn't given any INSTALL, autoconf found one for us
# now we test, if it supports the -p flag
AC_MSG_CHECKING(for -p flag to install)
rm -f confinst.$$.* > /dev/null 2>&1
echo "Testtest" > confinst.$$.orig
ac_res=no
if ${INSTALL} -p confinst.$$.orig confinst.$$.new > /dev/null 2>&1 ; then
if test -f confinst.$$.new ; then
# OK, -p seems to do no harm to install
INSTALL="${INSTALL} -p"
ac_res=yes
fi
fi
rm -f confinst.$$.*
AC_MSG_RESULT($ac_res)
dnl the following tries to resolve some signs and wonders coming up
dnl with different autoconf/automake versions
dnl e.g.:
dnl *automake 1.4 install-strip sets A_M_INSTALL_PROGRAM_FLAGS to -s
dnl and has INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(A_M_INSTALL_PROGRAM_FLAGS)
dnl it header-vars.am, so there the actual INSTALL_PROGRAM gets the -s
dnl *automake 1.4a (and above) use INSTALL_STRIP_FLAG and only has
dnl INSTALL_PROGRAM = @INSTALL_PROGRAM@ there, but changes the
dnl install-@DIR@PROGRAMS targets to explicitly use that flag
dnl *autoconf 2.13 is dumb, and thinks it can use INSTALL_PROGRAM as
dnl INSTALL_SCRIPT, which breaks with automake <= 1.4
dnl *autoconf >2.13 (since 10.Apr 1999) has not that failure
dnl to clean up that mess we:
dnl +set INSTALL_PROGRAM to use INSTALL_STRIP_FLAG
dnl which cleans KDE's program with automake > 1.4;
dnl +set INSTALL_SCRIPT to only use INSTALL, to clean up autoconf's problems
dnl with automake<=1.4
dnl note that dues to this sometimes two '-s' flags are used
INSTALL_PROGRAM='${INSTALL} $(INSTALL_STRIP_FLAG)'
INSTALL_SCRIPT='${INSTALL}'
])dnl
# ===========================================================================
# http://autoconf-archive.cryp.to/ax_boost_base.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_BOOST_BASE([MINIMUM-VERSION])
#
# DESCRIPTION
#
# Test for the Boost C++ libraries of a particular version (or newer)
#
# If no path to the installed boost library is given the macro searchs
# under /usr, /usr/local, /opt and /opt/local and evaluates the
# $BOOST_ROOT environment variable. Further documentation is available at
# <http://randspringer.de/boost/index.html>.
#
# This macro calls:
#
# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS)
#
# And sets:
#
# HAVE_BOOST
#
# LAST MODIFICATION
#
# 2008-04-12
#
# COPYLEFT
#
# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved.
AC_DEFUN([AX_BOOST_BASE],
[
AC_ARG_WITH([boost],
AS_HELP_STRING([--with-boost@<:@=DIR@:>@], [use boost (default is yes) - it is possible to specify the root directory for boost (optional)]),
[
if test "$withval" = "no"; then
want_boost="no"
elif test "$withval" = "yes"; then
want_boost="yes"
ac_boost_path=""
else
want_boost="yes"
ac_boost_path="$withval"
fi
],
[want_boost="yes"])
AC_ARG_WITH([boost-libdir],
AS_HELP_STRING([--with-boost-libdir=LIB_DIR],
[Force given directory for boost libraries. Note that this will overwrite library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]),
[
if test -d $withval
then
ac_boost_lib_path="$withval"
else
AC_MSG_ERROR(--with-boost-libdir expected directory name)
fi
],
[ac_boost_lib_path=""]
)
if test "x$want_boost" = "xyes"; then
boost_lib_version_req=ifelse([$1], ,1.20.0,$1)
boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'`
boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'`
boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
if test "x$boost_lib_version_req_sub_minor" = "x" ; then
boost_lib_version_req_sub_minor="0"
fi
WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req)
succeeded=no
dnl first we check the system location for boost libraries
dnl this location ist chosen if boost libraries are installed with the --layout=system option
dnl or if you install boost with RPM
if test "$ac_boost_path" != ""; then
BOOST_LDFLAGS="-L$ac_boost_path/lib"
BOOST_CPPFLAGS="-I$ac_boost_path/include"
else
for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do
if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib"
BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
break;
fi
done
fi
dnl overwrite ld flags if we have required special directory with
dnl --with-boost-libdir parameter
if test "$ac_boost_lib_path" != ""; then
BOOST_LDFLAGS="-L$ac_boost_lib_path"
fi
CPPFLAGS_SAVED="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
export CPPFLAGS
LDFLAGS_SAVED="$LDFLAGS"
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
export LDFLAGS
AC_LANG_PUSH(C++)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@include <boost/version.hpp>
]], [[
#if BOOST_VERSION >= $WANT_BOOST_VERSION
// Everything is okay
#else
# error Boost version is too old
#endif
]])],[
AC_MSG_RESULT(yes)
succeeded=yes
found_system=yes
],[
])
AC_LANG_POP([C++])
dnl if we found no boost with system layout we search for boost libraries
dnl built and installed without the --layout=system option or for a staged(not installed) version
if test "x$succeeded" != "xyes"; then
_version=0
if test "$ac_boost_path" != ""; then
if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
_version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
V_CHECK=`expr $_version_tmp \> $_version`
if test "$V_CHECK" = "1" ; then
_version=$_version_tmp
fi
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
done
fi
else
for ac_boost_path in /usr /usr/local /opt /opt/local ; do
if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
_version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
V_CHECK=`expr $_version_tmp \> $_version`
if test "$V_CHECK" = "1" ; then
_version=$_version_tmp
best_path=$ac_boost_path
fi
done
fi
done
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
if test "$ac_boost_lib_path" = ""
then
BOOST_LDFLAGS="-L$best_path/lib"
fi
if test "x$BOOST_ROOT" != "x"; then
if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/lib" && test -r "$BOOST_ROOT/stage/lib"; then
version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'`
stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'`
stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'`
V_CHECK=`expr $stage_version_shorten \>\= $_version`
if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then
AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT)
BOOST_CPPFLAGS="-I$BOOST_ROOT"
BOOST_LDFLAGS="-L$BOOST_ROOT/stage/lib"
fi
fi
fi
fi
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
export CPPFLAGS
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
export LDFLAGS
AC_LANG_PUSH(C++)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@include <boost/version.hpp>
]], [[
#if BOOST_VERSION >= $WANT_BOOST_VERSION
// Everything is okay
#else
# error Boost version is too old
#endif
]])],[
AC_MSG_RESULT(yes)
succeeded=yes
found_system=yes
],[
])
AC_LANG_POP([C++])
fi
if test "$succeeded" != "yes" ; then
if test "$_version" = "0" ; then
AC_MSG_ERROR([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]])
else
AC_MSG_ERROR([Your boost libraries seems to old (version $_version).])
fi
else
AC_SUBST(BOOST_CPPFLAGS)
AC_SUBST(BOOST_LDFLAGS)
AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available])
fi
CPPFLAGS="$CPPFLAGS_SAVED"
LDFLAGS="$LDFLAGS_SAVED"
fi
])

38
am2dsp.cfg Normal file
View File

@@ -0,0 +1,38 @@
type = StaticLibrary,Multithreaded,
exclude_dir = threads
include_path = .
include_path = ..
include_path = .\SimGear
include_path = ..\zlib-1.2.3
include_path = "..\OpenAL 1.0 Software Development Kit\include"
define = _USE_MATH_DEFINES
define = _CRT_SECURE_NO_DEPRECATE
define = HAVE_CONFIG_H
# Rule to create simgear_config.h
add_source_file = SOURCE=.\simgear\simgear_config.h.vc5\
\
!IF "$(CFG)" == "SimGear - Win32 Release"\
\
# Begin Custom Build - Creating config.h\
InputPath=.\simgear\simgear_config.h.vc5\
\
".\simgear\simgear_config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\
copy .\simgear\simgear_config.h.vc5 .\simgear\simgear_config.h\
\
# End Custom Build\
\
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"\
\
# Begin Custom Build - Creating config.h\
InputPath=.\simgear\simgear_config.h.vc5\
\
".\simgear\simgear_config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\
copy .\simgear\simgear_config.h.vc5 .\simgear\simgear_config.h\
\
# End Custom Build\
\
!ENDIF\

52
autogen.sh Executable file
View File

@@ -0,0 +1,52 @@
#!/bin/sh
OSTYPE=`uname -s`
MACHINE=`uname -m`
AUTO_MAKE_VERSION=`automake --version | head -1 | awk '{print $4}' | sed -e 's/\.\([0-9]*\).*/\1/'`
if test $AUTO_MAKE_VERSION -lt 15; then
echo ""
echo "You need to upgrade to automake version 1.5 or greater."
echo "Most distributions have packages available to install or you can"
echo "find the source for the most recent version at"
echo "ftp://ftp.gnu.org/gnu/automake"
exit 1
fi
echo "Host info: $OSTYPE $MACHINE"
echo -n " automake: `automake --version | head -1 | awk '{print $4}'`"
echo " ($AUTO_MAKE_VERSION)"
echo ""
echo "Running aclocal"
aclocal
echo "Running autoheader"
autoheader
if [ ! -e simgear/simgear_config.h.in ]; then
echo "ERROR: autoheader didn't create simgear/simgear_config.h.in!"
exit 1
fi
echo "Running automake --add-missing"
automake --add-missing
echo "Running autoconf"
autoconf
if [ ! -e configure ]; then
echo "ERROR: configure was not created!"
exit 1
fi
echo ""
echo "======================================"
if [ -f config.cache ]; then
echo "config.cache exists. Removing the config.cache file will force"
echo "the ./configure script to rerun all it's tests rather than using"
echo "the previously cached values."
echo ""
fi
echo "Now you are ready to run './configure'"
echo "======================================"

670
configure.ac Normal file
View File

@@ -0,0 +1,670 @@
dnl Process this file with autogen.sh to produce a working configure
dnl script.
AC_INIT(SimGear, m4_esyscmd([cat ./version | tr -d '\n']), [http://www.flightgear.org])
dnl Ensure touching the version causes autoconf to re-run
AC_SUBST([CONFIGURE_DEPENDENCIES], ['$(top_srcdir)/version'])
AC_CONFIG_SRCDIR([simgear/bucket/newbucket.cxx])
dnl Require at least automake 2.52
AC_PREREQ(2.52)
dnl Initialize the automake stuff
dnl Specify KAI C++ compiler and flags.
dnl Borrowed with slight modification from blitz distribution.
AC_ARG_WITH(cxx,
[ --with-cxx=COMPILER[:name-flags] set options for COMPILER (KCC)],
[case "$withval" in
KCC*) # KAI C++ http://www.kai.com/
echo "Configuring for KAI C++"
AC_SG_SET_COMPILER($withval,"KCC","--restrict --strict_warnings")
CXX_OPTIMIZE_FLAGS=="+K3 -O3"
CXX_DEBUG_FLAGS="-g +K0"
;;
esac
])
dnl set the $host variable based on local machine/os
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([dist-bzip2])
AC_ARG_ENABLE(headless,
AS_HELP_STRING([--enable-headless],[Enable only packages for headless build]))
AC_MSG_CHECKING([for headless mode])
AC_MSG_RESULT([$enable_headless])
AM_CONDITIONAL(WANT_HEADLESS,[test "x$enable_headless" = "xyes"])
AC_MSG_CHECKING([CXX])
AC_MSG_RESULT([$CXX])
AC_MSG_CHECKING([CC])
AC_MSG_RESULT([$CC])
dnl Checks for programs.
AC_PROG_MAKE_SET
AC_PROG_CC
AC_PROG_CPP
AC_PROG_CXX
AC_PROG_CXXCPP
AC_PROG_RANLIB
AC_PROG_INSTALL
AC_PROG_LN_S
AX_BOOST_BASE([1.37.0])
if test "x$BOOST_CPPFLAGS" != "x-I/usr/include" ; then
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
fi
dnl set the $host variable based on local machine/os
AC_CANONICAL_HOST
dnl Used on the Irix platform
case "${host}" in
*-*-irix*)
if test "x$CXX" = "xCC" -o "x$CXX" = "xccache CC"; then
AR="$CXX -ar"
ARFLAGS="-o"
CXXFLAGS="$CXXFLAGS -I$(top_srcdir)/simgear/compatibility/MIPSpro740"
compatibility_DIR="compatibility"
MIPSpro_DIRS="MIPSpro740"
AC_MSG_CHECKING([for MIPSpro compiler version 7.4 or newer])
AC_TRY_RUN([
int main() {
if ( _COMPILER_VERSION < 740 ) {
return -1;
}
return 0;
}
], AC_MSG_RESULT(yes),
[ AC_MSG_RESULT(no)
CXXFLAGS="$CXXFLAGS -I$(top_srcdir)/simgear/compatibility/MIPSpro721"
MIPSpro_DIRS="$(MIPSpro_DIRS) MIPSpro721"
AC_MSG_WARN([Using our own subset of the STL headers])
], AC_MSG_RESULT(yes))
AC_SUBST(MIPSpro_DIRS)
fi
;;
*)
AR="ar"
ARFLAGS="cru"
compatibility_DIR=
;;
esac
AC_SUBST(AR)
AC_SUBST(ARFLAGS)
AC_SUBST(compatibility_DIR)
# Show all compiler warnings by default
CXXFLAGS="$CXXFLAGS -Wall"
CFLAGS="$CFLAGS -Wall"
if echo $includedir | egrep "simgear$" > /dev/null; then
echo "includedir is" $includedir "libdir is" $libdir
else
includedir="${includedir}/simgear"
echo "includedir changed to" $includedir "libdir is" $libdir
fi
dnl set logging; default value of with_logging=yes
AC_ARG_WITH(logging, [ --with-logging Include logging output (default)])
if test "x$with_logging" = "xno" ; then
AC_DEFINE([FG_NDEBUG], 1, [Define for no logging output])
fi
# Specify if we want to build with Norman's jpeg image server support.
# This requires libjpeg to be installed and available.
# Default to with_jpeg_server=no
JPEGLIB=''
AC_ARG_WITH(jpeg_factory, [ --with-jpeg-factory Include Norman's jpeg image factory support code])
if test "x$with_jpeg_factory" = "xyes" ; then
echo "Building with Norman's jpeg image factory support"
AC_CHECK_LIB(jpeg, jpeg_start_compress)
if test "x$ac_cv_lib_jpeg_jpeg_start_compress" != "xyes" ; then
echo
echo "In order to build the jpeg factory code you need libjpeg installed."
echo "otherwise please configure with the --with-jpeg-sever=no option"
echo
echo "libjpeg is available at :"
echo " ftp://ftp.uu.net in the directory graphics/jpeg"
exit 1
fi
else
echo "Building without Norman's jpeg image server support"
fi
AM_CONDITIONAL(ENABLE_JPEG_SERVER, test "x$with_jpeg_factory" = "xyes")
# specify the osg location
AC_ARG_WITH(osg, [ --with-osg=PREFIX Specify the prefix path to osg])
if test "x$with_osg" != "x" ; then
echo "osg prefix is $with_osg"
EXTRA_DIRS="${EXTRA_DIRS} $with_osg"
fi
AC_ARG_WITH(osg_framework, [ --with-osg-framework=PREFIX Specify the prefix path to OSG.framework ])
if test "x$with_osg_framework" != "x"; then
echo "osg framework prefix is $with_osg_framework"
CPPFLAGS = "$CPPFLAGS -F$with-osg-framework"
export DYLD_FRAMEWORK_PATH="$DYLD_FRAMEWORK_PATH:$with_osg_framework"
fi
dnl specifying ALUT.framework (for user provided ALUT.framework)
AC_ARG_WITH(alut_framework, [ --with-alut-framework=PREFIX Specify the prefix path to ALUT.framework ])
if test "x$with_alut_framework" != "x"; then
echo "ALUT framework prefix is $with_alut_framework"
fi
# specify the rti13 location
AC_ARG_WITH(rti13, [ --with-rti13=PREFIX Specify the prefix path to a HLA13 rti])
if test "x$with_rti13" != "x" ; then
echo "rti13 prefix is $with_rti13"
EXTRA_DIRS="${EXTRA_DIRS} $with_rti13"
fi
# specify the rti13 location
AC_ARG_WITH(rti1516, [ --with-rti1516=PREFIX Specify the prefix path to a HLA1516 rti])
if test "x$with_rti1516" != "x" ; then
echo "rti1516 prefix is $with_rti1516"
EXTRA_DIRS="${EXTRA_DIRS} $with_rti1516"
fi
dnl Determine an extra directories to add to include/lib search paths
case "${host}" in
*-apple-darwin* | *-*-cygwin* | *-*-mingw32*)
echo no EXTRA_DIRS for $host
;;
*)
if test -d /usr/X11R6 ; then
EXTRA_DIR1="/usr/X11R6"
fi
if test -d /opt/X11R6 ; then
EXTRA_DIR2="/opt/X11R6"
fi
EXTRA_DIRS="${EXTRA_DIRS} $EXTRA_DIR1 $EXTRA_DIR2"
;;
esac
wi_EXTRA_DIRS(no, ${EXTRA_DIRS})
dnl Using AM_CONDITIONAL is a step out of the protected little
dnl automake fold so it is potentially dangerous. But, we are
dnl beginning to run into cases where the standard checks are not
dnl enough. AM_CONDITIONALS are then referenced to conditionally
dnl build a Makefile.in from a Makefile.am which lets us define custom
dnl includes, compile alternative source files, etc.
dnl X11 might be installed on Mac OS X or cygwin/mingwin, we don't want
dnl to use it if it is.
case "${host}" in
*-apple-darwin* | *-*-cygwin* | *-*-mingw32*)
echo no fancy X11 check
;;
*)
AC_PATH_XTRA
;;
esac
dnl Checks for libraries.
dnl Thread related checks
AC_CHECK_HEADER(pthread.h)
AC_SEARCH_LIBS(pthread_exit, [pthread c_r])
if test "x$ac_cv_header_pthread_h" = "xyes"; then
CXXFLAGS="$CXXFLAGS -D_REENTRANT"
CFLAGS="$CFLAGS -D_REENTRANT"
if test "x$ac_cv_search_pthread_exit" = "x-lc_r"; then
CXXFLAGS="-pthread $CXXFLAGS"
CFLAGS="-pthread $CFLAGS"
fi
fi
AM_CONDITIONAL(HAVE_THREADS, test "x$ac_cv_header_pthread_h" = "xyes")
thread_LIBS="$LIBS"
LIBS=""
dnl search for network related libraries
AC_SEARCH_LIBS(inet_addr, xnet)
AC_SEARCH_LIBS(socket, socket)
network_LIBS="$LIBS"
LIBS=""
dnl check for some default libraries
AC_SEARCH_LIBS(cos, m)
AC_SEARCH_LIBS(clock_gettime, rt)
base_LIBS="$LIBS"
dnl check for OpenGL related libraries
case "${host}" in
*-*-cygwin* | *-*-mingw32*)
dnl CygWin under Windoze.
echo Win32 specific hacks...
AC_DEFINE([WIN32], 1, [Define for Win32 platforms])
AC_DEFINE([NOMINMAX], 1, [Define for Win32 platforms])
LIBS="$LIBS -lglu32 -lopengl32"
LIBS="$LIBS -luser32 -lgdi32 -lwinmm"
dnl add -lwsock32 for mingwin
case "${host}" in
*-*-mingw32*)
base_LIBS="$base_LIBS -lws2_32"
;;
esac
echo "Will link apps with $LIBS"
;;
*-apple-darwin*)
dnl Mac OS X
LIBS="$LIBS -framework OpenGL -framework Carbon -lobjc"
;;
*)
dnl X-Windows based machines
AC_SEARCH_LIBS(XCreateWindow, X11)
AC_SEARCH_LIBS(XShmCreateImage, Xext)
AC_SEARCH_LIBS(XGetExtensionVersion, Xi)
AC_SEARCH_LIBS(IceOpenConnection, ICE)
AC_SEARCH_LIBS(SmcOpenConnection, SM)
AC_SEARCH_LIBS(XtMalloc, Xt)
AC_SEARCH_LIBS(XmuLookupStandardColormap, Xmu)
AC_SEARCH_LIBS(glNewList, [ GL GLcore MesaGL ])
if test "x$ac_cv_search_glNewList" = "x-lGLcore"; then
dnl if GLcore found, then also check for GL
AC_SEARCH_LIBS(glXCreateContext, GL)
fi
dnl if using mesa, check for xmesa.h
if test "x$ac_cv_search_glNewList" = "x-lMesaGL"; then
AC_CHECK_HEADER(GL/fxmesa.h)
if test "x$ac_cv_header_GL_fxmesa_h" = "xyes"; then
AC_DEFINE([XMESA], 1, [Define for fxmesa])
AC_DEFINE([FX], 1, [Define for fxmesa])
fi
fi
AC_SEARCH_LIBS(gluLookAt, [ GLU MesaGLU ])
;;
esac
opengl_LIBS="$LIBS"
LIBS="$base_LIBS"
dnl check for OpenAL libraries
OPENAL_OK="no"
ALUT_OK="no"
case "${host}" in
*-*-cygwin* | *-*-mingw32*)
dnl CygWin under Windoze.
INCLUDES="$INCLUDES -I/usr/local/include/"
LIBS="$LIBS -L/usr/local/lib"
AC_SEARCH_LIBS(alGenBuffers, [ openal32 openal 'openal -ldsound -lwinmm' ] )
AC_SEARCH_LIBS(alutInit, [ openal32 ALut alut ] )
LIBS="$LIBS -lwinmm -ldsound -ldxguid -lole32"
openal_LIBS="$LIBS"
OPENAL_OK="$ac_cv_search_alGenBuffers"
ALUT_OK="$ac_cv_search_alutInit"
;;
*-apple-darwin*)
dnl Mac OS X
LIBS="$LIBS -framework IOKit -framework OpenAL -framework ALUT"
openal_LIBS="$LIBS"
if test "x$with_openal_lib" != "x"; then
echo "libopenal is not supported on Mac OS platform."
openal_LIBS=""
fi
AC_CHECK_HEADERS([OpenAL/al.h],[OPENAL_OK="yes"])
# Looking for alut.h
AC_CHECK_HEADERS([ALUT/alut.h],[ALUT_OK="yes"])
dnl Thank you Christian Bauer from SheepSaver
dnl Modified by Tatsuhiro Nishioka for accepting a given framework path
dnl AC_CHECK_FRAMEWORK($1=NAME, $2=INCLUDES, $3=FRAMEWORK_PATH, $4=ACTION_IF_TRUE) ; $3 is optional
AC_DEFUN([AC_CHECK_FRAMEWORK], [
AS_VAR_PUSHDEF([ac_Framework], [ac_cv_framework_$1])dnl
AC_CACHE_CHECK([whether compiler supports framework $1],
ac_Framework, [
saved_LIBS="$LIBS"
FRAMEWORKS="$FRAMEWORKS -framework $1"
if test "$3" = ""; then
FRAMEWORKS="$FRAMEWORKS $ADD2LD"
elif test "`echo $FRAMEWORKS | grep -- -F$3`" = ""; then
FRAMEWORKS="$FRAMEWORKS -F$3"
CXXFLAGS="$CXXFLAGS -F$3"
CPPFLAGS="$CPPFLAGS -F$3"
CCFLAGS="$CCFLAGS -F$3"
dnl This is needed for AC_TRY_LINK when a framework path is specified
export DYLD_FRAMEWORK_PATH="${DYLD_FRAMEWORK_PATH}:$3"
fi
AC_TRY_LINK(
[$2], [],
[AS_VAR_SET(ac_Framework, yes)], [AS_VAR_SET(ac_Framework, no); LIBS="$saved_LIBS"]
)
])
AS_IF([test AS_VAR_GET(ac_Framework) = yes],
[AC_DEFINE(AS_TR_CPP(HAVE_FRAMEWORK_$1), 1, [Define if framework $1 is available.])]
)
AS_IF([test AS_VAR_GET(ac_Framework) = yes], $4)
AS_VAR_POPDEF([ac_Framework])dnl
])
dnl Check for ALUT.framework when --with-alut-framework is specified
if test "x$with_alut_framework" != "x"; then
AC_CHECK_FRAMEWORK(ALUT, [#include <ALUT/alut.h>], $with_alut_framework, [ALUT_OK="yes"])
fi
;;
*)
dnl default unix style machines
save_LIBS=$LIBS
LIBS="$LIBS $thread_LIBS"
AC_SEARCH_LIBS(alGenBuffers, openal)
AC_SEARCH_LIBS(alutInit, [ alut openal ] )
OPENAL_OK="$ac_cv_search_alGenBuffers"
ALUT_OK="$ac_cv_search_alutInit"
openal_LIBS="$LIBS"
LIBS=$save_LIBS
;;
esac
if test "$OPENAL_OK" == "no" -a "x$enable_headless" != "xyes"; then
echo
echo "You *must* have the openal library installed on your system to build"
echo "SimGear!"
echo
echo "Please see README.OpenAL for more details."
echo
echo "configure aborted."
exit
fi
if test "$ALUT_OK" == "no" -a "x$enable_headless" != "xyes"; then
echo
echo "You *must* have the alut library installed on your system to build"
echo "SimGear!"
echo
echo "Please see README.OpenAL for more details."
echo
echo "configure aborted."
exit
fi
LIBS="$base_LIBS"
AC_SUBST(base_LIBS)
AC_SUBST(openal_LIBS)
AC_SUBST(opengl_LIBS)
AC_SUBST(thread_LIBS)
AC_SUBST(network_LIBS)
dnl Check for MS Windows environment
AC_CHECK_HEADER(windows.h)
AM_CONDITIONAL(EXTGL_NEEDED, test "x$ac_cv_header_windows_h" = "xyes")
# The following are C++ items that need to be tested for with the c++
# compiler
CXXCPP="g++ -E"
AC_LANG_PUSH(C++)
# OpenSceneGraph
case "${host}" in
*-apple-darwin*)
if test "x$with_osg_framework" != "x"; then
# AC_CHECK_FRAMEWORK(osgViewer, [#include <osgViewer/Version>], $with_osg_framework)
# AC_CHECK_FRAMEWORK(osgGA, [#include <osgGA/Version>], $with_osg_framework)
# AC_CHECK_FRAMEWORK(osgText, [#include <osgText/Version>], $with_osg_framework)
# AC_CHECK_FRAMEWORK(osgFX, [#include <osgFX/AnisotropicLighting>], $with_osg_framework)
# AC_CHECK_FRAMEWORK(osgUtil, [#include <osgUtil/Version>], $with_osg_framework)
# AC_CHECK_FRAMEWORK(osgDB, [#include <osgDB/Version>], $with_osg_framework)
# AC_CHECK_FRAMEWORK(osgSim, [#include <osgSim/Version>], $with_osg_framework)
# AC_CHECK_FRAMEWORK(osgParticle, [#include <osgParticle/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osg, [#include <osg/Version>], $with_osg_framework)
# osg_FRAMEWORKS="$FRAMEWORKS"
# FRAMEWORKS=""
# AC_SUBST(osg_FRAMEWORKS)
AC_CHECK_FRAMEWORK(OpenThreads, [#include <OpenThreads/Version>], $with_osg_framework)
openthreads_FRAMEWORK="$FRAMEWORKS"
FRAMEWORKS=""
AC_SUBST(openthreads_FRAMEWORK)
else
dnl
dnl This is needed when osg dynamic libs are specified
dnl instead of OSG frameworks on Mac OS X
dnl
AC_CHECK_LIB(OpenThreads,OpenThreadsGetVersion)
fi
;;
*)
if test "x$enable_osgdebug" = "xyes"; then
AC_CHECK_LIB(OpenThreadsd,OpenThreadsGetVersion)
else
AC_CHECK_LIB(OpenThreads,OpenThreadsGetVersion)
fi
;;
esac
AM_CONDITIONAL(HAVE_FRAMEWORK_OSG, test "x$ac_cv_framework_osg" != "x")
AC_CHECK_HEADER(osg/Version)
if test "x$ac_cv_header_osg_Version" != "xyes" -o "x$ac_cv_lib_OpenThreads_OpenThreadsGetVersion" != "xyes"; then
if test "x$ac_cv_framework_osg" != "xyes"; then
echo
echo "You *must* have the OpenThreads library installed on your system"
echo "to build this version of SimGear!"
echo " Maybe you need to specify --with-osg=DIR."
echo " Maybe you need to specify some LDFLAGS to help the linker."
echo
echo " LIBS: '$LIBS'"
echo " LDFLAGS: '$LDFLAGS'"
echo " CPPFLAGS: '$CPPFLAGS'"
echo
echo "Please see README.OSG for more details."
echo
echo "configure aborted."
exit
fi
fi
AC_CHECK_HEADER(boost/version.hpp)
if test "x$ac_cv_header_boost_version_hpp" != "xyes"; then
echo
echo "You *must* have the Boost library installed on your system"
echo "to build this version of SimGear!"
echo
echo " LIBS: '$LIBS'"
echo " LDFLAGS: '$LDFLAGS'"
echo " CPPFLAGS: '$CPPFLAGS'"
echo
echo "configure aborted."
exit
fi
dnl Check for a HLA13 rti.
dnl This is really tricky because of the ancient iostream stuff in RTI13
saved_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -DRTI_USES_STD_FSTREAM"
AC_CHECK_HEADER(RTI.hh)
CPPFLAGS="${saved_CPPFLAGS}"
dnl Up to now only RTI13
AM_CONDITIONAL(ENABLE_HLA, test "x$ac_cv_header_RTI_hh" = "xyes")
AM_CONDITIONAL(ENABLE_HLA13, test "x$ac_cv_header_RTI_hh" = "xyes")
AC_LANG_POP
dnl Check for system installed zlib
AC_CHECK_HEADER(zlib.h)
if test "x$ac_cv_header_zlib_h" != "xyes"; then
echo
echo "zlib library not found."
echo
echo "If your OS does not provide an installable package for zlib"
echo "you will have to compile and install it first yourself. A copy"
echo "of zlib-1.1.4.tar.gz is included with SimGear. You will"
echo "have to untar this source code, and follow its included instructions"
echo "to compile and install on your system."
echo
echo "configure aborted."
echo
fi
dnl Check for Subversion library support
# libsvn support defaults to yes
save_LIBS=$LIBS
save_CPPFLAGS=$CPPFLAGS
AC_ARG_WITH(libsvn, [ --without-libsvn Do not use built-in subversion (libsvn) for simgear [default=no]], [], [with_libsvn=yes])
if test "x$with_libsvn" = "xyes"; then
LIBS="`apr-1-config --link-ld`"
CPPFLAGS="-I/usr/include/subversion-1 `apr-1-config --includes --cppflags`"
AC_CHECK_HEADERS([svn_client.h])
if test "x$ac_cv_header_svn_client_h" = "xyes"; then
echo "Using built-in subversion (libsvn) for scenery downloads."
AC_SEARCH_LIBS(svn_client_checkout, svn_client-1,
[AC_DEFINE([HAVE_LIBSVN_CLIENT_1], [1], [Define to 1 if you have libsvn_client-1])],
[AC_MSG_ERROR(svn_client-1 library not found.)],)
AC_SEARCH_LIBS(svn_cmdline_init, svn_subr-1, , [AC_MSG_ERROR(svn_subr-1 library not found.)],)
AC_SEARCH_LIBS(svn_ra_initialize, svn_ra-1, , [AC_MSG_ERROR(svn_ra-1 library not found.)],)
svn_LIBS=$LIBS
svn_CPPFLAGS=$CPPFLAGS
AC_SUBST(svn_LIBS)
AC_SUBST(svn_CPPFLAGS)
else
echo "Libsvn not found. Will use command line subversion for scenery downloads."
svn_LIBS=""
svn_CPPFLAGS=""
fi
else
echo "Libsvn explicitly disabled. Will use command line subversion for scenery downloads."
svn_LIBS=""
svn_CPPFLAGS=""
fi
LIBS=$save_LIBS
CPPFLAGS=$save_CPPFLAGS
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS( \
fcntl.h getopt.h malloc.h memory.h stdint.h stdlib.h sys/param.h \
sys/stat.h sys/time.h sys/timeb.h unistd.h values.h )
if test "x$ac_cv_header_stdint_h" = "xyes"; then
AC_DEFINE([HAVE_STDINT_H], 1, [Define if stdint.h exists])
fi
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_SIZE_T
AC_TYPE_MODE_T
AC_HEADER_TIME
AC_STRUCT_TM
dnl Checks for library functions.
old_LIBS=$LIBS
LIBS="$base_LIBS $network_LIBS $opengl_LIBS"
AC_TYPE_SIGNAL
AC_FUNC_VPRINTF
AC_CHECK_FUNCS( [ \
ftime gettimeofday timegm memcpy bcopy mktime strstr rand \
random drand48 setitimer getitimer signal GetLocalTime rint getrusage ] )
LIBS=$old_LIBS
AM_CONFIG_HEADER(simgear/simgear_config.h)
AC_CONFIG_FILES([ \
Makefile \
SimGear.spec \
simgear/Makefile \
simgear/version.h \
simgear/compatibility/Makefile \
simgear/compatibility/MIPSpro721/Makefile \
simgear/compatibility/MIPSpro740/Makefile \
simgear/bucket/Makefile \
simgear/debug/Makefile \
simgear/ephemeris/Makefile \
simgear/hla/Makefile \
simgear/io/Makefile \
simgear/magvar/Makefile \
simgear/math/Makefile \
simgear/environment/Makefile \
simgear/misc/Makefile \
simgear/nasal/Makefile \
simgear/props/Makefile \
simgear/route/Makefile \
simgear/scene/Makefile \
simgear/scene/bvh/Makefile \
simgear/scene/material/Makefile \
simgear/scene/model/Makefile \
simgear/scene/sky/Makefile \
simgear/scene/tgdb/Makefile \
simgear/scene/util/Makefile \
simgear/scene/tsync/Makefile \
simgear/screen/Makefile \
simgear/serial/Makefile \
simgear/sound/Makefile \
simgear/structure/Makefile \
simgear/threads/Makefile \
simgear/timing/Makefile \
simgear/xml/Makefile \
])
AC_OUTPUT
echo ""
echo "Configure Summary"
echo "================="
echo "Prefix: $prefix"
if test "x$with_logging" != "x"; then
echo "Debug messages: $with_logging"
else
echo "Debug messages: yes"
fi
echo -n "Automake version: "
automake --version | head -1
if test "x$with_jpeg_factory" = "xyes"; then
echo "With JPEG Factory support"
else
echo "Without JPEG Factory support"
fi
if test "x$ac_cv_header_pthread_h" = "xyes"; then
echo "Threads: pthread lib found."
else
echo "Threads: no threads (pthread lib not found.)"
fi

View File

@@ -1,13 +0,0 @@
Building a SimGear RPM package for Red Hat
Please see the "package/openSUSE" directory for an
example how to build a SimGear RPM package with
shared SimGear libraries.
You may need to adapt the names (exact spelling) of some
of the package dependencies in the openSUSE RPM spec,
since these may slightly differ for Red Hat.
(If you have a working and tested Red Hat RPM spec,
you're welcome to contribute it to this project.)

View File

@@ -1,23 +0,0 @@
Building a SimGear RPM package for openSUSE
(Last tested with openSUSE 11.4+12.1)
This directory contains the files which, along with
the source code tar files, can be used to build
an RPM package targeted at an openSUSE Linux system.
To build SimGear from source do the following:
1. obtain simgear-2.8.0.tar.bz2 (adapt version if
necessary) and copy it into ~/rpmbuild/SOURCES
2. look in the BuildRequires section of SimGear.spec
and check that all the packages referred to are
installed (note, some of these packages may be part
of openSUSE's "games" repository).
3. run 'rpmbuild -ba simgear.spec' and find the RPM
build result in ~/rpmbuild/RPMS
That's all!

View File

@@ -1,63 +0,0 @@
Summary: Simulator Construction Gear
Name: SimGear
Version: 2.8.0
Release: 1
License: LGPL
URL: http://www.flightgear.org
Group: Amusements/Games/3D/Simulation
Source: http://mirrors.ibiblio.org/pub/mirrors/flightgear/ftp/Source/simgear-%{version}.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: gcc, gcc-c++, cmake
BuildRequires: libopenal1-soft, openal-soft
BuildRequires: libOpenSceneGraph-devel >= 3.0
BuildRequires: zlib, zlib-devel
BuildRequires: libjpeg62, libjpeg62-devel
BuildRequires: boost-devel >= 1.37
BuildRequires: subversion-devel, libapr1-devel
Requires: OpenSceneGraph-plugins >= 3.0
%description
This package contains a tools and libraries useful for constructing
simulation and visualization applications such as FlightGear or TerraGear.
%package devel
Group: Development/Libraries/Other
Summary: Development header files for SimGear
Requires: SimGear = %{version}
%description devel
Development headers and libraries for building applications against SimGear.
%prep
%setup -T -q -n simgear-%{version} -b 0
%build
export CFLAGS="$RPM_OPT_FLAGS"
export CXXFLAGS="$RPM_OPT_FLAGS"
# build SHARED simgear libraries
cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} -DSIMGEAR_SHARED:BOOL=ON -DENABLE_TESTS:BOOL=OFF -DJPEG_FACTORY:BOOL=ON
make %{?_smp_mflags}
%install
make DESTDIR=%{buildroot} install
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files
%defattr (-, root, root, -)
%doc AUTHORS COPYING ChangeLog NEWS README
%{_libdir}/libSimGear*.so.*
%files devel
%defattr(-,root,root,-)
%dir %{_includedir}/simgear
%{_includedir}/simgear/*
%{_libdir}/libSimGear*.so
%changelog
* Mon Jul 02 2012 thorstenb@flightgear.org
- Initial version

2
projects/VC100/README Normal file
View File

@@ -0,0 +1,2 @@
The handmade VS2010 project files have been replaced by the Cmake build system.
Please use Cmake to build FlightGear with Visual Studio 2010.

3
projects/VC90/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*.user
Win32
x64

2052
projects/VC90/SimGear.vcproj Normal file

File diff suppressed because it is too large Load Diff

2
simgear/.gitignore vendored
View File

@@ -1,2 +1,4 @@
simgear_config.h
simgear_config.h.*
stamp-h1
version.h

View File

@@ -3,141 +3,56 @@ file(WRITE ${PROJECT_BINARY_DIR}/simgear/version.h "#define SIMGEAR_VERSION ${SI
foreach( mylibfolder
bucket
bvh
debug
ephemeris
hla
io
magvar
math
misc
nasal
nasal/cppbind
props
route
serial
structure
threads
timing
xml
package
)
add_subdirectory(${mylibfolder})
endforeach( mylibfolder )
if(NOT SIMGEAR_HEADLESS)
add_subdirectory(canvas)
if (NOT SIMGEAR_HEADLESS)
add_subdirectory(environment)
add_subdirectory(screen)
add_subdirectory(scene)
add_subdirectory(sound)
endif(NOT SIMGEAR_HEADLESS)
endif()
if(ENABLE_RTI)
add_subdirectory(hla)
endif(ENABLE_RTI)
set(HEADERS compiler.h constants.h sg_inlines.h ${PROJECT_BINARY_DIR}/simgear/version.h)
install (FILES ${HEADERS} DESTINATION include/simgear/)
get_property(coreSources GLOBAL PROPERTY CORE_SOURCES)
get_property(sceneSources GLOBAL PROPERTY SCENE_SOURCES)
get_property(publicHeaders GLOBAL PROPERTY PUBLIC_HEADERS)
get_property(localExpatSources GLOBAL PROPERTY LOCAL_EXPAT_SOURCES)
if(SIMGEAR_SHARED)
message(STATUS "Library building mode: SHARED LIBRARIES")
add_library(SimGearCore SHARED ${coreSources} ${localExpatSources})
message(STATUS "building shared library")
get_property(allSources GLOBAL PROPERTY ALL_SOURCES)
get_property(publicHeaders GLOBAL PROPERTY PUBLIC_HEADERS)
set_property(TARGET SimGearCore PROPERTY LINKER_LANGUAGE CXX)
set_property(TARGET SimGearCore PROPERTY VERSION ${SIMGEAR_VERSION})
set_property(TARGET SimGearCore PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
install(TARGETS SimGearCore EXPORT SimGearCoreConfig LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(EXPORT SimGearCoreConfig DESTINATION share/SimGearCore)
if(NOT SIMGEAR_HEADLESS)
add_library(SimGearScene SHARED ${sceneSources})
set_property(TARGET SimGearScene PROPERTY LINKER_LANGUAGE CXX)
set_property(TARGET SimGearScene PROPERTY VERSION ${SIMGEAR_VERSION})
set_property(TARGET SimGearScene PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
# EXPORT SimGearSceneConfig
install(TARGETS SimGearScene LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} )
# install(EXPORT SimGearSceneConfig DESTINATION share/SimGearScene)
endif()
else()
message(STATUS "Library building mode: STATIC LIBRARIES")
get_property(FG_GROUPS_CORE_SOURCES_C GLOBAL PROPERTY FG_GROUPS_CORE_SOURCES_C)
string(REPLACE "@" ";" groups ${FG_GROUPS_CORE_SOURCES_C} )
foreach(g ${groups})
string(REPLACE "#" ";" g2 ${g})
list(GET g2 0 name)
list(REMOVE_AT g2 0)
source_group("${name}\\Sources" FILES ${g2})
endforeach()
get_property(FG_GROUPS_CORE_SOURCES_H GLOBAL PROPERTY FG_GROUPS_CORE_SOURCES_H)
string(REPLACE "@" ";" groups ${FG_GROUPS_CORE_SOURCES_H} )
foreach(g ${groups})
string(REPLACE "#" ";" g2 ${g})
list(GET g2 0 name)
list(REMOVE_AT g2 0)
source_group("${name}\\Headers" FILES ${g2})
endforeach()
add_library(SimGearCore STATIC ${coreSources} ${localExpatSources})
install(TARGETS SimGearCore ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(NOT SIMGEAR_HEADLESS)
get_property(FG_GROUPS_SCENE_SOURCES_C GLOBAL PROPERTY FG_GROUPS_SCENE_SOURCES_C)
string(REPLACE "@" ";" groups ${FG_GROUPS_SCENE_SOURCES_C} )
foreach(g ${groups})
string(REPLACE "#" ";" g2 ${g})
list(GET g2 0 name)
list(REMOVE_AT g2 0)
source_group("${name}\\Sources" FILES ${g2})
endforeach()
get_property(FG_GROUPS_SCENE_SOURCES_H GLOBAL PROPERTY FG_GROUPS_SCENE_SOURCES_H)
string(REPLACE "@" ";" groups ${FG_GROUPS_SCENE_SOURCES_H} )
foreach(g ${groups})
string(REPLACE "#" ";" g2 ${g})
list(GET g2 0 name)
list(REMOVE_AT g2 0)
source_group("${name}\\Headers" FILES ${g2})
endforeach()
add_library(SimGearScene STATIC ${sceneSources})
install(TARGETS SimGearScene ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif(NOT SIMGEAR_HEADLESS)
add_library(SimGear SHARED ${allSources})
set_property(TARGET SimGear PROPERTY FRAMEWORK 1)
message(STATUS "public header: ${publicHeaders}")
set_property(TARGET SimGear PROPERTY PUBLIC_HEADER "${publicHeaders}")
set_property(TARGET SimGear PROPERTY LINKER_LANGUAGE CXX)
target_link_libraries(SimGear ${ZLIB_LIBRARY}
${OPENSCENEGRAPH_LIBRARIES}
${OPENAL_LIBRARY} ${ALUT_LIBRARY}
${OPENGL_LIBRARY})
install(TARGETS SimGear LIBRARY DESTINATION lib${LIB_SUFFIX}
PUBLIC_HEADER DESTINATION include/simgear)
endif(SIMGEAR_SHARED)
target_link_libraries(SimGearCore
${ZLIB_LIBRARY}
${RT_LIBRARY}
${DL_LIBRARY}
${EXPAT_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
${CORE_SERVICES_LIBRARY})
if(NOT SIMGEAR_HEADLESS)
target_link_libraries(SimGearScene
SimGearCore
${ZLIB_LIBRARY}
${OPENSCENEGRAPH_LIBRARIES}
${OPENAL_LIBRARY}
${OPENGL_LIBRARY}
${JPEG_LIBRARY})
endif()
if(ENABLE_RTI)
# Ugly first aid to make hla compile agian
set_property(SOURCE hla/RTI13InteractionClass.cxx hla/RTI13ObjectClass.cxx
hla/RTI13ObjectInstance.cxx hla/RTI13Federate.cxx
hla/RTI13FederateFactory.cxx
APPEND PROPERTY COMPILE_FLAGS "-I${RTI_INCLUDE_DIR}")
endif(ENABLE_RTI)

50
simgear/Makefile.am Normal file
View File

@@ -0,0 +1,50 @@
if ENABLE_HLA
HLA_DIR = hla
else
HLA_DIR =
endif
EXTRA_DIST = simgear_config.h.vc5 simgear_config.h-msvc71 version.h.in
include_HEADERS = \
compiler.h constants.h sg_inlines.h version.h
if WANT_HEADLESS
SG_EXTRA_DIRS =
METAR_DIRS =
else
SG_EXTRA_DIRS = scene sound screen
METAR_DIRS = environment
endif
if HAVE_THREADS
SGTHREAD_DIR = threads
else
SGTHREAD_DIR =
endif
SUBDIRS_ALWAYS = \
xml \
debug \
misc \
structure \
bucket \
ephemeris \
$(HLA_DIR) \
io \
magvar \
math \
nasal \
props \
route \
serial \
timing
SUBDIRS = $(SUBDIRS_ALWAYS) \
$(compatibility_DIR) \
$(METAR_DIRS) \
$(SG_EXTRA_DIRS) \
$(SGTHREAD_DIR)
DIST_SUBDIRS = $(SUBDIRS_ALWAYS) compatibility scene sound screen environment threads

View File

@@ -0,0 +1,17 @@
includedir = @includedir@/bucket
lib_LIBRARIES = libsgbucket.a
include_HEADERS = newbucket.hxx
libsgbucket_a_SOURCES = newbucket.cxx
# noinst_PROGRAMS = testbucket
# testbucket_SOURCES = testbucket.cxx
# testbucket_LDADD = \
# libsgbucket.a \
# $(top_builddir)/misc/libsgmisc.a
INCLUDES = -I$(top_srcdir)

View File

@@ -212,7 +212,7 @@ std::string SGBucket::gen_base_path() const {
main_lat *= -1;
}
snprintf(raw_path, 256, "%c%03d%c%02d/%c%03d%c%02d",
sprintf(raw_path, "%c%03d%c%02d/%c%03d%c%02d",
hem, top_lon, pole, top_lat,
hem, main_lon, pole, main_lat);
@@ -224,6 +224,17 @@ std::string SGBucket::gen_base_path() const {
// return width of the tile in degrees
double SGBucket::get_width() const {
if (lon==-180 && (lat==-89 || lat==88) ) {
/* Normally the tile at 180W in 88N and 89S
* would cover 184W to 176W and the next
* on the east side starts at 176W.
* To correct, make this a special tile
* from 180W to 176W with 4 degrees width
* instead of the normal 8 degrees at
* that latitude.
*/
return 4.0;
}
return sg_bucket_span( get_center_lat() );
}
@@ -345,13 +356,4 @@ void sgBucketDiff( const SGBucket& b1, const SGBucket& b2, int *dx, int *dy ) {
#endif
}
void sgGetBuckets( const SGGeod& min, const SGGeod& max, std::vector<SGBucket>& list ) {
double lon, lat, span;
for (lat = min.getLatitudeDeg(); lat <= max.getLatitudeDeg(); lat += SG_BUCKET_SPAN) {
span = sg_bucket_span( lat );
for (lon = min.getLongitudeDeg(); lon <= max.getLongitudeDeg(); lon += span) {
list.push_back( SGBucket(lon , lat) );
}
}
}

View File

@@ -42,7 +42,6 @@
#include <cstdio> // sprintf()
#include <ostream>
#include <string>
#include <vector>
/**
* standard size of a bucket in degrees (1/8 of a degree)
@@ -58,7 +57,9 @@
// return the horizontal tile span factor based on latitude
static double sg_bucket_span( double l ) {
if ( l >= 89.0 ) {
return 12.0;
return 360.0;
} else if ( l >= 88.0 ) {
return 8.0;
} else if ( l >= 86.0 ) {
return 4.0;
} else if ( l >= 83.0 ) {
@@ -79,10 +80,12 @@ static double sg_bucket_span( double l ) {
return 1.0;
} else if ( l >= -86.0 ) {
return 2.0;
} else if ( l >= -89.0 ) {
} else if ( l >= -88.0 ) {
return 4.0;
} else if ( l >= -89.0 ) {
return 8.0;
} else {
return 12.0;
return 360.0;
}
}
@@ -323,15 +326,6 @@ SGBucket sgBucketOffset( double dlon, double dlat, int x, int y );
void sgBucketDiff( const SGBucket& b1, const SGBucket& b2, int *dx, int *dy );
/**
* \relates SGBucket
* retrieve a list of buckets in the given bounding box
* @param min min lon,lat of bounding box in degrees
* @param max max lon,lat of bounding box in degrees
* @param list standard vector of buckets within the bounding box
*/
void sgGetBuckets( const SGGeod& min, const SGGeod& max, std::vector<SGBucket>& list );
/**
* Write the bucket lon, lat, x, and y to the output stream.
* @param out output stream

View File

@@ -1,75 +0,0 @@
// Copyright (C) 2008 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef BVHMaterial_hxx
#define BVHMaterial_hxx
#include <simgear/structure/SGReferenced.hxx>
namespace simgear {
class BVHMaterial : public SGReferenced {
public:
BVHMaterial();
virtual ~BVHMaterial();
/**
* Return if the surface material is solid, if it is not solid, a fluid
* can be assumed, that is usually water.
*/
bool get_solid () const { return _solid; }
/**
* Get the friction factor for that material
*/
double get_friction_factor () const { return _friction_factor; }
/**
* Get the rolling friction for that material
*/
double get_rolling_friction () const { return _rolling_friction; }
/**
* Get the bumpines for that material
*/
double get_bumpiness () const { return _bumpiness; }
/**
* Get the load resistance
*/
double get_load_resistance () const { return _load_resistance; }
protected:
// True if the material is solid, false if it is a fluid
bool _solid;
// the friction factor of that surface material
double _friction_factor;
// the rolling friction of that surface material
double _rolling_friction;
// the bumpiness of that surface material
double _bumpiness;
// the load resistance of that surface material
double _load_resistance;
};
}
#endif

View File

@@ -1,66 +0,0 @@
// Copyright (C) 2008 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef BVHPageNode_hxx
#define BVHPageNode_hxx
#include <list>
#include <simgear/structure/SGSharedPtr.hxx>
#include "BVHGroup.hxx"
#include "BVHVisitor.hxx"
namespace simgear {
class BVHPager;
class BVHPageRequest;
class BVHPageNode : public BVHGroup {
public:
BVHPageNode();
virtual ~BVHPageNode();
virtual void accept(BVHVisitor& visitor);
/// Return the usage stamp of the last access
unsigned getUseStamp() const
{ return _useStamp; }
virtual SGSphered computeBoundingSphere() const = 0;
virtual BVHPageRequest* newRequest() = 0;
protected:
virtual void invalidateBound() = 0;
bool getRequested() const
{ return _requested; }
void setRequested(bool requested)
{ _requested = requested; }
private:
friend class BVHPager;
std::list<SGSharedPtr<BVHPageNode> >::iterator _iterator;
unsigned _useStamp;
bool _requested;
};
}
#endif

View File

@@ -1,42 +0,0 @@
// Copyright (C) 2008 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef BVHPageRequest_hxx
#define BVHPageRequest_hxx
#include <simgear/structure/SGReferenced.hxx>
namespace simgear {
class BVHPageNode;
class BVHPageRequest : public SGReferenced {
public:
virtual ~BVHPageRequest();
/// Happens in the pager thread, do not modify the calling bvh tree
virtual void load() = 0;
/// Happens in the bvh main thread where the bvh is actually used.
/// So inside here it is safe to modify the paged node
virtual void insert() = 0;
/// The page node this request is for
virtual BVHPageNode* getPageNode() = 0;
};
}
#endif

View File

@@ -1,236 +0,0 @@
// Copyright (C) 2008 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "BVHPager.hxx"
#include <list>
#include <simgear/threads/SGThread.hxx>
#include <simgear/threads/SGGuard.hxx>
#include "BVHPageNode.hxx"
#include "BVHPageRequest.hxx"
namespace simgear {
struct BVHPager::_PrivateData : protected SGThread {
typedef SGSharedPtr<BVHPageRequest> _Request;
typedef std::list<_Request> _RequestList;
typedef std::list<SGSharedPtr<BVHPageNode> > _PageNodeList;
struct _LockedQueue {
void _push(const _Request& request)
{
SGGuard<SGMutex> scopeLock(_mutex);
_requestList.push_back(request);
}
_Request _pop()
{
SGGuard<SGMutex> scopeLock(_mutex);
if (_requestList.empty())
return _Request();
_Request request;
request.swap(_requestList.front());
_requestList.pop_front();
return request;
}
private:
SGMutex _mutex;
_RequestList _requestList;
};
struct _WorkQueue {
void _stop()
{
_push(_Request());
}
void _push(const _Request& request)
{
SGGuard<SGMutex> scopeLock(_mutex);
bool needSignal = _requestList.empty();
_requestList.push_back(request);
if (needSignal)
_waitCondition.signal();
}
_Request _pop()
{
SGGuard<SGMutex> scopeLock(_mutex);
while (_requestList.empty())
_waitCondition.wait(_mutex);
_Request request;
request.swap(_requestList.front());
_requestList.pop_front();
return request;
}
private:
SGMutex _mutex;
SGWaitCondition _waitCondition;
_RequestList _requestList;
};
_PrivateData() :
_started(false),
_useStamp(0)
{
}
virtual ~_PrivateData()
{
_stop();
}
virtual void run()
{
for (;;) {
_Request request = _pendingRequests._pop();
// This means stop working
if (!request.valid())
return;
request->load();
_processedRequests._push(request);
}
}
bool _start()
{
if (_started)
return true;
if (!start())
return false;
_started = true;
return true;
}
void _stop()
{
if (!_started)
return;
// send a stop request ...
_pendingRequests._stop();
// ... and wait for the thread to finish
join();
_started = false;
}
void _use(BVHPageNode& pageNode)
{
if (pageNode._requested) {
// move it forward in the lru list
_pageNodeList.splice(_pageNodeList.end(), _pageNodeList,
pageNode._iterator);
} else {
_Request request = pageNode.newRequest();
if (!request.valid())
return;
pageNode._iterator = _pageNodeList.insert(_pageNodeList.end(),
&pageNode);
pageNode._requested = true;
if (_started) {
_pendingRequests._push(request);
} else {
request->load();
request->insert();
}
}
pageNode._useStamp = _useStamp;
}
void _update(unsigned expiry)
{
// Insert all processed requests
for (;;) {
SGSharedPtr<BVHPageRequest> request;
request = _processedRequests._pop();
if (!request.valid())
break;
request->insert();
}
// ... and throw away stuff that is not used for a long time
unsigned useStamp = _useStamp - expiry;
_PageNodeList::iterator i = _pageNodeList.begin();
while (i != _pageNodeList.end()) {
// Ok, this means if the highest bit in the below difference
// is set which is aequivalent to having a negative difference
// but being wraparound save.
unsigned diff = (*i)->_useStamp - useStamp;
// test the sign bit of the difference
if (!(diff & (~((~0u) >> 1))))
break;
(*i)->clear();
(*i)->_requested = false;
i = _pageNodeList.erase(i);
}
}
bool _started;
unsigned _useStamp;
_WorkQueue _pendingRequests;
_LockedQueue _processedRequests;
// Store the rcu list of loaded nodes so that they can expire
_PageNodeList _pageNodeList;
};
BVHPager::BVHPager() :
_privateData(new _PrivateData)
{
}
BVHPager::~BVHPager()
{
delete _privateData;
_privateData = 0;
}
bool
BVHPager::start()
{
return _privateData->_start();
}
void
BVHPager::stop()
{
_privateData->_stop();
}
void
BVHPager::use(BVHPageNode& pageNode)
{
_privateData->_use(pageNode);
}
void
BVHPager::update(unsigned expiry)
{
_privateData->_update(expiry);
}
void
BVHPager::setUseStamp(unsigned stamp)
{
_privateData->_useStamp = stamp;
}
unsigned
BVHPager::getUseStamp() const
{
return _privateData->_useStamp;
}
}

View File

@@ -1,60 +0,0 @@
// Copyright (C) 2008 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef BVHPager_hxx
#define BVHPager_hxx
#include <simgear/structure/SGSharedPtr.hxx>
namespace simgear {
class BVHPageNode;
class BVHPageRequest;
class BVHPager {
public:
BVHPager();
~BVHPager();
/// Starts the pager thread
bool start();
/// Stops the pager thread
void stop();
/// Use this page node, if loaded make it as used, if not loaded schedule
void use(BVHPageNode& pageNode);
/// Call this from the main thread to incorporate the processed page
/// requests into the bounding volume tree
void update(unsigned expiry);
/// The usage stamp to mark usage of BVHPageNodes
void setUseStamp(unsigned stamp);
unsigned getUseStamp() const;
private:
BVHPager(const BVHPager&);
BVHPager& operator=(const BVHPager&);
struct _PrivateData;
_PrivateData* _privateData;
};
}
#endif

View File

@@ -1,34 +0,0 @@
include (SimGearComponent)
set(HEADERS
canvas_fwd.hxx
Canvas.hxx
CanvasEvent.hxx
CanvasEventManager.hxx
CanvasEventTypes.hxx
CanvasEventVisitor.hxx
CanvasMgr.hxx
CanvasObjectPlacement.hxx
CanvasPlacement.hxx
CanvasSystemAdapter.hxx
MouseEvent.hxx
ODGauge.hxx
VGInitOperation.hxx
)
set(SOURCES
Canvas.cxx
CanvasEvent.cxx
CanvasEventManager.cxx
CanvasEventVisitor.cxx
CanvasMgr.cxx
CanvasObjectPlacement.cxx
CanvasPlacement.cxx
ODGauge.cxx
VGInitOperation.cxx
)
add_subdirectory(ShivaVG/src)
add_subdirectory(elements)
simgear_scene_component(canvas canvas "${SOURCES}" "${HEADERS}")

View File

@@ -1,662 +0,0 @@
// The canvas for rendering with the 2d API
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include "Canvas.hxx"
#include "CanvasEventManager.hxx"
#include "CanvasEventVisitor.hxx"
#include <simgear/canvas/MouseEvent.hxx>
#include <simgear/canvas/CanvasPlacement.hxx>
#include <simgear/scene/util/parse_color.hxx>
#include <simgear/scene/util/RenderConstants.hxx>
#include <osg/Camera>
#include <osg/Geode>
#include <osgText/Text>
#include <osgViewer/Viewer>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/foreach.hpp>
namespace simgear
{
namespace canvas
{
//----------------------------------------------------------------------------
Canvas::CullCallback::CullCallback(const CanvasWeakPtr& canvas):
_canvas( canvas )
{
}
//----------------------------------------------------------------------------
void Canvas::CullCallback::operator()( osg::Node* node,
osg::NodeVisitor* nv )
{
if( (nv->getTraversalMask() & simgear::MODEL_BIT) && !_canvas.expired() )
_canvas.lock()->enableRendering();
traverse(node, nv);
}
//----------------------------------------------------------------------------
Canvas::Canvas(SGPropertyNode* node):
PropertyBasedElement(node),
_canvas_mgr(0),
_event_manager(new EventManager),
_size_x(-1),
_size_y(-1),
_view_width(-1),
_view_height(-1),
_status(node, "status"),
_status_msg(node, "status-msg"),
_sampling_dirty(false),
_render_dirty(true),
_visible(true),
_render_always(false)
{
_status = 0;
setStatusFlags(MISSING_SIZE_X | MISSING_SIZE_Y);
}
//----------------------------------------------------------------------------
Canvas::~Canvas()
{
}
//----------------------------------------------------------------------------
void Canvas::onDestroy()
{
if( _root_group )
{
_root_group->clearEventListener();
_root_group->onDestroy();
}
}
//----------------------------------------------------------------------------
void Canvas::setCanvasMgr(CanvasMgr* canvas_mgr)
{
_canvas_mgr = canvas_mgr;
}
//----------------------------------------------------------------------------
CanvasMgr* Canvas::getCanvasMgr() const
{
return _canvas_mgr;
}
//----------------------------------------------------------------------------
bool Canvas::isInit() const
{
return _texture.serviceable();
}
//----------------------------------------------------------------------------
void Canvas::addParentCanvas(const CanvasWeakPtr& canvas)
{
if( canvas.expired() )
{
SG_LOG
(
SG_GENERAL,
SG_WARN,
"Canvas::addParentCanvas(" << _node->getPath(true) << "): "
"got an expired parent!"
);
return;
}
_parent_canvases.insert(canvas);
}
//----------------------------------------------------------------------------
void Canvas::addChildCanvas(const CanvasWeakPtr& canvas)
{
if( canvas.expired() )
{
SG_LOG
(
SG_GENERAL,
SG_WARN,
"Canvas::addChildCanvas(" << _node->getPath(true) << "): "
" got an expired child!"
);
return;
}
_child_canvases.insert(canvas);
}
//----------------------------------------------------------------------------
void Canvas::removeParentCanvas(const CanvasWeakPtr& canvas)
{
_parent_canvases.erase(canvas);
}
//----------------------------------------------------------------------------
void Canvas::removeChildCanvas(const CanvasWeakPtr& canvas)
{
_child_canvases.erase(canvas);
}
//----------------------------------------------------------------------------
GroupPtr Canvas::createGroup(const std::string& name)
{
return _root_group->createChild<Group>(name);
}
//----------------------------------------------------------------------------
GroupPtr Canvas::getGroup(const std::string& name)
{
return _root_group->getChild<Group>(name);
}
//----------------------------------------------------------------------------
GroupPtr Canvas::getOrCreateGroup(const std::string& name)
{
return _root_group->getOrCreateChild<Group>(name);
}
//----------------------------------------------------------------------------
GroupPtr Canvas::getRootGroup()
{
return _root_group;
}
//----------------------------------------------------------------------------
void Canvas::enableRendering(bool force)
{
_visible = true;
if( force )
_render_dirty = true;
}
//----------------------------------------------------------------------------
void Canvas::update(double delta_time_sec)
{
if( (!_texture.serviceable() && _status != STATUS_DIRTY)
|| (_status & CREATE_FAILED) )
return;
if( _status == STATUS_DIRTY )
{
_texture.setSize(_size_x, _size_y);
if( !_texture.serviceable() )
{
_texture.useImageCoords(true);
_texture.useStencil(true);
_texture.allocRT(/*_camera_callback*/);
}
else
{
// Resizing causes a new texture to be created so we need to reapply all
// existing placements
reloadPlacements();
}
osg::Camera* camera = _texture.getCamera();
// TODO Allow custom render order? For now just keep in order with
// property tree.
camera->setRenderOrder(osg::Camera::PRE_RENDER, _node->getIndex());
osg::Vec4 clear_color(0.0f, 0.0f, 0.0f , 1.0f);
parseColor(_node->getStringValue("background"), clear_color);
camera->setClearColor(clear_color);
camera->addChild(_root_group->getMatrixTransform());
if( _texture.serviceable() )
{
setStatusFlags(STATUS_OK);
setStatusFlags(STATUS_DIRTY, false);
_render_dirty = true;
}
else
{
setStatusFlags(CREATE_FAILED);
return;
}
}
if( _visible || _render_always )
{
BOOST_FOREACH(CanvasWeakPtr canvas, _child_canvases)
{
// TODO should we check if the image the child canvas is displayed
// within is really visible?
if( !canvas.expired() )
canvas.lock()->_visible = true;
}
if( _render_dirty )
{
// Also mark all canvases this canvas is displayed within as dirty
BOOST_FOREACH(CanvasWeakPtr canvas, _parent_canvases)
{
if( !canvas.expired() )
canvas.lock()->_render_dirty = true;
}
}
_texture.setRender(_render_dirty);
_render_dirty = false;
_visible = false;
}
else
_texture.setRender(false);
_root_group->update(delta_time_sec);
if( _sampling_dirty )
{
_texture.setSampling(
_node->getBoolValue("mipmapping"),
_node->getIntValue("coverage-samples"),
_node->getIntValue("color-samples")
);
_sampling_dirty = false;
_render_dirty = true;
}
while( !_dirty_placements.empty() )
{
SGPropertyNode *node = _dirty_placements.back();
_dirty_placements.pop_back();
if( node->getIndex() >= static_cast<int>(_placements.size()) )
// New placement
_placements.resize(node->getIndex() + 1);
else
// Remove possibly existing placements
_placements[ node->getIndex() ].clear();
// Get new placements
PlacementFactoryMap::const_iterator placement_factory =
_placement_factories.find( node->getStringValue("type", "object") );
if( placement_factory != _placement_factories.end() )
{
Placements& placements = _placements[ node->getIndex() ] =
placement_factory->second
(
node,
boost::static_pointer_cast<Canvas>(_self.lock())
);
node->setStringValue
(
"status-msg",
placements.empty() ? "No match" : "Ok"
);
}
else
node->setStringValue("status-msg", "Unknown placement type");
}
}
//----------------------------------------------------------------------------
bool Canvas::addEventListener( const std::string& type,
const EventListener& cb )
{
if( !_root_group.get() )
throw std::runtime_error("Canvas::AddEventListener: no root group!");
return _root_group->addEventListener(type, cb);
}
//----------------------------------------------------------------------------
void Canvas::setSizeX(int sx)
{
if( _size_x == sx )
return;
_size_x = sx;
setStatusFlags(STATUS_DIRTY);
if( _size_x <= 0 )
setStatusFlags(MISSING_SIZE_X);
else
setStatusFlags(MISSING_SIZE_X, false);
// reset flag to allow creation with new size
setStatusFlags(CREATE_FAILED, false);
}
//----------------------------------------------------------------------------
void Canvas::setSizeY(int sy)
{
if( _size_y == sy )
return;
_size_y = sy;
setStatusFlags(STATUS_DIRTY);
if( _size_y <= 0 )
setStatusFlags(MISSING_SIZE_Y);
else
setStatusFlags(MISSING_SIZE_Y, false);
// reset flag to allow creation with new size
setStatusFlags(CREATE_FAILED, false);
}
//----------------------------------------------------------------------------
int Canvas::getSizeX() const
{
return _size_x;
}
//----------------------------------------------------------------------------
int Canvas::getSizeY() const
{
return _size_y;
}
//----------------------------------------------------------------------------
void Canvas::setViewWidth(int w)
{
if( _view_width == w )
return;
_view_width = w;
_texture.setViewSize(_view_width, _view_height);
}
//----------------------------------------------------------------------------
void Canvas::setViewHeight(int h)
{
if( _view_height == h )
return;
_view_height = h;
_texture.setViewSize(_view_width, _view_height);
}
//----------------------------------------------------------------------------
int Canvas::getViewWidth() const
{
return _texture.getViewSize().x();
}
//----------------------------------------------------------------------------
int Canvas::getViewHeight() const
{
return _texture.getViewSize().y();
}
//----------------------------------------------------------------------------
SGRect<int> Canvas::getViewport() const
{
return SGRect<int>(0, 0, getViewWidth(), getViewHeight());
}
//----------------------------------------------------------------------------
bool Canvas::handleMouseEvent(const MouseEventPtr& event)
{
if( !_root_group.get() )
return false;
EventVisitor visitor( EventVisitor::TRAVERSE_DOWN,
event->getClientPos(),
event->getDelta(),
_root_group );
if( !_root_group->accept(visitor) )
return false;
return _event_manager->handleEvent(event, visitor.getPropagationPath());
}
//----------------------------------------------------------------------------
void Canvas::childAdded( SGPropertyNode * parent,
SGPropertyNode * child )
{
if( parent != _node )
return;
if( child->getNameString() == "placement" )
_dirty_placements.push_back(child);
else if( _root_group.get() )
static_cast<Element*>(_root_group.get())->childAdded(parent, child);
}
//----------------------------------------------------------------------------
void Canvas::childRemoved( SGPropertyNode * parent,
SGPropertyNode * child )
{
_render_dirty = true;
if( parent != _node )
return;
if( child->getNameString() == "placement" )
_placements[ child->getIndex() ].clear();
else if( _root_group.get() )
static_cast<Element*>(_root_group.get())->childRemoved(parent, child);
}
//----------------------------------------------------------------------------
void Canvas::valueChanged(SGPropertyNode* node)
{
if( boost::starts_with(node->getNameString(), "status")
|| node->getParent()->getNameString() == "bounding-box" )
return;
_render_dirty = true;
bool handled = true;
if( node->getParent()->getParent() == _node
&& node->getParent()->getNameString() == "placement" )
{
size_t index = node->getIndex();
if( index < _placements.size() )
{
Placements& placements = _placements[index];
if( !placements.empty() )
{
bool placement_dirty = false;
BOOST_FOREACH(PlacementPtr& placement, placements)
{
// check if change can be directly handled by placement
if( placement->getProps() == node->getParent()
&& !placement->childChanged(node) )
placement_dirty = true;
}
if( !placement_dirty )
return;
}
}
// prevent double updates...
for( size_t i = 0; i < _dirty_placements.size(); ++i )
{
if( node->getParent() == _dirty_placements[i] )
return;
}
_dirty_placements.push_back(node->getParent());
}
else if( node->getParent() == _node )
{
if( node->getNameString() == "background" )
{
osg::Vec4 color;
if( _texture.getCamera() && parseColor(node->getStringValue(), color) )
{
_texture.getCamera()->setClearColor(color);
_render_dirty = true;
}
}
else if( node->getNameString() == "mipmapping"
|| node->getNameString() == "coverage-samples"
|| node->getNameString() == "color-samples" )
{
_sampling_dirty = true;
}
else if( node->getNameString() == "additive-blend" )
{
_texture.useAdditiveBlend( node->getBoolValue() );
}
else if( node->getNameString() == "render-always" )
{
_render_always = node->getBoolValue();
}
else if( node->getNameString() == "size" )
{
if( node->getIndex() == 0 )
setSizeX( node->getIntValue() );
else if( node->getIndex() == 1 )
setSizeY( node->getIntValue() );
}
else if( node->getNameString() == "view" )
{
if( node->getIndex() == 0 )
setViewWidth( node->getIntValue() );
else if( node->getIndex() == 1 )
setViewHeight( node->getIntValue() );
}
else if( node->getNameString() == "freeze" )
_texture.setRender( node->getBoolValue() );
else
handled = false;
}
else
handled = false;
if( !handled && _root_group.get() )
_root_group->valueChanged(node);
}
//----------------------------------------------------------------------------
osg::Texture2D* Canvas::getTexture() const
{
return _texture.getTexture();
}
//----------------------------------------------------------------------------
Canvas::CullCallbackPtr Canvas::getCullCallback() const
{
return _cull_callback;
}
//----------------------------------------------------------------------------
void Canvas::reloadPlacements(const std::string& type)
{
for(size_t i = 0; i < _placements.size(); ++i)
{
if( _placements[i].empty() )
continue;
SGPropertyNode* child = _placements[i].front()->getProps();
if( type.empty()
// reload if type matches or no type specified
|| child->getStringValue("type", type.c_str()) == type )
{
_dirty_placements.push_back(child);
}
}
}
//----------------------------------------------------------------------------
void Canvas::addPlacementFactory( const std::string& type,
PlacementFactory factory )
{
if( _placement_factories.find(type) != _placement_factories.end() )
SG_LOG
(
SG_GENERAL,
SG_WARN,
"Canvas::addPlacementFactory: replace existing factory '" << type << "'"
);
_placement_factories[type] = factory;
}
//----------------------------------------------------------------------------
void Canvas::removePlacementFactory(const std::string& type)
{
PlacementFactoryMap::iterator it = _placement_factories.find(type);
if( it == _placement_factories.end() )
SG_LOG
(
SG_GENERAL,
SG_WARN,
"Canvas::removePlacementFactory: no such factory '" << type << "'"
);
else
_placement_factories.erase(it);
}
//----------------------------------------------------------------------------
void Canvas::setSystemAdapter(const SystemAdapterPtr& system_adapter)
{
_system_adapter = system_adapter;
}
//----------------------------------------------------------------------------
SystemAdapterPtr Canvas::getSystemAdapter()
{
return _system_adapter;
}
//----------------------------------------------------------------------------
void Canvas::setSelf(const PropertyBasedElementPtr& self)
{
PropertyBasedElement::setSelf(self);
CanvasPtr canvas = boost::static_pointer_cast<Canvas>(self);
_root_group.reset( new Group(canvas, _node) );
_root_group->setSelf(_root_group);
// Remove automatically created property listener as we forward them on our
// own
_root_group->removeListener();
_cull_callback = new CullCallback(canvas);
}
//----------------------------------------------------------------------------
void Canvas::setStatusFlags(unsigned int flags, bool set)
{
if( set )
_status |= flags;
else
_status &= ~flags;
if( (_status & MISSING_SIZE_X) && (_status & MISSING_SIZE_Y) )
_status_msg = "Missing size";
else if( _status & MISSING_SIZE_X )
_status_msg = "Missing size-x";
else if( _status & MISSING_SIZE_Y )
_status_msg = "Missing size-y";
else if( _status & CREATE_FAILED )
_status_msg = "Creating render target failed";
else if( _status == STATUS_DIRTY )
_status_msg = "Creation pending...";
else
_status_msg = "Ok";
}
//----------------------------------------------------------------------------
Canvas::PlacementFactoryMap Canvas::_placement_factories;
SystemAdapterPtr Canvas::_system_adapter;
} // namespace canvas
} // namespace simgear

View File

@@ -1,222 +0,0 @@
// The canvas for rendering with the 2d API
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef CANVAS_HXX_
#define CANVAS_HXX_
#include "canvas_fwd.hxx"
#include "ODGauge.hxx"
#include <simgear/canvas/elements/CanvasGroup.hxx>
#include <simgear/math/SGRect.hxx>
#include <simgear/props/PropertyBasedElement.hxx>
#include <simgear/props/propertyObject.hxx>
#include <osg/NodeCallback>
#include <osg/observer_ptr>
#include <boost/scoped_ptr.hpp>
#include <string>
namespace simgear
{
namespace canvas
{
class CanvasMgr;
class MouseEvent;
class Canvas:
public PropertyBasedElement
{
public:
enum StatusFlags
{
STATUS_OK,
STATUS_DIRTY = 1,
MISSING_SIZE_X = STATUS_DIRTY << 1,
MISSING_SIZE_Y = MISSING_SIZE_X << 1,
CREATE_FAILED = MISSING_SIZE_Y << 1
};
/**
* This callback is installed on every placement of the canvas in the
* scene to only render the canvas if at least one placement is visible
*/
class CullCallback:
public osg::NodeCallback
{
public:
CullCallback(const CanvasWeakPtr& canvas);
private:
CanvasWeakPtr _canvas;
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
};
typedef osg::ref_ptr<CullCallback> CullCallbackPtr;
Canvas(SGPropertyNode* node);
virtual ~Canvas();
virtual void onDestroy();
void setCanvasMgr(CanvasMgr* canvas_mgr);
CanvasMgr* getCanvasMgr() const;
bool isInit() const;
/**
* Add a canvas which should be marked as dirty upon any change to this
* canvas.
*
* This mechanism is used to eg. redraw a canvas if it's displaying
* another canvas (recursive canvases)
*/
void addParentCanvas(const CanvasWeakPtr& canvas);
/**
* Add a canvas which should be marked visible if this canvas is visible.
*/
void addChildCanvas(const CanvasWeakPtr& canvas);
/**
* Stop notifying the given canvas upon changes
*/
void removeParentCanvas(const CanvasWeakPtr& canvas);
void removeChildCanvas(const CanvasWeakPtr& canvas);
/**
* Create a new group
*/
GroupPtr createGroup(const std::string& name = "");
/**
* Get an existing group with the given name
*/
GroupPtr getGroup(const std::string& name);
/**
* Get an existing group with the given name or otherwise create a new
* group
*/
GroupPtr getOrCreateGroup(const std::string& name);
/**
* Get the root group of the canvas
*/
GroupPtr getRootGroup();
/**
* Enable rendering for the next frame
*
* @param force Force redraw even if nothing has changed (if dirty flag
* is not set)
*/
void enableRendering(bool force = false);
void update(double delta_time_sec);
bool addEventListener(const std::string& type, const EventListener& cb);
void setSizeX(int sx);
void setSizeY(int sy);
int getSizeX() const;
int getSizeY() const;
void setViewWidth(int w);
void setViewHeight(int h);
int getViewWidth() const;
int getViewHeight() const;
SGRect<int> getViewport() const;
bool handleMouseEvent(const MouseEventPtr& event);
virtual void childAdded( SGPropertyNode * parent,
SGPropertyNode * child );
virtual void childRemoved( SGPropertyNode * parent,
SGPropertyNode * child );
virtual void valueChanged (SGPropertyNode * node);
osg::Texture2D* getTexture() const;
CullCallbackPtr getCullCallback() const;
void reloadPlacements( const std::string& type = std::string() );
static void addPlacementFactory( const std::string& type,
PlacementFactory factory );
static void removePlacementFactory(const std::string& type);
/**
* Set global SystemAdapter for all Canvas/ODGauge instances.
*
* The SystemAdapter is responsible for application specific operations
* like loading images/fonts and adding/removing cameras to the scene
* graph.
*/
static void setSystemAdapter(const SystemAdapterPtr& system_adapter);
static SystemAdapterPtr getSystemAdapter();
protected:
CanvasMgr *_canvas_mgr;
boost::scoped_ptr<EventManager> _event_manager;
int _size_x,
_size_y,
_view_width,
_view_height;
PropertyObject<int> _status;
PropertyObject<std::string> _status_msg;
bool _sampling_dirty,
_render_dirty,
_visible;
ODGauge _texture;
GroupPtr _root_group;
CullCallbackPtr _cull_callback;
bool _render_always; //<! Used to disable automatic lazy rendering (culling)
std::vector<SGPropertyNode*> _dirty_placements;
std::vector<Placements> _placements;
std::set<CanvasWeakPtr> _parent_canvases, //<! Canvases showing this canvas
_child_canvases; //<! Canvases displayed within
// this canvas
typedef std::map<std::string, PlacementFactory> PlacementFactoryMap;
static PlacementFactoryMap _placement_factories;
virtual void setSelf(const PropertyBasedElementPtr& self);
void setStatusFlags(unsigned int flags, bool set = true);
private:
static SystemAdapterPtr _system_adapter;
Canvas(const Canvas&); // = delete;
Canvas& operator=(const Canvas&); // = delete;
};
} // namespace canvas
} // namespace simgear
#endif /* CANVAS_HXX_ */

View File

@@ -1,104 +0,0 @@
// Canvas Event for event model similar to DOM Level 3 Event Model
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include "CanvasEvent.hxx"
namespace simgear
{
namespace canvas
{
//----------------------------------------------------------------------------
Event::Event():
type(UNKNOWN),
propagation_stopped(false)
{
}
//----------------------------------------------------------------------------
Event::~Event()
{
}
//----------------------------------------------------------------------------
Event::Type Event::getType() const
{
return type;
}
//----------------------------------------------------------------------------
std::string Event::getTypeString() const
{
switch( type )
{
# define ENUM_MAPPING(name, str) case name: return str;
# include "CanvasEventTypes.hxx"
# undef ENUM_MAPPING
default:
return "unknown";
}
}
//----------------------------------------------------------------------------
ElementWeakPtr Event::getTarget() const
{
return target;
}
//----------------------------------------------------------------------------
ElementWeakPtr Event::getCurrentTarget() const
{
return current_target;
}
//----------------------------------------------------------------------------
double Event::getTime() const
{
return time;
}
//----------------------------------------------------------------------------
void Event::stopPropagation()
{
propagation_stopped = true;
}
//----------------------------------------------------------------------------
Event::Type Event::strToType(const std::string& str)
{
typedef std::map<std::string, Type> TypeMap;
static TypeMap type_map;
if( type_map.empty() )
{
# define ENUM_MAPPING(type, str) type_map[ str ] = type;
# include "CanvasEventTypes.hxx"
# undef ENUM_MAPPING
}
TypeMap::const_iterator it = type_map.find(str);
if( it == type_map.end() )
return UNKNOWN;
return it->second;
}
} // namespace canvas
} // namespace simgear

View File

@@ -1,72 +0,0 @@
// Canvas Event for event model similar to DOM Level 3 Event Model
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef CANVAS_EVENT_HXX_
#define CANVAS_EVENT_HXX_
#include "canvas_fwd.hxx"
namespace simgear
{
namespace canvas
{
class Event
{
public:
enum Type
{
UNKNOWN,
# define ENUM_MAPPING(name, str) name,
# include "CanvasEventTypes.hxx"
# undef ENUM_MAPPING
USER_TYPE ///<! first unused id to be used for user defined types (not
/// implemented yet)
};
Type type;
ElementWeakPtr target,
current_target;
double time;
bool propagation_stopped;
Event();
// We need a vtable to allow nasal::Ghost to determine the dynamic type
// of the actual event instances.
virtual ~Event();
Type getType() const;
std::string getTypeString() const;
ElementWeakPtr getTarget() const;
ElementWeakPtr getCurrentTarget() const;
double getTime() const;
void stopPropagation();
static Type strToType(const std::string& str);
};
} // namespace canvas
} // namespace simgear
#endif /* CANVAS_EVENT_HXX_ */

View File

@@ -1,348 +0,0 @@
// Manage event handling inside a Canvas similar to the DOM Level 3 Event Model
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include "CanvasEventManager.hxx"
#include "MouseEvent.hxx"
#include <simgear/canvas/elements/CanvasElement.hxx>
#include <cmath>
namespace simgear
{
namespace canvas
{
const unsigned int drag_threshold = 8;
const double multi_click_timeout = 0.4;
//----------------------------------------------------------------------------
EventManager::StampedPropagationPath::StampedPropagationPath():
time(0)
{
}
//----------------------------------------------------------------------------
EventManager::StampedPropagationPath::StampedPropagationPath(
const EventPropagationPath& path,
double time
):
path(path),
time(time)
{
}
//----------------------------------------------------------------------------
void EventManager::StampedPropagationPath::clear()
{
path.clear();
time = 0;
}
//----------------------------------------------------------------------------
bool EventManager::StampedPropagationPath::valid() const
{
return !path.empty() && time > 0;
}
//----------------------------------------------------------------------------
EventManager::EventManager():
_current_click_count(0)
{
}
//----------------------------------------------------------------------------
bool EventManager::handleEvent( const MouseEventPtr& event,
const EventPropagationPath& path )
{
bool handled = false;
switch( event->type )
{
case Event::MOUSE_DOWN:
_last_mouse_down = StampedPropagationPath(path, event->getTime());
break;
case Event::MOUSE_UP:
{
// If the mouse has moved while a button was down (aka. dragging) we
// need to notify the original element that the mouse has left it, and
// the new element that it has been entered
if( _last_mouse_down.path != path )
handled |= handleMove(event, path);
// normal mouseup
handled |= propagateEvent(event, path);
if( _last_mouse_down.path.empty() )
// Ignore mouse up without any previous mouse down
return handled;
// now handle click/dblclick
if( checkClickDistance(path, _last_mouse_down.path) )
handled |=
handleClick(event, getCommonAncestor(_last_mouse_down.path, path));
_last_mouse_down.clear();
return handled;
}
case Event::DRAG:
if( !_last_mouse_down.valid() )
return false;
else
return propagateEvent(event, _last_mouse_down.path);
case Event::MOUSE_MOVE:
handled |= handleMove(event, path);
break;
case Event::MOUSE_LEAVE:
// Mouse leaves window and therefore also current mouseover element
handleMove(event, EventPropagationPath());
// Event is only send if mouse is moved outside the window or dragging
// has ended somewhere outside the window. In both cases a mouse button
// has been released, so no more mouse down or click...
_last_mouse_down.clear();
_last_click.clear();
return true;
case Event::WHEEL:
break;
default:
return false;
}
return handled | propagateEvent(event, path);
}
//----------------------------------------------------------------------------
bool EventManager::handleClick( const MouseEventPtr& event,
const EventPropagationPath& path )
{
MouseEventPtr click(new MouseEvent(*event));
click->type = Event::CLICK;
if( event->getTime() > _last_click.time + multi_click_timeout )
_current_click_count = 1;
else
{
// Maximum current click count is 3
_current_click_count = (_current_click_count % 3) + 1;
if( _current_click_count > 1 )
{
// Reset current click count if moved too far
if( !checkClickDistance(path, _last_click.path) )
_current_click_count = 1;
}
}
click->click_count = _current_click_count;
MouseEventPtr dbl_click;
if( _current_click_count == 2 )
{
dbl_click.reset(new MouseEvent(*click));
dbl_click->type = Event::DBL_CLICK;
}
bool handled = propagateEvent(click, path);
if( dbl_click )
handled |= propagateEvent( dbl_click,
getCommonAncestor(_last_click.path, path) );
_last_click = StampedPropagationPath(path, event->getTime());
return handled;
}
//----------------------------------------------------------------------------
bool EventManager::handleMove( const MouseEventPtr& event,
const EventPropagationPath& path )
{
EventPropagationPath& last_path = _last_mouse_over.path;
if( last_path == path )
return false;
bool handled = false;
// Leave old element
if( !last_path.empty() )
{
MouseEventPtr mouseout(new MouseEvent(*event));
mouseout->type = Event::MOUSE_OUT;
handled |= propagateEvent(mouseout, last_path);
// Send a mouseleave event to all ancestors of the currently left element
// which are not ancestor of the new element currently entered
EventPropagationPath path_leave = last_path;
for(size_t i = path_leave.size() - 1; i > 0; --i)
{
if( i < path.size() && path[i] == path_leave[i] )
break;
MouseEventPtr mouseleave(new MouseEvent(*event));
mouseleave->type = Event::MOUSE_LEAVE;
handled |= propagateEvent(mouseleave, path_leave);
path_leave.pop_back();
}
}
// Enter new element
if( !path.empty() )
{
MouseEventPtr mouseover(new MouseEvent(*event));
mouseover->type = Event::MOUSE_OVER;
handled |= propagateEvent(mouseover, path);
// Send a mouseenter event to all ancestors of the currently entered
// element which are not ancestor of the old element currently being
// left
EventPropagationPath path_enter;
for(size_t i = 0; i < path.size(); ++i)
{
path_enter.push_back(path[i]);
if( i < last_path.size() && path[i] == last_path[i] )
continue;
MouseEventPtr mouseenter(new MouseEvent(*event));
mouseenter->type = Event::MOUSE_ENTER;
handled |= propagateEvent(mouseenter, path_enter);
}
}
_last_mouse_over.path = path;
return handled;
}
//----------------------------------------------------------------------------
bool EventManager::propagateEvent( const EventPtr& event,
const EventPropagationPath& path )
{
event->target = path.back().element;
MouseEventPtr mouse_event = boost::dynamic_pointer_cast<MouseEvent>(event);
// Event propagation similar to DOM Level 3 event flow:
// http://www.w3.org/TR/DOM-Level-3-Events/#event-flow
// Capturing phase
// for( EventPropagationPath::const_iterator it = path.begin();
// it != path.end();
// ++it )
// {
// if( !it->element.expired() )
// std::cout << it->element.lock()->getProps()->getPath() << std::endl;
// }
// Check if event supports bubbling
const Event::Type types_no_bubbling[] = {
Event::MOUSE_ENTER,
Event::MOUSE_LEAVE,
};
const size_t num_types_no_bubbling = sizeof(types_no_bubbling)
/ sizeof(types_no_bubbling[0]);
bool do_bubble = true;
for( size_t i = 0; i < num_types_no_bubbling; ++i )
if( event->type == types_no_bubbling[i] )
{
do_bubble = false;
break;
}
// Bubbling phase
for( EventPropagationPath::const_reverse_iterator
it = path.rbegin();
it != path.rend();
++it )
{
ElementPtr el = it->element.lock();
if( !el )
{
// Ignore element if it has been destroyed while traversing the event
// (eg. removed by another event handler)
if( do_bubble )
continue;
else
break;
}
// TODO provide functions to convert delta to local coordinates on demand.
// Maybe also provide a clone method for events as local coordinates
// might differ between different elements receiving the same event.
if( mouse_event ) //&& event->type != Event::DRAG )
{
// TODO transform pos and delta for drag events. Maybe we should just
// store the global coordinates and convert to local coordinates
// on demand.
// Position and delta are specified in local coordinate system of
// current element
mouse_event->local_pos = it->local_pos;
//mouse_event->delta = it->local_delta;
}
event->current_target = el;
el->handleEvent(event);
if( event->propagation_stopped || !do_bubble )
return true;
}
return true;
}
//----------------------------------------------------------------------------
bool
EventManager::checkClickDistance( const EventPropagationPath& path1,
const EventPropagationPath& path2 ) const
{
osg::Vec2 delta = path1.front().local_pos - path2.front().local_pos;
return std::fabs(delta.x()) < drag_threshold
&& std::fabs(delta.y()) < drag_threshold;
}
//----------------------------------------------------------------------------
EventPropagationPath
EventManager::getCommonAncestor( const EventPropagationPath& path1,
const EventPropagationPath& path2 ) const
{
if( path1.empty() || path2.empty() )
return EventPropagationPath();
if( path1.back().element.lock() == path2.back().element.lock() )
return path2;
EventPropagationPath path;
for( size_t i = 0; i < path1.size() && i < path2.size(); ++i )
{
if( path1[i].element.lock() != path2[i].element.lock() )
break;
path.push_back(path2[i]);
}
return path;
}
} // namespace canvas
} // namespace simgear

View File

@@ -1,100 +0,0 @@
// Manage event handling inside a Canvas similar to the DOM Level 3 Event Model
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef CANVAS_EVENT_MANAGER_HXX_
#define CANVAS_EVENT_MANAGER_HXX_
#include "canvas_fwd.hxx"
#include <deque>
namespace simgear
{
namespace canvas
{
struct EventTarget
{
ElementWeakPtr element;
osg::Vec2f local_pos,
local_delta;
};
typedef std::deque<EventTarget> EventPropagationPath;
inline bool operator==(const EventTarget& t1, const EventTarget& t2)
{
return t1.element.lock() == t2.element.lock();
}
class EventManager
{
public:
EventManager();
bool handleEvent( const MouseEventPtr& event,
const EventPropagationPath& path );
protected:
struct StampedPropagationPath
{
StampedPropagationPath();
StampedPropagationPath(const EventPropagationPath& path, double time);
void clear();
bool valid() const;
EventPropagationPath path;
double time;
};
// TODO if we really need the paths modify to not copy around the paths
// that much.
StampedPropagationPath _last_mouse_down,
_last_click,
_last_mouse_over;
size_t _current_click_count;
/**
* Propagate click event and handle multi-click (eg. create dblclick)
*/
bool handleClick( const MouseEventPtr& event,
const EventPropagationPath& path );
/**
* Handle mouseover/enter/out/leave
*/
bool handleMove( const MouseEventPtr& event,
const EventPropagationPath& path );
bool propagateEvent( const EventPtr& event,
const EventPropagationPath& path );
/**
* Check if two click events (either mousedown/up or two consecutive
* clicks) are inside a maximum distance to still create a click or
* dblclick event respectively.
*/
bool checkClickDistance( const EventPropagationPath& path1,
const EventPropagationPath& path2 ) const;
EventPropagationPath
getCommonAncestor( const EventPropagationPath& path1,
const EventPropagationPath& path2 ) const;
};
} // namespace canvas
} // namespace simgear
#endif /* CANVAS_EVENT_MANAGER_HXX_ */

View File

@@ -1,33 +0,0 @@
// Mapping between canvas gui Event types and their names
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef ENUM_MAPPING
# error "Don't include this file directly!"
#endif
ENUM_MAPPING(MOUSE_DOWN, "mousedown")
ENUM_MAPPING(MOUSE_UP, "mouseup")
ENUM_MAPPING(CLICK, "click")
ENUM_MAPPING(DBL_CLICK, "dblclick")
ENUM_MAPPING(DRAG, "drag")
ENUM_MAPPING(WHEEL, "wheel")
ENUM_MAPPING(MOUSE_MOVE, "mousemove")
ENUM_MAPPING(MOUSE_OVER, "mouseover")
ENUM_MAPPING(MOUSE_OUT, "mouseout")
ENUM_MAPPING(MOUSE_ENTER, "mouseenter")
ENUM_MAPPING(MOUSE_LEAVE, "mouseleave")

View File

@@ -1,109 +0,0 @@
// Visitor for traversing a canvas element hierarchy similar to the traversal
// of the DOM Level 3 Event Model
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include "CanvasEvent.hxx"
#include "CanvasEventVisitor.hxx"
#include <simgear/canvas/elements/CanvasElement.hxx>
#include <iostream>
namespace simgear
{
namespace canvas
{
//----------------------------------------------------------------------------
EventVisitor::EventVisitor( TraverseMode mode,
const osg::Vec2f& pos,
const osg::Vec2f& delta,
const ElementPtr& root ):
_traverse_mode( mode ),
_root(root)
{
if( mode == TRAVERSE_DOWN )
{
EventTarget target = {ElementWeakPtr(), pos, delta};
_target_path.push_back(target);
}
}
//----------------------------------------------------------------------------
EventVisitor::~EventVisitor()
{
}
//----------------------------------------------------------------------------
bool EventVisitor::traverse(Element& el)
{
if( _traverse_mode == TRAVERSE_UP )
return el.ascend(*this);
else
return el.traverse(*this);
}
//----------------------------------------------------------------------------
bool EventVisitor::apply(Element& el)
{
// We only need to check for hits while traversing down
if( _traverse_mode == TRAVERSE_DOWN )
{
// Transform event to local coordinates
const osg::Matrix& m = el.getMatrixTransform()->getInverseMatrix();
const osg::Vec2f& pos = _target_path.back().local_pos;
const osg::Vec2f local_pos
(
m(0, 0) * pos[0] + m(1, 0) * pos[1] + m(3, 0),
m(0, 1) * pos[0] + m(1, 1) * pos[1] + m(3, 1)
);
// Don't check specified root element for collision, as its purpose is to
// catch all events which have no target. This allows for example calling
// event listeners attached to the canvas itself (its root group) even if
// no element has been hit.
if( _root.get() != &el && !el.hitBound(pos, local_pos) )
return false;
const osg::Vec2f& delta = _target_path.back().local_delta;
const osg::Vec2f local_delta
(
m(0, 0) * delta[0] + m(1, 0) * delta[1],
m(0, 1) * delta[0] + m(1, 1) * delta[1]
);
EventTarget target = {el.getWeakPtr(), local_pos, local_delta};
_target_path.push_back(target);
if( el.traverse(*this) || &el == _root.get() )
return true;
_target_path.pop_back();
return false;
}
else
return el.ascend(*this);
}
//----------------------------------------------------------------------------
const EventPropagationPath& EventVisitor::getPropagationPath() const
{
return _target_path;
}
} // namespace canvas
} // namespace simgear

View File

@@ -1,70 +0,0 @@
// Visitor for traversing a canvas element hierarchy similar to the traversal
// of the DOM Level 3 Event Model
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef CANVAS_EVENT_VISITOR_HXX_
#define CANVAS_EVENT_VISITOR_HXX_
#include "canvas_fwd.hxx"
#include "CanvasEventManager.hxx"
namespace simgear
{
namespace canvas
{
class EventVisitor
{
public:
enum TraverseMode
{
TRAVERSE_UP,
TRAVERSE_DOWN
};
/**
*
* @param mode
* @param pos Mouse position
* @param delta Mouse movement since last mouse move event
* @param root Element to dispatch events to if no element is hit
*/
EventVisitor( TraverseMode mode,
const osg::Vec2f& pos,
const osg::Vec2f& delta,
const ElementPtr& root = ElementPtr() );
virtual ~EventVisitor();
virtual bool traverse(Element& el);
virtual bool apply(Element& el);
const EventPropagationPath& getPropagationPath() const;
protected:
TraverseMode _traverse_mode;
EventPropagationPath _target_path;
ElementPtr _root;
};
} // namespace canvas
} // namespace simgear
#endif /* CANVAS_EVENTVISITOR_HXX_ */

View File

@@ -1,71 +0,0 @@
// Canvas with 2D rendering API
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include "CanvasMgr.hxx"
#include "Canvas.hxx"
#include "CanvasEventManager.hxx"
#include <boost/bind.hpp>
namespace simgear
{
namespace canvas
{
/**
* Canvas factory
*/
CanvasPtr canvasFactory(SGPropertyNode* node)
{
return CanvasPtr(new Canvas(node));
}
//----------------------------------------------------------------------------
CanvasMgr::CanvasMgr(SGPropertyNode_ptr node):
PropertyBasedMgr(node, "texture", &canvasFactory)
{
}
//----------------------------------------------------------------------------
CanvasPtr CanvasMgr::createCanvas(const std::string& name)
{
return boost::static_pointer_cast<Canvas>( createElement(name) );
}
//----------------------------------------------------------------------------
CanvasPtr CanvasMgr::getCanvas(size_t index) const
{
return boost::static_pointer_cast<Canvas>( getElement(index) );
}
//----------------------------------------------------------------------------
CanvasPtr CanvasMgr::getCanvas(const std::string& name) const
{
return boost::static_pointer_cast<Canvas>( getElement(name) );
}
//----------------------------------------------------------------------------
void CanvasMgr::elementCreated(PropertyBasedElementPtr element)
{
CanvasPtr canvas = boost::static_pointer_cast<Canvas>(element);
canvas->setCanvasMgr(this);
}
} // namespace canvas
} // namespace simgear

View File

@@ -1,70 +0,0 @@
// Canvas with 2D rendering API
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef SG_CANVAS_MGR_H_
#define SG_CANVAS_MGR_H_
#include "canvas_fwd.hxx"
#include <simgear/props/PropertyBasedMgr.hxx>
namespace simgear
{
namespace canvas
{
class CanvasMgr:
public PropertyBasedMgr
{
public:
/**
* @param node Root node of branch used to control canvasses
*/
CanvasMgr(SGPropertyNode_ptr node);
/**
* Create a new canvas
*
* @param name Name of the new canvas
*/
CanvasPtr createCanvas(const std::string& name = "");
/**
* Get ::Canvas by index
*
* @param index Index of texture node in /canvas/by-index/
*/
CanvasPtr getCanvas(size_t index) const;
/**
* Get ::Canvas by name
*
* @param name Value of child node "name" in
* /canvas/by-index/texture[i]/name
*/
CanvasPtr getCanvas(const std::string& name) const;
protected:
virtual void elementCreated(PropertyBasedElementPtr element);
};
} // namespace canvas
} // namespace simgear
#endif /* SG_CANVAS_MGR_H_ */

View File

@@ -1,244 +0,0 @@
// Canvas placement for placing a canvas texture onto osg objects.
//
// It also provides a SGPickCallback for passing mouse events to the canvas and
// manages emissive lighting of the placed canvas.
//
// Copyright (C) 2013 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include "Canvas.hxx"
#include "CanvasObjectPlacement.hxx"
#include "MouseEvent.hxx"
#include <simgear/props/props.hxx>
#include <simgear/scene/util/SGPickCallback.hxx>
#include <osgGA/GUIEventAdapter>
namespace simgear
{
namespace canvas
{
/**
* Handle picking events on object with a canvas placed onto
*/
class ObjectPickCallback:
public SGPickCallback
{
public:
ObjectPickCallback(const CanvasWeakPtr& canvas):
_canvas(canvas)
{}
virtual bool needsUV() const { return true; }
virtual bool buttonPressed( int,
const osgGA::GUIEventAdapter& ea,
const Info& info )
{
MouseEventPtr event(new MouseEvent(ea));
updatePosFromUV(event, info.uv);
if( ea.getEventType() == osgGA::GUIEventAdapter::SCROLL )
{
event->type = Event::WHEEL;
event->delta.set(0,0);
switch( ea.getScrollingMotion() )
{
case osgGA::GUIEventAdapter::SCROLL_UP:
event->delta.y() = 1;
break;
case osgGA::GUIEventAdapter::SCROLL_DOWN:
event->delta.y() = -1;
break;
default:
return false;
}
}
else
{
event->type = Event::MOUSE_DOWN;
}
return handleEvent(event);
}
virtual void buttonReleased( int,
const osgGA::GUIEventAdapter& ea,
const Info* info )
{
if( ea.getEventType() != osgGA::GUIEventAdapter::RELEASE )
return;
MouseEventPtr event(new MouseEvent(ea));
event->type = Event::MOUSE_UP;
updatePosFromUV(event, info ? info->uv : SGVec2d(-1,-1));
handleEvent(event);
}
virtual void mouseMoved( const osgGA::GUIEventAdapter& ea,
const Info* info )
{
// drag (currently only with LMB)
if( ea.getEventType() != osgGA::GUIEventAdapter::DRAG )
return;
MouseEventPtr event(new MouseEvent(ea));
event->type = Event::DRAG;
updatePosFromUV(event, info ? info->uv : SGVec2d(-1,-1));
handleEvent(event);
}
virtual bool hover( const osg::Vec2d& windowPos,
const Info& info )
{
// TODO somehow get more info about event (time, modifiers, pressed
// buttons, ...)
MouseEventPtr event(new MouseEvent);
event->type = Event::MOUSE_MOVE;
event->screen_pos = windowPos;
updatePosFromUV(event, info.uv);
return handleEvent(event);
}
virtual void mouseLeave( const osg::Vec2d& windowPos )
{
MouseEventPtr event(new MouseEvent);
event->type = Event::MOUSE_LEAVE;
event->screen_pos = windowPos;
handleEvent(event);
}
protected:
CanvasWeakPtr _canvas;
osg::Vec2f _last_pos,
_last_delta;
void updatePosFromUV(const MouseEventPtr& event, const SGVec2d& uv)
{
CanvasPtr canvas = _canvas.lock();
if( !canvas )
return;
osg::Vec2d pos( uv.x() * canvas->getViewWidth(),
(1 - uv.y()) * canvas->getViewHeight() );
_last_delta = pos - _last_pos;
_last_pos = pos;
event->client_pos = pos;
event->delta = _last_delta;
}
bool handleEvent(const MouseEventPtr& event)
{
CanvasPtr canvas = _canvas.lock();
if( !canvas )
return false;
return canvas->handleMouseEvent(event);
}
};
//----------------------------------------------------------------------------
ObjectPlacement::ObjectPlacement( SGPropertyNode* node,
const GroupPtr& group,
const CanvasWeakPtr& canvas ):
Placement(node),
_group(group),
_canvas(canvas)
{
// TODO make more generic and extendable for more properties
if( node->hasValue("emission") )
setEmission( node->getFloatValue("emission") );
if( node->hasValue("capture-events") )
setCaptureEvents( node->getBoolValue("capture-events") );
}
//----------------------------------------------------------------------------
ObjectPlacement::~ObjectPlacement()
{
assert( _group->getNumChildren() == 1 );
osg::Node *child = _group->getChild(0);
if( _group->getNumParents() )
{
osg::Group *parent = _group->getParent(0);
parent->addChild(child);
parent->removeChild(_group);
}
_group->removeChild(child);
}
//----------------------------------------------------------------------------
void ObjectPlacement::setEmission(float emit)
{
emit = SGMiscf::clip(emit, 0, 1);
if( !_material )
{
_material = new osg::Material;
_material->setColorMode(osg::Material::OFF);
_material->setDataVariance(osg::Object::DYNAMIC);
_group->getOrCreateStateSet()
->setAttribute(_material, ( osg::StateAttribute::ON
| osg::StateAttribute::OVERRIDE ) );
}
_material->setEmission(
osg::Material::FRONT_AND_BACK,
osg::Vec4(emit, emit, emit, emit)
);
}
//----------------------------------------------------------------------------
void ObjectPlacement::setCaptureEvents(bool enable)
{
if( !enable && _scene_user_data )
return;
if( enable && !_pick_cb )
_pick_cb = new ObjectPickCallback(_canvas);
_scene_user_data = SGSceneUserData::getOrCreateSceneUserData(_group);
_scene_user_data->setPickCallback(enable ? _pick_cb.get() : 0);
}
//----------------------------------------------------------------------------
bool ObjectPlacement::childChanged(SGPropertyNode* node)
{
if( node->getParent() != _node )
return false;
if( node->getNameString() == "emission" )
setEmission( node->getFloatValue() );
else if( node->getNameString() == "capture-events" )
setCaptureEvents( node->getBoolValue() );
else
return false;
return true;
}
} // namespace canvas
} // namespace simgear

View File

@@ -1,75 +0,0 @@
// Canvas placement for placing a canvas texture onto osg objects.
//
// It also provides a SGPickCallback for passing mouse events to the canvas and
// manages emissive lighting of the placed canvas.
//
// Copyright (C) 2013 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef CANVAS_PICK_PLACEMENT_HXX_
#define CANVAS_OBJECT_PLACEMENT_HXX_
#include "CanvasPlacement.hxx"
#include "canvas_fwd.hxx"
#include <simgear/scene/util/SGSceneUserData.hxx>
#include <osg/Material>
namespace simgear
{
namespace canvas
{
class ObjectPlacement:
public Placement
{
public:
typedef osg::ref_ptr<osg::Group> GroupPtr;
typedef osg::ref_ptr<osg::Material> MaterialPtr;
ObjectPlacement( SGPropertyNode* node,
const GroupPtr& group,
const CanvasWeakPtr& canvas );
virtual ~ObjectPlacement();
/**
* Set emissive lighting of the object the canvas is placed on.
*/
void setEmission(float emit);
/**
* Set whether pick events should be captured.
*/
void setCaptureEvents(bool enable);
virtual bool childChanged(SGPropertyNode* child);
protected:
typedef SGSharedPtr<SGPickCallback> PickCallbackPtr;
typedef osg::ref_ptr<SGSceneUserData> SGSceneUserDataPtr;
GroupPtr _group;
MaterialPtr _material;
CanvasWeakPtr _canvas;
PickCallbackPtr _pick_cb;
SGSceneUserDataPtr _scene_user_data;
};
} // namespace canvas
} // namespace simgear
#endif /* CANVAS_PICK_PLACEMENT_HXX_ */

View File

@@ -1,59 +0,0 @@
// Base class for canvas placements
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include "CanvasPlacement.hxx"
#include <simgear/props/props.hxx>
namespace simgear
{
namespace canvas
{
//----------------------------------------------------------------------------
Placement::Placement(SGPropertyNode* node):
_node(node)
{
}
//----------------------------------------------------------------------------
Placement::~Placement()
{
}
//----------------------------------------------------------------------------
SGConstPropertyNode_ptr Placement::getProps() const
{
return _node;
}
//----------------------------------------------------------------------------
SGPropertyNode_ptr Placement::getProps()
{
return _node;
}
//----------------------------------------------------------------------------
bool Placement::childChanged(SGPropertyNode* child)
{
return false;
}
} // namespace canvas
} // namespace simgear

View File

@@ -1,51 +0,0 @@
// Base class for canvas placements
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef CANVAS_PLACEMENT_HXX_
#define CANVAS_PLACEMENT_HXX_
#include <simgear/props/propsfwd.hxx>
namespace simgear
{
namespace canvas
{
class Placement
{
public:
Placement(SGPropertyNode* node);
virtual ~Placement() = 0;
SGConstPropertyNode_ptr getProps() const;
SGPropertyNode_ptr getProps();
virtual bool childChanged(SGPropertyNode* child);
protected:
SGPropertyNode_ptr _node;
private:
Placement(const Placement&) /* = delete */;
Placement& operator=(const Placement&) /* = delete */;
};
} // namespace canvas
} // namespace simgear
#endif /* CANVAS_PLACEMENT_HXX_ */

View File

@@ -1,43 +0,0 @@
// Adapter for using the canvas with different applications
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef SG_CANVAS_SYSTEM_ADAPTER_HXX_
#define SG_CANVAS_SYSTEM_ADAPTER_HXX_
#include "canvas_fwd.hxx"
namespace simgear
{
namespace canvas
{
class SystemAdapter
{
public:
virtual ~SystemAdapter() {}
virtual FontPtr getFont(const std::string& name) const = 0;
virtual void addCamera(osg::Camera* camera) const = 0;
virtual void removeCamera(osg::Camera* camera) const = 0;
virtual osg::Image* getImage(const std::string& path) const = 0;
};
} // namespace canvas
} // namespace simgear
#endif /* SG_CANVAS_SYSTEM_ADAPTER_HXX_ */

View File

@@ -1,82 +0,0 @@
// Mouse event
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef CANVAS_MOUSE_EVENT_HXX_
#define CANVAS_MOUSE_EVENT_HXX_
#include "CanvasEvent.hxx"
#include <osgGA/GUIEventAdapter>
namespace simgear
{
namespace canvas
{
class MouseEvent:
public Event
{
public:
MouseEvent():
button(-1),
state(-1),
mod(-1),
click_count(0)
{}
MouseEvent(const osgGA::GUIEventAdapter& ea):
button(ea.getButton()),
state(ea.getButtonMask()),
mod(ea.getModKeyMask()),
click_count(0)
{
time = ea.getTime();
}
osg::Vec2f getScreenPos() const { return screen_pos; }
osg::Vec2f getClientPos() const { return client_pos; }
osg::Vec2f getLocalPos() const { return local_pos; }
osg::Vec2f getDelta() const { return delta; }
float getScreenX() const { return screen_pos.x(); }
float getScreenY() const { return screen_pos.y(); }
float getClientX() const { return client_pos.x(); }
float getClientY() const { return client_pos.y(); }
float getLocalX() const { return local_pos.x(); }
float getLocalY() const { return local_pos.y(); }
float getDeltaX() const { return delta.x(); }
float getDeltaY() const { return delta.y(); }
int getCurrentClickCount() const { return click_count; }
osg::Vec2f screen_pos, //<! Position in screen coordinates
client_pos, //<! Position in window/canvas coordinates
local_pos, //<! Position in local/element coordinates
delta;
int button, //<! Button for this event
state, //<! Current button state
mod, //<! Keyboard modifier state
click_count; //<! Current click count
};
} // namespace canvas
} // namespace simgear
#endif /* CANVAS_MOUSE_EVENT_HXX_ */

View File

@@ -1,379 +0,0 @@
// Owner Drawn Gauge helper class
//
// Written by Harald JOHNSEN, started May 2005.
//
// Copyright (C) 2005 Harald JOHNSEN
//
// Ported to OSG by Tim Moore - Jun 2007
//
// Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April 2012
// Supports now multisampling/mipmapping, usage of the stencil buffer and placing
// the texture in the scene by certain filter criteria
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include "ODGauge.hxx"
#include "Canvas.hxx"
#include "CanvasSystemAdapter.hxx"
#include <simgear/debug/logstream.hxx>
#include <simgear/scene/util/RenderConstants.hxx>
#include <osg/Texture2D>
#include <osg/AlphaFunc>
#include <osg/BlendFunc>
#include <osg/Camera>
#include <osg/Matrix>
#include <osg/PolygonMode>
#include <osg/ShadeModel>
#include <osg/StateSet>
#include <osg/FrameBufferObject> // for GL_DEPTH_STENCIL_EXT on Windows
#include <osgUtil/RenderBin>
#include <cassert>
namespace simgear
{
namespace canvas
{
class PreOrderBin:
public osgUtil::RenderBin
{
public:
PreOrderBin()
{}
PreOrderBin( const RenderBin& rhs,
const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY ):
RenderBin(rhs, copyop)
{}
virtual osg::Object* cloneType() const
{
return new PreOrderBin();
}
virtual osg::Object* clone(const osg::CopyOp& copyop) const
{
return new PreOrderBin(*this,copyop);
}
virtual bool isSameKindAs(const osg::Object* obj) const
{
return dynamic_cast<const PreOrderBin*>(obj) != 0L;
}
virtual const char* className() const
{
return "PreOrderBin";
}
virtual void sort()
{
// Do not sort to keep traversal order...
}
};
#ifndef OSG_INIT_SINGLETON_PROXY
/**
* http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk/include/osg/Object
*
* Helper macro that creates a static proxy object to call singleton function
* on it's construction, ensuring that the singleton gets initialized at
* startup.
*/
# define OSG_INIT_SINGLETON_PROXY(ProxyName, Func)\
static struct ProxyName{ ProxyName() { Func; } } s_##ProxyName;
#endif
OSG_INIT_SINGLETON_PROXY(
PreOrderBinProxy,
(osgUtil::RenderBin::addRenderBinPrototype("PreOrderBin", new PreOrderBin))
);
//----------------------------------------------------------------------------
ODGauge::ODGauge():
_size_x( -1 ),
_size_y( -1 ),
_view_width( -1 ),
_view_height( -1 ),
_flags(0),
_coverage_samples( 0 ),
_color_samples( 0 )
{
}
//----------------------------------------------------------------------------
ODGauge::~ODGauge()
{
clear();
}
//----------------------------------------------------------------------------
void ODGauge::setSize(int size_x, int size_y)
{
_size_x = size_x;
_size_y = size_y < 0 ? size_x : size_y;
if( serviceable() )
reinit();
else if( texture )
texture->setTextureSize(_size_x, _size_y);
}
//----------------------------------------------------------------------------
void ODGauge::setViewSize(int width, int height)
{
_view_width = width;
_view_height = height < 0 ? width : height;
if( camera )
updateCoordinateFrame();
}
//----------------------------------------------------------------------------
osg::Vec2s ODGauge::getViewSize() const
{
return osg::Vec2s(_view_width, _view_height);
}
//----------------------------------------------------------------------------
void ODGauge::useImageCoords(bool use)
{
if( updateFlag(USE_IMAGE_COORDS, use) && texture )
updateCoordinateFrame();
}
//----------------------------------------------------------------------------
void ODGauge::useStencil(bool use)
{
if( updateFlag(USE_STENCIL, use) && texture )
updateStencil();
}
//----------------------------------------------------------------------------
void ODGauge::useAdditiveBlend(bool use)
{
if( updateFlag(USE_ADDITIVE_BLEND, use) && camera )
updateBlendMode();
}
//----------------------------------------------------------------------------
void ODGauge::setSampling( bool mipmapping,
int coverage_samples,
int color_samples )
{
if( !updateFlag(USE_MIPMAPPING, mipmapping)
&& _coverage_samples == coverage_samples
&& _color_samples == color_samples )
return;
if( color_samples > coverage_samples )
{
SG_LOG
(
SG_GL,
SG_WARN,
"ODGauge::setSampling: color_samples > coverage_samples not allowed!"
);
color_samples = coverage_samples;
}
_coverage_samples = coverage_samples;
_color_samples = color_samples;
updateSampling();
}
//----------------------------------------------------------------------------
void ODGauge::setRender(bool render)
{
// Only the far camera should trigger this texture to be rendered.
camera->setNodeMask(render ? simgear::BACKGROUND_BIT : 0);
}
//----------------------------------------------------------------------------
bool ODGauge::serviceable() const
{
return _flags & AVAILABLE;
}
//----------------------------------------------------------------------------
void ODGauge::allocRT(osg::NodeCallback* camera_cull_callback)
{
camera = new osg::Camera;
camera->setDataVariance(osg::Object::DYNAMIC);
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setRenderOrder(osg::Camera::PRE_RENDER);
camera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f , 0.0f));
camera->setClearStencil(0);
camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT,
osg::Camera::FRAME_BUFFER );
if( camera_cull_callback )
camera->setCullCallback(camera_cull_callback);
setRender(true);
updateCoordinateFrame();
updateStencil();
osg::StateSet* stateSet = camera->getOrCreateStateSet();
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
stateSet->setAttributeAndModes(
new osg::PolygonMode( osg::PolygonMode::FRONT_AND_BACK,
osg::PolygonMode::FILL ),
osg::StateAttribute::ON );
stateSet->setAttributeAndModes(
new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.001f),
osg::StateAttribute::ON );
stateSet->setAttribute(new osg::ShadeModel(osg::ShadeModel::FLAT));
if( !texture )
{
texture = new osg::Texture2D;
texture->setResizeNonPowerOfTwoHint(false);
texture->setTextureSize(_size_x, _size_y);
texture->setInternalFormat(GL_RGBA);
}
updateSampling();
updateBlendMode();
if( Canvas::getSystemAdapter() )
Canvas::getSystemAdapter()->addCamera(camera.get());
_flags |= AVAILABLE;
}
//----------------------------------------------------------------------------
void ODGauge::reinit()
{
osg::NodeCallback* cull_callback = camera ? camera->getCullCallback() : 0;
clear();
allocRT(cull_callback);
}
//----------------------------------------------------------------------------
void ODGauge::clear()
{
if( camera.valid() && Canvas::getSystemAdapter() )
Canvas::getSystemAdapter()->removeCamera(camera.get());
camera.release();
texture.release();
_flags &= ~AVAILABLE;
}
//----------------------------------------------------------------------------
bool ODGauge::updateFlag(Flags flag, bool enable)
{
if( bool(_flags & flag) == enable )
return false;
_flags ^= flag;
return true;
}
//----------------------------------------------------------------------------
void ODGauge::updateCoordinateFrame()
{
assert( camera );
if( _view_width < 0 )
_view_width = _size_x;
if( _view_height < 0 )
_view_height = _size_y;
camera->setViewport(0, 0, _size_x, _size_y);
if( _flags & USE_IMAGE_COORDS )
camera->setProjectionMatrix(
osg::Matrix::ortho2D(0, _view_width, _view_height, 0)
);
else
camera->setProjectionMatrix(
osg::Matrix::ortho2D( -_view_width/2., _view_width/2.,
-_view_height/2., _view_height/2. )
);
}
//----------------------------------------------------------------------------
void ODGauge::updateStencil()
{
assert( camera );
GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
if( _flags & USE_STENCIL )
{
camera->attach( osg::Camera::PACKED_DEPTH_STENCIL_BUFFER,
GL_DEPTH_STENCIL_EXT );
mask |= GL_STENCIL_BUFFER_BIT;
}
else
{
camera->detach(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER);
}
camera->setClearMask(mask);
}
//----------------------------------------------------------------------------
void ODGauge::updateSampling()
{
assert( camera );
assert( texture );
texture->setFilter(
osg::Texture2D::MIN_FILTER,
(_flags & USE_MIPMAPPING) ? osg::Texture2D::LINEAR_MIPMAP_LINEAR
: osg::Texture2D::LINEAR
);
camera->attach(
osg::Camera::COLOR_BUFFER,
texture.get(),
0, 0,
_flags & USE_MIPMAPPING,
_coverage_samples,
_color_samples
);
}
//----------------------------------------------------------------------------
void ODGauge::updateBlendMode()
{
assert( camera );
camera->getOrCreateStateSet()
->setAttributeAndModes
(
(_flags & USE_ADDITIVE_BLEND)
? new osg::BlendFunc( osg::BlendFunc::SRC_ALPHA,
osg::BlendFunc::ONE_MINUS_SRC_ALPHA,
osg::BlendFunc::ONE,
osg::BlendFunc::ONE )
: new osg::BlendFunc( osg::BlendFunc::SRC_ALPHA,
osg::BlendFunc::ONE_MINUS_SRC_ALPHA )
);
}
} // namespace canvas
} // namespace simgear

View File

@@ -1,172 +0,0 @@
// Owner Drawn Gauge helper class
//
// Written by Harald JOHNSEN, started May 2005.
//
// Copyright (C) 2005 Harald JOHNSEN - hjohnsen@evc.net
//
// Ported to OSG by Tim Moore - Jun 2007
//
// Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April 2012
// Supports now multisampling/mipmapping, usage of the stencil buffer and placing
// the texture in the scene by certain filter criteria
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef _SG_OD_GAUGE_HXX
#define _SG_OD_GAUGE_HXX
#include "canvas_fwd.hxx"
#include <osg/NodeCallback>
#include <osg/Group>
namespace osg
{
class Camera;
class Texture2D;
}
namespace simgear
{
namespace canvas
{
/**
* Owner Drawn Gauge (aka render-to-texture) helper class
*/
class ODGauge
{
public:
ODGauge();
virtual ~ODGauge();
/**
* Set the size of the render target.
*
* @param size_x X size
* @param size_y Y size. Defaults to size_x if not specified
*/
void setSize(int size_x, int size_y = -1);
/**
* Set the size of the viewport
*
* @param width
* @param height Defaults to width if not specified
*/
void setViewSize(int width, int height = -1);
osg::Vec2s getViewSize() const;
/**
* DEPRECATED
*
* Get size of squared texture
*/
int size() const { return _size_x; }
/**
* Set whether to use image coordinates or not.
*
* Default: origin == center of texture
* Image Coords: origin == top left corner
*/
void useImageCoords(bool use = true);
/**
* Enable/Disable using a stencil buffer
*/
void useStencil(bool use = true);
/**
* Enable/Disable additive alpha blending (Can improve results with
* transparent background)
*/
void useAdditiveBlend(bool use = true);
/**
* Set sampling parameters for mipmapping and coverage sampling
* antialiasing.
*
* @note color_samples is not allowed to be higher than coverage_samples
*
*/
void setSampling( bool mipmapping,
int coverage_samples = 0,
int color_samples = 0 );
/**
* Enable/Disable updating the texture (If disabled the contents of the
* texture remains with the outcome of the last rendering pass)
*/
void setRender(bool render);
/**
* Say if we can render to a texture.
* @return true if rtt is available
*/
bool serviceable() const;
/**
* Get the OSG camera for drawing this gauge.
*/
osg::Camera* getCamera() const { return camera.get(); }
osg::Texture2D* getTexture() const { return texture.get(); }
// Real initialization function. Bad name.
void allocRT(osg::NodeCallback* camera_cull_callback = 0);
void reinit();
void clear();
protected:
int _size_x,
_size_y,
_view_width,
_view_height;
enum Flags
{
AVAILABLE = 1,
USE_IMAGE_COORDS = AVAILABLE << 1,
USE_STENCIL = USE_IMAGE_COORDS << 1,
USE_MIPMAPPING = USE_STENCIL << 1,
USE_ADDITIVE_BLEND = USE_MIPMAPPING << 1
};
uint32_t _flags;
// Multisampling parameters
int _coverage_samples,
_color_samples;
osg::ref_ptr<osg::Camera> camera;
osg::ref_ptr<osg::Texture2D> texture;
bool updateFlag(Flags flag, bool enable);
void updateCoordinateFrame();
void updateStencil();
void updateSampling();
void updateBlendMode();
};
} // namespace canvas
} // namespace simgear
#endif // _SG_OD_GAUGE_HXX

View File

@@ -1,12 +0,0 @@
===============================================================================
ShivaVG - an open-source LGPL ANSI C implementation of the OpenVG specification
===============================================================================
Lead developer:
Ivan Leben <ivan.leben@gmail.com>
Occasional patches:
Daniel Turing
Vincenzo Pupillo

View File

@@ -1,504 +0,0 @@
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!

View File

@@ -1,67 +0,0 @@
04 Feb 2008 Ivan Leben <ivan.leben@gmail.com>
* shImage.c: shCopyPixels uses memcpy when formats are
equal.
04 Feb 2008 Ivan Leben <ivan.leben@gmail.com>
* openvg.h: changed typedef of VGHandle to void*. Code
compiles with no warnings on 64-bit systems now and
it's much safer anyway.
03 Feb 2008 Ivan Leben <ivan.leben@gmail.com>
* shContest.c: fixed a bug in SHContext destructor where
resource deletion loop was iterating image array while
freeing paint objects
03 Feb 2008 Ivan Leben <ivan.leben@gmail.com>
* a patch by Vincenzo Pupillo fixes array constructor behavior
when it runs out of memory plus makes its destructor a bit
more robust
03 Feb 2008 Ivan Leben <ivan.leben@gmail.com>
* autogen.sh: added --force to autoreconf call
03 Feb 2008 Ivan Leben <ivan.leben@gmail.com>
* Removed automake/autoconf generated files. Added autogen.sh
to generate them.
03 Feb 2008 Ivan Leben <ivan.leben@gmail.com>
* configure.in: changed order of checks for glut library and
glXGetProcAddress in -lGL so that latter doesn't fail when
glut is not installed.
30 Jan 2008 Ivan Leben <ivan.leben@gmail.com>
* shGeometry.c: shStrokePath() fixed to handle zero-length line
segments gracefully
* fixed the image color component ordering to be valid against the
spec
* shImage.c, shImage.h: completely overhauled to support multiple
image formats. Everything but _PRE and _BW_1 now supported.
24 Jan 2008 Ivan Leben <ivan.leben@gmail.com>
* Moved release-related info from ChangeLog to NEWS. ChangeLog will
now include info regarding each commit to repository
* Rearranged the path tesselletaion and user-to-surface transformation
steps in the pipeline to produce higher curve resolution when path is
scaled up
* Using new pipeline design, transformed bound-box query can now return
really tight bounds
* Inserted empty/nop definitions for all non-implemented function so
that linking against the library doesn't fail.
22 Jan 2008 Ivan Leben <ivan.leben@gmail.com>
* Fixed a bug where vgGetError would always return VG_NO_ERROR

View File

@@ -1,80 +0,0 @@
shIsValid* functions do a search through array!!!
That is required because user handles are actually pointers and need to be found in the valid path array. Solution would be to use indices into an array of pointers for internal handle-to-pointer conversion. When a path is deleted, an empty space would be left in the array and used when the next path is created.
How to speed up image upload / manipulation
=============================================
1) shCopyPixels uses memcpy
First, manipulation can be speeded up by modifying shCopyPixels
to copy lines using memcpy directly when source and target
formats are equal. If stride is same too, than we can memcpy
the whole block of memory.
2) What about mapping image manipulation directly to OpenGL
texture manipulation calls? Which formats could support this?
PROBLEM: if NOPS textures are not supported, then writing
and reading the image data back results in a precision loss!
Even if PBO available we'd need to gluScaleImage into it.
--> means: no NOPS, need intermediate buffer anyway
=== Solution1: PBO are available ====
Extension required: EXT_pixel_buffer_object (ARB_pixel_buffer_object ?)
Complexity of implementation: really easy - PBO simply
replaces the buffer that would be used if NOPS were not there
Cannot just glBindBuffer(GL_PIXEL_UNPACK_BUFFER) and then
glReadPixels into client memory, because glPixelStore
doesn't allow for random row byte size ("stride" must be
a multiple of pixel byte size).
We can safely glMapBuffer and copy from it whatever we want
however we want, and do any kind of conversion inbetween.
Is glMapBuffer + memcpy into user memory faster than just
glGetTexImage? Probably yes, since glGetTexImage probably
first downloads the data from GPU anyway.
glMapBuffer better anyway, because we can directly do the format
conversions unsupported by OpenGL (premultiplied to unpremultiplied,
grayscale conversion with different per component coefficients
instead of simple averaging etc.). We use all the exact same code
as when NOPS not supported.
=== Solution2: no PBOs ===
- vgImageSubData => glTexSubImage2D
- vgGetImageSubData => glGetTexImage
- vgCopyImage => glGetTexImage, glTexSubImage2D
- vgSetPixels => glGetTexImage, glDrawPixels
(PROBLEM: for glGetTexImage, row length in glPixelStore must
be a multiple of pixel byte size!)
- when copying pixels to/from the texture, we still need to
manually clip the working pixel region to the intersection
of the source and destination rectangles, since opengl spec
says INVALID_VALUE error is generated for invalid regions
(e.g. dstX + copyW > dstW)
How to solve great slow-down when scaled up?
=============================================
Reasons:
- cpu is subdividing a loooong path
- fill-rate is a bad thing
1. By writing gradient shaders, there would be no need to
draw into stencil first and then fill the whole area where stencil
odd - at least not when drawing stroke (optimizes half of the pipeline)
2. Real tesselation would reduce fill rate for filled paths, but does
the CPU bottleneck outweight the gain?
3. Early path discarding (transformed bounds outside surface? maybe
early convex-hull rule removal?)

View File

@@ -1,38 +0,0 @@
version 0.2.0 to 0.2.1 (20 Mar 2009):
* Implemented scissoring for 1 scissor rectangle
version 0.2.0 (20 Jan 2008):
* Fixed a bug where rotation in the paint-to-user matrix broke radial
gradient fill.
* vgCreateContextSH interface changed to allow for specification of
surface width and height
* new extension: vgResizeSurfaceSH to be called whenever the surface
needs to be resized to match the new window size
* #define GL_GLEXT_LEGACY in shExtensions.h prior to including gl.h
so it doesn't include glext.h automatically, which enables us to
check for OpenGL version and define OpenGL extension functions
manually.
* Optimized image uploading by replacing the call to gluBuild2DMipmaps
with glTexImage2D and changing the filter used to GL_LINEAR
* Added detection of ARB_texture_non_power_of_two extension to upload
rectangular images directly instead of scaling them and loosing
precision
* Pattern paint implemented
* Include folder changed to "vg" (lowercase)
* Added a message to test_blend program to notify the user that it
has not been implemented yet (black screen is therefore fine)
* All the calls to glLoadMatrix replaced with glPushMatrix,
glMultMatrix, glPopMatrix.
* Replaced images used in example programs for royalty-free
* README file written

View File

@@ -1,252 +0,0 @@
ShivaVG
=============================
See AUTHORS for the list of contributors
ShivaVG is an open-source LGPL ANSI C implementation of the Khronos
Group OpenVG specification.
I. BUILD
II. TESTING
III. IMPLEMENTATION STATUS
IV. EXTENSIONS
I. BUILD
=============================
* Prerequisites:
OpenGL development libraries and headers should be installed.
Othe than that, since it's ANSI C should compile with any modern
C compiler. jpeglib needs to be installed for example programs
that use images.
* Compiling under UNIX systems:
Read the INSTALL file for more detailed (though generic) directions.
This library uses the standard ./configure ; make. The example
programs are automatically compiled. However, compilation of each
example program can be toggled by ./configure --with-example-xxx
command where xxx denotes the name of the example. Run ./configure
--help for a list of such options.
* Compiling on Mac:
No XCode project files provided yet. The easiest way is by just
using gcc, in which case look under UNIX compiling section.
* Compiling natively on Windows platform:
Solution files are provided for Visual C++ version 7 and 8. For
the example programs using images to compile, you will need the
appropriate build of jpeglib to match your Visual C++ version.
* Compiling in mingw / cygwin environment:
Might work just as fine as any UNIX-flavored system, but hasn't
been tested yet.
II. TESTING
=============================
There is no real testing suite yet. The example programs are there
just to play with what the implementation can currently do, but
can hardly provide any proper validation, since no reference images
are provided. Here is a description of each example program and
what features it highlights:
* 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.
III. IMPLEMENTATION STATUS
=============================
Khronos states in the OpenVG specification, that the contexts for all
their client APIs are expected to be created via the EGL API. Since
EGL to use with ShivaVG has not been implemented yet, there is a set
of extension functions provided for the task of creating, maintaining
and destroying the OpenVG context. (See next section EXTENSIONS for
details.)
What follows is a description of which functions or to what extent
a certain function has been implemented. When a function is marked
as PARTIALLY implemented, the TODO file or the comments in the code
itself would provide further clues.
* General:
vgGetError ............................ FULLY implemented
vgFlush ............................... FULLY implemented
vgFinish .............................. FULLY implemented
* Getters and setters:
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:
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:
vgMask ................................ NOT implemented
vgClear ............................... FULLY implemented
* Paths:
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:
vgCreatePaint ......................... FULLY implemented
vgDestroyPaint ........................ FULLY implemented
vgSetPaint ............................ FULLY implemented
vgGetPaint ............................ FULLY implemented
vgSetColor ............................ FULLY implemented
vgGetColor ............................ FULLY implemented
vgPaintPattern ........................ FULLY implemented
* Images:
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 ........................... FULLY implemented
vgWritePixels ......................... FULLY implemented
vgGetPixels ........................... FULLY implemented
vgReadPixels .......................... FULLY implemented
vgCopyPixels .......................... FULLY implemented
* Image Filters:
vgColorMatrix ......................... NOT implemented
vgConvolve ............................ NOT implemented
vgSeparableConvolve ................... NOT implemented
vgGaussianBlur ........................ NOT implemented
vgLookup .............................. NOT implemented
vgLookupSingle ........................ NOT implemented
* Hardware Queries:
vgHardwareQuery ....................... NOT implemented
* Renderer and Extension Information:
vgGetString ........................... FULLY implemented
* VGU
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
IV. EXTENSIONS
=============================
There are three extensions to the API that 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.

View File

@@ -1,42 +0,0 @@
----------
Known bugs
----------
- outofmemory in arrays silently ignored
- blending doesn't use premultiplied colors (not porter-duff model)
- gradient color ramp is not interpolated in linear space
- linear and non-linear image formats behave both linearly
- radial gradient circle has got a fixed step instead of
proportional to its radius
-------------------------
Incomplete functionality:
-------------------------
- non-zero fill mode
- proper porter-duff blending
- masking
- scissoring
- child images
- VG_DRAW_IMAGE_STENCIL
- _PRE and BW_1 image formats
- VGU warp matrices
- EGL (image drawing targets)
- boundbox / point-on-path / tangent-on-path queries
- RENDERING_QUALITY_FASTER == RENDERING_QUALITY_BETTER
---------------------------
Possible portability issues
---------------------------
- GL_UNSIGNED_INT_8_8_8_8 and other for images
- GL_MIRRORED_REPEAT for gradients
- GL_CLAMP_TO_EDGE for gradients and pattern paints
- GL_CLAMP_TO_BORDER for pattern paints
- multitexturing for VG_DRAW_IMAGE_MULTIPLY, VG_DRAW_IMAGE_STENCIL
------
Bonus:
------
- gradient shaders? antialiasing shader?

View File

@@ -1,638 +0,0 @@
/*
* 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);
#if defined (__cplusplus)
} /* extern "C" */
#endif
#endif /* _OPENVG_H */

View File

@@ -1,104 +0,0 @@
/*
* 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 */

View File

@@ -1,30 +0,0 @@
include(SimGearComponent)
set(HEADERS
../include/vg/openvg.h
../include/vg/vgu.h
)
set(SOURCES
shArrays.c
shArrays.h
shContext.c
shContext.h
shExtensions.c
shExtensions.h
shGeometry.c
shGeometry.h
shImage.c
shImage.h
shPaint.c
shPaint.h
shParams.c
shPath.c
shPath.h
shPipeline.c
shVectors.c
shVectors.h
shVgu.c
)
simgear_scene_component(ShivaVG canvas/ShivaVG "${SOURCES}" "${HEADERS}")

View File

@@ -1,370 +0,0 @@
/*
* 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

View File

@@ -1,50 +0,0 @@
/*
* 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"

View File

@@ -1,55 +0,0 @@
/*
* 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

View File

@@ -1,41 +0,0 @@
#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
#else
// Unsupported system
#error This operating system is not supported by SFML library
#endif
#endif // __SHCONFIG_H

View File

@@ -1,500 +0,0 @@
/*
* 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 <vg/openvg.h>
#include "shContext.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);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,width,0,height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();*/
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 */
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,width,0,height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
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(VGContext *c);
void VGContext_ctor(VGContext *c)
{
/* Surface info */
c->surfaceWidth = 0;
c->surfaceHeight = 0;
/* GetString info */
strncpy(c->vendor, "Ivan Leben", sizeof(c->vendor));
strncpy(c->renderer, "ShivaVG 0.1.0", sizeof(c->renderer));
strncpy(c->version, "1.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;
}

View File

@@ -1,169 +0,0 @@
/*
* 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 */
SHint isGLAvailable_ClampToEdge;
SHint isGLAvailable_MirroredRepeat;
SHint isGLAvailable_Multitexture;
SHint isGLAvailable_TextureNonPowerOfTwo;
SH_PGLACTIVETEXTURE pglActiveTexture;
SH_PGLMULTITEXCOORD1F pglMultiTexCoord1f;
SH_PGLMULTITEXCOORD2F pglMultiTexCoord2f;
} 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 */

View File

@@ -1,179 +0,0 @@
/*
* 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>
#ifndef VG_API_MACOSX
# 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_SIZE 1024
#define SH_GRADIENT_TEX_COORDSIZE 4096 /* 1024 * RGBA */
/* OpenGL headers */
#if defined(VG_API_LINUX)
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glx.h>
#elif defined(VG_API_MACOSX)
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#elif defined(VG_API_WINDOWS)
#include <GL/gl.h>
#include <GL/glu.h>
#else
#define GL_GLEXT_LEGACY /* don't include glext.h */
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glx.h>
#endif
#include "shExtensions.h"
#endif /* __SHDEFS_H */

View File

@@ -1,131 +0,0 @@
/*
* 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 <vg/openvg.h>
#include "shDefs.h"
#include "shExtensions.h"
#include "shContext.h"
#include <stdio.h>
#include <string.h>
/*-----------------------------------------------------
* Extensions check
*-----------------------------------------------------*/
void fallbackActiveTexture(GLenum texture) {
}
void fallbackMultiTexCoord1f(GLenum target, GLfloat x) {
glTexCoord1f(x);
}
void fallbackMultiTexCoord2f(GLenum target, GLfloat x, GLfloat y) {
glTexCoord2f(x, y);
}
static int checkExtension(const char *extensions, const char *name)
{
int nlen = (int)strlen(name);
int elen = (int)strlen(extensions);
const char *e = extensions;
SH_ASSERT(nlen > 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);
#elif defined(__APPLE__)
/* TODO: Mac OS glGetProcAddress implementation */
return (PFVOID)NULL;
#else
return (PFVOID)glXGetProcAddress((const unsigned char *)name);
#endif
}
void shLoadExtensions(VGContext *c)
{
const char *ext = (const char*)glGetString(GL_EXTENSIONS);
/* GL_TEXTURE_CLAMP_TO_EDGE */
if (checkExtension(ext, "GL_EXT_texture_edge_clamp"))
c->isGLAvailable_ClampToEdge = 1;
else if (checkExtension(ext, "GL_SGIS_texture_edge_clamp"))
c->isGLAvailable_ClampToEdge = 1;
else /* Unavailable */
c->isGLAvailable_ClampToEdge = 0;
/* GL_TEXTURE_MIRRORED_REPEAT */
if (checkExtension(ext, "GL_ARB_texture_mirrored_repeat"))
c->isGLAvailable_MirroredRepeat = 1;
else if(checkExtension(ext, "GL_IBM_texture_mirrored_repeat"))
c->isGLAvailable_MirroredRepeat = 1;
else /* Unavailable */
c->isGLAvailable_MirroredRepeat = 0;
/* glActiveTexture, glMultiTexCoord1f */
if (checkExtension(ext, "GL_ARB_multitexture")) {
c->isGLAvailable_Multitexture = 1;
c->pglActiveTexture = (SH_PGLACTIVETEXTURE)
shGetProcAddress("glActiveTextureARB");
c->pglMultiTexCoord1f = (SH_PGLMULTITEXCOORD1F)
shGetProcAddress("glMultiTexCoord1fARB");
c->pglMultiTexCoord2f = (SH_PGLMULTITEXCOORD2F)
shGetProcAddress("glMultiTexCoord2fARB");
if (c->pglActiveTexture == NULL || c->pglMultiTexCoord1f == NULL ||
c->pglMultiTexCoord2f == NULL)
c->isGLAvailable_Multitexture = 0;
}else{ /* Unavailable */
c->isGLAvailable_Multitexture = 0;
c->pglActiveTexture = (SH_PGLACTIVETEXTURE)fallbackActiveTexture;
c->pglMultiTexCoord1f = (SH_PGLMULTITEXCOORD1F)fallbackMultiTexCoord1f;
c->pglMultiTexCoord2f = (SH_PGLMULTITEXCOORD2F)fallbackMultiTexCoord2f;
}
/* Non-power-of-two textures */
if (checkExtension(ext, "GL_ARB_texture_non_power_of_two"))
c->isGLAvailable_TextureNonPowerOfTwo = 1;
else /* Unavailable */
c->isGLAvailable_TextureNonPowerOfTwo = 0;
}

View File

@@ -1,64 +0,0 @@
/*
* 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
/* Define missing constants and route missing
functions to extension pointers */
#ifndef APIENTRY
#define APIENTRY
#endif
#ifndef APIENTRYP
#define APIENTRYP APIENTRY *
#endif
#ifndef GL_VERSION_1_2
# define GL_BGRA 0x80E1
# define GL_UNSIGNED_SHORT_5_6_5 0x8363
# define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
# define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
# define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
# define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
# define GL_UNSIGNED_INT_8_8_8_8 0x8035
# define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
# define GL_CLAMP_TO_EDGE 0x812F
#endif
#ifndef GL_VERSION_1_3
# define GL_MULTISAMPLE 0x809D
# define GL_TEXTURE0 0x84C0
# define GL_TEXTURE1 0x84C1
# define GL_CLAMP_TO_BORDER 0x812D
# define glActiveTexture context->pglActiveTexture
# define glMultiTexCoord1f context->pglMultiTexCoord1f
# define glMultiTexCoord2f context->pglMultiTexCoord2f
#endif
#ifndef GL_VERSION_1_4
# define GL_MIRRORED_REPEAT 0x8370
#endif
typedef void (APIENTRYP SH_PGLACTIVETEXTURE) (GLenum);
typedef void (APIENTRYP SH_PGLMULTITEXCOORD1F) (GLenum, GLfloat);
typedef void (APIENTRYP SH_PGLMULTITEXCOORD2F) (GLenum, GLfloat, GLfloat);
#endif

View File

@@ -1,936 +0,0 @@
/*
* 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 <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)
{
}

View File

@@ -1,33 +0,0 @@
/*
* 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 */

File diff suppressed because it is too large Load Diff

View File

@@ -1,154 +0,0 @@
/*
* 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 */

View File

@@ -1,789 +0,0 @@
/*
* 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 <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"
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;
glGenTextures(1, &p->texture);
glBindTexture(GL_TEXTURE_1D, p->texture);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, SH_GRADIENT_TEX_SIZE, 0,
GL_RGBA, GL_FLOAT, NULL);
}
void SHPaint_dtor(SHPaint *p)
{
SH_DEINITOBJ(SHStopArray, p->instops);
SH_DEINITOBJ(SHStopArray, p->stops);
if (glIsTexture(p->texture))
glDeleteTextures(1, &p->texture);
}
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)
{
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_SIZE-1));
SH_ASSERT(x1 >= 0 && x1 < SH_GRADIENT_TEX_SIZE &&
x2 >= 0 && x2 < SH_GRADIENT_TEX_SIZE &&
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_1D, p->texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, SH_GRADIENT_TEX_SIZE,
GL_RGBA, GL_FLOAT, rgba);
}
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)
{
glBindTexture(GL_TEXTURE_1D, p->texture);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
switch (p->spreadMode) {
case VG_COLOR_RAMP_SPREAD_PAD:
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); break;
case VG_COLOR_RAMP_SPREAD_REPEAT:
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); break;
case VG_COLOR_RAMP_SPREAD_REFLECT:
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); break;
}
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor4f(1,1,1,1);
}
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;
}
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor4f(1,1,1,1);
}
int shDrawLinearGradientMesh(SHPaint *p, SHVector2 *min, SHVector2 *max,
VGPaintMode mode, GLenum texUnit)
{
SHint i;
SHfloat n;
SHfloat x1 = p->linearGradient[0];
SHfloat y1 = p->linearGradient[1];
SHfloat x2 = p->linearGradient[2];
SHfloat y2 = p->linearGradient[3];
SHVector2 c, ux, uy;
SHVector2 cc, uux, uuy;
SHMatrix3x3 *m = 0;
SHMatrix3x3 mi;
SHint invertible;
SHVector2 corners[4];
SHfloat minOffset = 0.0f;
SHfloat maxOffset = 0.0f;
SHfloat left = 0.0f;
SHfloat right = 0.0f;
SHVector2 l1,r1,l2,r2;
/* Pick paint transform matrix */
SH_GETCONTEXT(0);
if (mode == VG_FILL_PATH)
m = &context->fillTransform;
else if (mode == VG_STROKE_PATH)
m = &context->strokeTransform;
/* Gradient center and unit vectors */
SET2(c, x1, y1);
SET2(ux, x2-x1, y2-y1);
SET2(uy, -ux.y, ux.x);
n = NORM2(ux);
DIV2(ux, n);
NORMALIZE2(uy);
/* Apply paint-to-user transformation */
ADD2V(ux, c); ADD2V(uy, c);
TRANSFORM2TO(c, (*m), cc);
TRANSFORM2TO(ux, (*m), uux);
TRANSFORM2TO(uy, (*m), uuy);
SUB2V(ux,c); SUB2V(uy,c);
SUB2V(uux,cc); SUB2V(uuy,cc);
/* Boundbox corners */
SET2(corners[0], min->x, min->y);
SET2(corners[1], max->x, min->y);
SET2(corners[2], max->x, max->y);
SET2(corners[3], min->x, max->y);
/* Find inverse transformation (back to paint space) */
invertible = shInvertMatrix(m, &mi);
if (!invertible || n==0.0f) {
/* Fill boundbox with color at offset 1 */
SHColor *c = &p->stops.items[p->stops.size-1].color;
glColor4fv((GLfloat*)c); glBegin(GL_QUADS);
for (i=0; i<4; ++i) glVertex2fv((GLfloat*)&corners[i]);
glEnd();
return 1;
}
/*--------------------------------------------------------*/
for (i=0; i<4; ++i) {
/* Find min/max offset and perpendicular span */
SHfloat o, s;
TRANSFORM2(corners[i], mi);
SUB2V(corners[i], c);
o = DOT2(corners[i], ux) / n;
s = DOT2(corners[i], uy);
if (o < minOffset || i==0) minOffset = o;
if (o > maxOffset || i==0) maxOffset = o;
if (s < left || i==0) left = s;
if (s > right || i==0) right = s;
}
/*---------------------------------------------------------*/
/* Corners of boundbox in gradient system */
SET2V(l1, cc); SET2V(r1, cc);
SET2V(l2, cc); SET2V(r2, cc);
OFFSET2V(l1, uuy, left); OFFSET2V(l1, uux, minOffset * n);
OFFSET2V(r1, uuy, right); OFFSET2V(r1, uux, minOffset * n);
OFFSET2V(l2, uuy, left); OFFSET2V(l2, uux, maxOffset * n);
OFFSET2V(r2, uuy, right); OFFSET2V(r2, uux, maxOffset * n);
/* Draw quad using color-ramp texture */
glActiveTexture(texUnit);
shSetGradientTexGLState(p);
glEnable(GL_TEXTURE_1D);
glBegin(GL_QUAD_STRIP);
glMultiTexCoord1f(texUnit, minOffset);
glVertex2fv((GLfloat*)&r1);
glVertex2fv((GLfloat*)&l1);
glMultiTexCoord1f(texUnit, maxOffset);
glVertex2fv((GLfloat*)&r2);
glVertex2fv((GLfloat*)&l2);
glEnd();
glDisable(GL_TEXTURE_1D);
return 1;
}
int shDrawRadialGradientMesh(SHPaint *p, SHVector2 *min, SHVector2 *max,
VGPaintMode mode, GLenum texUnit)
{
SHint i, j;
float a, n;
SHfloat cx = p->radialGradient[0];
SHfloat cy = p->radialGradient[1];
SHfloat fx = p->radialGradient[2];
SHfloat fy = p->radialGradient[3];
float r = p->radialGradient[4];
float fcx, fcy, rr, C;
SHVector2 ux;
SHVector2 uy;
SHVector2 c, f;
SHVector2 cf;
SHMatrix3x3 *m = 0;
SHMatrix3x3 mi;
SHint invertible;
SHVector2 corners[4];
SHVector2 fcorners[4];
SHfloat minOffset=0.0f;
SHfloat maxOffset=0.0f;
SHint maxI=0, maxJ=0;
SHfloat maxA=0.0f;
SHfloat startA=0.0f;
int numsteps = 100;
float step = 2*PI/numsteps;
SHVector2 tmin, tmax;
SHVector2 min1, max1, min2, max2;
/* Pick paint transform matrix */
SH_GETCONTEXT(0);
if (mode == VG_FILL_PATH)
m = &context->fillTransform;
else if (mode == VG_STROKE_PATH)
m = &context->strokeTransform;
/* Move focus into circle if outside */
SET2(cf, fx,fy);
SUB2(cf, cx,cy);
n = NORM2(cf);
if (n > r) {
DIV2(cf, n);
fx = cx + 0.995f * r * cf.x;
fy = cy + 0.995f * r * cf.y;
}
/* Precalculations */
rr = r*r;
fcx = fx - cx;
fcy = fy - cy;
C = fcx*fcx + fcy*fcy - rr;
/* Apply paint-to-user transformation
to focus and unit vectors */
SET2(f, fx, fy);
SET2(c, cx, cy);
SET2(ux, 1, 0);
SET2(uy, 0, 1);
ADD2(ux, cx, cy);
ADD2(uy, cx, cy);
TRANSFORM2(f, (*m));
TRANSFORM2(c, (*m));
TRANSFORM2(ux, (*m));
TRANSFORM2(uy, (*m));
SUB2V(ux, c); SUB2V(uy, c);
/* Boundbox corners */
SET2(corners[0], min->x, min->y);
SET2(corners[1], max->x, min->y);
SET2(corners[2], max->x, max->y);
SET2(corners[3], min->x, max->y);
/* Find inverse transformation (back to paint space) */
invertible = shInvertMatrix(m, &mi);
if (!invertible || r <= 0.0f) {
/* Fill boundbox with color at offset 1 */
SHColor *c = &p->stops.items[p->stops.size-1].color;
glColor4fv((GLfloat*)c); glBegin(GL_QUADS);
for (i=0; i<4; ++i) glVertex2fv((GLfloat*)&corners[i]);
glEnd();
return 1;
}
/*--------------------------------------------------------*/
/* Find min/max offset */
for (i=0; i<4; ++i) {
/* Transform to paint space */
SHfloat ax,ay, A,B,D,t, off;
TRANSFORM2TO(corners[i], mi, fcorners[i]);
SUB2(fcorners[i], fx, fy);
n = NORM2(fcorners[i]);
if (n == 0.0f) {
/* Avoid zero-length vectors */
off = 0.0f;
}else{
/* Distance from focus to circle at corner angle */
DIV2(fcorners[i], n);
ax = fcorners[i].x;
ay = fcorners[i].y;
A = ax*ax + ay*ay;
B = 2 * (fcx*ax + fcy*ay);
D = B*B - 4*A*C;
t = (-B + SH_SQRT(D)) / (2*A);
/* Relative offset of boundbox corner */
if (D <= 0.0f) off = 1.0f;
else off = n / t;
}
/* Find smallest and largest offset */
if (off < minOffset || i==0) minOffset = off;
if (off > maxOffset || i==0) maxOffset = off;
}
/* Is transformed focus inside original boundbox? */
if (f.x >= min->x && f.x <= max->x &&
f.y >= min->y && f.y <= max->y) {
/* Draw whole circle */
minOffset = 0.0f;
startA = 0.0f;
maxA = 2*PI;
}else{
/* Find most distant corner pair */
for (i=0; i<3; ++i) {
if (ISZERO2(fcorners[i])) continue;
for (j=i+1; j<4; ++j) {
if (ISZERO2(fcorners[j])) continue;
a = ANGLE2N(fcorners[i], fcorners[j]);
if (a > maxA || maxA == 0.0f)
{maxA=a; maxI=i; maxJ=j;}
}}
/* Pick starting angle */
if (CROSS2(fcorners[maxI],fcorners[maxJ]) > 0.0f)
startA = shVectorOrientation(&fcorners[maxI]);
else startA = shVectorOrientation(&fcorners[maxJ]);
}
/*---------------------------------------------------------*/
/* TODO: for minOffset we'd actually need to find minimum
of the gradient function when X and Y are substitued
with a line equation for each bound-box edge. As a
workaround we use 0.0f for now. */
minOffset = 0.0f;
step = PI/50;
numsteps = (SHint)SH_CEIL(maxA / step) + 1;
glActiveTexture(texUnit);
shSetGradientTexGLState(p);
glEnable(GL_TEXTURE_1D);
glBegin(GL_QUADS);
/* Walk the steps and draw gradient mesh */
for (i=0, a=startA; i<numsteps; ++i, a+=step) {
/* Distance from focus to circle border
at current angle (gradient space) */
float ax = SH_COS(a);
float ay = SH_SIN(a);
float A = ax*ax + ay*ay;
float B = 2 * (fcx*ax + fcy*ay);
float D = B*B - 4*A*C;
float t = (-B + SH_SQRT(D)) / (2*A);
if (D <= 0.0f) t = 0.0f;
/* Vectors pointing towards minimum and maximum
offset at current angle (gradient space) */
tmin.x = ax * t * minOffset;
tmin.y = ay * t * minOffset;
tmax.x = ax * t * maxOffset;
tmax.y = ay * t * maxOffset;
/* Transform back to user space */
min2.x = f.x + tmin.x * ux.x + tmin.y * uy.x;
min2.y = f.y + tmin.x * ux.y + tmin.y * uy.y;
max2.x = f.x + tmax.x * ux.x + tmax.y * uy.x;
max2.y = f.y + tmax.x * ux.y + tmax.y * uy.y;
/* Draw quad */
if (i!=0) {
glMultiTexCoord1f(texUnit, minOffset);
glVertex2fv((GLfloat*)&min1);
glVertex2fv((GLfloat*)&min2);
glMultiTexCoord1f(texUnit, maxOffset);
glVertex2fv((GLfloat*)&max2);
glVertex2fv((GLfloat*)&max1);
}
/* Save prev points */
min1 = min2;
max1 = max2;
}
glEnd();
glDisable(GL_TEXTURE_1D);
return 1;
}
int shDrawPatternMesh(SHPaint *p, SHVector2 *min, SHVector2 *max,
VGPaintMode mode, GLenum texUnit)
{
SHMatrix3x3 *m = 0;
SHMatrix3x3 mi;
SHfloat migl[16];
SHint invertible;
SHVector2 corners[4];
VGfloat sx, sy;
SHImage *img;
int i;
/* Pick paint transform matrix */
SH_GETCONTEXT(0);
if (mode == VG_FILL_PATH)
m = &context->fillTransform;
else if (mode == VG_STROKE_PATH)
m = &context->strokeTransform;
/* Boundbox corners */
SET2(corners[0], min->x, min->y);
SET2(corners[1], max->x, min->y);
SET2(corners[2], max->x, max->y);
SET2(corners[3], min->x, max->y);
/* Find inverse transformation (back to paint space) */
invertible = shInvertMatrix(m, &mi);
if (!invertible) {
/* Fill boundbox with tile fill color */
SHColor *c = &context->tileFillColor;
glColor4fv((GLfloat*)c); glBegin(GL_QUADS);
for (i=0; i<4; ++i) glVertex2fv((GLfloat*)&corners[i]);
glEnd();
return 1;
}
/* Setup texture coordinate transform */
img = (SHImage*)p->pattern;
sx = 1.0f/(VGfloat)img->texwidth;
sy = 1.0f/(VGfloat)img->texheight;
glActiveTexture(texUnit);
shMatrixToGL(&mi, migl);
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glScalef(sx, sy, 1.0f);
glMultMatrixf(migl);
/* Draw boundbox with same texture coordinates
that will get transformed back to paint space */
shSetPatternTexGLState(p, context);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
for (i=0; i<4; ++i) {
glMultiTexCoord2f(texUnit, corners[i].x, corners[i].y);
glVertex2fv((GLfloat*)&corners[i]);
}
glEnd();
glDisable(GL_TEXTURE_2D);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
return 1;
}

View File

@@ -1,82 +0,0 @@
/*
* 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;
#define SH_GRADIENT_TEX_SIZE 1024
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 shDrawLinearGradientMesh(SHPaint *p, SHVector2 *min, SHVector2 *max,
VGPaintMode mode, GLenum texUnit);
int shDrawRadialGradientMesh(SHPaint *p, SHVector2 *min, SHVector2 *max,
VGPaintMode mode, GLenum texUnit);
int shDrawPatternMesh(SHPaint *p, SHVector2 *min, SHVector2 *max,
VGPaintMode mode, GLenum texUnit);
#endif /* __SHPAINT_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,142 +0,0 @@
/*
* 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 */

View File

@@ -1,595 +0,0 @@
/*
* 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 <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)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, p->stroke.items);
glDrawArrays(GL_TRIANGLES, 0, p->stroke.size);
glDisableClientState(GL_VERTEX_ARRAY);
}
/*-----------------------------------------------------------
* 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 */
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, sizeof(SHVertex), p->vertices.items);
while (start < p->vertices.size) {
size = p->vertices.items[start].flags;
glDrawArrays(mode, start, size);
start += size;
}
glDisableClientState(GL_VERTEX_ARRAY);
}
/*-------------------------------------------------------------
* Draw a single quad that covers the bounding box of a path
*-------------------------------------------------------------*/
static void shDrawBoundBox(VGContext *c, SHPath *p, VGPaintMode mode)
{
SHfloat K = 1.0f;
if (mode == VG_STROKE_PATH)
K = SH_CEIL(c->strokeMiterLimit * c->strokeLineWidth) + 1.0f;
glBegin(GL_QUADS);
glVertex2f(p->min.x-K, p->min.y-K);
glVertex2f(p->max.x+K, p->min.y-K);
glVertex2f(p->max.x+K, p->max.y+K);
glVertex2f(p->min.x-K, p->max.y+K);
glEnd();
}
/*--------------------------------------------------------------
* 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:
shDrawLinearGradientMesh(p, min, max, mode, texUnit);
break;
case VG_PAINT_TYPE_RADIAL_GRADIENT:
shDrawRadialGradientMesh(p, min, max, mode, texUnit);
break;
case VG_PAINT_TYPE_PATTERN:
if (p->pattern != VG_INVALID_HANDLE) {
shDrawPatternMesh(p, min, max, mode, texUnit);
break;
}/* else behave as a color paint */
case VG_PAINT_TYPE_COLOR:
glColor4fv((GLfloat*)&p->color);
glBegin(GL_QUADS);
glVertex2f(pmin.x, pmin.y);
glVertex2f(pmax.x, pmin.y);
glVertex2f(pmax.x, pmax.y);
glVertex2f(pmin.x, pmax.y);
glEnd();
break;
}
}
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);
}
/* TODO: Turn antialiasing on/off */
glDisable(GL_LINE_SMOOTH);
glDisable(GL_POLYGON_SMOOTH);
glEnable(GL_MULTISAMPLE);
/* 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);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glMultMatrixf(mgl);
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);
/* Clear stencil for sure */
/* TODO: Is there any way to do this safely along
with the paint generation pass?? */
glDisable(GL_BLEND);
glDisable(GL_MULTISAMPLE);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
shDrawBoundBox(context, p, VG_FILL_PATH);
/* Reset state */
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDisable(GL_STENCIL_TEST);
glDisable(GL_BLEND);
}
/* TODO: Turn antialiasing on/off */
glDisable(GL_LINE_SMOOTH);
glDisable(GL_POLYGON_SMOOTH);
glEnable(GL_MULTISAMPLE);
if ((paintModes & VG_STROKE_PATH) &&
context->strokeLineWidth > 0.0f) {
if (1) {/*context->strokeLineWidth > 1.0f) {*/
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);
/* Clear stencil for sure */
glDisable(GL_BLEND);
glDisable(GL_MULTISAMPLE);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
shDrawBoundBox(context, p, VG_STROKE_PATH);
/* Reset state */
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDisable(GL_STENCIL_TEST);
glDisable(GL_BLEND);
}else{
/* Simulate thin stroke by alpha */
SHColor c = stroke->color;
if (context->strokeLineWidth < 1.0f)
c.a *= context->strokeLineWidth;
/* Draw contour as a line */
glDisable(GL_MULTISAMPLE);
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4fv((GLfloat*)&c);
shDrawVertices(p, GL_LINE_STRIP);
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
}
}
glPopMatrix();
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];
SHfloat texGenS[4] = {0,0,0,0};
SHfloat texGenT[4] = {0,0,0,0};
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);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glMultMatrixf(mgl);
/* 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);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
/* 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);
glDisable(GL_MULTISAMPLE);
}else{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glEnable(GL_MULTISAMPLE);
}
/* Generate image texture coords automatically */
texGenS[0] = 1.0f / i->texwidth;
texGenT[1] = 1.0f / i->texheight;
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, texGenS);
glTexGenfv(GL_T, GL_OBJECT_PLANE, texGenT);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
/* Pick fill paint */
fill = (context->fillPaint ? context->fillPaint : &context->defaultPaint);
/* Use paint color when multiplying with a color-paint */
if (context->imageMode == VG_DRAW_IMAGE_MULTIPLY &&
fill->type == VG_PAINT_TYPE_COLOR)
glColor4fv((GLfloat*)&fill->color);
else glColor4f(1,1,1,1);
/* Check image drawing mode */
if (context->imageMode == VG_DRAW_IMAGE_MULTIPLY &&
fill->type != VG_PAINT_TYPE_COLOR) {
/* Draw image quad into stencil */
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 1, 1);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
glBegin(GL_QUADS);
glVertex2i(0, 0);
glVertex2i(i->width, 0);
glVertex2i(i->width, i->height);
glVertex2i(0, i->height);
glEnd();
/* Setup blending */
updateBlendingStateGL(context, 0);
/* Draw gradient mesh where stencil 1*/
glEnable(GL_TEXTURE_2D);
glStencilFunc(GL_EQUAL, 1, 1);
glStencilOp(GL_ZERO,GL_ZERO,GL_ZERO);
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
SET2(min,0,0);
SET2(max, (SHfloat)i->width, (SHfloat)i->height);
if (fill->type == VG_PAINT_TYPE_RADIAL_GRADIENT) {
shDrawRadialGradientMesh(fill, &min, &max, VG_FILL_PATH, GL_TEXTURE1);
}else if (fill->type == VG_PAINT_TYPE_LINEAR_GRADIENT) {
shDrawLinearGradientMesh(fill, &min, &max, VG_FILL_PATH, GL_TEXTURE1);
}else if (fill->type == VG_PAINT_TYPE_PATTERN) {
shDrawPatternMesh(fill, &min, &max, VG_FILL_PATH, GL_TEXTURE1); }
glActiveTexture(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D);
glDisable(GL_STENCIL_TEST);
}else if (context->imageMode == VG_DRAW_IMAGE_STENCIL) {
}else{/* Either normal mode or multiplying with a color-paint */
/* Setup blending */
updateBlendingStateGL(context, 0);
/* Draw textured quad */
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glVertex2i(0, 0);
glVertex2i(i->width, 0);
glVertex2i(i->width, i->height);
glVertex2i(0, i->height);
glEnd();
glDisable(GL_TEXTURE_2D);
}
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glPopMatrix();
if (context->scissoring == VG_TRUE)
glDisable( GL_SCISSOR_TEST );
VG_RETURN(VG_NO_RETVAL);
}

View File

@@ -1,135 +0,0 @@
/*
* 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] = m->m[2][0]; mgl[6] = m->m[2][1]; mgl[10] = 1.0f; mgl[14] = m->m[2][1];
mgl[3] = 0.0f; mgl[7] = 0.0f; mgl[11] = 0.0f; mgl[15] = 1.0f;
}
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;
}

View File

@@ -1,275 +0,0 @@
/*
* 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);
#endif/* __SHVECTORS_H */

Some files were not shown because too many files have changed in this diff Show More