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
cvfBase64.h
cvfCharArray.h
cvfCodeLocation.h
cvfCollection.h
cvfCollection.inl
cvfColor3.h
@ -24,6 +25,11 @@ cvfFlags.h
cvfFlags.inl
cvfFunctorRange.h
cvfLibCore.h
cvfLogDestination.h
cvfLogDestinationConsole.h
cvfLogDestinationFile.h
cvfLogEvent.h
cvfLogManager.h
cvfLogger.h
cvfMath.h
cvfMath.inl
@ -31,6 +37,7 @@ cvfMatrix3.h
cvfMatrix3.inl
cvfMatrix4.h
cvfMatrix4.inl
cvfMutex.h
cvfObject.h
cvfObject.inl
cvfPlane.h
@ -60,11 +67,17 @@ set(CEE_SOURCE_FILES
cvfAssert.cpp
cvfBase64.cpp
cvfCharArray.cpp
cvfCodeLocation.cpp
cvfColor3.cpp
cvfColor4.cpp
cvfDebugTimer.cpp
cvfLogDestinationConsole.cpp
cvfLogDestinationFile.cpp
cvfLogEvent.cpp
cvfLogManager.cpp
cvfLogger.cpp
cvfMath.cpp
cvfMutex.cpp
cvfObject.cpp
cvfPlane.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 "cvfLogger.h"
#include "cvfTrace.h"
#include "cvfLogEvent.h"
#include "cvfLogDestination.h"
namespace cvf {
@ -31,17 +32,20 @@ namespace cvf {
/// \ingroup Core
///
/// 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
//--------------------------------------------------------------------------------------------------
Logger::Logger()
: m_debugLogging(false)
Logger::Logger(const String& loggerName, int logLevel, LogDestination* logDestination)
: m_name(loggerName),
m_logLevel(logLevel),
m_destination(logDestination)
{
}
@ -51,62 +55,145 @@ 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
/// \param line Use system macro __LINE__ for source code line number
//--------------------------------------------------------------------------------------------------
const String& Logger::name() const
{
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
/// source code file the error message was logged at.
/// Set a level of 0 to disable all logging for this logger.
//--------------------------------------------------------------------------------------------------
void Logger::error(const String& message, const char* fileName, int lineNumber)
void Logger::setLevel(int logLevel)
{
String tmp;
tmp = String(fileName) + "(" + String(lineNumber) + "): error: " + message;
Trace::show(tmp);
m_logLevel = logLevel;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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
String tmp;
tmp = "debug: " + message;
Trace::show(tmp);
log(message, LL_ERROR, location);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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

View File

@ -21,9 +21,14 @@
#include "cvfObject.h"
#include "cvfString.h"
#include "cvfCodeLocation.h"
namespace cvf {
class LogEvent;
class LogDestination;
//==================================================================================================
//
@ -33,20 +38,57 @@ namespace cvf {
class Logger : public Object
{
public:
Logger();
enum Level
{
LL_ERROR = 1,
LL_WARNING,
LL_INFO,
LL_DEBUG
};
public:
Logger(const String& loggerName, int logLevel, LogDestination* logDestination);
~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);
bool isDebugEnabled() const;
void debug(const String& message, const char* fileName, int lineNumber);
void error(const String& message);
void error(const String& message, const CodeLocation& location);
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:
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

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;
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;
void replace(const String& before, const String& after);

View File

@ -20,6 +20,7 @@ include_directories(glew)
set(CEE_HEADER_FILES
cvfBufferObjectManaged.h
cvfCamera.h
cvfCameraAnimation.h
cvfDrawable.h
cvfDrawableGeo.h
cvfDrawableText.h
@ -98,6 +99,7 @@ cvfViewport.h
set(CEE_SOURCE_FILES
cvfBufferObjectManaged.cpp
cvfCamera.cpp
cvfCameraAnimation.cpp
cvfDrawable.cpp
cvfDrawableGeo.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
/// 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);
// TODO! !!! !! !!
CVF_UNUSED(distanceScaleFactor);
cvf::Vec3d corners[8];
boundingBox.cornerVertices(corners);
@ -312,8 +322,8 @@ void Camera::fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec
distUp += (centerToCornerSide*boxEyeNorm);
// Adjust for the distance scale factor
distRight /= distanceScaleFactor;
distUp /= distanceScaleFactor;
distRight /= coverageFactor;
distUp /= coverageFactor;
dist = CVF_MAX(dist, distRight);
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
Vec3d eye = boundingBox.center()- dir.getNormalized()*dist;
// Will update cached values
setFromLookAt(eye, boundingBox.center(), up);
return eye;
}
@ -1023,6 +1032,5 @@ void Camera::applyOpenGL() const
#endif
}
} // 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 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);
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
{
CVF_ASSERT(intersectionPoint);
bool anyHits = false;
double minDistSquared = 1.0e300;
@ -1314,19 +1312,23 @@ bool DrawableGeo::rayIntersect(const Ray& ray, Vec3d* intersectionPoint, uint* f
double distSquared = (ray.origin() - localIntersect).lengthSquared();
#pragma omp critical
{
if (distSquared < minDistSquared)
if (distSquared < minDistSquared)
{
if (intersectionPoint)
{
*intersectionPoint = localIntersect;
minDistSquared = distSquared;
if (faceHit)
{
*faceHit = i + accumulatedFaceCount;
}
*intersectionPoint = localIntersect;
}
anyHits = true;
}
minDistSquared = distSquared;
if (faceHit)
{
*faceHit = i + accumulatedFaceCount;
}
}
anyHits = true;
}
}
} // End omp parallel for
accumulatedFaceCount += numPrimFaces;
}

View File

@ -64,7 +64,8 @@ DrawableText::DrawableText()
m_borderColor(Color3::BLACK),
m_drawBackground(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))
{
// 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]);
}
}
@ -355,12 +365,13 @@ void DrawableText::renderText(OpenGLContext* oglContext, ShaderProgram* shaderPr
drawer.setBorderColor(m_borderColor);
drawer.setDrawBorder(m_drawBorder);
drawer.setDrawBackground(m_drawBackground);
drawer.setUseDepthBuffer(m_useDepthBuffer);
size_t i;
for (i = 0; i < textsToDraw.size(); i++)
{
Vec3f pos = projCoords[i];
drawer.addText(textsToDraw[i], Vec2f(pos));
drawer.addText(textsToDraw[i], pos);
}
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

View File

@ -30,6 +30,7 @@ class Font;
class DrawableGeo;
class ShaderProgram;
class BufferObjectManaged;
class Camera;
//==================================================================================================
@ -55,6 +56,7 @@ public:
void setDrawBackground(bool drawBackground);
void setDrawBorder(bool drawBorder);
void setCheckPosVisible(bool checkpos);
void setUseDepthBuffer(bool useDepthBuffer);
virtual void createUploadBufferObjectsGPU(OpenGLContext* /*oglContext*/) {}
virtual void releaseBufferObjectsGPU() {}
@ -69,6 +71,7 @@ public:
virtual BoundingBox boundingBox() 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!
virtual void renderFixedFunction(OpenGLContext* oglContext, const MatrixState& matrixState) { renderSoftware(oglContext, matrixState); }
@ -92,6 +95,7 @@ private:
bool m_drawBackground;
bool m_drawBorder;
bool m_checkPosVisible;
bool m_useDepthBuffer;
BoundingBox m_boundingBox; //
};

View File

@ -136,7 +136,7 @@ String OpenGL::mapOpenGLErrorToString(cvfGLenum errorCode)
//--------------------------------------------------------------------------------------------------
/// 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
CVF_ASSERT(oglContext);
@ -157,7 +157,7 @@ bool OpenGL::testAndReportOpenGLError(OpenGLContext* oglContext, const char* ope
String errCodeStr = mapOpenGLErrorToString(err);
String msg = String("Operation: ") + operation;
msg += "OGL(" + errCodeStr + "): ";
logger->error(msg, fileName, line);
logger->error(msg, codeLocation);
}
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)
{
@ -186,7 +186,7 @@ void OpenGL::cvf_check_ogl(OpenGLContext* oglContext, const char* fileName, int
{
String errCodeStr = mapOpenGLErrorToString(err);
String msg = "OGL(" + errCodeStr + "): ";
logger->error(msg, fileName, line);
logger->error(msg, codeLocation);
}
err = glGetError();

View File

@ -84,6 +84,7 @@
#include "cvfOpenGLTypes.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
#include "cvfOpenGLContext.h"
@ -105,9 +106,9 @@ public:
static void clearOpenGLError(OpenGLContext* oglContext);
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 bool isCheckOglEnabled();
@ -123,8 +124,8 @@ private:
#define CVF_OGL_BUFFER_OFFSET(BYTE_OFFSET) ((char*)NULL + (BYTE_OFFSET))
// 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_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;
};
#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()

View File

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

View File

@ -40,6 +40,7 @@
#ifndef CVF_OPENGL_ES
#include "cvfRenderState_FF.h"
#endif
#include "cvfTexture2D_FF.h"
namespace cvf {
@ -164,6 +165,19 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons
RenderStateLighting_FF light(false);
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
projCam.applyOpenGL();
}
@ -200,6 +214,18 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons
m_shaderProgram->clearUniformApplyTracking();
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);
@ -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;
v3[0] = max.x(); v3[1] = max.y(); v3[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)
{
@ -233,7 +253,7 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons
if (software)
{
#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);
glTexCoord2f(textureCoords[0], textureCoords[1]);
glVertex3fv(v1);
@ -263,6 +283,17 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons
blend.applyOpenGL(oglContext);
}
RenderStateDepth resetDepth;
resetDepth.applyOpenGL(oglContext);
if (software)
{
#ifndef CVF_OPENGL_ES
RenderStateTextureMapping_FF resetTextureMapping;
resetTextureMapping.applyOpenGL(oglContext);
#endif
}
if (!software)
{
glDisableVertexAttribArray(ShaderProgram::VERTEX);
@ -280,8 +311,7 @@ void OverlayImage::setImage(TextureImage* image)
m_texture = new Texture(image);
m_textureBindings = new cvf::RenderStateTextureBindings;
m_textureBindings->addBinding(m_texture.p(), m_sampler.p(), "u_texture2D");
m_textureBindings = NULL;
}

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,8 @@
#include "cvfBoundingBox.h"
#include "cvfCollection.h"
#include <map>
namespace cvf {
class Camera;
@ -35,7 +37,7 @@ class Font;
class ShaderProgram;
class MatrixState;
class TextureImage;
class RenderState;
//==================================================================================================
//
@ -45,8 +47,8 @@ class TextureImage;
class OverlayNavigationCube: public OverlayItem
{
public:
enum NavCubeFace {
NCF_NONE,
enum NavCubeFace
{
NCF_X_POS,
NCF_X_NEG,
NCF_Y_POS,
@ -55,8 +57,31 @@ public:
NCF_Z_NEG
};
// Note that the order of the items starting at the VT_NCFI_BOTTOM_LEFT is important (in a CCW order)
enum NavCubeFaceItem {
public:
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_CENTER,
NCFI_BOTTOM_LEFT,
@ -111,77 +136,76 @@ public:
NCI_ROTATE_CCW
};
public:
OverlayNavigationCube(Camera* camera, Font* font);
~OverlayNavigationCube();
private:
void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software);
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();
virtual Vec2ui maximumSize();
virtual Vec2ui minimumSize();
void createCubeGeos();
void createCubeFaceGeos(NavCubeFace face, Vec3f p1, Vec3f p2, Vec3f p3, Vec3f p4);
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);
virtual void renderSoftware(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size);
NavCubeItem navCubeItem(NavCubeFace face, NavCubeFaceItem item) const;
void setSize(const Vec2ui& size);
void updateHighlight(int winCoordX, int winCoordY);
void processSelection(int winCoordX, int winCoordY, const BoundingBox& boundingBox, Vec3d* eye, Vec3d* viewDirection);
void configureLocalCamera(Camera* camera, const Vec2i& position, const Vec2ui& size);
void setAxisLabels(const String& xLabel, const String& yLabel, const String& zlabel);
void setAxisLabelsColor(const Color3f& color);
void viewConfigurationFromNavCubeItem(NavCubeItem item, Vec3d* viewDir, Vec3d* up);
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:
void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software, const Mat4d& viewMatrix);
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);
ref<Camera> m_camera; // This camera's view matrix will be used to orient the axis cross
ref<Font> m_font;
String m_xLabel; // Label to display on x axis, default 'x'
String m_yLabel;
String m_zLabel;
Color3f m_textColor; // Text color
void createCubeGeos();
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);
Vec2ui m_size; // Pixel size of the nav cube area
NavCubeItem navCubeItem(NavCubeFace face, NavCubeFaceItem item) const;
void faceOrientation(NavCubeFace face, Vec3f* normal, Vec3f* upVector, Vec3f* rightVector) const;
Vec3d m_homeViewDirection;
Vec3d m_homeUp;
private:
ref<Camera> m_camera; // This camera's view matrix will be used to orient the axis cross
String m_xLabel; // Label to display on x axis, default 'x'
String m_yLabel;
String m_zLabel;
Color3f m_textColor; // Text color
ref<Font> m_font;
Collection<DrawableGeo> m_cubeGeos; // These arrays have the same length
std::vector<NavCubeItem> m_cubeItemType; // These arrays have the same length
std::vector<NavCubeFace> m_cubeGeoFace; // These arrays have the same length
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_cubeGeoTextureShader;
ref<DrawableVectors> m_axis;
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_frontVector; ///< Specify the front vector, which is used for the orientation of the top and bottom faces
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_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
String m_xNegAxisName; ///< The name of the X_NEG face
String m_yPosAxisName; ///< The name of the Y_POS face
String m_yNegAxisName; ///< The name of the Y_NEG face
String m_zPosAxisName; ///< The name of the Z_POS face
String m_zNegAxisName; ///< The name of the Z_NEG face
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
Color3f m_itemHighlightColor;
Color3f m_2dItemsColor;
ref<TextureImage> m_texturePosXAxis; ///< The texture to draw on the X_POS face. If NULL, the specified text will be drawn.
ref<TextureImage> m_textureNegXAxis; ///< The texture to draw on the X_NEG face. If NULL, the specified text will be drawn.
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
std::map<NavCubeFace, ref<TextureImage> > m_faceTextures;
std::map<NavCubeFace, ref<RenderState> > m_faceTextureBindings;
};
}

View File

@ -34,6 +34,7 @@
#include "cvfMatrixState.h"
#include "cvfRenderStateDepth.h"
#include "cvfRenderStateBlending.h"
#include "cvfRenderStatePolygonOffset.h"
#ifndef CVF_OPENGL_ES
#include "cvfRenderState_FF.h"
@ -60,7 +61,8 @@ TextDrawer::TextDrawer(Font* font)
m_textColor(Color3::GRAY),
m_backgroundColor(1.0f, 1.0f, 0.8f),
m_borderColor(Color3::DARK_GRAY),
m_verticalAlignment(0) // BASELINE
m_useDepthBuffer(false),
m_verticalAlignment(0) // BASELINE
{
CVF_ASSERT(font);
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
//--------------------------------------------------------------------------------------------------
@ -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
//--------------------------------------------------------------------------------------------------
@ -284,7 +311,7 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix
MatrixState projMatrixState(projCam);
// Turn off depth test
RenderStateDepth depth(false, RenderStateDepth::LESS, false);
RenderStateDepth depth(m_useDepthBuffer, RenderStateDepth::LESS, m_useDepthBuffer);
depth.applyOpenGL(oglContext);
// Setup viewport
@ -322,6 +349,13 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix
// -------------------------------------------------------------------------
if (m_drawBackground || m_drawBorder)
{
if (m_useDepthBuffer)
{
RenderStatePolygonOffset polygonOffset;
polygonOffset.configurePolygonPositiveOffset();
polygonOffset.applyOpenGL(oglContext);
}
ref<ShaderProgram> backgroundShader;
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);
// Draw the background triangle
v1[0] = min.x(); v1[1] = min.y();
v2[0] = max.x(); v2[1] = min.y();
v3[0] = max.x(); v3[1] = max.y();
v4[0] = min.x(); v4[1] = max.y();
v1[0] = min.x(); v1[1] = min.y(); v1[2] = pos.z();
v2[0] = max.x(); v2[1] = min.y(); v2[2] = pos.z();
v3[0] = max.x(); v3[1] = max.y(); v3[2] = pos.z();
v4[0] = min.x(); v4[1] = max.y(); v4[2] = pos.z();
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
@ -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
pos.x() = cvf::Math::floor(pos.x());
pos.y() = cvf::Math::floor(pos.y());
pos.z() = cvf::Math::floor(pos.z());
// Cursor incrementor
Vec2f cursor(pos);
@ -484,18 +523,22 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix
// Lower left corner
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[2] = pos.z();
// Lower right corner
v2[0] = v1[0] + textureWidth;
v2[1] = v1[1];
v2[2] = pos.z();
// Upper right corner
v3[0] = v2[0];
v3[1] = v1[1] + textureHeight;
v3[2] = pos.z();
// Upper left corner
v4[0] = v1[0];
v4[1] = v3[1];
v4[2] = pos.z();
glyph->setupAndBindTexture(oglContext, softwareRendering);
@ -591,4 +634,32 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix
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

View File

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

View File

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

View File

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