Integrated new version of the Visualization modules:

From change List number 20662.
p4#: 20667
This commit is contained in:
Jacob Støren 2013-02-28 11:37:32 +01:00
parent 1a05676551
commit 5a84a12864
39 changed files with 3071 additions and 264 deletions

View File

@ -14,6 +14,7 @@ cvfAssert.h
cvfBase.h cvfBase.h
cvfBase64.h cvfBase64.h
cvfCharArray.h cvfCharArray.h
cvfCodeLocation.h
cvfCollection.h cvfCollection.h
cvfCollection.inl cvfCollection.inl
cvfColor3.h cvfColor3.h
@ -24,6 +25,11 @@ cvfFlags.h
cvfFlags.inl cvfFlags.inl
cvfFunctorRange.h cvfFunctorRange.h
cvfLibCore.h cvfLibCore.h
cvfLogDestination.h
cvfLogDestinationConsole.h
cvfLogDestinationFile.h
cvfLogEvent.h
cvfLogManager.h
cvfLogger.h cvfLogger.h
cvfMath.h cvfMath.h
cvfMath.inl cvfMath.inl
@ -31,6 +37,7 @@ cvfMatrix3.h
cvfMatrix3.inl cvfMatrix3.inl
cvfMatrix4.h cvfMatrix4.h
cvfMatrix4.inl cvfMatrix4.inl
cvfMutex.h
cvfObject.h cvfObject.h
cvfObject.inl cvfObject.inl
cvfPlane.h cvfPlane.h
@ -60,11 +67,17 @@ set(CEE_SOURCE_FILES
cvfAssert.cpp cvfAssert.cpp
cvfBase64.cpp cvfBase64.cpp
cvfCharArray.cpp cvfCharArray.cpp
cvfCodeLocation.cpp
cvfColor3.cpp cvfColor3.cpp
cvfColor4.cpp cvfColor4.cpp
cvfDebugTimer.cpp cvfDebugTimer.cpp
cvfLogDestinationConsole.cpp
cvfLogDestinationFile.cpp
cvfLogEvent.cpp
cvfLogManager.cpp
cvfLogger.cpp cvfLogger.cpp
cvfMath.cpp cvfMath.cpp
cvfMutex.cpp
cvfObject.cpp cvfObject.cpp
cvfPlane.cpp cvfPlane.cpp
cvfPropertySet.cpp cvfPropertySet.cpp

View File

@ -0,0 +1,163 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfCodeLocation.h"
#include <algorithm>
#include <cstring>
namespace cvf {
//==================================================================================================
///
/// \class cvf::CodeLocation
/// \ingroup Core
///
/// Represents a source code location.
///
/// Typically used with logging, asserts etc. Typically initialized using built-in compiler macros
/// such as __FILE__ and __LINE__.
///
/// Note that the strings parameters for file name and function must be a static strings with a
/// lifetime that's longer than the lifetime of the CodeLocation object
///
//==================================================================================================
static const char* const EMPTY_STRING = "";
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
CodeLocation::CodeLocation()
: m_fileName(EMPTY_STRING),
m_functionName(EMPTY_STRING),
m_lineNumber(-1)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
CodeLocation::CodeLocation(const char* fileName, const char* functionName, int lineNumber)
: m_fileName(fileName),
m_functionName(functionName),
m_lineNumber(lineNumber)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
CodeLocation::CodeLocation(const CodeLocation& other)
: m_fileName(other.m_fileName),
m_functionName(other.m_functionName),
m_lineNumber(other.m_lineNumber)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const CodeLocation& CodeLocation::operator=(CodeLocation rhs)
{
// Copy-and-swap (copy already done since parameter is passed by value)
rhs.swap(*this);
return *this;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const char* CodeLocation::fileName() const
{
return m_fileName ? m_fileName : EMPTY_STRING;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const char* CodeLocation::shortFileName() const
{
if (m_fileName)
{
const char* ptrToLastSlash = strrchr(m_fileName, '/');
#ifdef WIN32
const char* ptrToLastBwdSlash = strrchr(m_fileName, '\\');
if (ptrToLastBwdSlash > ptrToLastSlash)
{
ptrToLastSlash = ptrToLastBwdSlash;
}
#endif
if (ptrToLastSlash)
{
return ptrToLastSlash + 1;
}
else
{
return m_fileName;
}
}
else
{
return EMPTY_STRING;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const char* CodeLocation::functionName() const
{
return m_functionName ? m_functionName : EMPTY_STRING;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int CodeLocation::lineNumber() const
{
return m_lineNumber;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void CodeLocation::swap(CodeLocation& other)
{
std::swap(m_fileName, other.m_fileName);
std::swap(m_functionName, other.m_functionName);
std::swap(m_lineNumber, other.m_lineNumber);
}
} // namespace cvf

View File

@ -0,0 +1,65 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#pragma once
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class CodeLocation
{
public:
CodeLocation();
CodeLocation(const char* fileName, const char* functionName, int lineNumber);
CodeLocation(const CodeLocation& other);
const CodeLocation& operator=(CodeLocation rhs);
const char* fileName() const;
const char* shortFileName() const;
const char* functionName() const;
int lineNumber() const;
void swap(CodeLocation& other);
private:
const char* m_fileName;
const char* m_functionName;
int m_lineNumber;
};
#if defined(_MSC_VER)
#define CVF_CODELOC_FUNCNAME __FUNCSIG__
#elif defined(__GNUC__)
#define CVF_CODELOC_FUNCNAME __PRETTY_FUNCTION__
#else
#define CVF_CODELOC_FUNCNAME ""
#endif
#define CVF_CODE_LOCATION ::cvf::CodeLocation(__FILE__, CVF_CODELOC_FUNCNAME, __LINE__)
} // cvf

View File

@ -0,0 +1,44 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfObject.h"
namespace cvf {
class LogEvent;
//==================================================================================================
//
// Interface for log destinations
//
//==================================================================================================
class LogDestination : public Object
{
public:
virtual void log(const LogEvent& logEvent) = 0;
};
} // cvf

View File

@ -0,0 +1,141 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfLogDestinationConsole.h"
#include "cvfLogEvent.h"
#ifdef WIN32
#pragma warning (push)
#pragma warning (disable: 4668)
#include <windows.h>
#pragma warning (pop)
#else
#include <cstdio>
#include <cstdarg>
#endif
namespace cvf {
//==================================================================================================
///
/// \class cvf::LogDestinationConsole
/// \ingroup Core
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogDestinationConsole::log(const LogEvent& logEvent)
{
String str;
bool addLocationInfo = false;
Logger::Level logEventLevel = logEvent.level();
if (logEventLevel == Logger::LL_ERROR)
{
str = "ERROR: " + logEvent.message();
addLocationInfo = true;
}
else if (logEventLevel == Logger::LL_WARNING)
{
str = "warn: " + logEvent.message();
}
else if (logEventLevel == Logger::LL_INFO)
{
str = "info: " + logEvent.message();
}
else if (logEventLevel == Logger::LL_DEBUG)
{
str = "debug: " + logEvent.message();
}
if (addLocationInfo)
{
str += "\n";
str += String(" -func: %1\n").arg(logEvent.location().functionName());
str += String(" -file: %1(%2)").arg(logEvent.location().shortFileName()).arg(logEvent.location().lineNumber());
}
CharArray charArrMsg = str.toAscii();
const char* szMsg = charArrMsg.ptr();
{
Mutex::ScopedLock lock(m_mutex);
#ifdef WIN32
writeToWindowsConsole(szMsg, true);
#else
writeToStderr(szMsg, true);
#endif
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogDestinationConsole::writeToWindowsConsole(const char* theString, bool addNewLine)
{
#ifdef WIN32
CVF_ASSERT(theString);
AllocConsole();
HANDLE hStdOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
if (hStdOutputHandle && theString)
{
DWORD stringLength = static_cast<DWORD>(System::strlen(theString));
unsigned long iDum = 0;
WriteConsoleA(hStdOutputHandle, theString, stringLength, &iDum, NULL);
if (addNewLine) WriteConsole(hStdOutputHandle, "\n", 1, &iDum, NULL);
}
#else
CVF_UNUSED(theString);
CVF_UNUSED(addNewLine);
#endif
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogDestinationConsole::writeToStderr(const char* theString, bool addNewLine)
{
CVF_ASSERT(theString);
if (theString)
{
fprintf(stderr, "%s", theString);
if (addNewLine)
{
fprintf(stderr, "\n");
}
}
}
} // namespace cvf

View File

@ -0,0 +1,49 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfLogDestination.h"
#include "cvfMutex.h"
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class LogDestinationConsole : public LogDestination
{
public:
virtual void log(const LogEvent& logEvent);
private:
static void writeToWindowsConsole(const char* theString, bool addNewLine);
static void writeToStderr(const char* theString, bool addNewLine);
private:
Mutex m_mutex;
};
} // cvf

View File

@ -0,0 +1,169 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfLogDestinationFile.h"
#include "cvfLogEvent.h"
#ifdef WIN32
#pragma warning (push)
#pragma warning (disable: 4668)
#include <windows.h>
#pragma warning (pop)
#else
#include <cstdio>
#include <cstdarg>
#endif
namespace cvf {
class FileWrapper
{
public:
FileWrapper(const String& fileName)
: m_fileName(fileName),
m_filePtr(NULL)
{
}
~FileWrapper()
{
if (m_filePtr)
{
fclose(m_filePtr);
}
}
bool open(const String& mode)
{
CVF_ASSERT(m_filePtr == NULL);
#ifdef WIN32
if (_wfopen_s(&m_filePtr, m_fileName.c_str(), mode.c_str()) != 0)
{
m_filePtr = NULL;
}
#else
m_filePtr = ::fopen(m_fileName.toUtf8().ptr(), mode.toUtf8().ptr());
#endif
return m_filePtr != NULL;
}
FILE* filePtr()
{
return m_filePtr;
}
private:
String m_fileName;
FILE* m_filePtr;
};
//==================================================================================================
///
/// \class cvf::LogDestinationFile
/// \ingroup Core
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogDestinationFile::log(const LogEvent& logEvent)
{
String str;
bool addLocationInfo = false;
Logger::Level logEventLevel = logEvent.level();
if (logEventLevel == Logger::LL_ERROR)
{
str = "ERROR: " + logEvent.message();
addLocationInfo = true;
}
else if (logEventLevel == Logger::LL_WARNING)
{
str = "warn: " + logEvent.message();
}
else if (logEventLevel == Logger::LL_INFO)
{
str = "info: " + logEvent.message();
}
else if (logEventLevel == Logger::LL_DEBUG)
{
str = "debug: " + logEvent.message();
}
if (addLocationInfo)
{
str += "\n";
str += String(" -func: %1\n").arg(logEvent.location().functionName());
str += String(" -file: %1(%2)").arg(logEvent.location().shortFileName()).arg(logEvent.location().lineNumber());
}
CharArray charArrMsg = str.toAscii();
const char* szMsg = charArrMsg.ptr();
Mutex::ScopedLock lock(m_mutex);
writeToFile(szMsg, true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogDestinationFile::writeToFile(const char* theString, bool addNewLine)
{
FileWrapper file(m_fileName);
if (m_firstTimeOpen)
{
if (!file.open("wt"))
{
return;
}
m_firstTimeOpen = false;
}
else
{
if (!file.open("at"))
{
return;
}
}
if (file.filePtr() && theString)
{
if (addNewLine)
{
fprintf(file.filePtr(), "%s\n", theString);
}
else
{
fprintf(file.filePtr(), "%s", theString);
}
}
}
} // namespace cvf

View File

@ -0,0 +1,53 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfLogDestination.h"
#include "cvfString.h"
#include "cvfMutex.h"
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class LogDestinationFile : public LogDestination
{
public:
LogDestinationFile(const String& fileName);
virtual void log(const LogEvent& logEvent);
private:
void writeToFile(const char* theString, bool addNewLine);
private:
String m_fileName;
bool m_firstTimeOpen; // Initialized to true, Will be set to false after first write operation
Mutex m_mutex;
};
} // cvf

View File

@ -0,0 +1,128 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfLogEvent.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::LogEvent
/// \ingroup Core
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogEvent::LogEvent()
: m_level(Logger::LL_ERROR)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogEvent::LogEvent(const String& source, const String& message, Logger::Level level, const CodeLocation& codeLocation)
: m_source(source),
m_message(message),
m_level(level),
m_codeLocation(codeLocation)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogEvent::LogEvent(const LogEvent& other)
: m_source(other.m_source),
m_message(other.m_message),
m_level(other.m_level),
m_codeLocation(other.m_codeLocation)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const LogEvent& LogEvent::operator=(LogEvent rhs)
{
// Copy-and-swap (copy already done since parameter is passed by value)
rhs.swap(*this);
return *this;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const String& LogEvent::source() const
{
return m_source;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Logger::Level LogEvent::level() const
{
return m_level;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const String& LogEvent::message() const
{
return m_message;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const CodeLocation& LogEvent::location() const
{
return m_codeLocation;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogEvent::swap(LogEvent& other)
{
m_source.swap(other.m_source);
m_message.swap(other.m_message);
std::swap(m_level, other.m_level);
m_codeLocation.swap(other.m_codeLocation);
}
} // namespace cvf

View File

@ -0,0 +1,62 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfObject.h"
#include "cvfString.h"
#include "cvfLogger.h"
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class LogEvent
{
public:
LogEvent();
LogEvent(const String& source, const String& message, Logger::Level level, const CodeLocation& codeLocation);
LogEvent(const LogEvent& other);
const LogEvent& operator=(LogEvent rhs);
const String& source() const;
Logger::Level level() const;
const String& message() const;
const CodeLocation& location() const;
private:
void swap(LogEvent& other);
private:
String m_source;
String m_message;
Logger::Level m_level;
CodeLocation m_codeLocation;
};
} // cvf

View File

@ -0,0 +1,236 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfLogManager.h"
#include "cvfLogger.h"
#include "cvfLogDestinationConsole.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::LogManager
/// \ingroup Core
///
///
///
//==================================================================================================
cvf::ref<LogManager> LogManager::sm_logManagerInstance;
Mutex LogManager::sm_instanceMutex;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogManager::LogManager()
{
// Create the root logger
ref<Logger> rootLogger = new Logger("", Logger::LL_WARNING, new LogDestinationConsole);
m_loggerMap[""] = rootLogger;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogManager::~LogManager()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogManager* LogManager::instance()
{
Mutex::ScopedLock mutexLock(sm_instanceMutex);
if (sm_logManagerInstance.isNull())
{
sm_logManagerInstance = new LogManager;
}
return sm_logManagerInstance.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogManager::setInstance(LogManager* logManagerInstance)
{
Mutex::ScopedLock mutexLock(sm_instanceMutex);
sm_logManagerInstance = logManagerInstance;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogManager::shutdownInstance()
{
Mutex::ScopedLock mutexLock(sm_instanceMutex);
sm_logManagerInstance = NULL;
}
//--------------------------------------------------------------------------------------------------
/// Returns logger with the specified name
///
/// Will create the logger if it doesn't already exist. In this case, the newly created logger will
/// be initialized with the same logging level and appender as its parent.
//--------------------------------------------------------------------------------------------------
Logger* LogManager::logger(const String& loggerName)
{
Mutex::ScopedLock mutexLock(m_mutex);
ref<Logger> theLogger = find(loggerName);
if (theLogger.isNull())
{
// Must create a new logger
// Try and find parent (optionally we'll use the root logger) and use its settings to initialize level and appender
String parentLoggerName = LogManager::nameOfParentLogger(loggerName);
ref<Logger> parentLogger = find(parentLoggerName);
if (parentLogger.isNull())
{
parentLogger = rootLogger();
}
CVF_ASSERT(parentLogger.notNull());
theLogger = new Logger(loggerName, parentLogger->level(), parentLogger->destination());
m_loggerMap[loggerName] = theLogger;
}
return theLogger.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Logger* LogManager::rootLogger()
{
return logger(String());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogManager::setLevelRecursive(const String& baseLoggerName, int logLevel)
{
Mutex::ScopedLock mutexLock(m_mutex);
const size_t baseNameLength = baseLoggerName.size();
const bool baseNameIsRoot = (baseNameLength == 0);
for (LoggerMap_T::iterator it = m_loggerMap.begin(); it != m_loggerMap.end(); ++it)
{
Logger* logger = it->second.p();
if (baseNameIsRoot)
{
logger->setLevel(logLevel);
}
else
{
const String& loggerName = logger->name();
if (loggerName.startsWith(baseLoggerName) &&
((loggerName.size() == baseNameLength) || (loggerName[baseNameLength] == '.')) )
{
logger->setLevel(logLevel);
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogManager::setDestinationRecursive(const String& baseLoggerName, LogDestination* logDestination)
{
Mutex::ScopedLock mutexLock(m_mutex);
const size_t baseNameLength = baseLoggerName.size();
const bool baseNameIsRoot = (baseNameLength == 0);
for (LoggerMap_T::iterator it = m_loggerMap.begin(); it != m_loggerMap.end(); ++it)
{
Logger* logger = it->second.p();
if (baseNameIsRoot)
{
logger->setDestination(logDestination);
}
else
{
const String& loggerName = logger->name();
if (loggerName.startsWith(baseLoggerName) &&
((loggerName.size() == baseNameLength) || (loggerName[baseNameLength] == '.')) )
{
logger->setDestination(logDestination);
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Logger* LogManager::find(const String& loggerName)
{
LoggerMap_T::iterator it = m_loggerMap.find(loggerName);
if (it != m_loggerMap.end())
{
return it->second.p();
}
else
{
return NULL;
}
}
//--------------------------------------------------------------------------------------------------
/// Determine name of the parent logger of \a childLoggerName
//--------------------------------------------------------------------------------------------------
String LogManager::nameOfParentLogger(const String& childLoggerName)
{
std::wstring childName = childLoggerName.toStdWString();
std::wstring::size_type pos = childName.rfind('.');
if (pos != std::wstring::npos)
{
std::wstring parentName = childName.substr(0, pos);
return parentName;
}
else
{
return String();
}
}
} // namespace cvf

View File

@ -0,0 +1,74 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfObject.h"
#include "cvfString.h"
#include "cvfMutex.h"
#include <map>
namespace cvf {
class Logger;
class LogDestination;
//==================================================================================================
//
//
//
//==================================================================================================
class LogManager : public Object
{
public:
LogManager();
~LogManager();
static LogManager* instance();
static void setInstance(LogManager* logManagerInstance);
static void shutdownInstance();
Logger* logger(const String& loggerName);
Logger* rootLogger();
void setLevelRecursive(const String& baseLoggerName, int logLevel);
void setDestinationRecursive(const String& baseLoggerName, LogDestination* logDestination);
private:
Logger* find(const String& loggerName);
static String nameOfParentLogger(const String& childLoggerName);
private:
typedef std::map<String, cvf::ref<Logger> > LoggerMap_T;
LoggerMap_T m_loggerMap;
Mutex m_mutex;
static cvf::ref<LogManager> sm_logManagerInstance;
static Mutex sm_instanceMutex;
CVF_DISABLE_COPY_AND_ASSIGN(LogManager);
};
} // cvf

View File

@ -19,7 +19,8 @@
#include "cvfBase.h" #include "cvfBase.h"
#include "cvfLogger.h" #include "cvfLogger.h"
#include "cvfTrace.h" #include "cvfLogEvent.h"
#include "cvfLogDestination.h"
namespace cvf { namespace cvf {
@ -31,17 +32,20 @@ namespace cvf {
/// \ingroup Core /// \ingroup Core
/// ///
/// Logger class /// Logger class
///
/// Currently, output is written using Trace, and special formatting of the string makes it possible
/// to navigate to source code using F4 in Visual Studio. See http://msdn.microsoft.com/en-us/library/yxkt8b26.aspx
/// ///
/// Note that in itself, the Logger is not thread safe. This means that logger configuration, such
/// as setting the logging level and specifying the log destination, must be done in a single
/// threaded environment.
///
//================================================================================================== //==================================================================================================
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Constructor /// Constructor
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
Logger::Logger() Logger::Logger(const String& loggerName, int logLevel, LogDestination* logDestination)
: m_debugLogging(false) : m_name(loggerName),
m_logLevel(logLevel),
m_destination(logDestination)
{ {
} }
@ -51,62 +55,145 @@ Logger::Logger()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
Logger::~Logger() Logger::~Logger()
{ {
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Use file and line to create a specially formatted string for Visual Studio.
/// ///
/// \param message The actual error message //--------------------------------------------------------------------------------------------------
/// \param fileName Use system macro __FILE__ for source code file name const String& Logger::name() const
/// \param line Use system macro __LINE__ for source code line number {
return m_name;
}
//--------------------------------------------------------------------------------------------------
/// Set the logging level of this logger
/// ///
/// __FILE__ and __LINE__ are used to create the variables used to navigate to the line in the /// Set a level of 0 to disable all logging for this logger.
/// source code file the error message was logged at.
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void Logger::error(const String& message, const char* fileName, int lineNumber) void Logger::setLevel(int logLevel)
{ {
String tmp; m_logLevel = logLevel;
tmp = String(fileName) + "(" + String(lineNumber) + "): error: " + message;
Trace::show(tmp);
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void Logger::enableDebug(bool enableDebugLogging) int Logger::level() const
{ {
m_debugLogging = enableDebugLogging; return m_logLevel;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
bool Logger::isDebugEnabled() const LogDestination* Logger::destination()
{ {
return m_debugLogging; return m_destination.p();
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void Logger::debug(const String& message, const char* /*fileName*/, int /*lineNumber*/) void Logger::setDestination(LogDestination* logDestination)
{ {
if (m_debugLogging) m_destination = logDestination;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::error(const String& message)
{
error(message, CodeLocation());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::error(const String& message, const CodeLocation& location)
{
if (m_logLevel >= LL_ERROR && m_destination.notNull())
{ {
// For now, don't report file and line log(message, LL_ERROR, location);
String tmp;
tmp = "debug: " + message;
Trace::show(tmp);
} }
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::warning(const String& message)
{
warning(message, CodeLocation());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::warning(const String& message, const CodeLocation& location)
{
if (m_logLevel >= LL_WARNING && m_destination.notNull())
{
log(message, LL_WARNING, location);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::info(const String& message)
{
info(message, CodeLocation());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::info(const String& message, const CodeLocation& location)
{
if (m_logLevel >= LL_INFO && m_destination.notNull())
{
log(message, LL_INFO, location);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::debug(const String& message, const CodeLocation& location)
{
if (m_logLevel >= LL_DEBUG && m_destination.notNull())
{
log(message, LL_DEBUG, location);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::log(const String& message, Logger::Level messageLevel, const CodeLocation& location)
{
if (m_logLevel >= messageLevel && m_destination.notNull())
{
m_destination->log(LogEvent(m_name, message, messageLevel, location));
}
}
} // namespace cvf } // namespace cvf

View File

@ -21,9 +21,14 @@
#include "cvfObject.h" #include "cvfObject.h"
#include "cvfString.h" #include "cvfString.h"
#include "cvfCodeLocation.h"
namespace cvf { namespace cvf {
class LogEvent;
class LogDestination;
//================================================================================================== //==================================================================================================
// //
@ -33,20 +38,57 @@ namespace cvf {
class Logger : public Object class Logger : public Object
{ {
public: public:
Logger(); enum Level
{
LL_ERROR = 1,
LL_WARNING,
LL_INFO,
LL_DEBUG
};
public:
Logger(const String& loggerName, int logLevel, LogDestination* logDestination);
~Logger(); ~Logger();
void error(const String& message, const char* fileName, int lineNumber); const String& name() const;
int level() const;
void setLevel(int logLevel);
LogDestination* destination();
void setDestination(LogDestination* logDestination);
void enableDebug(bool enableDebugLogging); void error(const String& message);
bool isDebugEnabled() const; void error(const String& message, const CodeLocation& location);
void debug(const String& message, const char* fileName, int lineNumber); void warning(const String& message);
void warning(const String& message, const CodeLocation& location);
void info(const String& message);
void info(const String& message, const CodeLocation& location);
void debug(const String& message, const CodeLocation& location);
bool isErrorEnabled() const { return m_logLevel >= LL_ERROR; }
bool isWarningEnabled() const { return m_logLevel >= LL_WARNING; }
bool isInfoEnabled() const { return m_logLevel >= LL_INFO; }
bool isDebugEnabled() const { return m_logLevel >= LL_DEBUG; }
private: private:
bool m_debugLogging; // Whether debug messages get logged or not void log(const String& message, Logger::Level messageLevel, const CodeLocation& location);
private:
String m_name; // Logger name
int m_logLevel; // Logging level, all messages with a level less than or equal to this level will be logged
ref<LogDestination> m_destination;
CVF_DISABLE_COPY_AND_ASSIGN(Logger);
}; };
// Helper macros for writing log messages to a logger
#define CVF_LOG_ERROR(theLogger, theMessage) if ((theLogger)->isErrorEnabled()) { (theLogger)->error((theMessage), CVF_CODE_LOCATION); }
#define CVF_LOG_WARNING(theLogger, theMessage) if ((theLogger)->isWarningEnabled()) { (theLogger)->warning((theMessage), CVF_CODE_LOCATION); }
#define CVF_LOG_INFO(theLogger, theMessage) if ((theLogger)->isInfoEnabled()) { (theLogger)->info((theMessage), CVF_CODE_LOCATION); }
#define CVF_LOG_DEBUG(theLogger, theMessage) if ((theLogger)->isDebugEnabled()) { (theLogger)->debug((theMessage), CVF_CODE_LOCATION); }
} // cvf } // cvf

View File

@ -0,0 +1,202 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfMutex.h"
#ifdef WIN32
#pragma warning (push)
#pragma warning (disable: 4668)
#include <windows.h>
#pragma warning (pop)
#endif
#ifdef CVF_LINUX
#include <pthread.h>
#endif
namespace cvf {
//==================================================================================================
//
// Win32 implementation using critical section
//
//==================================================================================================
#ifdef WIN32
class MutexImpl
{
public:
MutexImpl()
{
::InitializeCriticalSection(&m_critSection);
}
~MutexImpl()
{
::DeleteCriticalSection(&m_critSection);
}
void lock()
{
::EnterCriticalSection(&m_critSection);
}
void unlock()
{
::LeaveCriticalSection(&m_critSection);
}
private:
CRITICAL_SECTION m_critSection;
};
#endif
//==================================================================================================
//
// Linux implementation using POSIX/Pthreads
//
//==================================================================================================
#ifdef CVF_LINUX
class MutexImpl
{
public:
MutexImpl()
{
pthread_mutexattr_t mutexAttribs;
int errCode = 0;
CVF_UNUSED(errCode);
errCode = pthread_mutexattr_init(&mutexAttribs);
CVF_ASSERT(errCode == 0);
// Use a recursive mutex to be aligned with Win32 implementation
errCode = pthread_mutexattr_settype(&mutexAttribs, PTHREAD_MUTEX_RECURSIVE);
CVF_ASSERT(errCode == 0);
errCode = pthread_mutex_init(&m_mutex, &mutexAttribs);
CVF_ASSERT(errCode == 0);
// We're done with the attribs object
errCode = pthread_mutexattr_destroy(&mutexAttribs);
CVF_ASSERT(errCode == 0);
}
~MutexImpl()
{
int errCode = pthread_mutex_destroy(&m_mutex);
CVF_UNUSED(errCode);
CVF_TIGHT_ASSERT(errCode == 0);
}
void lock()
{
int errCode = pthread_mutex_lock(&m_mutex);
CVF_UNUSED(errCode);
CVF_TIGHT_ASSERT(errCode == 0);
}
void unlock()
{
int errCode = pthread_mutex_unlock(&m_mutex);
CVF_UNUSED(errCode);
CVF_TIGHT_ASSERT(errCode == 0);
}
private:
pthread_mutex_t m_mutex;
};
#endif
//==================================================================================================
///
/// \class cvf::Mutex
/// \ingroup Core
///
/// Implements a recursive mutex where the same thread can acquire the lock multiple times.
///
/// The mutex is implemented as an recursive mutex since on Windows platforms its implementation
/// is based critical sections. Win32 critical sections are always recursive, and therefore we also
/// make the other platform implementations recursive for consistency.
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Mutex::Mutex()
: m_pimpl(new MutexImpl)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Mutex::~Mutex()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Mutex::lock()
{
m_pimpl->lock();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Mutex::unlock()
{
m_pimpl->unlock();
}
//==================================================================================================
///
/// \class cvf::Mutex::ScopedLock
/// \ingroup Core
///
///
///
//==================================================================================================
Mutex::ScopedLock::ScopedLock(Mutex& mutex)
: m_theMutex(mutex)
{
m_theMutex.lock();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Mutex::ScopedLock::~ScopedLock()
{
m_theMutex.unlock();
}
} // namespace cvf

View File

@ -0,0 +1,60 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include <memory>
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class Mutex
{
public:
Mutex();
~Mutex();
void lock();
void unlock();
class ScopedLock
{
public:
ScopedLock(Mutex& mutex);
~ScopedLock();
private:
Mutex& m_theMutex;
};
private:
std::auto_ptr<class MutexImpl> m_pimpl;
CVF_DISABLE_COPY_AND_ASSIGN(Mutex);
};
} // cvf

View File

@ -1063,6 +1063,15 @@ size_t String::find(const String& str, size_t start) const
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool String::startsWith(const String& str) const
{
return (find(str) == 0);
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -69,6 +69,7 @@ public:
std::vector<String> split(const String& delimiters = " ") const; std::vector<String> split(const String& delimiters = " ") const;
size_t find(const String& str, size_t start = 0) const; size_t find(const String& str, size_t start = 0) const;
bool startsWith(const String& str) const;
String subString(size_t start, size_t length = npos) const; String subString(size_t start, size_t length = npos) const;
void replace(const String& before, const String& after); void replace(const String& before, const String& after);

View File

@ -20,6 +20,7 @@ include_directories(glew)
set(CEE_HEADER_FILES set(CEE_HEADER_FILES
cvfBufferObjectManaged.h cvfBufferObjectManaged.h
cvfCamera.h cvfCamera.h
cvfCameraAnimation.h
cvfDrawable.h cvfDrawable.h
cvfDrawableGeo.h cvfDrawableGeo.h
cvfDrawableText.h cvfDrawableText.h
@ -98,6 +99,7 @@ cvfViewport.h
set(CEE_SOURCE_FILES set(CEE_SOURCE_FILES
cvfBufferObjectManaged.cpp cvfBufferObjectManaged.cpp
cvfCamera.cpp cvfCamera.cpp
cvfCameraAnimation.cpp
cvfDrawable.cpp cvfDrawable.cpp
cvfDrawableGeo.cpp cvfDrawableGeo.cpp
cvfDrawableVectors.cpp cvfDrawableVectors.cpp

View File

@ -268,13 +268,23 @@ void Camera::setProjectionAsPixelExact2D()
/// the view to. The relativeDistance parameter specifies the distance from the camera to the /// the view to. The relativeDistance parameter specifies the distance from the camera to the
/// center of the bounding box /// center of the bounding box
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void Camera::fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double distanceScaleFactor) void Camera::fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double coverageFactor)
{
// Use old view direction, but look towards model center
Vec3d eye = fitViewEyePosition(boundingBox, dir, up, coverageFactor);
// Will update cached values
setFromLookAt(eye, boundingBox.center(), up);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Vec3d Camera::fitViewEyePosition(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double coverageFactor) const
{ {
CVF_ASSERT(projection() == PERSPECTIVE); CVF_ASSERT(projection() == PERSPECTIVE);
// TODO! !!! !! !!
CVF_UNUSED(distanceScaleFactor);
cvf::Vec3d corners[8]; cvf::Vec3d corners[8];
boundingBox.cornerVertices(corners); boundingBox.cornerVertices(corners);
@ -312,8 +322,8 @@ void Camera::fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec
distUp += (centerToCornerSide*boxEyeNorm); distUp += (centerToCornerSide*boxEyeNorm);
// Adjust for the distance scale factor // Adjust for the distance scale factor
distRight /= distanceScaleFactor; distRight /= coverageFactor;
distUp /= distanceScaleFactor; distUp /= coverageFactor;
dist = CVF_MAX(dist, distRight); dist = CVF_MAX(dist, distRight);
dist = CVF_MAX(dist, distUp); dist = CVF_MAX(dist, distUp);
@ -328,8 +338,7 @@ void Camera::fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec
// Use old view direction, but look towards model center // Use old view direction, but look towards model center
Vec3d eye = boundingBox.center()- dir.getNormalized()*dist; Vec3d eye = boundingBox.center()- dir.getNormalized()*dist;
// Will update cached values return eye;
setFromLookAt(eye, boundingBox.center(), up);
} }
@ -1023,6 +1032,5 @@ void Camera::applyOpenGL() const
#endif #endif
} }
} // namespace cvf } // namespace cvf

View File

@ -66,6 +66,8 @@ public:
void fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double coverageFactor = 0.9); void fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double coverageFactor = 0.9);
void fitViewOrtho(const BoundingBox& boundingBox, double eyeDist, const Vec3d& dir, const Vec3d& up, double coverageFactor = 0.9); void fitViewOrtho(const BoundingBox& boundingBox, double eyeDist, const Vec3d& dir, const Vec3d& up, double coverageFactor = 0.9);
Vec3d fitViewEyePosition(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double coverageFactor = 0.9) const;
void setClipPlanesFromBoundingBox(const BoundingBox& boundingBox, double minNearPlaneDistance = 0.01); void setClipPlanesFromBoundingBox(const BoundingBox& boundingBox, double minNearPlaneDistance = 0.01);
const Mat4d& viewMatrix() const; const Mat4d& viewMatrix() const;

View File

@ -0,0 +1,109 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfCameraAnimation.h"
#include "cvfCamera.h"
#include "cvfTimer.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::CameraAnimation
/// \ingroup Render
///
/// Support class for creating a camera path animation from one camera configuration to another.
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Configures the animation with start and end point
//--------------------------------------------------------------------------------------------------
CameraAnimation::CameraAnimation(const Vec3d& currentPos, const Vec3d& currentDir, const Vec3d& currentUp, const Vec3d& newPos, const Vec3d& newDir, const Vec3d& newUp)
: m_currentPos(currentPos),
m_currentDir(currentDir),
m_currentUp(currentUp),
m_newPos(newPos),
m_newDir(newDir),
m_newUp(newUp),
m_animDuration(0.75),
m_animDone(false)
{
}
//--------------------------------------------------------------------------------------------------
/// Returns the next position in the animation. After the duration of the animation is used up,
/// the method returns the end point and after that always returns false.
///
/// So usage would be:
/// \code
/// cvf::Vec3d pos, dir, up;
/// while(anim.newPosition(&pos, &dir, &up))
/// {
/// m_camera->setFromLookAt(pos, pos + dir, up);
/// repaint();
/// }
/// \endcode
//--------------------------------------------------------------------------------------------------
bool CameraAnimation::newPosition(Vec3d* pos, Vec3d* dir, Vec3d* up)
{
if (m_animDone)
{
return false;
}
if (m_timer.isNull())
{
m_timer = new Timer;
}
double timeNow = m_timer->time();
if (timeNow > m_animDuration)
{
*pos = m_newPos;
*dir = m_newDir;
*up = m_newUp;
m_animDone = true;
return true;
}
*pos = m_currentPos + (m_newPos - m_currentPos)*(timeNow/m_animDuration);
*dir = m_currentDir + (m_newDir - m_currentDir)*(timeNow/m_animDuration);
*up = m_currentUp + (m_newUp - m_currentUp )*(timeNow/m_animDuration);
return true;
}
//--------------------------------------------------------------------------------------------------
/// Sets the duration of the animation
//--------------------------------------------------------------------------------------------------
void CameraAnimation::setDuration(double seconds)
{
m_animDuration = seconds;
}
} // namespace cvf

View File

@ -0,0 +1,56 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 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 General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfObject.h"
#include "cvfVector3.h"
namespace cvf {
class Timer;
//==================================================================================================
//
// Camera animation class
//
//==================================================================================================
class CameraAnimation : public Object
{
public:
CameraAnimation(const Vec3d& currentPos, const Vec3d& currentDir, const Vec3d& currentUp, const Vec3d& newPos, const Vec3d& newDir, const Vec3d& newUp);
void setDuration(double seconds);
bool newPosition(Vec3d* pos, Vec3d* dir, Vec3d* up);
private:
Vec3d m_currentPos;
Vec3d m_currentDir;
Vec3d m_currentUp;
Vec3d m_newPos;
Vec3d m_newDir;
Vec3d m_newUp;
ref<Timer> m_timer;
double m_animDuration;
bool m_animDone;
};
}

View File

@ -1273,8 +1273,6 @@ BoundingBox DrawableGeo::boundingBox() const
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
bool DrawableGeo::rayIntersect(const Ray& ray, Vec3d* intersectionPoint, uint* faceHit) const bool DrawableGeo::rayIntersect(const Ray& ray, Vec3d* intersectionPoint, uint* faceHit) const
{ {
CVF_ASSERT(intersectionPoint);
bool anyHits = false; bool anyHits = false;
double minDistSquared = 1.0e300; double minDistSquared = 1.0e300;
@ -1314,19 +1312,23 @@ bool DrawableGeo::rayIntersect(const Ray& ray, Vec3d* intersectionPoint, uint* f
double distSquared = (ray.origin() - localIntersect).lengthSquared(); double distSquared = (ray.origin() - localIntersect).lengthSquared();
#pragma omp critical #pragma omp critical
{ {
if (distSquared < minDistSquared) if (distSquared < minDistSquared)
{
if (intersectionPoint)
{ {
*intersectionPoint = localIntersect; *intersectionPoint = localIntersect;
minDistSquared = distSquared;
if (faceHit)
{
*faceHit = i + accumulatedFaceCount;
}
} }
anyHits = true;
} minDistSquared = distSquared;
if (faceHit)
{
*faceHit = i + accumulatedFaceCount;
}
}
anyHits = true;
} }
}
} // End omp parallel for } // End omp parallel for
accumulatedFaceCount += numPrimFaces; accumulatedFaceCount += numPrimFaces;
} }

View File

@ -64,7 +64,8 @@ DrawableText::DrawableText()
m_borderColor(Color3::BLACK), m_borderColor(Color3::BLACK),
m_drawBackground(true), m_drawBackground(true),
m_drawBorder(true), m_drawBorder(true),
m_checkPosVisible(true) m_checkPosVisible(true),
m_useDepthBuffer(false)
{ {
} }
@ -158,6 +159,15 @@ void DrawableText::setCheckPosVisible(bool checkpos)
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void DrawableText::setUseDepthBuffer(bool useDepthBuffer)
{
m_useDepthBuffer = useDepthBuffer;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -323,7 +333,7 @@ void DrawableText::renderText(OpenGLContext* oglContext, ShaderProgram* shaderPr
if (!m_checkPosVisible || labelAnchorVisible(oglContext, proj, m_positions[pos], shaderProgram == NULL)) if (!m_checkPosVisible || labelAnchorVisible(oglContext, proj, m_positions[pos], shaderProgram == NULL))
{ {
// Note: Need to adjust for the current viewport, as the coords returned from project are in global windows coordinates // Note: Need to adjust for the current viewport, as the coords returned from project are in global windows coordinates
projCoords.push_back(Vec3f(static_cast<float>(proj.x() - matrixState.viewportPosition().x()), static_cast<float>(proj.y() - matrixState.viewportPosition().y()), 0.0f)); projCoords.push_back(Vec3f(static_cast<float>(proj.x() - matrixState.viewportPosition().x()), static_cast<float>(proj.y() - matrixState.viewportPosition().y()), static_cast<float>(1.0 - 2.0*proj.z()))); // Map z into 1 .. -1
textsToDraw.push_back(m_texts[pos]); textsToDraw.push_back(m_texts[pos]);
} }
} }
@ -355,12 +365,13 @@ void DrawableText::renderText(OpenGLContext* oglContext, ShaderProgram* shaderPr
drawer.setBorderColor(m_borderColor); drawer.setBorderColor(m_borderColor);
drawer.setDrawBorder(m_drawBorder); drawer.setDrawBorder(m_drawBorder);
drawer.setDrawBackground(m_drawBackground); drawer.setDrawBackground(m_drawBackground);
drawer.setUseDepthBuffer(m_useDepthBuffer);
size_t i; size_t i;
for (i = 0; i < textsToDraw.size(); i++) for (i = 0; i < textsToDraw.size(); i++)
{ {
Vec3f pos = projCoords[i]; Vec3f pos = projCoords[i];
drawer.addText(textsToDraw[i], Vec2f(pos)); drawer.addText(textsToDraw[i], pos);
} }
if (shaderProgram) if (shaderProgram)
@ -423,4 +434,38 @@ bool DrawableText::labelAnchorVisible(OpenGLContext* oglContext, const Vec3d win
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool DrawableText::rayIntersect(const Ray& ray, const Camera& camera, Vec3d* intersectionPoint)
{
Vec3d pickCoord2d;
camera.project(ray.origin(), &pickCoord2d);
size_t i;
for (i = 0; i < m_positions.size(); i++)
{
Vec3d proj;
camera.project(Vec3d(m_positions[i]), &proj);
Vec3f posTextDrawer = Vec3f(static_cast<float>(proj.x() - camera.viewport()->x()), static_cast<float>(proj.y() - camera.viewport()->y()), static_cast<float>(1.0 - 2.0*proj.z())); // Map z into 1 .. -1
if (TextDrawer::pickText(Vec3f(pickCoord2d), m_texts[i], posTextDrawer, m_font.p()))
{
if (m_useDepthBuffer)
{
*intersectionPoint = Vec3d(m_positions[i]);
}
else
{
*intersectionPoint = ray.origin();
}
return true;
}
}
return false;
}
} // namespace cvf } // namespace cvf

View File

@ -30,6 +30,7 @@ class Font;
class DrawableGeo; class DrawableGeo;
class ShaderProgram; class ShaderProgram;
class BufferObjectManaged; class BufferObjectManaged;
class Camera;
//================================================================================================== //==================================================================================================
@ -55,6 +56,7 @@ public:
void setDrawBackground(bool drawBackground); void setDrawBackground(bool drawBackground);
void setDrawBorder(bool drawBorder); void setDrawBorder(bool drawBorder);
void setCheckPosVisible(bool checkpos); void setCheckPosVisible(bool checkpos);
void setUseDepthBuffer(bool useDepthBuffer);
virtual void createUploadBufferObjectsGPU(OpenGLContext* /*oglContext*/) {} virtual void createUploadBufferObjectsGPU(OpenGLContext* /*oglContext*/) {}
virtual void releaseBufferObjectsGPU() {} virtual void releaseBufferObjectsGPU() {}
@ -69,6 +71,7 @@ public:
virtual BoundingBox boundingBox() const; virtual BoundingBox boundingBox() const;
virtual bool rayIntersectCreateDetail(const Ray& ray, Vec3d* intersectionPoint, ref<HitDetail>* hitDetail) const; virtual bool rayIntersectCreateDetail(const Ray& ray, Vec3d* intersectionPoint, ref<HitDetail>* hitDetail) const;
bool rayIntersect(const Ray& ray, const Camera& camera, Vec3d* intersectionPoint);
// TO BE REMOVED! // TO BE REMOVED!
virtual void renderFixedFunction(OpenGLContext* oglContext, const MatrixState& matrixState) { renderSoftware(oglContext, matrixState); } virtual void renderFixedFunction(OpenGLContext* oglContext, const MatrixState& matrixState) { renderSoftware(oglContext, matrixState); }
@ -92,6 +95,7 @@ private:
bool m_drawBackground; bool m_drawBackground;
bool m_drawBorder; bool m_drawBorder;
bool m_checkPosVisible; bool m_checkPosVisible;
bool m_useDepthBuffer;
BoundingBox m_boundingBox; // BoundingBox m_boundingBox; //
}; };

View File

@ -136,7 +136,7 @@ String OpenGL::mapOpenGLErrorToString(cvfGLenum errorCode)
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Returns false if no error. /// Returns false if no error.
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
bool OpenGL::testAndReportOpenGLError(OpenGLContext* oglContext, const char* operation, const char* fileName, int line) bool OpenGL::testAndReportOpenGLError(OpenGLContext* oglContext, const char* operation, const CodeLocation& codeLocation)
{ {
// glGetError will end up in an endless loop if no context is current // glGetError will end up in an endless loop if no context is current
CVF_ASSERT(oglContext); CVF_ASSERT(oglContext);
@ -157,7 +157,7 @@ bool OpenGL::testAndReportOpenGLError(OpenGLContext* oglContext, const char* ope
String errCodeStr = mapOpenGLErrorToString(err); String errCodeStr = mapOpenGLErrorToString(err);
String msg = String("Operation: ") + operation; String msg = String("Operation: ") + operation;
msg += "OGL(" + errCodeStr + "): "; msg += "OGL(" + errCodeStr + "): ";
logger->error(msg, fileName, line); logger->error(msg, codeLocation);
} }
err = glGetError(); err = glGetError();
@ -170,7 +170,7 @@ bool OpenGL::testAndReportOpenGLError(OpenGLContext* oglContext, const char* ope
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void OpenGL::cvf_check_ogl(OpenGLContext* oglContext, const char* fileName, int line) void OpenGL::cvf_check_ogl(OpenGLContext* oglContext, const CodeLocation& codeLocation)
{ {
if (OpenGL::m_enableCheckOgl) if (OpenGL::m_enableCheckOgl)
{ {
@ -186,7 +186,7 @@ void OpenGL::cvf_check_ogl(OpenGLContext* oglContext, const char* fileName, int
{ {
String errCodeStr = mapOpenGLErrorToString(err); String errCodeStr = mapOpenGLErrorToString(err);
String msg = "OGL(" + errCodeStr + "): "; String msg = "OGL(" + errCodeStr + "): ";
logger->error(msg, fileName, line); logger->error(msg, codeLocation);
} }
err = glGetError(); err = glGetError();

View File

@ -84,6 +84,7 @@
#include "cvfOpenGLTypes.h" #include "cvfOpenGLTypes.h"
#include "cvfString.h" #include "cvfString.h"
#include "cvfCodeLocation.h"
// As long as we're using GLEW we will almost always need the context and context group when doing OpenGL calls // As long as we're using GLEW we will almost always need the context and context group when doing OpenGL calls
#include "cvfOpenGLContext.h" #include "cvfOpenGLContext.h"
@ -105,9 +106,9 @@ public:
static void clearOpenGLError(OpenGLContext* oglContext); static void clearOpenGLError(OpenGLContext* oglContext);
static String mapOpenGLErrorToString(cvfGLenum errorCode); static String mapOpenGLErrorToString(cvfGLenum errorCode);
static bool testAndReportOpenGLError(OpenGLContext* oglContext, const char* operation, const char* fileName, int line); static bool testAndReportOpenGLError(OpenGLContext* oglContext, const char* operation, const CodeLocation& codeLocation);
static void cvf_check_ogl(OpenGLContext* oglContext, const char* fileName, int line); static void cvf_check_ogl(OpenGLContext* oglContext, const CodeLocation& codeLocation);
static void enableCheckOgl(bool enable); static void enableCheckOgl(bool enable);
static bool isCheckOglEnabled(); static bool isCheckOglEnabled();
@ -123,8 +124,8 @@ private:
#define CVF_OGL_BUFFER_OFFSET(BYTE_OFFSET) ((char*)NULL + (BYTE_OFFSET)) #define CVF_OGL_BUFFER_OFFSET(BYTE_OFFSET) ((char*)NULL + (BYTE_OFFSET))
// Define used to log error messages with file and line // Define used to log error messages with file and line
#define CVF_CHECK_OGL(OGL_CTX_PTR) cvf::OpenGL::cvf_check_ogl(OGL_CTX_PTR, __FILE__, __LINE__) #define CVF_CHECK_OGL(OGL_CTX_PTR) cvf::OpenGL::cvf_check_ogl(OGL_CTX_PTR, CVF_CODE_LOCATION)
#define CVF_CLEAR_OGL_ERROR(OGL_CTX_PTR) cvf::OpenGL::clearOpenGLError(OGL_CTX_PTR) #define CVF_CLEAR_OGL_ERROR(OGL_CTX_PTR) cvf::OpenGL::clearOpenGLError(OGL_CTX_PTR)
#define CVF_TEST_AND_REPORT_OPENGL_ERROR(OGL_CTX_PTR, OPERATION) cvf::OpenGL::testAndReportOpenGLError(OGL_CTX_PTR, OPERATION, __FILE__, __LINE__) #define CVF_TEST_AND_REPORT_OPENGL_ERROR(OGL_CTX_PTR, OPERATION) cvf::OpenGL::testAndReportOpenGLError(OGL_CTX_PTR, OPERATION, CVF_CODE_LOCATION)

View File

@ -58,9 +58,9 @@ private:
friend class OpenGLContextGroup; friend class OpenGLContextGroup;
}; };
#define CVF_LOG_RENDER_ERROR(OGL_CTX_PTR, THE_MESSAGE) OGL_CTX_PTR->group()->logger()->error((THE_MESSAGE), __FILE__, __LINE__ ) #define CVF_LOG_RENDER_ERROR(OGL_CTX_PTR, THE_MESSAGE) OGL_CTX_PTR->group()->logger()->error((THE_MESSAGE), CVF_CODE_LOCATION)
#define CVF_LOG_RENDER_DEBUG(OGL_CTX_PTR, THE_MESSAGE) OGL_CTX_PTR->group()->logger()->debug((THE_MESSAGE), __FILE__, __LINE__ ) #define CVF_LOG_RENDER_DEBUG(OGL_CTX_PTR, THE_MESSAGE) OGL_CTX_PTR->group()->logger()->debug((THE_MESSAGE), CVF_CODE_LOCATION)
#define CVF_SHOULD_LOG_RENDER_DEBUG(OGL_CTX_PTR) OGL_CTX_PTR->group()->logger()->isDebugEnabled() #define CVF_SHOULD_LOG_RENDER_DEBUG(OGL_CTX_PTR) OGL_CTX_PTR->group()->logger()->isDebugEnabled()

View File

@ -23,7 +23,7 @@
#include "cvfOpenGLContext.h" #include "cvfOpenGLContext.h"
#include "cvfOpenGLResourceManager.h" #include "cvfOpenGLResourceManager.h"
#include "cvfOpenGLCapabilities.h" #include "cvfOpenGLCapabilities.h"
#include "cvfTrace.h" #include "cvfLogDestinationConsole.h"
#include <memory.h> #include <memory.h>
@ -58,7 +58,7 @@ OpenGLContextGroup::OpenGLContextGroup()
m_wglewContextStruct(NULL) m_wglewContextStruct(NULL)
{ {
m_resourceManager = new OpenGLResourceManager; m_resourceManager = new OpenGLResourceManager;
m_logger = new Logger; m_logger = new Logger("cvf.OpenGL", Logger::LL_WARNING, new LogDestinationConsole);
m_capabilities = new OpenGLCapabilities; m_capabilities = new OpenGLCapabilities;
} }

View File

@ -40,6 +40,7 @@
#ifndef CVF_OPENGL_ES #ifndef CVF_OPENGL_ES
#include "cvfRenderState_FF.h" #include "cvfRenderState_FF.h"
#endif #endif
#include "cvfTexture2D_FF.h"
namespace cvf { namespace cvf {
@ -164,6 +165,19 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons
RenderStateLighting_FF light(false); RenderStateLighting_FF light(false);
light.applyOpenGL(oglContext); light.applyOpenGL(oglContext);
// Use fixed function texture setup
ref<Texture2D_FF> texture = new Texture2D_FF(m_image.p());
texture->setWrapMode(Texture2D_FF::CLAMP);
texture->setMinFilter(Texture2D_FF::NEAREST);
texture->setMagFilter(Texture2D_FF::NEAREST);
texture->setupTexture(oglContext);
texture->setupTextureParams(oglContext);
ref<RenderStateTextureMapping_FF> textureMapping = new RenderStateTextureMapping_FF(texture.p());
textureMapping->setTextureFunction(m_blendMode == TEXTURE_ALPHA ? RenderStateTextureMapping_FF::MODULATE : RenderStateTextureMapping_FF::DECAL);
m_textureBindings = textureMapping;
#endif #endif
projCam.applyOpenGL(); projCam.applyOpenGL();
} }
@ -200,6 +214,18 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons
m_shaderProgram->clearUniformApplyTracking(); m_shaderProgram->clearUniformApplyTracking();
m_shaderProgram->applyFixedUniforms(oglContext, projMatrixState); m_shaderProgram->applyFixedUniforms(oglContext, projMatrixState);
} }
if (m_texture->textureOglId() == 0)
{
m_texture->setupTexture(oglContext);
}
if (m_textureBindings.isNull())
{
cvf::RenderStateTextureBindings* textureBindings = new cvf::RenderStateTextureBindings;
textureBindings->addBinding(m_texture.p(), m_sampler.p(), "u_texture2D");
m_textureBindings = textureBindings;
}
} }
Vec3f min(1.0f, 1.0f, 0.0f); Vec3f min(1.0f, 1.0f, 0.0f);
@ -214,12 +240,6 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons
v2[0] = max.x(); v2[1] = min.y(); v2[2] = 0.0f; v2[0] = max.x(); v2[1] = min.y(); v2[2] = 0.0f;
v3[0] = max.x(); v3[1] = max.y(); v3[2] = 0.0f; v3[0] = max.x(); v3[1] = max.y(); v3[2] = 0.0f;
v4[0] = min.x(); v4[1] = max.y(); v4[2] = 0.0f; v4[0] = min.x(); v4[1] = max.y(); v4[2] = 0.0f;
if (m_texture->textureOglId() == 0)
{
m_texture->setupTexture(oglContext);
}
if (m_blendMode != NO_BLENDING) if (m_blendMode != NO_BLENDING)
{ {
@ -233,7 +253,7 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons
if (software) if (software)
{ {
#ifndef CVF_OPENGL_ES #ifndef CVF_OPENGL_ES
glColor4f(1.0f, 1.0f, 1.0f, m_alpha); glColor4f(1.0f, 1.0f, 1.0f, m_blendMode == GLOBAL_ALPHA ? m_alpha : 1.0f);
glBegin(GL_TRIANGLE_FAN); glBegin(GL_TRIANGLE_FAN);
glTexCoord2f(textureCoords[0], textureCoords[1]); glTexCoord2f(textureCoords[0], textureCoords[1]);
glVertex3fv(v1); glVertex3fv(v1);
@ -263,6 +283,17 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons
blend.applyOpenGL(oglContext); blend.applyOpenGL(oglContext);
} }
RenderStateDepth resetDepth;
resetDepth.applyOpenGL(oglContext);
if (software)
{
#ifndef CVF_OPENGL_ES
RenderStateTextureMapping_FF resetTextureMapping;
resetTextureMapping.applyOpenGL(oglContext);
#endif
}
if (!software) if (!software)
{ {
glDisableVertexAttribArray(ShaderProgram::VERTEX); glDisableVertexAttribArray(ShaderProgram::VERTEX);
@ -280,8 +311,7 @@ void OverlayImage::setImage(TextureImage* image)
m_texture = new Texture(image); m_texture = new Texture(image);
m_textureBindings = new cvf::RenderStateTextureBindings; m_textureBindings = NULL;
m_textureBindings->addBinding(m_texture.p(), m_sampler.p(), "u_texture2D");
} }

View File

@ -25,7 +25,7 @@ namespace cvf {
class TextureImage; class TextureImage;
class Sampler; class Sampler;
class RenderStateTextureBindings; class RenderState;
class Texture; class Texture;
class ShaderProgram; class ShaderProgram;
@ -69,7 +69,7 @@ private:
Vec2ui m_size; Vec2ui m_size;
ref<TextureImage> m_image; ref<TextureImage> m_image;
ref<Sampler> m_sampler; ref<Sampler> m_sampler;
ref<RenderStateTextureBindings> m_textureBindings; ref<RenderState> m_textureBindings;
ref<Texture> m_texture; ref<Texture> m_texture;
ref<ShaderProgram> m_shaderProgram; ref<ShaderProgram> m_shaderProgram;

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,8 @@
#include "cvfBoundingBox.h" #include "cvfBoundingBox.h"
#include "cvfCollection.h" #include "cvfCollection.h"
#include <map>
namespace cvf { namespace cvf {
class Camera; class Camera;
@ -35,7 +37,7 @@ class Font;
class ShaderProgram; class ShaderProgram;
class MatrixState; class MatrixState;
class TextureImage; class TextureImage;
class RenderState;
//================================================================================================== //==================================================================================================
// //
@ -45,8 +47,8 @@ class TextureImage;
class OverlayNavigationCube: public OverlayItem class OverlayNavigationCube: public OverlayItem
{ {
public: public:
enum NavCubeFace { enum NavCubeFace
NCF_NONE, {
NCF_X_POS, NCF_X_POS,
NCF_X_NEG, NCF_X_NEG,
NCF_Y_POS, NCF_Y_POS,
@ -55,8 +57,31 @@ public:
NCF_Z_NEG NCF_Z_NEG
}; };
// Note that the order of the items starting at the VT_NCFI_BOTTOM_LEFT is important (in a CCW order) public:
enum NavCubeFaceItem { OverlayNavigationCube(Camera* camera, Font* font);
~OverlayNavigationCube();
virtual Vec2ui sizeHint();
virtual Vec2ui maximumSize();
virtual Vec2ui minimumSize();
virtual void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size);
virtual void renderSoftware(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size);
virtual bool pick(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size);
bool updateHighlight(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size);
bool processSelection(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size, Vec3d* viewDir, Vec3d* up);
void setSize(const Vec2ui& size);
void setHome(const Vec3d& viewDirection, const Vec3d& up);
void setAxisLabels(const String& xLabel, const String& yLabel, const String& zlabel);
void setAxisLabelsColor(const Color3f& color);
void setFaceTexture(NavCubeFace face, TextureImage* texture);
private:
// Note that the order of the items starting at the NCFI_BOTTOM_LEFT is important (in a CCW order)
enum NavCubeFaceItem
{
NCFI_NONE, NCFI_NONE,
NCFI_CENTER, NCFI_CENTER,
NCFI_BOTTOM_LEFT, NCFI_BOTTOM_LEFT,
@ -111,77 +136,76 @@ public:
NCI_ROTATE_CCW NCI_ROTATE_CCW
}; };
public: private:
OverlayNavigationCube(Camera* camera, Font* font); void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software);
~OverlayNavigationCube(); void createAxisGeometry(bool software);
void renderAxis(OpenGLContext* oglContext, const MatrixState& matrixState);
void renderAxisImmediateMode(OpenGLContext* oglContext, const MatrixState& matrixState);
void renderAxisLabels(OpenGLContext* oglContext, bool software, const MatrixState& matrixState);
void renderCubeGeos(OpenGLContext* oglContext, bool software, const MatrixState& matrixState);
void render2dItems(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software);
virtual Vec2ui sizeHint(); void createCubeGeos();
virtual Vec2ui maximumSize(); void createCubeFaceGeos(NavCubeFace face, Vec3f p1, Vec3f p2, Vec3f p3, Vec3f p4);
virtual Vec2ui minimumSize(); ref<DrawableGeo> createQuadGeo(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3, const Vec3f& v4, const Vec2f& t1, const Vec2f& t2, const Vec2f& t3, const Vec2f& t4);
void navCubeCornerPoints(Vec3f points[8]);
void create2dGeos();
ref<DrawableGeo> create2dArrow(const Vec3f& start, const Vec3f& end);
virtual void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size); NavCubeItem navCubeItem(NavCubeFace face, NavCubeFaceItem item) const;
virtual void renderSoftware(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size);
void setSize(const Vec2ui& size); void configureLocalCamera(Camera* camera, const Vec2i& position, const Vec2ui& size);
void updateHighlight(int winCoordX, int winCoordY);
void processSelection(int winCoordX, int winCoordY, const BoundingBox& boundingBox, Vec3d* eye, Vec3d* viewDirection);
void setAxisLabels(const String& xLabel, const String& yLabel, const String& zlabel); void viewConfigurationFromNavCubeItem(NavCubeItem item, Vec3d* viewDir, Vec3d* up);
void setAxisLabelsColor(const Color3f& color); Vec3d computeNewUpVector(const Vec3d& viewFrom, const Vec3d currentUp) const;
size_t pickItem(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size);
NavCubeItem pick2dItem(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size);
void updateTextureBindings(OpenGLContext* oglContext, bool software);
bool isFaceAlignedViewPoint() const;
static Vec3d snapToAxis(const Vec3d& vector, const Vec3d* pPreferIfEqual = NULL);
static bool vectorsParallelFuzzy(Vec3d v1, Vec3d v2);
static int findClosestAxis(const Vec3d& vector);
private: private:
void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software, const Mat4d& viewMatrix); ref<Camera> m_camera; // This camera's view matrix will be used to orient the axis cross
void createAxisGeometry(bool software); ref<Font> m_font;
void renderAxis(OpenGLContext* oglContext, const MatrixState& matrixState); String m_xLabel; // Label to display on x axis, default 'x'
void renderAxisImmediateMode(OpenGLContext* oglContext, const MatrixState& matrixState); String m_yLabel;
void renderAxisLabels(OpenGLContext* oglContext, bool software, const MatrixState& matrixState); String m_zLabel;
void renderCubeGeos(OpenGLContext* oglContext, bool software, const MatrixState& matrixState); Color3f m_textColor; // Text color
void createCubeGeos(); Vec2ui m_size; // Pixel size of the nav cube area
void createCubeFaceGeos(NavCubeFace face, Vec3f p1, Vec3f p2, Vec3f p3, Vec3f p4);//, const String& name, const Color3f& baseColor, TextureImage* texture);
void navCubeCornerPoints(Vec3f points[8]);
ref<DrawableGeo> createQuadGeo(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3, const Vec3f& v4);
NavCubeItem navCubeItem(NavCubeFace face, NavCubeFaceItem item) const; Vec3d m_homeViewDirection;
void faceOrientation(NavCubeFace face, Vec3f* normal, Vec3f* upVector, Vec3f* rightVector) const; Vec3d m_homeUp;
private: Collection<DrawableGeo> m_cubeGeos; // These arrays have the same length
ref<Camera> m_camera; // This camera's view matrix will be used to orient the axis cross std::vector<NavCubeItem> m_cubeItemType; // These arrays have the same length
String m_xLabel; // Label to display on x axis, default 'x' std::vector<NavCubeFace> m_cubeGeoFace; // These arrays have the same length
String m_yLabel;
String m_zLabel;
Color3f m_textColor; // Text color
ref<Font> m_font;
Vec2ui m_size; // Pixel size of the axis area ref<DrawableGeo> m_homeGeo; // These arrays have the same length
Collection<DrawableGeo> m_2dGeos; // These arrays have the same length
std::vector<NavCubeItem> m_2dItemType;
Collection<DrawableGeo> m_cubeGeos;
std::vector<NavCubeItem> m_cubeItemType;
ref<ShaderProgram> m_cubeGeoShader; ref<ShaderProgram> m_cubeGeoShader;
ref<ShaderProgram> m_cubeGeoTextureShader;
ref<DrawableVectors> m_axis; ref<DrawableVectors> m_axis;
NavCubeItem m_hightlightItem; ///< The currently highlighted cube item (face, corner, edge, buttons) NavCubeItem m_hightlightItem; ///< The currently highlighted cube item (face, corner, edge, buttons)
Vec3f m_upVector; ///< Specify the up vector, which is used for the orientation of the text and textures on the faces Vec3f m_upVector; ///< Specify the up vector, which is used for the orientation of the text and textures on the faces
Vec3f m_frontVector; ///< Specify the front vector, which is used for the orientation of the top and bottom faces Vec3f m_frontVector; ///< Specify the front vector, which is used for the orientation of the top and bottom faces
String m_xPosAxisName; ///< The name of the X_POS face Color3f m_xFaceColor; ///< The color of the X_POS and X_NEG faces
String m_xNegAxisName; ///< The name of the X_NEG face Color3f m_yFaceColor; ///< The color of the Y_POS and Y_NEG faces
String m_yPosAxisName; ///< The name of the Y_POS face Color3f m_zFaceColor; ///< The color of the Z_POS and Z_NEG faces
String m_yNegAxisName; ///< The name of the Y_NEG face Color3f m_itemHighlightColor;
String m_zPosAxisName; ///< The name of the Z_POS face Color3f m_2dItemsColor;
String m_zNegAxisName; ///< The name of the Z_NEG face
ref<TextureImage> m_texturePosXAxis; ///< The texture to draw on the X_POS face. If NULL, the specified text will be drawn. std::map<NavCubeFace, ref<TextureImage> > m_faceTextures;
ref<TextureImage> m_textureNegXAxis; ///< The texture to draw on the X_NEG face. If NULL, the specified text will be drawn. std::map<NavCubeFace, ref<RenderState> > m_faceTextureBindings;
ref<TextureImage> m_texturePosYAxis; ///< The texture to draw on the Y_POS face. If NULL, the specified text will be drawn.
ref<TextureImage> m_textureNegYAxis; ///< The texture to draw on the Y_NEG face. If NULL, the specified text will be drawn.
ref<TextureImage> m_texturePosZAxis; ///< The texture to draw on the Z_POS face. If NULL, the specified text will be drawn.
ref<TextureImage> m_textureNegZAxis; ///< The texture to draw on the Z_NEG face. If NULL, the specified text will be drawn.
Color3f m_xFaceColor; ///< The color of the X_POS and X_NEG faces
Color3f m_yFaceColor; ///< The color of the Y_POS and Y_NEG faces
Color3f m_zFaceColor; ///< The color of the Z_POS and Z_NEG faces
}; };
} }

View File

@ -34,6 +34,7 @@
#include "cvfMatrixState.h" #include "cvfMatrixState.h"
#include "cvfRenderStateDepth.h" #include "cvfRenderStateDepth.h"
#include "cvfRenderStateBlending.h" #include "cvfRenderStateBlending.h"
#include "cvfRenderStatePolygonOffset.h"
#ifndef CVF_OPENGL_ES #ifndef CVF_OPENGL_ES
#include "cvfRenderState_FF.h" #include "cvfRenderState_FF.h"
@ -60,7 +61,8 @@ TextDrawer::TextDrawer(Font* font)
m_textColor(Color3::GRAY), m_textColor(Color3::GRAY),
m_backgroundColor(1.0f, 1.0f, 0.8f), m_backgroundColor(1.0f, 1.0f, 0.8f),
m_borderColor(Color3::DARK_GRAY), m_borderColor(Color3::DARK_GRAY),
m_verticalAlignment(0) // BASELINE m_useDepthBuffer(false),
m_verticalAlignment(0) // BASELINE
{ {
CVF_ASSERT(font); CVF_ASSERT(font);
CVF_ASSERT(!font->isEmpty()); CVF_ASSERT(!font->isEmpty());
@ -88,6 +90,22 @@ void TextDrawer::addText(const String& text, const Vec2f& pos)
} }
//--------------------------------------------------------------------------------------------------
/// Add text to be drawn
///
/// Note: The Z coordinate needs to correspond with the orthographic projection that is setup
/// to render the text. So the range should be <1..-1> with 1 being closest to the near plane.
//--------------------------------------------------------------------------------------------------
void TextDrawer::addText(const String& text, const Vec3f& pos)
{
CVF_ASSERT(!text.isEmpty());
CVF_ASSERT(!pos.isUndefined());
m_texts.push_back(text);
m_positions.push_back(pos);
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Remove all texts in the drawer /// Remove all texts in the drawer
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -192,6 +210,15 @@ void TextDrawer::setDrawBorder(bool drawBorder)
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void TextDrawer::setUseDepthBuffer(bool useDepthBuffer)
{
m_useDepthBuffer = useDepthBuffer;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Returns the color used to draw the text /// Returns the color used to draw the text
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -284,7 +311,7 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix
MatrixState projMatrixState(projCam); MatrixState projMatrixState(projCam);
// Turn off depth test // Turn off depth test
RenderStateDepth depth(false, RenderStateDepth::LESS, false); RenderStateDepth depth(m_useDepthBuffer, RenderStateDepth::LESS, m_useDepthBuffer);
depth.applyOpenGL(oglContext); depth.applyOpenGL(oglContext);
// Setup viewport // Setup viewport
@ -322,6 +349,13 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
if (m_drawBackground || m_drawBorder) if (m_drawBackground || m_drawBorder)
{ {
if (m_useDepthBuffer)
{
RenderStatePolygonOffset polygonOffset;
polygonOffset.configurePolygonPositiveOffset();
polygonOffset.applyOpenGL(oglContext);
}
ref<ShaderProgram> backgroundShader; ref<ShaderProgram> backgroundShader;
if (!softwareRendering) if (!softwareRendering)
@ -353,10 +387,10 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix
Vec3f max = Vec3f(min.x() + static_cast<float>(textExtent.x()) + offset.x()*2.0f, min.y() + static_cast<float>(textExtent.y()) + offset.y()*2.0f, 0.0f); Vec3f max = Vec3f(min.x() + static_cast<float>(textExtent.x()) + offset.x()*2.0f, min.y() + static_cast<float>(textExtent.y()) + offset.y()*2.0f, 0.0f);
// Draw the background triangle // Draw the background triangle
v1[0] = min.x(); v1[1] = min.y(); v1[0] = min.x(); v1[1] = min.y(); v1[2] = pos.z();
v2[0] = max.x(); v2[1] = min.y(); v2[0] = max.x(); v2[1] = min.y(); v2[2] = pos.z();
v3[0] = max.x(); v3[1] = max.y(); v3[0] = max.x(); v3[1] = max.y(); v3[2] = pos.z();
v4[0] = min.x(); v4[1] = max.y(); v4[0] = min.x(); v4[1] = max.y(); v4[2] = pos.z();
if (m_drawBackground) if (m_drawBackground)
{ {
@ -408,6 +442,12 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix
} }
} }
} }
if (m_useDepthBuffer)
{
RenderStatePolygonOffset resetPolygonOffset;
resetPolygonOffset.applyOpenGL(oglContext);
}
} }
// Render texts // Render texts
@ -459,7 +499,6 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix
// Need to round off to integer positions to avoid buggy text drawing on iPad2 // Need to round off to integer positions to avoid buggy text drawing on iPad2
pos.x() = cvf::Math::floor(pos.x()); pos.x() = cvf::Math::floor(pos.x());
pos.y() = cvf::Math::floor(pos.y()); pos.y() = cvf::Math::floor(pos.y());
pos.z() = cvf::Math::floor(pos.z());
// Cursor incrementor // Cursor incrementor
Vec2f cursor(pos); Vec2f cursor(pos);
@ -484,18 +523,22 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix
// Lower left corner // Lower left corner
v1[0] = cursor.x() + static_cast<float>(glyph->horizontalBearingX()); v1[0] = cursor.x() + static_cast<float>(glyph->horizontalBearingX());
v1[1] = cursor.y() + static_cast<float>(glyph->horizontalBearingY()) - textureHeight + static_cast<float>(m_verticalAlignment); v1[1] = cursor.y() + static_cast<float>(glyph->horizontalBearingY()) - textureHeight + static_cast<float>(m_verticalAlignment);
v1[2] = pos.z();
// Lower right corner // Lower right corner
v2[0] = v1[0] + textureWidth; v2[0] = v1[0] + textureWidth;
v2[1] = v1[1]; v2[1] = v1[1];
v2[2] = pos.z();
// Upper right corner // Upper right corner
v3[0] = v2[0]; v3[0] = v2[0];
v3[1] = v1[1] + textureHeight; v3[1] = v1[1] + textureHeight;
v3[2] = pos.z();
// Upper left corner // Upper left corner
v4[0] = v1[0]; v4[0] = v1[0];
v4[1] = v3[1]; v4[1] = v3[1];
v4[2] = pos.z();
glyph->setupAndBindTexture(oglContext, softwareRendering); glyph->setupAndBindTexture(oglContext, softwareRendering);
@ -591,4 +634,32 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix
CVF_CHECK_OGL(oglContext); CVF_CHECK_OGL(oglContext);
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool TextDrawer::pickText(const Vec3f& pickCoord2d, const String& text, const Vec3f& pos, Font* font)
{
// Figure out margin
ref<Glyph> glyph = font->getGlyph(L'A');
float charHeight = static_cast<float>(glyph->height());
float charWidth = static_cast<float>(glyph->width());
float offsetX = cvf::Math::floor(charWidth/2.0f);
float offsetY = cvf::Math::floor(charHeight/2.0f);
Vec2ui textExtent = font->textExtent(text);
Vec3f min = pos;
Vec3f max = Vec3f(min.x() + static_cast<float>(textExtent.x()) + offsetX*2.0f, min.y() + static_cast<float>(textExtent.y()) + offsetY*2.0f, 0.0f);
if (pickCoord2d.x() > min.x() && pickCoord2d.x() < max.x() &&
pickCoord2d.y() > min.y() && pickCoord2d.y() < max.y())
{
return true;
}
return false;
}
} // namespace cvf } // namespace cvf

View File

@ -55,6 +55,7 @@ public:
virtual ~TextDrawer(); virtual ~TextDrawer();
void addText(const String& text, const Vec2f& pos); void addText(const String& text, const Vec2f& pos);
void addText(const String& text, const Vec3f& pos);
void removeAllTexts(); void removeAllTexts();
void setVerticalAlignment(Alignment alignment); void setVerticalAlignment(Alignment alignment);
@ -63,16 +64,21 @@ public:
void setBorderColor(const Color3f& color); void setBorderColor(const Color3f& color);
void setDrawBackground(bool drawBackground); void setDrawBackground(bool drawBackground);
void setDrawBorder(bool drawBorder); void setDrawBorder(bool drawBorder);
void setUseDepthBuffer(bool useDepthBuffer);
Color3f textColor() const; Color3f textColor() const;
Color3f backgroundColor() const; Color3f backgroundColor() const;
Color3f borderColor() const; Color3f borderColor() const;
bool drawBackground() const; bool drawBackground() const;
bool drawBorder() const; bool drawBorder() const;
bool useDepthBuffer() const;
void render(OpenGLContext* oglContext, const MatrixState& matrixState); void render(OpenGLContext* oglContext, const MatrixState& matrixState);
void renderSoftware(OpenGLContext* oglContext, const MatrixState& matrixState); void renderSoftware(OpenGLContext* oglContext, const MatrixState& matrixState);
static bool pickText(const Vec3f& pickCoord2d, const String& text, const Vec3f& pos, Font* font);
private: private:
void doRender2d(OpenGLContext* oglContext, const MatrixState& matrixState, bool softwareRendering); void doRender2d(OpenGLContext* oglContext, const MatrixState& matrixState, bool softwareRendering);
@ -87,6 +93,7 @@ private:
Color3f m_textColor; Color3f m_textColor;
Color3f m_backgroundColor; Color3f m_backgroundColor;
Color3f m_borderColor; Color3f m_borderColor;
bool m_useDepthBuffer;
short m_verticalAlignment;// Vertical alignment for horizontal text short m_verticalAlignment;// Vertical alignment for horizontal text
}; };

View File

@ -62,6 +62,7 @@ protected:
private: private:
CharArray m_name; CharArray m_name;
CVF_DISABLE_COPY_AND_ASSIGN(Uniform);
}; };
@ -85,6 +86,7 @@ public:
private: private:
IntArray m_data; IntArray m_data;
CVF_DISABLE_COPY_AND_ASSIGN(UniformInt);
}; };
@ -120,6 +122,7 @@ public:
private: private:
FloatArray m_data; FloatArray m_data;
CVF_DISABLE_COPY_AND_ASSIGN(UniformFloat);
}; };
@ -129,7 +132,7 @@ private:
// //
// //
//================================================================================================== //==================================================================================================
class UniformMatrixf: public Uniform class UniformMatrixf : public Uniform
{ {
public: public:
UniformMatrixf(const char* name); UniformMatrixf(const char* name);
@ -142,6 +145,7 @@ public:
private: private:
FloatArray m_data; FloatArray m_data;
CVF_DISABLE_COPY_AND_ASSIGN(UniformMatrixf);
}; };

View File

@ -904,6 +904,24 @@ OverlayItem* Rendering::overlayItemFromWindowCoordinates(int x, int y)
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Recti Rendering::overlayItemRect(OverlayItem* item)
{
OverlayItemRectMap itemRectMap;
calculateOverlayItemLayout(&itemRectMap);
OverlayItemRectMap::iterator it = itemRectMap.find(item);
if (it != itemRectMap.end())
{
return it->second;
}
return cvf::Recti();
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -963,6 +981,5 @@ String Rendering::debugString() const
return str; return str;
} }
} // namespace cvf } // namespace cvf

View File

@ -113,6 +113,7 @@ public:
OverlayItem* overlayItem(size_t index, OverlayItem::LayoutCorner* corner, OverlayItem::LayoutDirection* direction); OverlayItem* overlayItem(size_t index, OverlayItem::LayoutCorner* corner, OverlayItem::LayoutDirection* direction);
const OverlayItem* overlayItem(size_t index, OverlayItem::LayoutCorner* corner, OverlayItem::LayoutDirection* direction) const; const OverlayItem* overlayItem(size_t index, OverlayItem::LayoutCorner* corner, OverlayItem::LayoutDirection* direction) const;
OverlayItem* overlayItemFromWindowCoordinates(int x, int y); OverlayItem* overlayItemFromWindowCoordinates(int x, int y);
Recti overlayItemRect(OverlayItem* item);
void removeOverlayItem(const OverlayItem* overlayItem); void removeOverlayItem(const OverlayItem* overlayItem);
void removeAllOverlayItems(); void removeAllOverlayItems();