Browse Source

porting to Mali & investigating normals tangent bug

Panagiotis Christopoulos Charitos 12 years ago
parent
commit
b31fac9cba

+ 2 - 0
CMakeLists.txt

@@ -168,6 +168,8 @@ ELSE()
 	MESSAGE("++ AnKi debug: false")
 	MESSAGE("++ AnKi debug: false")
 ENDIF()
 ENDIF()
 
 
+SET(ANKI_GCC_TO_STRING_WORKAROUND "0" CACHE STRING "Enable workaround for C++11 GCC bug (0 or 1)")
+
 CONFIGURE_FILE("include/anki/Config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/anki/Config.h")
 CONFIGURE_FILE("include/anki/Config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/anki/Config.h")
 INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/anki/Config.h" DESTINATION "${INCLUDE_INSTALL_DIR}/anki")
 INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/anki/Config.h" DESTINATION "${INCLUDE_INSTALL_DIR}/anki")
 
 

+ 33 - 0
include/anki/Config.h.cmake

@@ -62,4 +62,37 @@
 #	define ANKI_RESTRICT
 #	define ANKI_RESTRICT
 #endif
 #endif
 
 
+// Workaround some GCC C++11 problems
+#if ${ANKI_GCC_TO_STRING_WORKAROUND}
+#	include <sstream>
+
+namespace std {
+
+template<typename T>
+std::string to_string(const T x)
+{
+	stringstream ss;
+	ss << x;
+	return ss.str();
+}
+
+inline float stof(const string& str)
+{
+	stringstream ss(str);
+	float f;
+	ss >> f;
+	return f;
+}
+
+inline int stoi(const string& str)
+{
+	stringstream ss(str);
+	int i;
+	ss >> i;
+	return i;
+}
+
+} // end namespace std
+#endif
+
 #endif
 #endif

+ 0 - 1
include/anki/gl/GlState.h

@@ -95,7 +95,6 @@ private:
 	/// @{
 	/// @{
 	Array<Bool, 7> flags;
 	Array<Bool, 7> flags;
 	Array<GLint, 4> viewport;
 	Array<GLint, 4> viewport;
-	Vec4 clearColor;
 	GLfloat clearDepthValue;
 	GLfloat clearDepthValue;
 	GLint clearStencilValue;
 	GLint clearStencilValue;
 	Array<GLenum, 2> blendFuncs;
 	Array<GLenum, 2> blendFuncs;

+ 3 - 1
include/anki/input/Input.h

@@ -20,7 +20,9 @@ class Input
 {
 {
 public:
 public:
 	Input()
 	Input()
-	{}
+	{
+		reset();
+	}
 	~Input();
 	~Input();
 
 
 	/// @name Acessors
 	/// @name Acessors

+ 1 - 6
include/anki/util/Allocator.h

@@ -194,12 +194,7 @@ inline bool operator!=(const Allocator<T1>&, const AnotherAllocator&)
 /// @note Don't ever EVER remove the double copy constructor and the double
 /// @note Don't ever EVER remove the double copy constructor and the double
 ///       operator=. The compiler will create defaults
 ///       operator=. The compiler will create defaults
 template<typename T, Bool deallocationFlag = false,
 template<typename T, Bool deallocationFlag = false,
-#if ANKI_CPU_ARCH == ANKI_CPU_ARCH_INTEL
-	U32 alignmentBits = 16
-#elif ANKI_CPU_ARCH == ANKI_CPU_ARCH_ARM
-	U32 alignmentBits = 32
-#endif
-	>
+	U32 alignmentBits = StackMemoryPool::SAFE_ALIGNMENT>
 class StackAllocator
 class StackAllocator
 {
 {
 	template<typename U, Bool deallocationFlag_, U32 alignmentBits_>
 	template<typename U, Bool deallocationFlag_, U32 alignmentBits_>

+ 11 - 1
include/anki/util/Memory.h

@@ -23,8 +23,18 @@ class Allocator;
 class StackMemoryPool: public NonCopyable
 class StackMemoryPool: public NonCopyable
 {
 {
 public:
 public:
+	static const U SAFE_ALIGNMENT = 
+#if ANKI_CPU_ARCH == ANKI_CPU_ARCH_INTEL
+		16
+#elif ANKI_CPU_ARCH == ANKI_CPU_ARCH_ARM
+		32
+#else
+#	error "See file"
+#endif
+		;
+
 	/// Default constructor
 	/// Default constructor
-	StackMemoryPool(PtrSize size, U32 alignmentBits = 16);
+	StackMemoryPool(PtrSize size, U32 alignmentBits = SAFE_ALIGNMENT);
 
 
 	/// Move
 	/// Move
 	StackMemoryPool(StackMemoryPool&& other)
 	StackMemoryPool(StackMemoryPool&& other)

+ 0 - 354
include/anki/util/Scanner.h

@@ -1,354 +0,0 @@
-#ifndef ANKI_UTIL_SCANNER_H
-#define ANKI_UTIL_SCANNER_H
-
-#include <exception>
-#include <array>
-#include <iosfwd>
-#include <fstream>
-
-namespace anki { namespace scanner {
-
-/// Scanner exception
-class Exception: public std::exception
-{
-public:
-	/// Constructor
-	Exception(const std::string& err, int errNo,
-		const std::string& scriptFilename, int scriptLineNmbr);
-
-	/// Copy constructor
-	Exception(const Exception& e);
-
-	/// Destructor. Do nothing
-	~Exception() throw()
-	{}
-
-	/// Return the error code
-	virtual const char* what() const throw();
-
-private:
-	std::string error;
-	int errNo; ///< Error number
-	std::string scriptFilename;
-	int scriptLineNmbr;
-	mutable std::string errWhat;
-};
-
-/// The max allowed length of a script line
-const int MAX_SCRIPT_LINE_LEN = 1024;
-
-/// The TokenCode is an enum that defines the Token type
-enum TokenCode
-{
-	// general codes
-	TC_ERROR, TC_END, TC_COMMENT, TC_NUMBER, TC_CHARACTER, TC_STRING,
-	TC_IDENTIFIER, TC_NEWLINE,
-
-	// keywords listed by strlen (dummy keywords at the moment)
-	TC_KE,
-	TC_KEY,
-	TC_KEYW,
-	TC_KEYWO,
-	TC_KEYWOR,
-	TC_KEYWORD,
-
-	// operators
-	TC_SCOPE_RESOLUTION, TC_L_SQ_BRACKET, TC_R_SQ_BRACKET, TC_L_PAREN,
-		TC_R_PAREN,
-	TC_DOT, TC_POINTER_TO_MEMBER, TC_L_BRACKET, TC_R_BRACKET, TC_COMMA,
-	TC_PERIOD, TC_UPDOWNDOT, TC_QUESTIONMARK, TC_SHARP, TC_EQUAL,
-	TC_NOT_EQUAL, TC_LESS, TC_GREATER, TC_LESS_EQUAL, TC_GREATER_EQUAL,
-	TC_LOGICAL_OR, TC_LOGICAL_AND, TC_PLUS, TC_MINUS, TC_STAR,
-	TC_BSLASH, TC_NOT, TC_BITWISE_AND, TC_BITWISE_OR, TC_UNARAY_COMPLEMENT,
-	TC_MOD, TC_XOR, TC_INC, TC_DEC, TC_SHL,
-	TC_SHR, TC_ASSIGN, TC_ASSIGN_ADD, TC_ASSIGN_SUB, TC_ASSIGN_MUL,
-	TC_ASSIGN_DIV, TC_ASSIGN_MOD, TC_ASSIGN_SHL, TC_ASSIGN_SHR, TC_ASSIGN_AND,
-	TC_ASSIGN_XOR, TC_ASSIGN_OR, TC_BACK_SLASH
-}; // end enum TokenCode
-
-/// The value of Token::dataType
-enum DataType
-{
-	DT_FLOAT,
-	DT_INT,
-	DT_CHAR,
-	DT_STR
-};
-
-/// Used inside the Token, its a variant that holds the data of the Token
-class TokenDataVal
-{
-	friend class Scanner;
-	friend class Token;
-
-public:
-	/// @name Accessors
-	/// @{
-
-	/// Access the data as C char
-	char getChar() const
-	{
-		return char_;
-	}
-
-	/// Access the data as unsigned int
-	unsigned long getInt() const
-	{
-		return int_;
-	}
-
-	/// Access the data as double
-	double getFloat() const
-	{
-		return float_;
-	}
-
-	/// Access the data as C string
-	const char* getString() const
-	{
-		return string;
-	}
-	/// @}
-
-private:
-	/// The data as unnamed union
-	union
-	{
-		char char_;
-		unsigned long int_;
-		double float_;
-		/// Points to @ref Token::asString if the token is string or
-		/// identifier
-		char* string;
-	};
-};
-
-/// The Token class
-class Token
-{
-	friend class Scanner;
-
-public:
-	Token()
-		: code(TC_ERROR)
-	{}
-
-	Token(const Token& b);
-
-	/// @name accessors
-	/// @{
-	const char* getString() const
-	{
-		return &asString[0];
-	}
-
-	TokenCode getCode() const
-	{
-		return code;
-	}
-
-	DataType getDataType() const
-	{
-		return dataType;
-	}
-
-	const TokenDataVal& getValue() const
-	{
-		return value;
-	}
-	/// @}
-
-	std::string getInfoString() const;
-
-	friend std::ostream& operator<<(std::ostream& s,
-		const Token& x);
-
-private:
-	std::array<char, MAX_SCRIPT_LINE_LEN> asString;
-	TokenCode code; ///< The first thing you should know about a token
-
-	/// Additional info in case @ref code is @ref TC_NUMBER
-	DataType dataType;
-	TokenDataVal value; ///< A value variant
-};
-
-/// C++ Tokenizer
-///
-/// The Scanner loads a file or an already loaded iostream and extracts the
-/// tokens. The script must be in C++ format. The class does not make any kind
-/// of memory allocations so it can be fast.
-class Scanner
-{
-public:
-	/// Constructor #1
-	/// @param newlinesAsWhitespace @see newlinesAsWhitespace
-	Scanner(bool newlinesAsWhitespace = true);
-
-	/// Constructor #2
-	/// @see loadFile
-	/// @param newlinesAsWhitespace @see newlinesAsWhitespace
-	/// @exception Exception
-	Scanner(const char* filename, bool newlinesAsWhitespace = true);
-
-	/// Constructor #3
-	/// @see loadIstream
-	/// @param newlinesAsWhitespace @see newlinesAsWhitespace
-	/// @exception Exception
-	Scanner(std::istream& istream_,
-		const char* scriptName_ = "unamed-istream",
-		bool newlinesAsWhitespace = true);
-
-	/// It only unloads the file if file is chosen
-	~Scanner()
-	{
-		unload();
-	}
-
-	/// Load a file to extract tokens
-	/// @param filename The filename of the file to read
-	/// @exception Exception
-	void loadFile(const char* filename);
-
-	/// Load a STL istream to extract tokens
-	/// @param istream_ The stream from where to read
-	/// @param scriptName_ The name of the stream. For error reporting
-	/// @exception Exception
-	void loadIstream(std::istream& istream_,
-		const char* scriptName_ = "unamed-istream");
-
-	/// Extracts all tokens and prints them. Used for debugging
-	void getAllPrintAll();
-
-	/// Get the next token from the stream. Its virtual and you can
-	/// override it
-	/// @return The next Token
-	/// @exception Exception
-	virtual const Token& getNextToken();
-
-	/// Accessor for the current token
-	/// @return The current Token
-	const Token& getCrntToken() const
-	{
-		return crntToken;
-	}
-
-	/// Get the name of the input stream
-	const char* getScriptName() const
-	{
-		return scriptName;
-	}
-
-	/// Get the current line the Scanner is processing
-	int getLineNumber() const
-	{
-		return lineNmbr;
-	}
-
-protected:
-	/// Every char in the Ascii table is binded with one characteristic
-	/// code type. This helps the scanning
-	enum AsciiFlag
-	{
-		AC_ERROR = 0,
-		AC_EOF = 1,
-		AC_LETTER = 2,
-		AC_DIGIT = 4,
-		AC_SPECIAL = 8,
-		AC_WHITESPACE = 16,
-		AC_QUOTE = 32,
-		AC_DOUBLEQUOTE = 64,
-		AC_ACCEPTABLE_IN_COMMENTS = 128 ///< Only accepted in comments
-	};
-
-	/// Reserved words like "int" "const" etc. Currently the reserved words
-	/// list is being populated with dummy data
-	struct ResWord
-	{
-		const char* string;
-		TokenCode   code;
-	};
-
-	static char eofChar; ///< Special end of file character
-
-	/// The array contains one AsciiFlag for every symbol of the ASCII table
-	static AsciiFlag asciiLookupTable[];
-
-	/// @name Reserved words
-	/// Groups of ResWord grouped by the length of the ResWord::string
-	/// @{
-	static ResWord rw2[], rw3[], rw4[], rw5[], rw6[], rw7[];
-	/// @}
-
-	/// The array contains all the groups of ResWord
-	static ResWord* rwTable[];
-
-	Token crntToken; ///< The current token
-	/// In contains the current line's text
-	char line[MAX_SCRIPT_LINE_LEN];
-	char* pchar; ///< Points somewhere to @ref line
-	int lineNmbr; ///< The number of the current line
-
-	/// Treat newlines as whitespace. If false means that the Scanner
-	/// returns (among others) newline tokens
-	bool newlinesAsWhitespace;
-
-	/// Commented lines number
-	/// Used to keep track of the newlines in multiline comments so we can
-	/// then return the correct number of newlines
-	/// in case of newlinesAsWhitespace is false
-	int commentedLines;
-
-	/// @name Input
-	/// @{
-
-	/// The file stream. Used if the @ref Scanner is initiated using
-	/// @ref loadFile
-	std::ifstream inFstream;
-	/// Points to either @ref inFstream or an external std::istream
-	std::istream* inStream;
-	/// The name of the input stream. Mainly used for error messaging
-	char scriptName[512];
-	/// @}
-
-	/// @name Checkers
-	/// @{
-	void checkWord();
-	void checkComment();
-	void checkNumber();
-	void checkString();
-	void checkChar();
-	void checkSpecial();
-	/// @}
-
-	/// It reads a new line from the iostream and it points @ref pchar to
-	/// the beginning of that line
-	void getLine();
-
-	/// Get the next char from the @ref line. If @ref line empty then get
-	/// new line. It returns '\\0' if we are in the
-	/// end of the line
-	char getNextChar();
-
-	/// Put the char that @ref getNextChar got back to the current line
-	char putBackChar();
-
-	/// Initializes the asciiLookupTable. It runs only once in the
-	/// construction of the first Scanner @see Scanner()
-	static void initAsciiMap();
-
-	/// A function to save us from typing
-	static AsciiFlag& lookupAscii(char c)
-	{
-		return asciiLookupTable[static_cast<int>(c)];
-	}
-
-	/// Common initialization code
-	void init(bool newlinesAsWhitespace_);
-
-	/// Unloads the file
-	void unload();
-};
-
-}} // end namespaces
-
-#endif

+ 2 - 2
shaders/CommonFrag.glsl

@@ -2,8 +2,8 @@
 #define ANKI_SHADERS_COMMON_FRAG_GLSL
 #define ANKI_SHADERS_COMMON_FRAG_GLSL
 
 
 #ifdef GL_ES
 #ifdef GL_ES
-precision mediump float;
-precision mediump int;
+precision highp float;
+precision highp int;
 #endif
 #endif
 
 
 #endif
 #endif

+ 1 - 1
shaders/MsCommonFrag.glsl

@@ -143,7 +143,7 @@ vec3 readRgbFromTexture(in sampler2D tex, in vec2 texCoords)
 #if defined(PASS_COLOR)
 #if defined(PASS_COLOR)
 #	define writeFais_DEFINED
 #	define writeFais_DEFINED
 void writeFais(
 void writeFais(
-	in vec3 diffCol, // Normalized
+	in vec3 diffCol, // from 0 to 1
 	in vec3 normal, 
 	in vec3 normal, 
 	in float specularComponent, // Streangth and shininess
 	in float specularComponent, // Streangth and shininess
 	in float blurring)
 	in float blurring)

+ 13 - 30
shaders/Pack.glsl

@@ -42,41 +42,24 @@ vec2 unpackSpecular(in float f)
 		- r * (16.0 * MAX_SPECULARITY / 15.0));
 		- r * (16.0 * MAX_SPECULARITY / 15.0));
 }
 }
 
 
-/// Pack a vec4 to float
-/// @node The components of v should be inside [0.0, 1.0]
-float pack4x8ToFloat(in vec4 v)
-{
-	const vec4 unshift = vec4(
-		1.0 / (256.0 * 256.0 * 256.0), 
-		1.0 / (256.0 * 256.0), 
-		1.0 / 256.0, 1.0);
-	return dot(v, unshift);
-}
-
-/// Unpack a float to vec4
-vec4 unpackFloatTo4x8(in float val) 
-{
-	const vec4 bitSh = vec4(
-		256.0 * 256.0 * 256.0, 
-		256.0* 256.0, 
-		256.0, 
-		1.0);
-	const vec4 bitMsk = vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
-
-	vec4 result = fract(val * bitSh);
-	result -= result.xxyz * bitMsk;
-	return result;
-}
-
 #if GL_ES
 #if GL_ES
 uint packUnorm4x8(in vec4 v)
 uint packUnorm4x8(in vec4 v)
 {
 {
-	return floatBitsToUint(pack4x8ToFloat(v));
-}
+	vec4 value = clamp(v, 0.0, 1.0) * 255.0;
 
 
+	return uint(value.x) | (uint(value.y) << 8) | (uint(value.z) << 16) |
+		(uint(value.w) << 24);
+}
+ 
 vec4 unpackUnorm4x8(in uint u)
 vec4 unpackUnorm4x8(in uint u)
 {
 {
-	return unpackFloatTo4x8(uintBitsToFloat(u));
-}
+	vec4 value;
+
+	value.x = float(u & 0xffU);
+	value.y = float((u >> 8) & 0xffU);
+	value.z = float((u >> 16) & 0xffU);
+	value.w = float((u >> 24) & 0xffU);
 
 
+	return value * (1.0 / 255.0);
+}
 #endif
 #endif

+ 1 - 1
shaders/Pps.glsl

@@ -16,7 +16,7 @@ in vec2 vTexCoords;
 
 
 layout(location = 0) out vec3 fColor;
 layout(location = 0) out vec3 fColor;
 
 
-const vec2 TEX_OFFSET = vec2(1.0 / FBO_WIDTH, 1.0 / FBO_HEIGHT);
+const vec2 TEX_OFFSET = vec2(1.0 / float(FBO_WIDTH), 1.0 / float(FBO_HEIGHT));
 
 
 vec2 KERNEL[8] = vec2[](
 vec2 KERNEL[8] = vec2[](
 	vec2(TEX_OFFSET.x, TEX_OFFSET.y),
 	vec2(TEX_OFFSET.x, TEX_OFFSET.y),

+ 2 - 1
src/core/App.cpp

@@ -86,8 +86,9 @@ void App::parseCommandLineArgs(int argc, char* argv[])
 //==============================================================================
 //==============================================================================
 void App::init(int argc, char* argv[])
 void App::init(int argc, char* argv[])
 {
 {
-	// Install signal handler
+	// Install signal handlers
 	signal(SIGSEGV, handler);
 	signal(SIGSEGV, handler);
+	signal(SIGBUS, handler);
 
 
 	// send output to handleMessageHanlderMsgs
 	// send output to handleMessageHanlderMsgs
 	ANKI_CONNECT(&LoggerSingleton::get(), messageRecieved, 
 	ANKI_CONNECT(&LoggerSingleton::get(), messageRecieved, 

+ 10 - 1
src/gl/BufferObject.cpp

@@ -66,12 +66,21 @@ void BufferObject::create(GLenum target_, U32 sizeInBytes_,
 //==============================================================================
 //==============================================================================
 void* BufferObject::map(U32 offset, U32 length, GLuint flags)
 void* BufferObject::map(U32 offset, U32 length, GLuint flags)
 {
 {
+	// XXX Remove this workaround
+#if ANKI_GL == ANKI_GL_ES
+	flags &= ~GL_MAP_INVALIDATE_BUFFER_BIT;
+#endif
+
+	// Precoditions
 	ANKI_ASSERT(isCreated());
 	ANKI_ASSERT(isCreated());
 #if ANKI_DEBUG
 #if ANKI_DEBUG
 	ANKI_ASSERT(mapped == false);
 	ANKI_ASSERT(mapped == false);
 #endif
 #endif
-	bind();
+	ANKI_ASSERT(length > 0);
 	ANKI_ASSERT(offset + length <= sizeInBytes);
 	ANKI_ASSERT(offset + length <= sizeInBytes);
+
+	// Do the mapping
+	bind();
 	void* mappedMem = glMapBufferRange(target, offset, length, flags);
 	void* mappedMem = glMapBufferRange(target, offset, length, flags);
 	ANKI_ASSERT(mappedMem != nullptr);
 	ANKI_ASSERT(mappedMem != nullptr);
 #if ANKI_DEBUG
 #if ANKI_DEBUG

+ 1 - 14
src/gl/GlState.cpp

@@ -123,9 +123,6 @@ void GlState::sync()
 	// viewport
 	// viewport
 	glGetIntegerv(GL_VIEWPORT, &viewport[0]);
 	glGetIntegerv(GL_VIEWPORT, &viewport[0]);
 
 
-	// clear color
-	glGetFloatv(GL_COLOR_CLEAR_VALUE, &clearColor[0]);
-
 	// clear depth value
 	// clear depth value
 	glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepthValue);
 	glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepthValue);
 
 
@@ -160,17 +157,7 @@ void GlState::setViewport(U32 x, U32 y, U32 w, U32 h)
 //==============================================================================
 //==============================================================================
 void GlState::setClearColor(const Vec4& color)
 void GlState::setClearColor(const Vec4& color)
 {
 {
-#if ANKI_DEBUG
-	Vec4 real;
-	glGetFloatv(GL_COLOR_CLEAR_VALUE, &real[0]);
-	ANKI_ASSERT(real == clearColor);
-#endif
-
-	if(clearColor != color)
-	{
-		glClearColor(color.x(), color.y(), color.z(), color.w());
-		clearColor == color;
-	}
+	glClearColor(color.x(), color.y(), color.z(), color.w());
 }
 }
 
 
 //==============================================================================
 //==============================================================================

+ 51 - 42
src/renderer/Is.cpp

@@ -501,58 +501,67 @@ void Is::lightPass()
 	//
 	//
 
 
 	// Map points
 	// Map points
-	ShaderPointLight* lightsMappedBuff = 
-		(ShaderPointLight*)pointLightsUbo.map(
-		0, 
-		sizeof(ShaderPointLight) * visiblePointLightsCount,
-		GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
-
-	WritePointLightsUbo jobs[ThreadPool::MAX_THREADS];
-	for(U i = 0; i < threadPool.getThreadsCount(); i++)
+	if(visiblePointLightsCount > 0)
 	{
 	{
-		jobs[i].shaderLights = lightsMappedBuff;
-		jobs[i].visibleLights = &visiblePointLights[0];
-		jobs[i].visibleLightsCount = visiblePointLightsCount;
-		jobs[i].is = this;
+		ShaderPointLight* lightsMappedBuff = 
+			(ShaderPointLight*)pointLightsUbo.map(
+			0, 
+			sizeof(ShaderPointLight) * visiblePointLightsCount,
+			GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+
+		WritePointLightsUbo jobs[ThreadPool::MAX_THREADS];
+		for(U i = 0; i < threadPool.getThreadsCount(); i++)
+		{
+			jobs[i].shaderLights = lightsMappedBuff;
+			jobs[i].visibleLights = &visiblePointLights[0];
+			jobs[i].visibleLightsCount = visiblePointLightsCount;
+			jobs[i].is = this;
 
 
-		threadPool.assignNewJob(i, &jobs[i]);
-	}
+			threadPool.assignNewJob(i, &jobs[i]);
+		}
 
 
-	// Done
-	threadPool.waitForAllJobsToFinish();
-	pointLightsUbo.unmap();
+		// Done
+		threadPool.waitForAllJobsToFinish();
+		pointLightsUbo.unmap();
+	}
 
 
 	// Map spots
 	// Map spots
-	ShaderSpotLight* shaderSpotLights = (ShaderSpotLight*)spotLightsUbo.map(
-		0,
-		sizeof(ShaderSpotLight) * visibleSpotLightsCount,
-		GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
-
-	WriteSpotLightsUbo jobs2[ThreadPool::MAX_THREADS];
-	for(U i = 0; i < threadPool.getThreadsCount(); i++)
+	if(visibleSpotLightsCount > 0)
 	{
 	{
-		jobs2[i].shaderLights = shaderSpotLights;
-		jobs2[i].visibleLights = &visibleSpotLights[0];
-		jobs2[i].visibleLightsCount = visibleSpotLightsCount;
-		jobs2[i].is = this;
+		ShaderSpotLight* shaderSpotLights = (ShaderSpotLight*)spotLightsUbo.map(
+			0,
+			sizeof(ShaderSpotLight) * visibleSpotLightsCount,
+			GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
 
 
-		threadPool.assignNewJob(i, &jobs2[i]);
-	}
+		WriteSpotLightsUbo jobs2[ThreadPool::MAX_THREADS];
+		for(U i = 0; i < threadPool.getThreadsCount(); i++)
+		{
+			jobs2[i].shaderLights = shaderSpotLights;
+			jobs2[i].visibleLights = &visibleSpotLights[0];
+			jobs2[i].visibleLightsCount = visibleSpotLightsCount;
+			jobs2[i].is = this;
 
 
-	// Done
-	threadPool.waitForAllJobsToFinish();
+			threadPool.assignNewJob(i, &jobs2[i]);
+		}
 
 
-	// Set shadow layer IDs
-	U32 i = 0;
-	ShaderSpotLight* shaderSpotLight = shaderSpotLights + spotsNoShadowCount;
-	for(; shaderSpotLight != shaderSpotLights + visibleSpotLightsCount;
-		++shaderSpotLight)
-	{
-		shaderSpotLight->diffuseColorShadowmapId.w() = (F32)shadowmapLayers[i];
-		++i;
-	}
+		// Done
+		threadPool.waitForAllJobsToFinish();
 
 
-	spotLightsUbo.unmap();
+		// Set shadow layer IDs
+		U32 i = 0;
+		ShaderSpotLight* shaderSpotLight = 
+			shaderSpotLights + spotsNoShadowCount;
+
+		for(; shaderSpotLight != shaderSpotLights + visibleSpotLightsCount;
+			++shaderSpotLight)
+		{
+			shaderSpotLight->diffuseColorShadowmapId.w() = 
+				(F32)shadowmapLayers[i];
+			++i;
+		}
+
+		spotLightsUbo.unmap();
+	}
 
 
 	//
 	//
 	// Update the tiles UBO
 	// Update the tiles UBO

+ 24 - 23
src/renderer/MainRenderer.cpp

@@ -67,14 +67,8 @@ void MainRenderer::initGl()
 	GlStateSingleton::get().setDepthMaskEnabled(true);
 	GlStateSingleton::get().setDepthMaskEnabled(true);
 	glDepthFunc(GL_LESS);
 	glDepthFunc(GL_LESS);
 
 
-	try
-	{
-		ANKI_CHECK_GL_ERROR();
-	}
-	catch(std::exception& e)
-	{
-		throw ANKI_EXCEPTION("OpenGL initialization failed") << e;
-	}
+	// Check for error
+	ANKI_CHECK_GL_ERROR();
 }
 }
 
 
 //==============================================================================
 //==============================================================================
@@ -110,11 +104,8 @@ void MainRenderer::render(SceneGraph& scene)
 		drawQuad();
 		drawQuad();
 	}
 	}
 
 
-	GLenum glerr = glGetError();
-	if(glerr != GL_NO_ERROR)
-	{
-		throw ANKI_EXCEPTION("GL error");
-	}
+	// Check for error
+	ANKI_CHECK_GL_ERROR();
 }
 }
 
 
 //==============================================================================
 //==============================================================================
@@ -144,24 +135,34 @@ void MainRenderer::takeScreenshotTga(const char* filename)
 	fs.write((char*)tgaHeaderUncompressed, sizeof(tgaHeaderUncompressed));
 	fs.write((char*)tgaHeaderUncompressed, sizeof(tgaHeaderUncompressed));
 	fs.write((char*)&header[0], sizeof(header));
 	fs.write((char*)&header[0], sizeof(header));
 
 
-	// get the buffer
-	Vector<U8> buffer;
-	buffer.resize(getWidth() * getHeight() * 3);
+	// Create the buffers
+	U outBufferSize = getWidth() * getHeight() * 3;
+	Vector<U8> outBuffer;
+	outBuffer.resize(outBufferSize);
 
 
-	glReadPixels(0, 0, getWidth(), getHeight(), GL_RGB, GL_UNSIGNED_BYTE,
-		&buffer[0]);
+	U rgbaBufferSize = getWidth() * getHeight() * 4;
+	Vector<U8> rgbaBuffer;
+	rgbaBuffer.resize(rgbaBufferSize);
 
 
-	for(U i = 0; i < getWidth() * getHeight() * 3; i += 3)
+	// Read pixels
+	glReadPixels(0, 0, getWidth(), getHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
+		&rgbaBuffer[0]);
+
+	U j = 0;
+	for(U i = 0; i < outBufferSize; i += 3)
 	{
 	{
-		U8 temp = buffer[i];
-		buffer[i] = buffer[i + 2];
-		buffer[i + 2] = temp;
+		outBuffer[i] = rgbaBuffer[j + 2];
+		outBuffer[i + 1] = rgbaBuffer[j + 1];
+		outBuffer[i + 2] = rgbaBuffer[j];
+
+		j += 4;
 	}
 	}
 
 
-	fs.write((char*)&buffer[0], getWidth() * getHeight() * 3);
+	fs.write((char*)&outBuffer[0], outBufferSize);
 
 
 	// end
 	// end
 	fs.close();
 	fs.close();
+	ANKI_CHECK_GL_ERROR();
 }
 }
 
 
 //==============================================================================
 //==============================================================================

+ 35 - 9
src/resource/MeshLoader.cpp

@@ -41,6 +41,13 @@ void MeshLoader::load(const char* filename)
 	// Try
 	// Try
 	try
 	try
 	{
 	{
+		std::cout << filename << std::endl;
+
+		if(filename == std::string("data/maps/sponza/sponza_07.mesh"))
+		{
+			std::cout << "ahoy" << std::endl;
+		}
+
 		// Open the file
 		// Open the file
 		std::fstream file(filename, std::fstream::in | std::fstream::binary);
 		std::fstream file(filename, std::fstream::in | std::fstream::binary);
 
 
@@ -252,9 +259,9 @@ void MeshLoader::createVertTangents()
 	for(uint i = 0; i < tris.size(); i++)
 	for(uint i = 0; i < tris.size(); i++)
 	{
 	{
 		const Triangle& tri = tris[i];
 		const Triangle& tri = tris[i];
-		const int i0 = tri.vertIds[0];
-		const int i1 = tri.vertIds[1];
-		const int i2 = tri.vertIds[2];
+		const I i0 = tri.vertIds[0];
+		const I i1 = tri.vertIds[1];
+		const I i2 = tri.vertIds[2];
 		const Vec3& v0 = vertCoords[i0];
 		const Vec3& v0 = vertCoords[i0];
 		const Vec3& v1 = vertCoords[i1];
 		const Vec3& v1 = vertCoords[i1];
 		const Vec3& v2 = vertCoords[i2];
 		const Vec3& v2 = vertCoords[i2];
@@ -263,12 +270,12 @@ void MeshLoader::createVertTangents()
 		Vec2 uvedge01 = texCoords[i1] - texCoords[i0];
 		Vec2 uvedge01 = texCoords[i1] - texCoords[i0];
 		Vec2 uvedge02 = texCoords[i2] - texCoords[i0];
 		Vec2 uvedge02 = texCoords[i2] - texCoords[i0];
 
 
-
-		float det = (uvedge01.y() * uvedge02.x()) -
+		F32 det = (uvedge01.y() * uvedge02.x()) -
 			(uvedge01.x() * uvedge02.y());
 			(uvedge01.x() * uvedge02.y());
 		if(isZero(det))
 		if(isZero(det))
 		{
 		{
 			//ANKI_LOGW(getRsrcName() << ": det == " << fixed << det);
 			//ANKI_LOGW(getRsrcName() << ": det == " << fixed << det);
+			std::cout << "det sucks" << std::endl;
 			det = 0.0001;
 			det = 0.0001;
 		}
 		}
 		else
 		else
@@ -278,8 +285,13 @@ void MeshLoader::createVertTangents()
 
 
 		Vec3 t = (edge02 * uvedge01.y() - edge01 * uvedge02.y()) * det;
 		Vec3 t = (edge02 * uvedge01.y() - edge01 * uvedge02.y()) * det;
 		Vec3 b = (edge02 * uvedge01.x() - edge01 * uvedge02.x()) * det;
 		Vec3 b = (edge02 * uvedge01.x() - edge01 * uvedge02.x()) * det;
-		t.normalize();
-		b.normalize();
+		//t.normalize();
+		//b.normalize();
+
+		if(i0 == 2 || i1 == 2 || i2 == 2)
+		{
+			std::cout << "t " << t << " b " << b << std::endl;
+		}
 
 
 		vertTangents[i0] += Vec4(t, 1.0);
 		vertTangents[i0] += Vec4(t, 1.0);
 		vertTangents[i1] += Vec4(t, 1.0);
 		vertTangents[i1] += Vec4(t, 1.0);
@@ -296,12 +308,26 @@ void MeshLoader::createVertTangents()
 		const Vec3& n = vertNormals[i];
 		const Vec3& n = vertNormals[i];
 		Vec3& b = bitagents[i];
 		Vec3& b = bitagents[i];
 
 
-		//t = t - n * n.dot(t);
+		if(t == Vec3(0.0))
+		{
+			std::cout << "t zero " << i << std::endl;
+		}
+		else
+		{
+			std::cout << "t NOT zero" << std::endl;
+		}
+
+		t = t - n * n.dot(t);
 		t.normalize();
 		t.normalize();
 
 
+		if(!isZero(t.getLength() - 1.0))
+		{
+			std::cout << "t" << t << std::endl;
+		}
+
 		b.normalize();
 		b.normalize();
 
 
-		float w = ((n.cross(t)).dot(b) < 0.0) ? 1.0 : -1.0;
+		F32 w = ((n.cross(t)).dot(b) < 0.0) ? 1.0 : -1.0;
 
 
 		vertTangents[i] = Vec4(t, w);
 		vertTangents[i] = Vec4(t, w);
 	}
 	}

+ 1 - 1
src/util/CMakeLists.txt

@@ -1,4 +1,4 @@
-SET(ANKI_UTIL_SOURCES Assert.cpp BinaryStream.cpp Exception.cpp Functions.cpp Scanner.cpp StringList.cpp Filesystem.cpp Allocator.cpp Memory.cpp)
+SET(ANKI_UTIL_SOURCES Assert.cpp BinaryStream.cpp Exception.cpp Functions.cpp StringList.cpp Filesystem.cpp Allocator.cpp Memory.cpp)
 
 
 IF(ANKI_PLATFORM STREQUAL "LINUX")
 IF(ANKI_PLATFORM STREQUAL "LINUX")
 	SET(ANKI_UTIL_SOURCES ${ANKI_UTIL_SOURCES} HighRezTimerPosix.cpp FilesystemPosix.cpp)
 	SET(ANKI_UTIL_SOURCES ${ANKI_UTIL_SOURCES} HighRezTimerPosix.cpp FilesystemPosix.cpp)

+ 1 - 0
src/util/FilesystemPosix.cpp

@@ -6,6 +6,7 @@
 #include <sys/stat.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/types.h>
 #include <ftw.h>
 #include <ftw.h>
+#include <cerrno>
 
 
 namespace anki {
 namespace anki {
 
 

+ 1 - 1
src/util/Memory.cpp

@@ -142,7 +142,7 @@ void StackMemoryPool::reset()
 //==============================================================================
 //==============================================================================
 PtrSize StackMemoryPool::calcAlignSize(PtrSize size) const
 PtrSize StackMemoryPool::calcAlignSize(PtrSize size) const
 {
 {
-	return size + alignmentBytes - (size % alignmentBytes);
+	return (size + alignmentBytes - 1) & ~(alignmentBytes - 1);
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

+ 0 - 1314
src/util/Scanner.cpp

@@ -1,1314 +0,0 @@
-#include "anki/util/Scanner.h"
-#include <cstring>
-#include <iostream>
-#include <iomanip>
-#include <cmath>
-#include <sstream>
-#include <cassert>
-
-namespace anki { namespace scanner {
-
-//==============================================================================
-Exception::Exception(const std::string& err, int errNo_,
-	const std::string& scriptFilename_, int scriptLineNmbr_)
-	: error(err), errNo(errNo_), scriptFilename(scriptFilename_),
-		scriptLineNmbr(scriptLineNmbr_)
-{}
-
-//==============================================================================
-Exception::Exception(const Exception& e)
-	: std::exception(e), error(e.error), errNo(e.errNo),
-		scriptFilename(e.scriptFilename), scriptLineNmbr(e.scriptLineNmbr)
-{}
-
-//==============================================================================
-const char* Exception::what() const throw()
-{
-	errWhat = "Scanner exception (#" 
-		+ std::to_string(errNo) 
-		+ ":" + scriptFilename + ':' 
-		+ std::to_string(scriptLineNmbr) + "): " + error;
-	return errWhat.c_str();
-}
-
-//==============================================================================
-Token::Token(const Token& b)
-	: code(b.code), dataType(b.dataType)
-{
-	switch(b.dataType)
-	{
-		case DT_FLOAT:
-			value.float_ = b.value.float_;
-			break;
-		case DT_INT:
-			value.int_ = b.value.int_;
-			break;
-		case DT_CHAR:
-			value.char_ = b.value.char_;
-			break;
-		case DT_STR:
-			value.string = b.value.string;
-			break;
-	}
-	memcpy(&asString[0], &b.asString[0], sizeof(asString));
-}
-
-//==============================================================================
-std::ostream& operator<<(std::ostream& s, const Token& x)
-{
-	const TokenDataVal& val = x.getValue();
-	TokenCode code = x.getCode();
-
-	switch(code)
-	{
-		case TC_COMMENT:
-			s << "comment";
-			break;
-		case TC_NEWLINE:
-			s << "newline";
-			break;
-		case TC_END:
-			s << "end of file";
-			break;
-		case TC_STRING:
-			s << "string \"" << val.getString() << "\"";
-			break;
-		case TC_CHARACTER:
-			s << "char '" << val.getChar() << "' (\"" <<
-				x.getString() << "\")";
-			break;
-		case TC_NUMBER:
-			if(x.getDataType() == DT_FLOAT)
-			{
-				s << "float " << val.getFloat() << " (\"" << x.getString() <<
-					"\")";
-			}
-			else
-			{
-				s << "int " << val.getInt() << " (\"" <<
-					x.getString() << "\")";
-			}
-			break;
-		case TC_IDENTIFIER:
-			s << "identifier \"" << val.getString() << "\"";
-			break;
-		case TC_ERROR:
-			s << "scanner error";
-			break;
-		default:
-			if(code >= TC_KE && code <= TC_KEYWORD)
-			{
-				s << "reserved word \"" << val.getString() << "\"";
-			}
-			else if(code >= TC_SCOPE_RESOLUTION && code <= TC_ASSIGN_OR)
-			{
-				s << "operator no " << (code - TC_SCOPE_RESOLUTION);
-			}
-	}
-
-	return s;
-}
-
-//==============================================================================
-std::string Token::getInfoString() const
-{
-	std::stringstream ss;
-	ss << *this;
-	return ss.str();
-}
-
-//==============================================================================
-
-#define SCANNER_EXCEPTION(x) \
-	Exception(std::string() + x, __LINE__, scriptName, lineNmbr)
-
-char Scanner::eofChar = 0x7F;
-
-// reserved words grouped by length
-Scanner::ResWord Scanner::rw2 [] =
-{
-	{"ke", TC_KE}, {NULL, TC_ERROR}
-};
-
-Scanner::ResWord Scanner::rw3 [] =
-{
-	{"key", TC_KEY}, {NULL, TC_ERROR}
-};
-
-Scanner::ResWord Scanner::rw4 [] =
-{
-	{"keyw", TC_KEYW}, {NULL, TC_ERROR}
-};
-
-Scanner::ResWord Scanner::rw5 [] =
-{
-	{"keywo", TC_KEYWO}, {NULL, TC_ERROR}
-};
-
-Scanner::ResWord Scanner::rw6 [] =
-{
-	{"keywor", TC_KEYWOR}, {NULL, TC_ERROR}
-};
-
-Scanner::ResWord Scanner::rw7 [] =
-{
-	{"keyword", TC_KEYWORD}, {NULL, TC_ERROR}
-};
-
-Scanner::ResWord* Scanner::rwTable [] =  // reserved word table
-{
-	NULL, NULL, rw2, rw3, rw4, rw5, rw6, rw7,
-};
-
-// ascii table
-Scanner::AsciiFlag Scanner::asciiLookupTable [128] = {AC_ERROR};
-
-//==============================================================================
-Scanner::Scanner(bool newlinesAsWhitespace)
-{
-	strcpy(scriptName, "unnamed-script");
-	init(newlinesAsWhitespace);
-}
-
-//==============================================================================
-Scanner::Scanner(const char* filename, bool newlinesAsWhitespace)
-{
-	strcpy(scriptName, "unnamed-script");
-	init(newlinesAsWhitespace);
-	loadFile(filename);
-}
-
-//==============================================================================
-Scanner::Scanner(std::istream& istream_, const char* scriptName_,
-	bool newlinesAsWhitespace)
-{
-	strcpy(scriptName, "unnamed-script");
-	init(newlinesAsWhitespace);
-	loadIstream(istream_, scriptName_);
-}
-
-//==============================================================================
-void Scanner::initAsciiMap()
-{
-	memset(&asciiLookupTable[0], AC_ERROR, sizeof(asciiLookupTable));
-	for(uint x = 'a'; x <= 'z'; x++)
-	{
-		lookupAscii(x) = AC_LETTER;
-	}
-
-	for(uint x = 'A'; x <= 'Z'; x++)
-	{
-		lookupAscii(x) = AC_LETTER;
-	}
-
-	for(uint x = '0'; x <= '9'; x++)
-	{
-		lookupAscii(x) = AC_DIGIT;
-	}
-
-	lookupAscii(':') = lookupAscii('[') = lookupAscii(']') =
-		lookupAscii('(') = lookupAscii(')') = lookupAscii('.') =
-		lookupAscii('{') = lookupAscii('}') = lookupAscii(',') =
-		lookupAscii(';') = lookupAscii('?') = lookupAscii('=') =
-		lookupAscii('!') = lookupAscii('<') = lookupAscii('>') =
-		lookupAscii('|') = lookupAscii('&') = lookupAscii('+') =
-		lookupAscii('-') = lookupAscii('*') = lookupAscii('/') =
-		lookupAscii('~') = lookupAscii('%') = lookupAscii('#') =
-		lookupAscii('^') = lookupAscii('\\') = AC_SPECIAL;
-
-	lookupAscii('\t') = lookupAscii(' ') = lookupAscii('\0') =
-		AC_WHITESPACE;
-	lookupAscii('\n') = AC_ERROR; // newline is unacceptable char
-
-	lookupAscii('@') = lookupAscii('`') = lookupAscii('$') =
-		AC_ACCEPTABLE_IN_COMMENTS;
-
-	lookupAscii('\"') = AC_DOUBLEQUOTE;
-	lookupAscii('\'') = AC_QUOTE;
-	lookupAscii((int)eofChar) = AC_EOF;
-	lookupAscii('_') = AC_LETTER;
-}
-
-//==============================================================================
-void Scanner::init(bool newlinesAsWhitespace_)
-{
-	newlinesAsWhitespace = newlinesAsWhitespace_;
-	commentedLines = 0;
-	inStream = NULL;
-
-	if(lookupAscii('a') != AC_LETTER)
-	{
-		initAsciiMap();
-	}
-
-	lineNmbr = 0;
-	memset(line, eofChar, sizeof(char) * MAX_SCRIPT_LINE_LEN);
-}
-
-//==============================================================================
-void Scanner::getLine()
-{
-	if(!inStream->getline(line, MAX_SCRIPT_LINE_LEN - 1, '\n'))
-	{
-		pchar = &eofChar;
-	}
-	else
-	{
-		pchar = &line[0];
-		++lineNmbr;
-	}
-
-	assert(inStream->gcount() <= MAX_SCRIPT_LINE_LEN - 10); // too big line
-}
-
-//==============================================================================
-char Scanner::getNextChar()
-{
-	if(*pchar=='\0')
-	{
-		getLine();
-	}
-	else
-	{
-		++pchar;
-	}
-
-	if(*pchar == '\r') // windows crap
-	{
-		*pchar = '\0';
-	}
-	else if(lookupAscii(*pchar) == AC_ERROR)
-	{
-		throw SCANNER_EXCEPTION("Unacceptable char '" + *pchar + "' 0x" +
-			std::to_string(static_cast<uint>(*pchar)));
-	}
-
-	return *pchar;
-}
-
-//==============================================================================
-char Scanner::putBackChar()
-{
-	if(pchar != line && *pchar != eofChar)
-	{
-		--pchar;
-	}
-
-	return *pchar;
-}
-
-//==============================================================================
-void Scanner::loadFile(const char* filename_)
-{
-	inFstream.open(filename_);
-	if(!inFstream.is_open())
-	{
-		throw SCANNER_EXCEPTION("Cannot open file \"" + filename_ + '\"');
-	}
-
-	loadIstream(inFstream, filename_);
-}
-
-//==============================================================================
-void Scanner::loadIstream(std::istream& istream_, const char* scriptName_)
-{
-	if(inStream != NULL)
-	{
-		throw SCANNER_EXCEPTION("Tokenizer already initialized");
-	}
-
-	inStream = &istream_;
-
-	// init globals
-
-	// Too big name
-	assert(strlen(scriptName_) <= sizeof(scriptName) / sizeof(char) - 1);
-	crntToken.code = TC_ERROR;
-	lineNmbr = 0;
-	strcpy(scriptName, scriptName_);
-
-	getLine();
-}
-
-//==============================================================================
-void Scanner::unload()
-{
-	inFstream.close();
-}
-
-//==============================================================================
-const Token& Scanner::getNextToken()
-{
-	start:
-
-	//if(crntToken.code == TC_NEWLINE) getNextChar();
-
-	if(commentedLines>0)
-	{
-		crntToken.code = TC_NEWLINE;
-		--commentedLines;
-		// the ultimate hack. I should remember not to do such crap in the
-		// future
-		++lineNmbr;
-	}
-	else if(*pchar == '/')
-	{
-		char ch = getNextChar();
-		if(ch == '/' || ch == '*')
-		{
-			putBackChar();
-			int line = getLineNumber();
-			checkComment();
-
-			commentedLines = getLineNumber() - line; // update commentedLines
-			lineNmbr -= commentedLines; // part of the ultimate hack
-		}
-		else
-		{
-			putBackChar();
-			goto crappyLabel;
-		}
-	}
-	else if(*pchar == '.')
-	{
-		uint asc = lookupAscii(getNextChar());
-		putBackChar();
-		if(asc == AC_DIGIT)
-		{
-			checkNumber();
-		}
-		else
-		{
-			checkSpecial();
-		}
-	}
-	else if(*pchar=='\0') // if newline
-	{
-		if(lookupAscii(getNextChar()) == AC_EOF)
-		{
-			crntToken.code = TC_END;
-		}
-		else
-		{
-			crntToken.code = TC_NEWLINE;
-		}
-	}
-	else
-	{
-		crappyLabel:
-		switch(lookupAscii(*pchar))
-		{
-			case AC_WHITESPACE :
-				getNextChar();
-				goto start;
-			case AC_LETTER:
-				checkWord();
-				break;
-			case AC_DIGIT:
-				checkNumber();
-				break;
-			case AC_SPECIAL:
-				checkSpecial();
-				break;
-			case AC_QUOTE:
-				checkChar();
-				break;
-			case AC_DOUBLEQUOTE:
-				checkString();
-				break;
-			case AC_EOF:
-				crntToken.code = TC_END;
-				break;
-			case AC_ERROR:
-			default:
-				getNextChar();
-				throw SCANNER_EXCEPTION("Unexpected character \'" + *pchar +
-					'\'');
-				goto start;
-		}
-	}
-
-	// skip comments
-	if(crntToken.code == TC_COMMENT)
-	{
-		goto start;
-	}
-	// skip newlines
-	if(crntToken.code == TC_NEWLINE && newlinesAsWhitespace)
-	{
-		goto start;
-	}
-
-	return crntToken;
-}
-
-//==============================================================================
-void Scanner::checkWord()
-{
-	char* tmpStr = &crntToken.asString[0];
-	char ch = *pchar;
-
-	//build the string
-	do
-	{
-		*tmpStr++ = ch;
-		ch = getNextChar();
-	} while(lookupAscii(ch) == AC_LETTER || lookupAscii(ch) == AC_DIGIT);
-
-	*tmpStr = '\0'; // finalize it
-
-	//check if reserved
-	int len = tmpStr - &crntToken.asString[0];
-	crntToken.code = TC_IDENTIFIER;
-	crntToken.value.string = &crntToken.asString[0];
-	crntToken.dataType = DT_STR; // not important
-
-	if(len <= 7 && len >= 2)
-	{
-		int x = 0;
-		while(true)
-		{
-			if(rwTable[len][x].string == NULL)
-			{
-				break;
-			}
-
-			if(strcmp(rwTable[len][x].string, &crntToken.asString[0]) == 0)
-			{
-				crntToken.code = rwTable[len][x].code;
-				break;
-			}
-			++x;
-		}
-	}
-}
-
-//==============================================================================
-void Scanner::checkComment()
-{
-	// Beginning
-	if(getNextChar()=='*')
-	{
-		goto cStyleCmnt;
-	}
-	// C++ style comment
-	else if(*pchar=='/')
-	{
-		while(true)
-		{
-			char ch = getNextChar();
-			if(ch == '\0')
-			{
-				crntToken.code = TC_COMMENT;
-				return;
-			}
-			else if(ch == '\\')
-			{
-				if(getNextChar() == '\0')
-				{
-					getNextChar();
-				}
-			}
-		}
-	}
-	else
-	{
-		goto error;
-	}
-
-	// C style comment
-	cStyleCmnt:
-		if(getNextChar()=='*')
-		{
-			goto finalizeCCmnt;
-		}
-		else if(*pchar==eofChar)
-		{
-			goto error;
-		}
-		else
-		{
-			goto cStyleCmnt;
-		}
-
-	// C++ style comment
-	finalizeCCmnt:
-		if(getNextChar()=='/')
-		{
-			crntToken.code = TC_COMMENT;
-			getNextChar();
-			return;
-		}
-		else
-		{
-			goto cStyleCmnt;
-		}
-
-	//error
-	error:
-		crntToken.code = TC_ERROR;
-		throw SCANNER_EXCEPTION("Incorrect comment ending");
-}
-
-//==============================================================================
-void Scanner::checkNumber()
-{
-	// This func is working great, dont try to understand it and dont even
-	// think to try touching it.
-
-	//RASSERT_THROW_EXCEPTION(sizeof(long) != 8); // ulong must be 64bit
-	long num = 0;     // value of the number & part of the float num before '.'
-	long fnum = 0;    // part of the float num after '.'
-	long dad = 0;     // digits after dot (for floats)
-	bool expSign = 0; // exponent sign in case float is represented in mant/exp
-	                  // format. 0 means positive and 1 negative
-	long exp = 0;     // the exponent in case float is represented in mant/exp
-	                  // format
-	char* tmpStr = &crntToken.asString[0];
-	crntToken.dataType = DT_INT;
-	uint asc;
-
-	// begin
-		if(*pchar == '0')
-		{
-			goto _0;
-		}
-		else if(lookupAscii(*pchar) == AC_DIGIT)
-		{
-			num = num*10 + *pchar-'0';
-			goto _0_9;
-		}
-		else if (*pchar == '.')
-		{
-			goto _float;
-		}
-		else
-		{
-			goto error;
-		}
-
-	// 0????
-	_0:
-		*tmpStr++ = *pchar;
-		getNextChar();
-		asc = lookupAscii(*pchar);
-		if (*pchar == 'x' || *pchar == 'X')
-		{
-			goto _0x;
-		}
-		else if(*pchar == 'e' || *pchar == 'E')
-		{
-			goto _0_9_dot_0_9_e;
-		}
-		else if(asc == AC_DIGIT)
-		{
-			putBackChar();
-			goto _0_9;
-		}
-		else if(*pchar == '.')
-		{
-			goto _float;
-		}
-		else if(asc == AC_SPECIAL || asc == AC_WHITESPACE || asc == AC_EOF)
-		{
-			goto finalize;
-		}
-		else
-		{
-			goto error;
-		}
-
-	// 0x????
-	_0x:
-		*tmpStr++ = *pchar;
-		getNextChar();
-		asc = lookupAscii(*pchar);
-		if((asc == AC_DIGIT)  ||
-				(*pchar >= 'a' && *pchar <= 'f') ||
-				(*pchar >= 'A' && *pchar <= 'F'))
-		{
-			num <<= 4;
-			if(*pchar>='a' && *pchar<='f')
-			{
-				num += *pchar - 'a' + 0xA;
-			}
-			else if(*pchar>='A' && *pchar<='F')
-			{
-				num += *pchar - 'A' + 0xA;
-			}
-			else
-			{
-				num += *pchar - '0';
-			}
-
-			goto _0x0_9orA_F;
-		}
-		else
-			goto error;
-
-	// 0x{0-9 || a-f}??
-	_0x0_9orA_F:
-		*tmpStr++ = *pchar;
-		getNextChar();
-		asc = lookupAscii(*pchar);
-		if((asc == AC_DIGIT)         ||
-				(*pchar >= 'a' && *pchar <= 'f') ||
-				(*pchar >= 'A' && *pchar <= 'F'))
-		{
-			num <<= 4;
-			if(*pchar>='a' && *pchar<='f')
-			{
-				num += *pchar - 'a' + 0xA;
-			}
-			else if(*pchar>='A' && *pchar<='F')
-			{
-				num += *pchar - 'A' + 0xA;
-			}
-			else
-			{
-				num += *pchar - '0';
-			}
-
-			goto _0x0_9orA_F;
-		}
-		else if(asc == AC_SPECIAL || asc == AC_WHITESPACE || asc == AC_EOF)
-		{
-			goto finalize;
-		}
-		else
-		{
-			goto error; // err
-		}
-
-	// {0-9}
-	_0_9:
-		*tmpStr++ = *pchar;
-		getNextChar();
-		asc = lookupAscii(*pchar);
-		if(asc == AC_DIGIT)
-		{
-			num = num * 10 + *pchar - '0';
-			goto _0_9;
-		}
-		else if(*pchar == 'e' || *pchar == 'E')
-		{
-			goto _0_9_dot_0_9_e;
-		}
-		else if(*pchar == '.')
-		{
-			goto _float;
-		}
-		else if(asc == AC_SPECIAL || asc == AC_WHITESPACE || asc == AC_EOF)
-		{
-			goto finalize;
-		}
-		else
-		{
-			goto error; // err
-		}
-
-	// {0-9}.??
-	_float:
-		*tmpStr++ = *pchar;
-		getNextChar();
-		asc = lookupAscii(*pchar);
-		crntToken.dataType = DT_FLOAT;
-		if(asc == AC_DIGIT)
-		{
-			fnum = fnum * 10 + *pchar - '0';
-			++dad;
-			goto _float;
-		}
-		else if(*pchar == '.')
-		{
-			*tmpStr++ = *pchar;
-			getNextChar();
-			goto error;
-		}
-		else if(*pchar == 'f' || *pchar == 'F')
-		{
-			goto _0_9_dot_0_9_f;
-		}
-		else if(*pchar == 'e' || *pchar == 'E')
-		{
-			goto _0_9_dot_0_9_e;
-		}
-		else if(asc == AC_SPECIAL || asc == AC_WHITESPACE || asc == AC_EOF)
-		{
-			goto finalize;
-		}
-		else
-		{
-			goto error;
-		}
-
-	// [{0-9}].[{0-9}]f??
-	_0_9_dot_0_9_f:
-		*tmpStr++ = *pchar;
-		getNextChar();
-		asc = lookupAscii(*pchar);
-
-		if(asc == AC_SPECIAL || asc == AC_WHITESPACE || asc == AC_EOF)
-		{
-			goto finalize;
-		}
-		else
-		{
-			goto error;
-		}
-
-	// [{0-9}].[{0-9}]e??
-	_0_9_dot_0_9_e:
-		*tmpStr++ = *pchar;
-		getNextChar();
-		asc = lookupAscii(*pchar);
-		crntToken.dataType = DT_FLOAT;
-
-		if(*pchar == '+' || *pchar == '-')
-		{
-			if(*pchar == '-') expSign = 1;
-			//*tmpStr++ = *pchar; getNextChar();
-			goto _0_9_dot_0_9_e_sign;
-		}
-		else if(asc == AC_DIGIT)
-		{
-			exp = exp * 10 + *pchar - '0';
-			goto _0_9_dot_0_9_e_sign_0_9;
-		}
-		else
-		{
-			goto error;
-		}
-
-	// [{0-9}].[{0-9}]e{+,-}??
-	// After the sign we want number
-	_0_9_dot_0_9_e_sign:
-		*tmpStr++ = *pchar;
-		getNextChar();
-		asc = lookupAscii(*pchar);
-
-		if(asc == AC_DIGIT)
-		{
-			exp = exp * 10 + *pchar - '0';
-			goto _0_9_dot_0_9_e_sign_0_9;
-		}
-		else
-		{
-			goto error;
-		}
-
-	// [{0-9}].[{0-9}]e{+,-}{0-9}??
-	// After the number in exponent we want other number or we finalize
-	_0_9_dot_0_9_e_sign_0_9:
-		*tmpStr++ = *pchar;
-		getNextChar();
-		asc = lookupAscii(*pchar);
-
-		if(asc == AC_DIGIT)
-		{
-			exp = exp * 10 + *pchar - '0';
-			goto _0_9_dot_0_9_e_sign_0_9;
-		}
-		else if(asc == AC_SPECIAL || asc == AC_WHITESPACE || asc == AC_EOF)
-		{
-			goto finalize;
-		}
-		else
-		{
-			goto error;
-		}
-
-	// finalize
-	finalize:
-		crntToken.code = TC_NUMBER;
-
-		if(crntToken.dataType == DT_INT)
-		{
-			crntToken.value.int_ = num;
-		}
-		else
-		{
-			double dbl = (double)num + (double)(pow(10, -dad)*fnum);
-			if(exp != 0) // if we have exponent
-			{
-				if(expSign == true)
-				{
-					exp = -exp; // change the sign if necessary
-				}
-				dbl = dbl * pow(10, exp);
-			}
-
-			crntToken.value.float_ = dbl;
-		}
-		*tmpStr = '\0';
-		return;
-
-	//error
-	error:
-		crntToken.code = TC_ERROR;
-
-		// run until white space or special
-		asc = lookupAscii(*pchar);
-		while(asc!=AC_WHITESPACE && asc!=AC_SPECIAL && asc!=AC_EOF)
-		{
-			*tmpStr++ = *pchar;
-			asc = lookupAscii(getNextChar());
-		}
-
-		*tmpStr = '\0';
-		throw SCANNER_EXCEPTION("Bad number suffix \"" +
-			&crntToken.asString[0] + '\"');
-}
-
-//==============================================================================
-void Scanner::checkString()
-{
-	char* tmpStr = &crntToken.asString[0];
-	char ch = getNextChar();
-
-	for(;;)
-	{
-		// Error
-		if(ch == '\0' || ch == eofChar) // if end of line or eof
-		{
-			crntToken.code = TC_ERROR;
-			*tmpStr = '\0';
-			throw SCANNER_EXCEPTION("Incorrect string ending \"" +
-				&crntToken.asString[0] + '\"');
-			return;
-		}
-		// Escape Codes
-		else if(ch == '\\')
-		{
-			ch = getNextChar();
-			if(ch == eofChar)
-			{
-				crntToken.code = TC_ERROR;
-				*tmpStr = '\0';
-				throw SCANNER_EXCEPTION("Incorrect string ending \"" +
-					&crntToken.asString[0] + '\"');
-				return;
-			}
-
-			switch(ch)
-			{
-				case 'n':
-					*tmpStr++ = '\n';
-					break;
-				case 't':
-					*tmpStr++ = '\t';
-					break;
-				case '0':
-					*tmpStr++ = '\0';
-					break;
-				case 'a':
-					*tmpStr++ = '\a';
-					break;
-				case '\"':
-					*tmpStr++ = '\"';
-					break;
-				case 'f':
-					*tmpStr++ = '\f';
-					break;
-				case 'v':
-					*tmpStr++ = '\v';
-					break;
-				case '\'':
-					*tmpStr++ = '\'';
-					break;
-				case '\\':
-					*tmpStr++ = '\\';
-					break;
-				case '\?':
-					*tmpStr++ = '\?';
-					break;
-				case '\0':
-					break; // not an escape char but works almost the same
-				default:
-					throw SCANNER_EXCEPTION(
-						"Unrecognized escape character \'\\" + ch + '\'');
-					*tmpStr++ = ch;
-			}
-		}
-		// End
-		else if(ch=='\"')
-		{
-			*tmpStr = '\0';
-			crntToken.code = TC_STRING;
-			crntToken.value.string = &crntToken.asString[0];
-			getNextChar();
-			return;
-		}
-		// Build str(main loop)
-		else
-		{
-			*tmpStr++ = ch;
-		}
-
-		ch = getNextChar();
-	}
-}
-
-//==============================================================================
-void Scanner::checkChar()
-{
-	char ch = getNextChar();
-	char ch0 = ch;
-	char* tmpStr = &crntToken.asString[0];
-
-	crntToken.code = TC_ERROR;
-	*tmpStr++ = ch;
-
-	if(ch=='\0' || ch==eofChar) // check char after '
-	{
-		throw SCANNER_EXCEPTION("Newline in constant");
-		return;
-	}
-
-	if (ch=='\'') // if '
-	{
-		throw SCANNER_EXCEPTION("Empty constant");
-		getNextChar();
-		return;
-	}
-
-	if (ch=='\\')                // if \ then maybe escape char
-	{
-		ch = getNextChar();
-		*tmpStr++ = ch;
-		if(ch == '\0' || ch == eofChar) //check again after the \.
-		{
-			throw SCANNER_EXCEPTION("Newline in constant");
-		}
-
-		switch (ch)
-		{
-			case 'n' :
-				ch0 = '\n';
-				break;
-			case 't' :
-				ch0 = '\t';
-				break;
-			case '0':
-				ch0 = '\0';
-				break;
-			case 'a':
-				ch0 = '\a';
-				break;
-			case '\"':
-				ch0 = '\"';
-				break;
-			case 'f':
-				ch0 = '\f';
-				break;
-			case 'v':
-				ch0 = '\v';
-				break;
-			case '\'':
-				ch0 = '\'';
-				break;
-			case '\\':
-				ch0 = '\\';
-				break;
-			case '\?':
-				ch0 = '\?';
-				break;
-			case 'r':
-				ch0 = '\r';
-				break;
-			default:
-				ch0 = ch;
-				throw SCANNER_EXCEPTION("Unrecognized escape character \'\\" +
-					ch + '\'');
-		}
-		crntToken.value.char_ = ch0;
-	}
-	else
-	{
-		crntToken.value.char_ = ch;
-	}
-
-	ch = getNextChar();
-	if(ch=='\'')    //end
-	{
-		*tmpStr = '\0';
-		crntToken.code = TC_CHARACTER;
-		getNextChar();
-		return;
-	}
-
-	throw SCANNER_EXCEPTION("Expected \'");
-}
-
-//==============================================================================
-void Scanner::checkSpecial()
-{
-	char ch = *pchar;
-	TokenCode code = TC_ERROR;
-
-	switch(ch)
-	{
-		case '#':
-			code = TC_SHARP;
-			break;
-		case ',':
-			code = TC_COMMA;
-			break;
-		case ';':
-			code = TC_PERIOD;
-			break;
-		case '(':
-			code = TC_L_PAREN;
-			break;
-		case ')':
-			code = TC_R_PAREN;
-			break;
-		case '[':
-			code = TC_L_SQ_BRACKET;
-			break;
-		case ']':
-			code = TC_R_SQ_BRACKET;
-			break;
-		case '{':
-			code = TC_L_BRACKET;
-			break;
-		case '}':
-			code = TC_R_BRACKET;
-			break;
-		case '?':
-			code = TC_QUESTIONMARK;
-			break;
-		case '~':
-			code = TC_UNARAY_COMPLEMENT;
-			break;
-		case '.':
-			ch = getNextChar();
-			switch(ch)
-			{
-				case '*':
-					code = TC_POINTER_TO_MEMBER;
-					break;
-				default:
-					putBackChar();
-					code = TC_DOT;
-			}
-			break;
-
-		case ':':
-			ch = getNextChar();
-			switch(ch)
-			{
-				case ':':
-					code = TC_SCOPE_RESOLUTION;
-					break;
-				default:
-					putBackChar();
-					code = TC_UPDOWNDOT;
-			}
-			break;
-
-		case '-':
-			ch = getNextChar();
-			switch(ch)
-			{
-				case '>':
-					code = TC_POINTER_TO_MEMBER;
-					break;
-				case '-':
-					code = TC_DEC;
-					break;
-				case '=':
-					code = TC_ASSIGN_SUB;
-					break;
-				default:
-					putBackChar();
-					code = TC_MINUS;
-			}
-			break;
-
-		case '=':
-			ch = getNextChar();
-			switch(ch)
-			{
-				case '=':
-					code = TC_EQUAL;
-					break;
-				default:
-					putBackChar();
-					code = TC_ASSIGN;
-			}
-			break;
-
-		case '!':
-			ch = getNextChar();
-			switch(ch)
-			{
-				case '=':
-					code = TC_NOT_EQUAL;
-					break;
-				default:
-					putBackChar();
-					code = TC_NOT;
-			}
-			break;
-
-		case '<':
-			ch = getNextChar();
-			switch(ch)
-			{
-				case '=':
-					code = TC_LESS_EQUAL;
-					break;
-				case '<':
-					ch = getNextChar();
-					switch(ch)
-					{
-						case '=':
-							code = TC_ASSIGN_SHL;
-							break;
-						default:
-							putBackChar();
-							code = TC_SHL;
-					}
-					break;
-				default:
-					putBackChar();
-					code = TC_LESS;
-			}
-			break;
-
-		case '>':
-			ch = getNextChar();
-			switch(ch)
-			{
-				case '=':
-					code = TC_GREATER_EQUAL;
-					break;
-				case '>':
-					ch = getNextChar();
-					switch(ch)
-					{
-						case '=':
-							code = TC_ASSIGN_SHR;
-							break;
-						default:
-							putBackChar();
-							code = TC_SHR;
-					}
-					break;
-				default:
-					putBackChar();
-					code = TC_GREATER;
-			}
-			break;
-
-		case '|':
-			ch = getNextChar();
-			switch(ch)
-			{
-				case '|':
-					code = TC_LOGICAL_OR;
-					break;
-				case '=':
-					code = TC_ASSIGN_OR;
-					break;
-				default:
-					putBackChar();
-					code = TC_BITWISE_OR;
-			}
-			break;
-
-		case '&':
-			ch = getNextChar();
-			switch(ch)
-			{
-				case '&':
-					code = TC_LOGICAL_AND;
-					break;
-				case '=':
-					code = TC_ASSIGN_AND;
-					break;
-				default:
-					putBackChar();
-					code = TC_BITWISE_AND;
-			}
-			break;
-
-		case '+':
-			ch = getNextChar();
-			switch(ch)
-			{
-				case '+':
-					code = TC_INC;
-					break;
-				case '=':
-					code = TC_ASSIGN_ADD;
-					break;
-				default:
-					putBackChar();
-					code = TC_PLUS;
-			}
-			break;
-
-		case '*':
-			ch = getNextChar();
-			switch(ch)
-			{
-				case '=':
-					code = TC_ASSIGN_MUL;
-					break;
-				default:
-					putBackChar();
-					code = TC_STAR;
-			}
-			break;
-
-		case '/':
-			ch = getNextChar();
-			switch(ch)
-			{
-				case '=':
-					code = TC_ASSIGN_DIV;
-					break;
-				default:
-					putBackChar();
-					code = TC_BSLASH;
-			}
-			break;
-
-		case '%':
-			ch = getNextChar();
-			switch(ch)
-			{
-				case '=':
-					code = TC_ASSIGN_MOD;
-					break;
-				default:
-					putBackChar();
-					code = TC_MOD;
-			}
-			break;
-
-		case '^':
-			ch = getNextChar();
-			switch(ch)
-			{
-				case '=':
-					code = TC_ASSIGN_XOR;
-					break;
-				default:
-					putBackChar();
-					code = TC_XOR;
-			}
-			break;
-
-		case '\\':
-			code = TC_BACK_SLASH;
-			break;
-	}
-
-	getNextChar();
-	crntToken.code = code;
-}
-
-}} // end namespaces

+ 2 - 4
testapp/Main.cpp

@@ -287,7 +287,7 @@ void init()
 	const F32 distPerSec = 2.0;
 	const F32 distPerSec = 2.0;
 	scene.getEventManager().newFollowPathEvent(-1.0, 
 	scene.getEventManager().newFollowPathEvent(-1.0, 
 		path->getDistance() / distPerSec, 
 		path->getDistance() / distPerSec, 
-		cam, path, distPerSec);
+		horse, path, distPerSec);
 }
 }
 
 
 //==============================================================================
 //==============================================================================
@@ -534,7 +534,7 @@ void initSubsystems(int argc, char* argv[])
 	initializer.ms.ez.enabled = true;
 	initializer.ms.ez.enabled = true;
 	initializer.dbg.enabled = false;
 	initializer.dbg.enabled = false;
 	initializer.is.sm.bilinearEnabled = true;
 	initializer.is.sm.bilinearEnabled = true;
-	initializer.is.groundLightEnabled = true;
+	initializer.is.groundLightEnabled = false;
 	initializer.is.sm.enabled = true;
 	initializer.is.sm.enabled = true;
 	initializer.is.sm.pcfEnabled = false;
 	initializer.is.sm.pcfEnabled = false;
 	initializer.is.sm.resolution = 512;
 	initializer.is.sm.resolution = 512;
@@ -570,8 +570,6 @@ int main(int argc, char* argv[])
 {
 {
 	int exitCode;
 	int exitCode;
 
 
-	std::cout << sizeof(Spatial) << std::endl;
-
 	try
 	try
 	{
 	{
 		initSubsystems(argc, argv);
 		initSubsystems(argc, argv);