aqsis-commits Mailing List for Aqsis Renderer (Page 2)
Brought to you by:
ltatkinson,
pgregory
You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(63) |
Nov
(118) |
Dec
(46) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(35) |
Feb
(208) |
Mar
(82) |
Apr
(161) |
May
(144) |
Jun
(48) |
Jul
(74) |
Aug
(153) |
Sep
(161) |
Oct
(92) |
Nov
(59) |
Dec
(49) |
2003 |
Jan
(130) |
Feb
(213) |
Mar
(178) |
Apr
(276) |
May
(212) |
Jun
(216) |
Jul
(115) |
Aug
(112) |
Sep
(148) |
Oct
(36) |
Nov
(71) |
Dec
(206) |
2004 |
Jan
(221) |
Feb
(364) |
Mar
(365) |
Apr
(196) |
May
(1144) |
Jun
(368) |
Jul
(180) |
Aug
(135) |
Sep
(15) |
Oct
(24) |
Nov
(70) |
Dec
(32) |
2005 |
Jan
(39) |
Feb
(12) |
Mar
(47) |
Apr
(300) |
May
(8) |
Jun
(98) |
Jul
(62) |
Aug
(75) |
Sep
(88) |
Oct
(143) |
Nov
(213) |
Dec
(114) |
2006 |
Jan
(168) |
Feb
(147) |
Mar
(34) |
Apr
(39) |
May
(13) |
Jun
(32) |
Jul
(49) |
Aug
(25) |
Sep
(18) |
Oct
(65) |
Nov
(107) |
Dec
(61) |
2007 |
Jan
(125) |
Feb
(83) |
Mar
(27) |
Apr
(80) |
May
(53) |
Jun
(99) |
Jul
(198) |
Aug
(164) |
Sep
(66) |
Oct
(94) |
Nov
(110) |
Dec
(28) |
2008 |
Jan
(34) |
Feb
(81) |
Mar
(66) |
Apr
(61) |
May
(92) |
Jun
(68) |
Jul
(100) |
Aug
(74) |
Sep
(63) |
Oct
(81) |
Nov
(58) |
Dec
(31) |
2009 |
Jan
(69) |
Feb
(59) |
Mar
(42) |
Apr
(14) |
May
(67) |
Jun
(64) |
Jul
(5) |
Aug
(53) |
Sep
(55) |
Oct
(35) |
Nov
(2) |
Dec
|
2010 |
Jan
(9) |
Feb
(30) |
Mar
(11) |
Apr
(10) |
May
(10) |
Jun
(10) |
Jul
(19) |
Aug
(57) |
Sep
(44) |
Oct
(57) |
Nov
(24) |
Dec
(2) |
2011 |
Jan
|
Feb
|
Mar
|
Apr
(39) |
May
(40) |
Jun
(16) |
Jul
(32) |
Aug
(30) |
Sep
(14) |
Oct
(5) |
Nov
|
Dec
(1) |
2012 |
Jan
(1) |
Feb
(12) |
Mar
(11) |
Apr
|
May
|
Jun
|
Jul
|
Aug
(4) |
Sep
|
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Paul G. <pgr...@us...> - 2012-02-26 09:36:17
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via 88f3090162632d1a11db8e25f774491545f494e5 (commit) via 5fc759aa5e76b4beba2fcd18e51c41e00b13f2fe (commit) via b501e4f6584c6bdc8619528409c8710604950e29 (commit) via 3c70b4d70e0131977a199ed920adb66c0a8bbd3e (commit) from 6512deff8b3307eb622502368bd15977f7379a5d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 88f3090162632d1a11db8e25f774491545f494e5 Author: Paul Gregory <pgr...@aq...> Date: Sun Feb 19 09:32:52 2012 +0000 Minor addition to the RSL compiler. * Under MinGW it's necessary to build with Boost shared, as such the aqsl tool needs to find the appropriate dlls at build time so they are added to the path. diff --git a/cmake/RSLCompile.cmake b/cmake/RSLCompile.cmake index eb8a881..b987c07 100644 --- a/cmake/RSLCompile.cmake +++ b/cmake/RSLCompile.cmake @@ -175,7 +175,7 @@ MACRO(add_rslshaders RSL_TARGET) else() file(TO_NATIVE_PATH "${aqsis_util_location}" aqsis_util_path) file(TO_NATIVE_PATH "${aqsis_slcomp_location}" aqsis_slcomp_path) - set(shared_lib_path "${aqsis_util_path}" "${aqsis_slcomp_path}") + set(shared_lib_path "${Boost_LIBRARY_DIRS}") get_target_property(aqsl_command ${RSL_COMPILER} LOCATION) add_custom_command( OUTPUT ${RSL_SHADER} @@ -186,6 +186,7 @@ MACRO(add_rslshaders RSL_TARGET) -DRSL_SOURCE="${RSL_SOURCE}" -Dutil_path="${aqsis_util_path}" -Dslcomp_path="${aqsis_slcomp_path}" + -Dshared_lib_path="${shared_lib_path}" -P ${CMAKE_SOURCE_DIR}/cmake/aqslcompile.cmake DEPENDS ${RSL_SHADER_DEPENDS} COMMENT "Compiling RSL shader ${RSL_SHADER}" diff --git a/cmake/aqslcompile.cmake b/cmake/aqslcompile.cmake index 5fa526e..4b8bd1d 100644 --- a/cmake/aqslcompile.cmake +++ b/cmake/aqslcompile.cmake @@ -1,4 +1,4 @@ -set(ENV{PATH} "$ENV{PATH};${util_path};${slcomp_path}") +set(ENV{PATH} "$ENV{PATH};${util_path};${slcomp_path};${shared_lib_path}") separate_arguments(RSL_COMPILE_FLAGS) execute_process(COMMAND ${RSL_COMPILER} ${RSL_COMPILE_FLAGS} ${RSL_DEPEND_FLAGS} -o ${RSL_SHADER} commit 5fc759aa5e76b4beba2fcd18e51c41e00b13f2fe Author: Paul Gregory <pgr...@aq...> Date: Sat Feb 18 10:33:35 2012 +0000 Minor MinGW support changes. * Seems that boost needs to be shared on MinGW, thread library issues. Needs further investigation to be certain. * Fix the preprocessor macro that control inclusion of Win32 headers to properly not do so when building with MinGW. diff --git a/CMakeLists.txt b/CMakeLists.txt index 413ff4f..f50a4be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,7 +68,9 @@ find_package(ZLIB) # Find boost. if(WIN32) set(BOOST_ROOT "${AQSIS_DEPENDENCIES}" CACHE PATH "Root location of the boost install") - set(Boost_USE_STATIC_LIBS ON) + if(NOT MINGW) + set(Boost_USE_STATIC_LIBS ON) + endif() else() set(BOOST_ROOT "$ENV{BOOST_ROOT}" CACHE PATH "Root location of the Boost install") endif() diff --git a/tools/eqsl/eqsl.cpp b/tools/eqsl/eqsl.cpp index de9e846..414870f 100644 --- a/tools/eqsl/eqsl.cpp +++ b/tools/eqsl/eqsl.cpp @@ -34,7 +34,7 @@ #include <cstdlib> #include <functional> -#if !defined AQSIS_SYSTEM_WIN32 || defined AQSIS_COMPILER_GCC +#if defined AQSIS_SYSTEM_WIN32 && !defined AQSIS_COMPILER_GCC # include <signal.h> # include <sys/wait.h> # include <sys/types.h> commit b501e4f6584c6bdc8619528409c8710604950e29 Author: Paul Gregory <pgr...@aq...> Date: Sat Feb 18 10:32:19 2012 +0000 Minor change to support Boost 1.48.0. * Seems filesystem has changed again, native() now returns a const string of type string_type, which on some systems may default to unicode. Instead, use the string() fuction which is templatised, and takes care of any necessary conversion based on the return type. diff --git a/libs/util/file.cpp b/libs/util/file.cpp index 290e40d..6182a38 100644 --- a/libs/util/file.cpp +++ b/libs/util/file.cpp @@ -272,7 +272,7 @@ std::vector<std::string> cliGlob(const std::string& pattern) std::string native(const boostfs::path& path) { #if BOOST_FILESYSTEM_VERSION == 3 - return path.native(); + return path.string(); #elif BOOST_FILESYSTEM_VERSION == 2 return path.file_string(); #endif @@ -282,7 +282,7 @@ std::string native(const boostfs::path& path) std::string filename(const boostfs::path& path) { #if BOOST_FILESYSTEM_VERSION == 3 - return path.filename().native(); + return path.filename().string(); #elif BOOST_FILESYSTEM_VERSION == 2 return path.leaf(); #endif commit 3c70b4d70e0131977a199ed920adb66c0a8bbd3e Author: Paul Gregory <pgr...@aq...> Date: Sun Feb 12 19:40:24 2012 +0000 Fix the recent MinGW commit. * The include conditions in eqsl.cpp were wrong, should only include those files if not on windows, or if on windows and running MinGW. * The CMake setup for ptview needed to have the qtmain.lib file to resolve the WinMain dependency. diff --git a/tools/eqsl/eqsl.cpp b/tools/eqsl/eqsl.cpp index 414870f..de9e846 100644 --- a/tools/eqsl/eqsl.cpp +++ b/tools/eqsl/eqsl.cpp @@ -34,7 +34,7 @@ #include <cstdlib> #include <functional> -#if defined AQSIS_SYSTEM_WIN32 && !defined AQSIS_COMPILER_GCC +#if !defined AQSIS_SYSTEM_WIN32 || defined AQSIS_COMPILER_GCC # include <signal.h> # include <sys/wait.h> # include <sys/types.h> diff --git a/tools/ptview/CMakeLists.txt b/tools/ptview/CMakeLists.txt index 7e16380..8010646 100644 --- a/tools/ptview/CMakeLists.txt +++ b/tools/ptview/CMakeLists.txt @@ -29,6 +29,10 @@ if(QT_FOUND AND OPENGL_FOUND) if(MINGW) list(APPEND ptview_link_libraries pthread) endif() + if(WIN32) + list(APPEND ptview_link_libraries ${QT_QTMAIN_LIBRARY}) + endif() + aqsis_add_executable(ptview ${srcs} GUIAPP LINK_LIBRARIES ${ptview_link_libraries}) ----------------------------------------------------------------------- Summary of changes: CMakeLists.txt | 4 +++- cmake/RSLCompile.cmake | 3 ++- cmake/aqslcompile.cmake | 2 +- libs/util/file.cpp | 4 ++-- tools/ptview/CMakeLists.txt | 4 ++++ 5 files changed, 12 insertions(+), 5 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Paul G. <pgr...@us...> - 2012-02-12 18:21:10
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via 6512deff8b3307eb622502368bd15977f7379a5d (commit) via 69c1404c2c1a6991b270728b75fc6f139cf39ba2 (commit) via 054b2a8a39a7dfeaa7ce33b4142e7ad39cde5017 (commit) from c1bb0a7022a6c387ee51a8620d13fae2ca48996f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6512deff8b3307eb622502368bd15977f7379a5d Author: Paul Gregory <pgr...@aq...> Date: Sun Feb 12 18:19:12 2012 +0000 Fix GL header inclusion. * No need to include GL/gl.h as Qt takes care of it, and GL/gl.h is not valid on MacOSX. diff --git a/tools/ptview/ptview.cpp b/tools/ptview/ptview.cpp index 897cc8b..97ddfe5 100644 --- a/tools/ptview/ptview.cpp +++ b/tools/ptview/ptview.cpp @@ -30,9 +30,6 @@ #define GL_GLEXT_PROTOTYPES -#include <GL/gl.h> -#include <GL/glext.h> - #include <QtCore/QSignalMapper> #include <QtGui/QApplication> #include <QtGui/QKeyEvent> commit 69c1404c2c1a6991b270728b75fc6f139cf39ba2 Author: Bart Janssens <bar...@li...> Date: Mon Jan 30 22:55:15 2012 +0100 Clean up MINGW build fixes * pthread linking is conditional as Paul suggested * export an additional symbol for linking with K-3D diff --git a/libs/core/renderer.h b/libs/core/renderer.h index 015fc23..42da935 100644 --- a/libs/core/renderer.h +++ b/libs/core/renderer.h @@ -106,7 +106,7 @@ enum EqRenderMode */ class CqRenderer; -extern CqRenderer* pCurrRenderer; +AQSIS_CORE_SHARE extern CqRenderer* pCurrRenderer; class CqRenderer : public IqRenderer { diff --git a/libs/shadervm/CMakeLists.txt b/libs/shadervm/CMakeLists.txt index 8111557..fb51127 100644 --- a/libs/shadervm/CMakeLists.txt +++ b/libs/shadervm/CMakeLists.txt @@ -29,11 +29,16 @@ source_group("Header Files" FILES ${shadervm_hdrs}) add_subproject(shaderexecenv) include_subproject(pointrender) +set(shadervm_link_libraries aqsis_math aqsis_util aqsis_tex ${Boost_REGEX_LIBRARY} ${pointrender_libs}) +if(MINGW) + list(APPEND shadervm_link_libraries pthread) +endif() + + aqsis_add_library(aqsis_shadervm ${shadervm_srcs} ${shadervm_hdrs} ${shaderexecenv_srcs} ${shaderexecenv_hdrs} ${pointrender_srcs} COMPILE_DEFINITIONS AQSIS_SHADERVM_EXPORTS - LINK_LIBRARIES aqsis_math aqsis_util aqsis_tex ${Boost_REGEX_LIBRARY} - ${pointrender_libs} pthread + LINK_LIBRARIES ${shadervm_link_libraries} ) aqsis_install_targets(aqsis_shadervm) diff --git a/tools/ptview/CMakeLists.txt b/tools/ptview/CMakeLists.txt index 1002733..7e16380 100644 --- a/tools/ptview/CMakeLists.txt +++ b/tools/ptview/CMakeLists.txt @@ -22,10 +22,15 @@ if(QT_FOUND AND OPENGL_FOUND) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS") endif() - aqsis_add_executable(ptview ${srcs} GUIAPP - LINK_LIBRARIES ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} + set(ptview_link_libraries ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} - ${OPENGL_gl_LIBRARY} ${pointrender_libs} aqsis_util pthread) + ${OPENGL_gl_LIBRARY} ${pointrender_libs} aqsis_util) + + if(MINGW) + list(APPEND ptview_link_libraries pthread) + endif() + aqsis_add_executable(ptview ${srcs} GUIAPP + LINK_LIBRARIES ${ptview_link_libraries}) aqsis_install_targets(ptview) endif() commit 054b2a8a39a7dfeaa7ce33b4142e7ad39cde5017 Author: Bart Janssens <bar...@li...> Date: Sun Jan 22 11:26:06 2012 +0100 Fix compile errors and a socket error in piqsl on mingw diff --git a/libs/riutil/CMakeLists.txt b/libs/riutil/CMakeLists.txt index 368809e..54bbe85 100644 --- a/libs/riutil/CMakeLists.txt +++ b/libs/riutil/CMakeLists.txt @@ -46,7 +46,7 @@ source_group("Header Files" FILES ${riutil_hdrs}) aqsis_add_library(aqsis_riutil ${riutil_srcs} ${riutil_hdrs} TEST_SOURCES ${riutil_test_srcs} COMPILE_DEFINITIONS AQSIS_RIUTIL_EXPORTS USE_GZIPPED_RIB - LINK_LIBRARIES aqsis_util ${Boost_IOSTREAMS_LIBRARY} ${Boost_ZLIB_LIBRARY} + LINK_LIBRARIES aqsis_util ${Boost_IOSTREAMS_LIBRARY} ${AQSIS_ZLIB_LIBRARIES} ) aqsis_install_targets(aqsis_riutil) diff --git a/libs/shadervm/CMakeLists.txt b/libs/shadervm/CMakeLists.txt index 2d501cd..8111557 100644 --- a/libs/shadervm/CMakeLists.txt +++ b/libs/shadervm/CMakeLists.txt @@ -33,7 +33,7 @@ aqsis_add_library(aqsis_shadervm ${shadervm_srcs} ${shadervm_hdrs} ${shaderexecenv_srcs} ${shaderexecenv_hdrs} ${pointrender_srcs} COMPILE_DEFINITIONS AQSIS_SHADERVM_EXPORTS LINK_LIBRARIES aqsis_math aqsis_util aqsis_tex ${Boost_REGEX_LIBRARY} - ${pointrender_libs} + ${pointrender_libs} pthread ) aqsis_install_targets(aqsis_shadervm) diff --git a/libs/util/file.cpp b/libs/util/file.cpp index 418ad11..290e40d 100644 --- a/libs/util/file.cpp +++ b/libs/util/file.cpp @@ -263,7 +263,6 @@ std::vector<std::string> cliGlob(const std::string& pattern) #endif // AQSIS_SYSTEM_WIN32 - // Define BOOST_FILESYSTEM_VERSION for convenience; older boost versions don't // define this for us. #ifndef BOOST_FILESYSTEM_VERSION @@ -289,5 +288,4 @@ std::string filename(const boostfs::path& path) #endif } - } // namespace Aqsis diff --git a/libs/util/win32/socket_system.cpp b/libs/util/win32/socket_system.cpp index 619309e..58ba76f 100644 --- a/libs/util/win32/socket_system.cpp +++ b/libs/util/win32/socket_system.cpp @@ -70,6 +70,7 @@ bool CqSocket::initialiseSockets() { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ + Aqsis::log() << error << "Error initializing sockets, code: " << err << std::endl; return(false); } diff --git a/tools/eqsl/eqsl.cpp b/tools/eqsl/eqsl.cpp index 7b1b256..414870f 100644 --- a/tools/eqsl/eqsl.cpp +++ b/tools/eqsl/eqsl.cpp @@ -34,7 +34,7 @@ #include <cstdlib> #include <functional> -#ifndef AQSIS_SYSTEM_WIN32 +#if defined AQSIS_SYSTEM_WIN32 && !defined AQSIS_COMPILER_GCC # include <signal.h> # include <sys/wait.h> # include <sys/types.h> @@ -169,7 +169,7 @@ void EqslMainWindow::renderFile() renderEngineArgsBundle.push_back("-nocolor"); // Call relevant commandline -#ifdef AQSIS_SYSTEM_WIN32 +#if defined AQSIS_SYSTEM_WIN32 && !defined AQSIS_COMPILER_GCC char acPath[256]; char root[256]; if( GetModuleFileName( NULL, acPath, 256 ) != 0) @@ -234,7 +234,7 @@ void EqslMainWindow::compileShader() std::string shaderCompilerFile = selectedFiles[0].toStdString(); // Call relevant commandline -#ifdef AQSIS_SYSTEM_WIN32 +#if defined AQSIS_SYSTEM_WIN32 && !defined AQSIS_COMPILER_GCC char acPath[256]; char root[256]; if( GetModuleFileName( NULL, acPath, 256 ) != 0) @@ -281,7 +281,7 @@ void EqslMainWindow::compileShader() void EqslMainWindow::openFramebuffer() { // Call relevant commandline -#ifdef AQSIS_SYSTEM_WIN32 +#if defined AQSIS_SYSTEM_WIN32 && !defined AQSIS_COMPILER_GCC char acPath[256]; char root[256]; if( GetModuleFileName( NULL, acPath, 256 ) != 0) @@ -307,7 +307,7 @@ void EqslMainWindow::openFramebuffer() std::string renderViewer = "piqsl"; std::string commandLine = renderViewer + " "; program.append(renderViewer); -#ifndef AQSIS_SYSTEM_WIN32 +#ifdef AQSIS_COMPILER_GCC std::vector<std::string> args; Aqsis::CqExecute tool(program, args, m_currentDirectory); Aqsis::CqExecute::TqCallback outputStdOut = std::bind1st( diff --git a/tools/piqsl/piqsl_ui.cpp b/tools/piqsl/piqsl_ui.cpp index 28f785b..91525eb 100644 --- a/tools/piqsl/piqsl_ui.cpp +++ b/tools/piqsl/piqsl_ui.cpp @@ -59,6 +59,8 @@ PiqslMainWindow::PiqslMainWindow(const QString& socketInterface, m_currentLibraryName() { setWindowTitle("piqsl"); + + Aqsis::CqSocket::initialiseSockets(); // File menu QMenu* fileMenu = menuBar()->addMenu(tr("&File")); diff --git a/tools/ptview/CMakeLists.txt b/tools/ptview/CMakeLists.txt index ffa041f..1002733 100644 --- a/tools/ptview/CMakeLists.txt +++ b/tools/ptview/CMakeLists.txt @@ -25,7 +25,7 @@ if(QT_FOUND AND OPENGL_FOUND) aqsis_add_executable(ptview ${srcs} GUIAPP LINK_LIBRARIES ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} - ${OPENGL_gl_LIBRARY} ${pointrender_libs} aqsis_util) + ${OPENGL_gl_LIBRARY} ${pointrender_libs} aqsis_util pthread) aqsis_install_targets(ptview) endif() diff --git a/tools/ptview/ptview.cpp b/tools/ptview/ptview.cpp index 97ddfe5..897cc8b 100644 --- a/tools/ptview/ptview.cpp +++ b/tools/ptview/ptview.cpp @@ -30,6 +30,9 @@ #define GL_GLEXT_PROTOTYPES +#include <GL/gl.h> +#include <GL/glext.h> + #include <QtCore/QSignalMapper> #include <QtGui/QApplication> #include <QtGui/QKeyEvent> ----------------------------------------------------------------------- Summary of changes: libs/core/renderer.h | 2 +- libs/riutil/CMakeLists.txt | 2 +- libs/shadervm/CMakeLists.txt | 9 +++++++-- libs/util/file.cpp | 2 -- libs/util/win32/socket_system.cpp | 1 + tools/eqsl/eqsl.cpp | 10 +++++----- tools/piqsl/piqsl_ui.cpp | 2 ++ tools/ptview/CMakeLists.txt | 9 +++++++-- 8 files changed, 24 insertions(+), 13 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Paul G. <pgr...@us...> - 2012-02-12 16:19:10
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via c1bb0a7022a6c387ee51a8620d13fae2ca48996f (commit) from 6e5f6965303c37557c75d8f77b934dd96b90de26 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c1bb0a7022a6c387ee51a8620d13fae2ca48996f Author: Paul Gregory <pgr...@aq...> Date: Sun Feb 12 16:11:21 2012 +0000 Various fixes to get building again on Win32. * Some new file util functions were accidentally put inside a non-Win32 ifdef block * Add PARTIO_WIN32 def to partio build config. * Fix some required includes for windows.h, and make sure that the min/max macros are supressed. * Add necessary Qt settings and libraries for eqsl. * Replace use of posix copysignf with boost equivalent. * Disable some GL stuff that isn't readily available on Win32, need to engage the ue of glew or similar to find extensions etc. diff --git a/include/aqsis/util/file.h b/include/aqsis/util/file.h index 20e2be0..cdb4d3e 100644 --- a/include/aqsis/util/file.h +++ b/include/aqsis/util/file.h @@ -157,7 +157,7 @@ typedef boost::tokenizer<CqSearchPathsTokenFunc<boostfs::path>, /// /// This is a portability wrapper for the boost::filesystem::path::native() /// function of boost filesystem v3 to support boost versions older than 1.44. -std::string native(const boostfs::path& path); +AQSIS_UTIL_SHARE std::string native(const boostfs::path& path); /// Get the file name component of a full path. @@ -165,7 +165,7 @@ std::string native(const boostfs::path& path); /// This is a portability wrapper for the boost::filesystem::path::filename() /// function of boost filesystem v3 to support boost versions older than /// 1.44. -std::string filename(const boostfs::path& path); +AQSIS_UTIL_SHARE std::string filename(const boostfs::path& path); //============================================================================== diff --git a/libs/pointrender/microbuffer.cpp b/libs/pointrender/microbuffer.cpp index 0a883ce..d9d6345 100644 --- a/libs/pointrender/microbuffer.cpp +++ b/libs/pointrender/microbuffer.cpp @@ -31,6 +31,7 @@ #include <OpenEXR/ImathFun.h> +#include <boost/math/special_functions/sign.hpp> namespace Aqsis { @@ -86,7 +87,7 @@ inline bool sphereOutsideCone(V3f p, float plen2, float r, // General case float lhs = x*cosConeAngle*cosConeAngle; float rhs = dot(p, n) + r*sinConeAngle; - return copysignf(lhs, cosConeAngle) > copysignf(rhs*rhs, rhs); + return boost::math::copysign(lhs, cosConeAngle) > boost::math::copysign(rhs*rhs, rhs); } diff --git a/libs/util/file.cpp b/libs/util/file.cpp index a57f896..418ad11 100644 --- a/libs/util/file.cpp +++ b/libs/util/file.cpp @@ -261,6 +261,8 @@ std::vector<std::string> cliGlob(const std::string& pattern) return std::vector<std::string>(1, pattern); } +#endif // AQSIS_SYSTEM_WIN32 + // Define BOOST_FILESYSTEM_VERSION for convenience; older boost versions don't // define this for us. @@ -288,6 +290,4 @@ std::string filename(const boostfs::path& path) } -#endif // AQSIS_SYSTEM_WIN32 - } // namespace Aqsis diff --git a/thirdparty/partio/project.cmake b/thirdparty/partio/project.cmake index ac9a4f0..239303e 100644 --- a/thirdparty/partio/project.cmake +++ b/thirdparty/partio/project.cmake @@ -18,5 +18,9 @@ make_absolute(partio_srcs ${partio_SOURCE_DIR}) include_directories(${partio_SOURCE_DIR}/src/src/lib) add_definitions(-DPARTIO_USE_ZLIB) +if(WIN32) + add_definitions(-DPARTIO_WIN32) +endif() +include_directories(${AQSIS_ZLIB_INCLUDE_DIR}) set(partio_libs ${AQSIS_ZLIB_LIBRARIES}) diff --git a/tools/eqsl/CMakeLists.txt b/tools/eqsl/CMakeLists.txt index 200298d..6e6973c 100644 --- a/tools/eqsl/CMakeLists.txt +++ b/tools/eqsl/CMakeLists.txt @@ -11,14 +11,18 @@ set(eqsl_srcs ${moc_srcs} ) +set(eql_link_libraries) + if(WIN32 AND NOT MINGW) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS") + set(eqsl_link_libraries ${eqsl_link_libraries} ${QT_QTMAIN_LIBRARY}) endif() include_directories(${QT_INCLUDES}) aqsis_add_executable(eqsl ${eqsl_srcs} GUIAPP LINK_LIBRARIES aqsis_util ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY} + ${eqsl_link_libraries} ${Boost_THREAD_LIBRARY} ${Boost_REGEX_LIBRARY}) aqsis_install_targets(eqsl) diff --git a/tools/eqsl/eqsl.cpp b/tools/eqsl/eqsl.cpp index bde3265..7b1b256 100644 --- a/tools/eqsl/eqsl.cpp +++ b/tools/eqsl/eqsl.cpp @@ -42,6 +42,10 @@ #ifdef AQSIS_SYSTEM_MACOSX # include <Carbon/Carbon.h> #endif +#ifdef AQSIS_SYSTEM_WIN32 +#define NOMINMAX +# include <windows.h> +#endif #include <QtGui/QApplication> #include <QtGui/QFileDialog> diff --git a/tools/ptview/CMakeLists.txt b/tools/ptview/CMakeLists.txt index eae4631..ffa041f 100644 --- a/tools/ptview/CMakeLists.txt +++ b/tools/ptview/CMakeLists.txt @@ -17,7 +17,11 @@ if(QT_FOUND AND OPENGL_FOUND) ${moc_srcs} ptview.cpp ) - + + if(WIN32 AND NOT MINGW) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS") + endif() + aqsis_add_executable(ptview ${srcs} GUIAPP LINK_LIBRARIES ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} diff --git a/tools/ptview/ptview.cpp b/tools/ptview/ptview.cpp index c92ed60..97ddfe5 100644 --- a/tools/ptview/ptview.cpp +++ b/tools/ptview/ptview.cpp @@ -40,6 +40,7 @@ #include <boost/program_options.hpp> +#define NOMINMAX #include <OpenEXR/ImathVec.h> #include <OpenEXR/ImathMatrix.h> @@ -618,7 +619,7 @@ QSize PointView::sizeHint() const void PointView::initializeGL() { - glEnable(GL_MULTISAMPLE); + //glEnable(GL_MULTISAMPLE); } @@ -880,10 +881,10 @@ void PointView::drawPoints(const PointArrayModel& points, VisMode visMode, glColor3f(1,1,1); // Set distance attenuation for points, following the usual 1/z // law. - GLfloat attenParams[3] = {0, 0, 1}; - glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, attenParams); - glPointParameterf(GL_POINT_SIZE_MIN, 0); - glPointParameterf(GL_POINT_SIZE_MAX, 100); + //GLfloat attenParams[3] = {0, 0, 1}; + //glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, attenParams); + //glPointParameterf(GL_POINT_SIZE_MIN, 0); + //glPointParameterf(GL_POINT_SIZE_MAX, 100); // Draw all points at once using vertex arrays. glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, 3*sizeof(float), @@ -924,7 +925,7 @@ void PointView::drawPoints(const PointArrayModel& points, VisMode visMode, // TODO: Why doesn't this work?? (handedness problems?) //glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); // rescaling of normals - glEnable(GL_RESCALE_NORMAL); + //glEnable(GL_RESCALE_NORMAL); } //glCullFace(GL_BACK); //glEnable(GL_CULL_FACE); ----------------------------------------------------------------------- Summary of changes: include/aqsis/util/file.h | 4 ++-- libs/pointrender/microbuffer.cpp | 3 ++- libs/util/file.cpp | 4 ++-- thirdparty/partio/project.cmake | 4 ++++ tools/eqsl/CMakeLists.txt | 4 ++++ tools/eqsl/eqsl.cpp | 4 ++++ tools/ptview/CMakeLists.txt | 6 +++++- tools/ptview/ptview.cpp | 13 +++++++------ 8 files changed, 30 insertions(+), 12 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2012-02-06 12:12:21
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via 6e5f6965303c37557c75d8f77b934dd96b90de26 (commit) via 50f693d6f806632d8301911874537b6bcb64187f (commit) via bad56a16720b399c3654bd5315862947efd2f428 (commit) from 46870dc8df122d51096bcc771a655210566e8e62 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6e5f6965303c37557c75d8f77b934dd96b90de26 Author: Chris Foster <chr...@gm...> Date: Sun Feb 5 17:48:09 2012 +1000 PNG portability fixes + make PNG support optional Contains a number of small fixes for portability to earlier boost versions and for running png test cases (mktemp and unlink are not portable). Also fix some compiler warnings, and make the PNG support optional in the build system - it is enabled by default, but can be turned off by disabling the AQSIS_USE_PNG flag. diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ec9588..413ff4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,7 @@ option(AQSIS_USE_TIMERS "Enable performance timers" ON) option(AQSIS_USE_PDIFF "Build the external pdiff perceptual image difference utility" OFF) option(AQSIS_USE_QT "Build the aqsis GUI components which rely on the Qt libraries" ON) option(AQSIS_USE_OPENEXR "Build aqsis with support for the OpenEXR image format" ON) +option(AQSIS_USE_PNG "Build aqsis with support for reading PNG image files" ON) option(AQSIS_USE_EXTERNAL_TINYXML "Try to find and use an external tinyxml library" OFF) mark_as_advanced(AQSIS_USE_PDIFF AQSIS_USE_EXTERNAL_TINYXML) @@ -62,7 +63,6 @@ mark_as_advanced(AQSIS_MAIN_CONFIG_NAME) # Required libs # ------------- find_package(TIFF) -find_package(PNG) find_package(ZLIB) # Find boost. @@ -118,11 +118,19 @@ if(AQSIS_USE_OPENEXR) find_package(OpenEXR) if(NOT AQSIS_OPENEXR_FOUND) - message("** Cannot find OpenEXR - aqsis will be build without support for the OpenEXR image format") + message("** Cannot find OpenEXR - aqsis will be built without support for the OpenEXR image format") set(AQSIS_USE_OPENEXR OFF) endif() endif() +if(AQSIS_USE_PNG) + find_package(PNG) + + if(NOT AQSIS_PNG_FOUND) + message("** Cannot find PNG - aqsis will be built without support for the PNG image format") + set(AQSIS_USE_PNG OFF) + endif() +endif() ## find tinyxml. If not found we use the version distributed with the aqsis ## source. diff --git a/libs/tex/CMakeLists.txt b/libs/tex/CMakeLists.txt index 0341e0f..40362d8 100644 --- a/libs/tex/CMakeLists.txt +++ b/libs/tex/CMakeLists.txt @@ -24,6 +24,10 @@ if(AQSIS_USE_OPENEXR) add_definitions(-DUSE_OPENEXR) list(APPEND linklibs ${AQSIS_OPENEXR_LIBRARIES}) endif() +if(AQSIS_USE_PNG) + include_directories(${AQSIS_PNG_INCLUDE_DIR}) + add_definitions(-DAQSIS_USE_PNG) +endif() list(APPEND linklibs ${AQSIS_ZLIB_LIBRARIES}) aqsis_add_library(aqsis_tex ${tex_srcs} ${tex_hdrs} diff --git a/libs/tex/io/itexinputfile.cpp b/libs/tex/io/itexinputfile.cpp index abb650b..80433ea 100644 --- a/libs/tex/io/itexinputfile.cpp +++ b/libs/tex/io/itexinputfile.cpp @@ -42,7 +42,9 @@ #include <aqsis/util/logging.h> #include "magicnumber.h" #include "tiffinputfile.h" -#include "pnginputfile.h" +#ifdef AQSIS_USE_PNG +# include "pnginputfile.h" +#endif #include "zinputfile.h" namespace Aqsis { @@ -87,10 +89,16 @@ boost::shared_ptr<IqTexInputFile> openInputFile( break; case ImageFile_AqsisZfile: file.reset(new CqZInputFile(fileName)); - break; - case ImageFile_Png: - file.reset(new CqPngInputFile(fileName)); - break; + break; + case ImageFile_Png: +# ifdef AQSIS_USE_PNG + file.reset(new CqPngInputFile(fileName)); +# else + AQSIS_THROW_XQERROR(XqInvalidFile, EqE_Unimplement, + "Cannot open file \"" << fileName << "\"" + ": Aqsis was compiled without PNG support"); +# endif + break; default: break; } diff --git a/libs/tex/io/pnginputfile.cpp b/libs/tex/io/pnginputfile.cpp index 8b8e48a..3dfb2a0 100644 --- a/libs/tex/io/pnginputfile.cpp +++ b/libs/tex/io/pnginputfile.cpp @@ -52,7 +52,7 @@ class CPNGReader public: CPNGReader(const boostfs::path& fileName) - : m_fileHandle(::fopen(fileName.c_str(), "rb")) + : m_fileHandle(::fopen(native(fileName).c_str(), "rb")) , m_PNGHandle(NULL) , m_infoPtr(NULL) @@ -147,7 +147,7 @@ private: m_ImageBuff = imagePtr; m_ImageBuffPtr = (png_bytepp)::calloc(rowCnt, sizeof(png_bytep)); - for (int i=0; i != rowCnt; ++i, imagePtr += bytesPerRow) + for (size_t i=0; i != rowCnt; ++i, imagePtr += bytesPerRow) { m_ImageBuffPtr[i] = imagePtr; } @@ -278,8 +278,6 @@ void CqPngInputFile::readPixelsImpl(TqUint8* buffer, TqInt startLine, const size_t destBytesPerPixel(getNrOfChannels() * sizeof(uint8_t)); const size_t destBytesPerLine(destBytesPerPixel * getWidth()); - const size_t srcBytesPerLine(getRowBytes()); - const size_t srcChannels(srcBytesPerLine / getWidth()); TqUint8* destBuff(buffer); @@ -288,7 +286,7 @@ void CqPngInputFile::readPixelsImpl(TqUint8* buffer, TqInt startLine, copyRGBPixel : // If the number of channels is 3 then use copyRGBPixel(...) copyRGBAPremultiPixel; // If the number of channels is 4 then use copyRGBAPremultiPixel(...) - for (size_t lineIdx = 0; lineIdx != numScanlines; ++lineIdx, destBuff += destBytesPerLine) + for (int lineIdx = 0; lineIdx != numScanlines; ++lineIdx, destBuff += destBytesPerLine) { const TqUint8* srcBuff(getRowPtr(lineIdx)); assert(srcBuff); diff --git a/libs/tex/io/pnginputfile.h b/libs/tex/io/pnginputfile.h index 40f48ba..f37da19 100644 --- a/libs/tex/io/pnginputfile.h +++ b/libs/tex/io/pnginputfile.h @@ -45,7 +45,6 @@ #include <png.h> #include <boost/shared_ptr.hpp> - #include <aqsis/tex/io/itexinputfile.h> namespace Aqsis { diff --git a/libs/tex/io/pnginputfile_test.cpp b/libs/tex/io/pnginputfile_test.cpp index fc3a11c..31f1485 100644 --- a/libs/tex/io/pnginputfile_test.cpp +++ b/libs/tex/io/pnginputfile_test.cpp @@ -41,9 +41,11 @@ #define BOOST_TEST_DYN_LINK #include <boost/test/auto_unit_test.hpp> #include <boost/test/floating_point_comparison.hpp> -#include <sstream> +#include <boost/filesystem.hpp> +#include <fstream> #include <aqsis/tex/buffers/texturebuffer.h> +#include <aqsis/util/tinyformat.h> /* This is a dump of a png image which is 7 pixels wide and 6 pixels height. * The image consists of three color components (RGB) and _no_ alpha channel. @@ -123,45 +125,38 @@ BOOST_AUTO_TEST_SUITE(pnginputfile_tests) */ class CTempBinDataAsFile { - char* m_Filename; + std::string m_fileName; public: CTempBinDataAsFile(const void* inData, size_t inDataSize) - : m_Filename((char*)::malloc(64)) { - ::strcpy(m_Filename, "/tmp/aqsis_tmpfile_XXXXX"); - char* tmpFilename = ::mktemp(m_Filename); - assert(tmpFilename); - if (tmpFilename) + // Horrible but hopefully portable alternative to mktemp. Could use + // tmpnam() if it wasn't so horrible, or boost::filesystem::unique_file + // if it was supported in v2 :( + for(int i = 0;; ++i) { - FILE* fileHd = ::fopen(m_Filename, "wb"); - assert(fileHd); - if (fileHd) + m_fileName = tfm::format("aqsis_tmpfile_%05d", i); + if(!boost::filesystem::exists(m_fileName)) { - int rc = ::fwrite(inData, 1, inDataSize, fileHd); - assert(rc == inDataSize); - - ::fclose(fileHd); + std::ofstream file(m_fileName.c_str(), + std::ios::out | std::ios::binary); + BOOST_REQUIRE(file); + file.write(reinterpret_cast<const char*>(inData), inDataSize); + break; } } - else - { - ::free(m_Filename); - m_Filename = NULL; - } } ~CTempBinDataAsFile() { - ::unlink(m_Filename); - ::free(m_Filename); + boost::filesystem::remove(m_fileName); } const char* getFileName() const { - return m_Filename; + return m_fileName.c_str(); } -}; // class CTempBinDataAsFile +}; /** This test utilizes the PNG image in order to load and parse a given PNG * image which is has the size 7 x 6 pixels and contains of the three diff --git a/libs/tex/io/project.cmake b/libs/tex/io/project.cmake index 921ed6a..99d0607 100644 --- a/libs/tex/io/project.cmake +++ b/libs/tex/io/project.cmake @@ -6,7 +6,6 @@ set(io_srcs texfileheader.cpp tiffdirhandle.cpp tiffinputfile.cpp - pnginputfile.cpp tiffoutputfile.cpp tifftest_examples.cpp tiledanyinputfile.cpp @@ -16,6 +15,9 @@ set(io_srcs if(AQSIS_USE_OPENEXR) list(APPEND io_srcs exrinputfile.cpp) endif() +if(AQSIS_USE_PNG) + list(APPEND io_srcs pnginputfile.cpp) +endif() make_absolute(io_srcs ${io_SOURCE_DIR}) set(io_hdrs @@ -38,8 +40,10 @@ set(io_test_srcs texfileheader_test.cpp tiffdirhandle_test.cpp tiffinputfile_test.cpp - pnginputfile_test.cpp ) +if(AQSIS_USE_PNG) + list(APPEND io_test_srcs pnginputfile_test.cpp) +endif() make_absolute(io_test_srcs ${io_SOURCE_DIR}) @@ -48,6 +52,8 @@ include_directories(${AQSIS_TIFF_INCLUDE_DIR}) set(io_linklibs ${AQSIS_TIFF_LIBRARIES} ${AQSIS_TIFFXX_LIBRARIES} - ${AQSIS_PNG_LIBRARIES} ) +if(AQSIS_USE_PNG) + list(APPEND io_linklibs ${AQSIS_PNG_LIBRARIES}) +endif() commit 50f693d6f806632d8301911874537b6bcb64187f Author: Hans-Peter Dusel <hd...@ta...> Date: Sat Feb 4 10:36:02 2012 +1000 PNG reading support for aqsis_tex This patch allows png files to be read by the texturing system, using the standard libpng library. Alpha is premultiplied to keep with the precendent set by libtiff. diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ec529b..6ec9588 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,7 @@ mark_as_advanced(AQSIS_MAIN_CONFIG_NAME) # Required libs # ------------- find_package(TIFF) +find_package(PNG) find_package(ZLIB) # Find boost. diff --git a/cmake/modules/FindPNG.cmake b/cmake/modules/FindPNG.cmake new file mode 100644 index 0000000..b12621d --- /dev/null +++ b/cmake/modules/FindPNG.cmake @@ -0,0 +1,54 @@ +# Custom Aqsis specific version of FindPNG +SET(AQSIS_PNG_FOUND 0) + +SET(AQSIS_PNG_INCLUDE_SEARCHPATH) + +IF(WIN32) + IF(AQSIS_WIN32LIBS) + SET(AQSIS_PNG_INCLUDE_SEARCHPATH ${AQSIS_PNG_INCLUDE_SEARCHPATH} ${AQSIS_WIN32LIBS}/libpng/include) + IF(MSVC AND MSVC80) + SET(AQSIS_PNG_LIBRARY_NAMES libpng) + SET(AQSIS_PNG_LIBRARIES_DIR ${AQSIS_WIN32LIBS}/libpng/lib/vc8_sp1 CACHE PATH "Semi-colon separated list of paths to search for the png libraries") + SET(AQSIS_PNG_LIBRARY_NAMES ${AQSIS_PNG_LIBRARY_NAMES} libpng) + ELSEIF(MSVC AND MSVC90) + SET(AQSIS_PNG_LIBRARY_NAMES libpng) + SET(AQSIS_PNG_LIBRARIES_DIR ${AQSIS_WIN32LIBS}/libpng/lib/vc9_sp1 CACHE PATH "Semi-colon separated list of paths to search for the png libraries") + SET(AQSIS_PNG_LIBRARY_NAMES ${AQSIS_PNG_LIBRARY_NAMES} libpng) + ELSE(MSVC AND MSVC80) + IF(MINGW) + SET(AQSIS_PNG_LIBRARY_NAMES png) + SET(AQSIS_PNG_LIBRARIES_DIR ${AQSIS_WIN32LIBS}/libpng/lib/mingw CACHE PATH "Semi-colon separated list of paths to search for the png libraries") + ENDIF(MINGW) + ENDIF(MSVC AND MSVC80) + ENDIF(AQSIS_WIN32LIBS) + if(MINGW) + LIST(APPEND AQSIS_PNG_INCLUDE_SEARCHPATH ${AQSIS_DEPENDENCIES}/include) + LIST(APPEND AQSIS_PNG_LIBRARIES_DIR ${AQSIS_DEPENDENCIES}/lib) + SET(AQSIS_PNG_LIBRARY_NAMES png) + endif() +ELSE(WIN32) + SET(AQSIS_PNG_LIBRARY_NAMES png) + SET(AQSIS_PNG_LIBRARIES_DIR CACHE PATH "Semi-colon separated list of paths to search for the png libraries") +ENDIF(WIN32) + +FIND_PATH(AQSIS_PNG_INCLUDE_DIR + png.h + PATHS ${AQSIS_PNG_INCLUDE_SEARCHPATH} + DOC "Location of the libpng headers" + ) + +FIND_LIBRARY(AQSIS_PNG_LIBRARIES + NAMES ${AQSIS_PNG_LIBRARY_NAMES} + PATHS ${AQSIS_PNG_LIBRARIES_DIR} + DOC "Location of the libpng library" + ) +MARK_AS_ADVANCED(AQSIS_PNG_LIBRARIES) + +STRING(COMPARE EQUAL "${AQSIS_PNG_INCLUDE_DIR}" "AQSIS_PNG_INCLUDE_DIR-NOTFOUND" AQSIS_PNG_INCLUDE_DIR_NOTFOUND) +STRING(COMPARE EQUAL "${AQSIS_PNG_LIBRARIES}" "AQSIS_PNG_LIBRARIES-NOTFOUND" AQSIS_PNG_LIBRARIES_NOTFOUND) + +IF(NOT AQSIS_PNG_LIBRARIES_NOTFOUND AND NOT AQSIS_PNG_INCLUDE_DIR_NOTFOUND) + SET(AQSIS_PNG_FOUND 1) + GET_FILENAME_COMPONENT(AQSIS_PNG_LIBRARIES_DIR ${AQSIS_PNG_LIBRARIES} PATH) +ENDIF(NOT AQSIS_PNG_LIBRARIES_NOTFOUND AND NOT AQSIS_PNG_INCLUDE_DIR_NOTFOUND) + diff --git a/cmake/modules/FindZLIB.cmake b/cmake/modules/FindZLIB.cmake index 512bdeb..085047e 100644 --- a/cmake/modules/FindZLIB.cmake +++ b/cmake/modules/FindZLIB.cmake @@ -1,4 +1,4 @@ -# Custom Aqsis specific version of FindTIFF +# Custom Aqsis specific version of FindZLIB SET(AQSIS_ZLIB_FOUND 0) SET(AQSIS_ZLIB_INCLUDE_SEARCHPATH) @@ -12,7 +12,7 @@ IF(WIN32) SET(AQSIS_ZLIB_LIBRARY_NAMES ${AQSIS_ZLIB_LIBRARY_NAMES} zlibstat) ELSEIF(MSVC AND MSVC90) SET(AQSIS_ZLIB_LIBRARIES_DIR ${AQSIS_WIN32LIBS}/zlib/lib/vc9_sp1 CACHE PATH "Semi-colon separated list of paths to search for zlib libraries") - SET(AQSIS_ZLIB_LIBRARY_NAMES ${AQSIS_ZLIB_LIBRARY_NAMES} zlibstat) + SET(AQSIS_ZLIB_LIBRARY_NAMES ${AQSIS_ZLIB_LIBRARY_NAMES} zlibstat) ELSE(MSVC AND MSVC80) IF(MINGW) SET(AQSIS_ZLIB_LIBRARIES_DIR ${AQSIS_WIN32LIBS}/zlib/lib/mingw CACHE PATH "Semi-colon separated list of paths to search for zlib libraries") @@ -35,7 +35,7 @@ FIND_PATH(AQSIS_ZLIB_INCLUDE_DIR ) FIND_LIBRARY(AQSIS_ZLIB_LIBRARIES - NAMES ${AQSIS_ZLIB_LIBRARY_NAMES} + NAMES ${AQSIS_ZLIB_LIBRARY_NAMES} PATHS ${AQSIS_ZLIB_LIBRARIES_DIR} DOC "Location of the zlib library" ) diff --git a/libs/tex/io/itexinputfile.cpp b/libs/tex/io/itexinputfile.cpp index 6baee62..abb650b 100644 --- a/libs/tex/io/itexinputfile.cpp +++ b/libs/tex/io/itexinputfile.cpp @@ -42,6 +42,7 @@ #include <aqsis/util/logging.h> #include "magicnumber.h" #include "tiffinputfile.h" +#include "pnginputfile.h" #include "zinputfile.h" namespace Aqsis { @@ -86,6 +87,10 @@ boost::shared_ptr<IqTexInputFile> openInputFile( break; case ImageFile_AqsisZfile: file.reset(new CqZInputFile(fileName)); + break; + case ImageFile_Png: + file.reset(new CqPngInputFile(fileName)); + break; default: break; } diff --git a/libs/tex/io/magicnumber.cpp b/libs/tex/io/magicnumber.cpp index 35fae3e..72f20f9 100644 --- a/libs/tex/io/magicnumber.cpp +++ b/libs/tex/io/magicnumber.cpp @@ -95,6 +95,14 @@ EqImageFileType guessFileType(std::istream& inStream) { return ImageFile_Exr; } + else if( magicNum.size() >= 4 && + magicNum[0] == (char)0x89 && + magicNum[1] == 'P' && + magicNum[2] == 'N' && + magicNum[3] == 'G') + { + return ImageFile_Png; + } else if( magicNum.size() >= 16 && std::equal(magicNum.begin(), magicNum.begin()+15, "Aqsis bake file") ) { diff --git a/libs/tex/io/magicnumber_test.cpp b/libs/tex/io/magicnumber_test.cpp index 4f5a3f6..719b488 100644 --- a/libs/tex/io/magicnumber_test.cpp +++ b/libs/tex/io/magicnumber_test.cpp @@ -87,4 +87,30 @@ BOOST_AUTO_TEST_CASE(bakeMagicNumber_test) BOOST_CHECK(Aqsis::guessFileType(inStream) == Aqsis::ImageFile_AqsisBake); } +/* This is a dump of a png image which is 7 pixels wide and 6 pixels height. + * The image consists of three color components (RGB) and _no_ alpha channel. + * + * It consists of three horizontal (pure) colored stripes each 2 pixels height: + * The first two rows are red, the second two are green and the last two rows are + * blue. + */ +const unsigned char pngHeadData[85] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52 + ,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x06,0x08,0x02,0x00,0x00,0x00,0x80,0x6c,0x13 + ,0x21,0x00,0x00,0x00,0x1c,0x49,0x44,0x41,0x54,0x78,0x9c,0x62,0xf8,0xcf,0xc0,0x80 + ,0x89,0xb0,0x08,0x81,0x44,0x71,0x08,0x53,0xaa,0x18,0x00,0x00,0x00,0xff,0xff,0x03 + ,0x00,0xca,0x46,0x29,0xd7,0x18,0x59,0x90,0xcd,0x00,0x00,0x00,0x00,0x49,0x45,0x4e + ,0x44,0xae,0x42,0x60,0x82 +}; /* end of rgb76_pngData */ + +BOOST_AUTO_TEST_CASE(pngMagicNumber_test) +{ + std::string pngStr(pngHeadData, pngHeadData + sizeof(pngHeadData)); + std::istringstream inStream(pngStr); + + // Check that what should be a tiff magic number actually checks out as + // one. + BOOST_CHECK(Aqsis::guessFileType(inStream) == Aqsis::ImageFile_Png); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/libs/tex/io/pnginputfile.cpp b/libs/tex/io/pnginputfile.cpp new file mode 100644 index 0000000..8b8e48a --- /dev/null +++ b/libs/tex/io/pnginputfile.cpp @@ -0,0 +1,329 @@ +// Aqsis +// Copyright (C) 2001, Paul C. Gregory and the other authors and contributors +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of the software's owners nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// (This is the New BSD license) + +/** \file + * + * \brief Scanline-oriented pixel access for TIFF input - implementation. + * + * \author Peter Dusel hdusel _at_ tangerine-soft.de + * + */ + +#include "pnginputfile.h" +#include "boost/scoped_array.hpp" +#include <stdlib.h> + +namespace Aqsis { + +class CPNGReader +{ + FILE* m_fileHandle; + png_structp m_PNGHandle; + png_infop m_infoPtr; + png_bytep m_ImageBuff; + png_bytepp m_ImageBuffPtr; + +public: + CPNGReader(const boostfs::path& fileName) + : m_fileHandle(::fopen(fileName.c_str(), "rb")) + , m_PNGHandle(NULL) + , m_infoPtr(NULL) + + , m_ImageBuff(NULL) + , m_ImageBuffPtr(NULL) + { + initAll(); + } + + ~CPNGReader() + { + releaseImageBuffer(); + if ( NULL != m_fileHandle ) + { + ::fclose(m_fileHandle); + } + ::png_destroy_read_struct(&m_PNGHandle, (png_infopp)&m_infoPtr,(png_infopp)NULL); + } + + int32_t getWidth() const + { + return isValid() ? ::png_get_image_width(m_PNGHandle, m_infoPtr) : -1; + } + + int32_t getHeight() const + { + return isValid() ? ::png_get_image_height(m_PNGHandle, m_infoPtr) : -1; + } + + int8_t getNrOfChannels() const + { + return isValid() ? ::png_get_channels(m_PNGHandle, m_infoPtr) : 0; + } + + int32_t getRowBytes() const + { + return isValid() ? ::png_get_rowbytes(m_PNGHandle, m_infoPtr) : 0; + } + + const TqUint8* const getRowPtr(size_t inRowIndex) const + { + return (const TqUint8 * const)(isValid() ? m_ImageBuffPtr[inRowIndex] : NULL); + } + + bool isValid() const {return NULL != m_fileHandle;} + +private: + bool initAll() + { + if (m_fileHandle) + { + bool success ( initialize_png_reader() ); + if (success) + { + ::png_init_io(m_PNGHandle, m_fileHandle); + ::png_read_info(m_PNGHandle, m_infoPtr); + + success = initImageBuffer(); + if (success) + { + return true; // success + } + } + + } + + ::fclose(m_fileHandle); + m_fileHandle = NULL; + return false; // failure + } + + bool initImageBuffer() + { + assert( NULL == m_ImageBuff ); + assert( NULL == m_ImageBuffPtr ); + + const size_t rowCnt(getHeight()); + + if (rowCnt > 0) + { + const size_t bytesPerRow(getRowBytes()); + + // Allocate the whole image buffer at once! + const size_t imageBuffSize(rowCnt * bytesPerRow); + png_bytep imagePtr = (png_bytep)::malloc(imageBuffSize); + if ( NULL == imagePtr ) + { + releaseImageBuffer(); + return false; // error + } + + m_ImageBuff = imagePtr; + m_ImageBuffPtr = (png_bytepp)::calloc(rowCnt, sizeof(png_bytep)); + + for (int i=0; i != rowCnt; ++i, imagePtr += bytesPerRow) + { + m_ImageBuffPtr[i] = imagePtr; + } + ::png_read_image(m_PNGHandle, m_ImageBuffPtr); + } + return true; + } + + void releaseImageBuffer() + { + if (m_ImageBuff) + { + ::free(m_ImageBuff); + m_ImageBuff = NULL; + } + + if (m_ImageBuffPtr) + { + ::free(m_ImageBuffPtr); + } + m_ImageBuffPtr = NULL; + } + + /* An example code fragment of how you would + initialize the progressive reader in your + application. */ + bool initialize_png_reader() + { + png_voidp user_error_ptr = NULL; + png_error_ptr user_error_fn = NULL; + png_error_ptr user_warning_fn = NULL; + + m_PNGHandle = ::png_create_read_struct(PNG_LIBPNG_VER_STRING, + (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn); + if ( NULL != m_PNGHandle ) + { + m_infoPtr = ::png_create_info_struct(m_PNGHandle); + if ( NULL != m_infoPtr ) + { + return true; // success + } + } + + ::png_destroy_read_struct(&m_PNGHandle, (png_infopp)&m_infoPtr,(png_infopp)NULL); + + return false; // fail + } +}; // class CPNGReader + +//------------------------------------------------------------------------------ +// CqPngInputFile - implementation + +CqPngInputFile::CqPngInputFile(const boostfs::path& fileName) +: IqTexInputFile() +, m_PNGReader(new CPNGReader(fileName)) +, m_fileName(fileName) +, m_header() +{ + if (m_PNGReader->isValid()) + { + m_header.setWidth(m_PNGReader->getWidth()); + m_header.setHeight(m_PNGReader->getHeight()); + + CqChannelList& channelList = m_header.channelList(); + + // set the channels + channelList.clear(); + + const uint8_t nrOfChannels ( m_PNGReader->getNrOfChannels() ); + + static const char* channelStructure[] = {"r","g","b","a"}; + + const EqChannelType chanType( Channel_Unsigned8 ); + for (int i=0; i!= nrOfChannels; ++i) + { + channelList.addChannel( SqChannelInfo(channelStructure[i], chanType) ); + } + } +} + +CqPngInputFile::~CqPngInputFile() +{ + delete m_PNGReader; +} + +static void copyRGBPixel(TqUint8* inDestBuff, const TqUint8* inSrcBuff, size_t buffSize) +{ + ::memcpy((void*)inDestBuff, inSrcBuff, buffSize); +} + +inline static TqUint8 premultiplyAlpha(TqUint8 inColorValue, TqUint8 inAlpha) +{ + return (((TqUint16)inColorValue) * inAlpha) / 255; +} + +/* Copy the pixels from a source buffer to a destination buffer by assuming that each pixel + * consists of 4 components (RGBA). + * + * It is noteworthy that PNG assumes "non premultiplied" data while Aqsis relies on + * premultiplied color components. + * + * This implies that loading PNG files which consists of a alpha component requires an additional + * precessing. + * + * In order to fulfill this needs this function performs a premultiply of each color component + * with the value of the alpha component. + */ +static void copyRGBAPremultiPixel(TqUint8* inDestBuff, const TqUint8* inSrcBuff, size_t buffSize) +{ + for(; buffSize >= 4 ; buffSize -= 4) + { + const TqUint8 alpha( inSrcBuff[3] ); + + *(inDestBuff++) = premultiplyAlpha(*(inSrcBuff++), alpha); + *(inDestBuff++) = premultiplyAlpha(*(inSrcBuff++), alpha); + *(inDestBuff++) = premultiplyAlpha(*(inSrcBuff++), alpha); + *(inDestBuff++) = *(inSrcBuff++); + } +} + +typedef void (*LineCopyFuncPtr)(TqUint8* inDestBuff, const TqUint8* inSrcBuff, size_t buffSize); + +void CqPngInputFile::readPixelsImpl(TqUint8* buffer, TqInt startLine, + TqInt numScanlines) const +{ + assert(buffer); + + const size_t destBytesPerPixel(getNrOfChannels() * sizeof(uint8_t)); + const size_t destBytesPerLine(destBytesPerPixel * getWidth()); + const size_t srcBytesPerLine(getRowBytes()); + const size_t srcChannels(srcBytesPerLine / getWidth()); + + TqUint8* destBuff(buffer); + + // Dependent from the color model use a special copy routine. + LineCopyFuncPtr lineCopyFunc = (getNrOfChannels() == 3) ? + copyRGBPixel : // If the number of channels is 3 then use copyRGBPixel(...) + copyRGBAPremultiPixel; // If the number of channels is 4 then use copyRGBAPremultiPixel(...) + + for (size_t lineIdx = 0; lineIdx != numScanlines; ++lineIdx, destBuff += destBytesPerLine) + { + const TqUint8* srcBuff(getRowPtr(lineIdx)); + assert(srcBuff); + if ( NULL != srcBuff ) + { + lineCopyFunc(destBuff, srcBuff, destBytesPerLine); + } + } +} + + // Private + +const TqUint8* const CqPngInputFile::getRowPtr(size_t inRowIndex) const +{ + return m_PNGReader->getRowPtr(inRowIndex); +} + +uint8_t CqPngInputFile::getNrOfChannels() const +{ + return m_PNGReader->getNrOfChannels(); +} + +uint32_t CqPngInputFile::getRowBytes() const +{ + return m_PNGReader->getRowBytes(); +} + +uint32_t CqPngInputFile::getWidth() const +{ + return m_PNGReader->getWidth(); +} + +uint32_t CqPngInputFile::getHeight() const +{ + return m_PNGReader->getHeight(); +} + +} // namespace Aqsis diff --git a/libs/tex/io/pnginputfile.h b/libs/tex/io/pnginputfile.h new file mode 100644 index 0000000..40f48ba --- /dev/null +++ b/libs/tex/io/pnginputfile.h @@ -0,0 +1,140 @@ +// Aqsis +// Copyright (C) 2001, Paul C. Gregory and the other authors and contributors +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of the software's owners nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// (This is the New BSD license) + +/** \file + * + * \brief Scanline-oriented pixel access for PNG input. + * + * \author Peter Dusel hdusel _at_ tangerine-soft.de + * + */ + +#ifndef PNGINPUTFILE_H_INCLUDED +#define PNGINPUTFILE_H_INCLUDED + +#include <aqsis/aqsis.h> + +#include <string> +#include <png.h> + +#include <boost/shared_ptr.hpp> + +#include <aqsis/tex/io/itexinputfile.h> + +namespace Aqsis { + +class CPNGReader; +//------------------------------------------------------------------------------ +/** \brief Scanline-oriented input class for PNG files. + * + * This class puts a scanline interface onto strip-based or tiled PNG files, + * and attempts to hide a lot of the complexity of the PNG format behind a + * uniform interface. + * + * For cases of unusual internal formats, the class falls back on the generic + * RGBA image handling built into libPNG. + */ +class AQSIS_TEX_SHARE CqPngInputFile : public IqTexInputFile +{ + CPNGReader *m_PNGReader; + boostfs::path m_fileName; + CqTexFileHeader m_header; + +public: + CqPngInputFile(const boostfs::path& fileName); + /** \param Read the tiff from an input stream rather than a file. + * + * \param inStream - Stream to read from. This is passed to the + * underlying tiff (tiffxx) library. + */ + // CqPngInputFile(std::istream& inStream); + + virtual ~CqPngInputFile(); + + // inherited + /// \name Metadata access + //@{ + /// get the file name + virtual boostfs::path fileName() const + { + return m_fileName; + } + + /// get a string representing the file type + virtual EqImageFileType fileType() const + { + return ImageFile_Png; + } + + /// Get the file header data + virtual const CqTexFileHeader& header() const + { + return m_header; + } + //@} + + /** \brief Low-level readPixels() function to be overridden by child classes + * + * The implementation of readPixels simply validates the input + * parameters against the image dimensions as reported by header(), + * sets up the buffer, and calls readPixelsImpl(). + * + * Implementations of readPixelsImpl() can assume that startLine and + * numScanlines specify a valid range. + * + * \note Don't use this low-level interface unless you have a good + * reason. The higher level readPixels() function is a lot safer and + * more user friendly. + * + * \param buffer - Raw buffer to read the data into. Must be large + * enough to read width*numScanlines pixels with the + * same channel structure specified in the image + * header. + * \param startLine - scanline to start reading the data from (top == 0) + * \param numScanlines - number of scanlines to read, must be positive! + */ + virtual void readPixelsImpl(TqUint8* buffer, TqInt startLine, + TqInt numScanlines) const; + +private: + uint8_t getNrOfChannels() const; + uint32_t getRowBytes() const; + + uint32_t getWidth() const; + uint32_t getHeight() const; + + const TqUint8* const getRowPtr(size_t inRowIndex) const; +}; +//============================================================================== +// Implementation details +//============================================================================== + +} // namespace Aqsis +#endif // PNGINPUTFILE_H_INCLUDED diff --git a/libs/tex/io/pnginputfile_test.cpp b/libs/tex/io/pnginputfile_test.cpp new file mode 100644 index 0000000..fc3a11c --- /dev/null +++ b/libs/tex/io/pnginputfile_test.cpp @@ -0,0 +1,433 @@ +// Aqsis +// Copyright (C) 2001, Paul C. Gregory and the other authors and contributors +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of the software's owners nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// (This is the New BSD license) + +/** \file + * + * \brief Unit tests for scanline-oriented pixel access for PNG input. + * + * \author Peter Dusel hdusel _at_ tangerine-soft.de + * + */ + +#include "pnginputfile.h" + +#define BOOST_TEST_DYN_LINK +#include <boost/test/auto_unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> +#include <sstream> + +#include <aqsis/tex/buffers/texturebuffer.h> + +/* This is a dump of a png image which is 7 pixels wide and 6 pixels height. + * The image consists of three color components (RGB) and _no_ alpha channel. + * + * It consists of three horizontal (pure) colored stripes each 2 pixels height: + * The first two rows are red, the second two are green and the last two rows are + * blue. + */ +const unsigned char rgb76_pngData[85] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52 + ,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x06,0x08,0x02,0x00,0x00,0x00,0x80,0x6c,0x13 + ,0x21,0x00,0x00,0x00,0x1c,0x49,0x44,0x41,0x54,0x78,0x9c,0x62,0xf8,0xcf,0xc0,0x80 + ,0x89,0xb0,0x08,0x81,0x44,0x71,0x08,0x53,0xaa,0x18,0x00,0x00,0x00,0xff,0xff,0x03 + ,0x00,0xca,0x46,0x29,0xd7,0x18,0x59,0x90,0xcd,0x00,0x00,0x00,0x00,0x49,0x45,0x4e + ,0x44,0xae,0x42,0x60,0x82 +}; /* end of rgb76_pngData */ + +/* This is a dump of a png image which is 7 pixels wide and 8 pixels height. + * The image consists of four color components (RGBA) thus it contains an alpha + * channel. + * + * It consists of four horizontal (pure) colored stripes each 2 pixels height: + * The first two rows are red, the second two are green and the last two rows are + * blue. These first three stripes are opaque which means that their alpha channel + * is 1.0. The last two rows of this image is pure transparent which means that + * its alpha channel value is 0.0. + */ +const unsigned char rgba78_pngData[96] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52 + ,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x08,0x08,0x06,0x00,0x00,0x00,0x35,0x04,0xe5 + ,0x06,0x00,0x00,0x00,0x27,0x49,0x44,0x41,0x54,0x78,0x9c,0x62,0xf8,0xcf,0xc0,0xf0 + ,0x1f,0x17,0x66,0xc0,0x2b,0x09,0x96,0xc7,0x05,0xf1,0x4b,0xe2,0x36,0x95,0x80,0xe4 + ,0x7f,0x3c,0x18,0xaf,0x24,0x00,0x00,0x00,0xff,0xff,0x03,0x00,0x10,0xb3,0x7d,0x83 + ,0x66,0x0e,0x6a,0x67,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; /* end of rgba78_pngData */ + +/* This is a dump of a png image which is 7 pixels wide and 8 pixels height. + * The image consists of four color components (RGBA) thus it contains an alpha + * channel. + * + * It consists of four horizontal (pure) colored stripes each 2 pixels height: + * The first two rows are red, the second two are green and the last two rows are + * blue. + * + * These first three stripes are 70 % opaque (30 % transparent) which means that their + * alpha channel is 0.7 + * The last two rows of this image is pure transparent which means that its alpha channel + * value is 0.0. + */ +const unsigned char rgba78_png_70_percent_opaqueData[284] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52 + ,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x08,0x08,0x06,0x00,0x00,0x00,0x35,0x04,0xe5 + ,0x06,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b + ,0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x97,0x74,0x45,0x58,0x74,0x43,0x6f + ,0x6d,0x6d,0x65,0x6e,0x74,0x00,0x63,0x48,0x52,0x4d,0x20,0x63,0x68,0x75,0x6e,0x6b + ,0x6c,0x65,0x6e,0x20,0x33,0x32,0x20,0x69,0x67,0x6e,0x6f,0x72,0x65,0x64,0x3a,0x0d + ,0x41,0x53,0x43,0x49,0x49,0x3a,0x20,0x2e,0x2e,0x7a,0x25,0x2e,0x2e,0xc3,0x84,0xc3 + ,0x89,0x2e,0x2e,0xcb,0x98,0xcb,0x87,0x2e,0x2e,0xc3,0x84,0xc3,0x88,0x2e,0x2e,0x75 + ,0x30,0x2e,0x2e,0xc3,0x8d,0x60,0x2e,0x2e,0x3a,0xc3,0xb2,0x2e,0x2e,0x2e,0x6f,0x0d + ,0x48,0x45,0x58,0x3a,0x20,0x30,0x30,0x30,0x30,0x37,0x41,0x32,0x35,0x30,0x30,0x30 + ,0x30,0x38,0x30,0x38,0x33,0x30,0x30,0x30,0x30,0x46,0x39,0x46,0x46,0x30,0x30,0x30 + ,0x30,0x38,0x30,0x45,0x39,0x30,0x30,0x30,0x30,0x37,0x35,0x33,0x30,0x30,0x30,0x30 + ,0x30,0x45,0x41,0x36,0x30,0x30,0x30,0x30,0x30,0x33,0x41,0x39,0x38,0x30,0x30,0x30 + ,0x30,0x31,0x37,0x36,0x46,0xa3,0xf6,0x8d,0x7b,0x00,0x00,0x00,0x2b,0x49,0x44,0x41 + ,0x54,0x78,0x9c,0x7c,0xc9,0x31,0x01,0x00,0x00,0x0c,0xc2,0xb0,0xfa,0xb7,0x83,0xc0 + ,0x6e,0x06,0xe0,0xc8,0x15,0x84,0x34,0xcc,0xfc,0x4d,0xb5,0x13,0xd3,0xad,0x54,0xab + ,0x99,0x07,0x00,0x00,0xff,0xff,0x03,0x00,0x13,0x06,0x71,0x0b,0x1a,0x23,0x85,0x8c + ,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; /* end of rgba78_png_70_percent_opaqueData */ + +BOOST_AUTO_TEST_SUITE(pnginputfile_tests) + +/* This is a helper class which will temporarily create a file which contains some + * arbitrary binary data. + * + * The file will be delete in the dtor. + */ +class CTempBinDataAsFile +{ + char* m_Filename; + +public: + CTempBinDataAsFile(const void* inData, size_t inDataSize) + : m_Filename((char*)::malloc(64)) + { + ::strcpy(m_Filename, "/tmp/aqsis_tmpfile_XXXXX"); + char* tmpFilename = ::mktemp(m_Filename); + assert(tmpFilename); + if (tmpFilename) + { + FILE* fileHd = ::fopen(m_Filename, "wb"); + assert(fileHd); + if (fileHd) + { + int rc = ::fwrite(inData, 1, inDataSize, fileHd); + assert(rc == inDataSize); + + ::fclose(fileHd); + } + } + else + { + ::free(m_Filename); + m_Filename = NULL; + } + } + + ~CTempBinDataAsFile() + { + ::unlink(m_Filename); + ::free(m_Filename); + } + + const char* getFileName() const + { + return m_Filename; + } +}; // class CTempBinDataAsFile + +/** This test utilizes the PNG image in order to load and parse a given PNG + * image which is has the size 7 x 6 pixels and contains of the three + * color components RGB. + * + * The image consists of three horizontal colord stripes each 2 pixels height. + * The first two pixels rows are _pure_ red, the second two are green and the + * last two rows are blue colored. + */ +BOOST_AUTO_TEST_CASE(CqPngInputFile_readRGBPixels_test) +{ + CTempBinDataAsFile tmpFile(rgb76_pngData, sizeof(rgb76_pngData)); + Aqsis::CqPngInputFile inFile(tmpFile.getFileName()); + + // Read the whole tiff into a buffer + Aqsis::CqTextureBuffer<TqUint8> buffer; + inFile.readPixels(buffer); + + // Check that the buffer is the right size. + BOOST_CHECK_EQUAL(buffer.width(), 7); + BOOST_CHECK_EQUAL(buffer.height(), 6); + BOOST_CHECK_EQUAL(buffer.numChannels(), 3); + + int x; + + // Check that the buffer contains the right data. + // part of the first two stripes (should be red) + for (x=0; x != buffer.width(); ++x) + { + // 1st row + BOOST_CHECK_CLOSE(buffer(x,0)[0], 1.0f, 1e-5); + BOOST_CHECK_CLOSE(buffer(x,0)[1], 0.0f, 1e-5); + BOOST_CHECK_CLOSE(buffer(x,0)[2], 0.0f, 1e-5); + + // 2nd row + BOOST_CHECK_CLOSE(buffer(x,1)[0], 1.0f, 1e-5); + BOOST_CHECK_CLOSE(buffer(x,1)[1], 0.0f, 1e-5); + BOOST_CHECK_CLOSE(buffer(x,1)[2], 0.0f, 1e-5); + } + + // Check that the buffer contains the right data. + // part of the second two stripes (should be green) + for (x=0; x != buffer.width(); ++x) + { + // 1st row + BOOST_CHECK_CLOSE(buffer(x,2)[0], 0.0f, 1e-5); + BOOST_CHECK_CLOSE(buffer(x,2)[1], 1.0f, 1e-5); + BOOST_CHECK_CLOSE(buffer(x,2)[2], 0.0f, 1e-5); + + // 2nd row + BOOST_CHECK_CLOSE(buffer(x,3)[0], 0.0f, 1e-5); + BOOST_CHECK_CLOSE(buffer(x,3)[1], 1.0f, 1e-5); + BOOST_CHECK_CLOSE(buffer(x,3)[2], 0.0f, 1e-5); + } + + // Check that the buffer contains the right data. + // part of the third two stripes (should be blue) + for (x=0; x != buffer.width(); ++x) + { + // 1st row + BOOST_CHECK_CLOSE(buffer(x,4)[0], 0.0f, 1e-5); + BOOST_CHECK_CLOSE(buffer(x,4)[1], 0.0f, 1e-5); + BOOST_CHECK_CLOSE(buffer(x,4)[2], 1.0f, 1e-5); + + // 2nd row + BOOST_CHECK_CLOSE(buffer(x,5)[0], 0.0f, 1e-5); + BOOST_CHECK_CLOSE(buffer(x,5)[1], 0.0f, 1e-5); + BOOST_CHECK_CLOSE(buffer(x,5)[2], 1.0f, 1e-5); + } + +} + +/** This test utilizes the PNG image in order to load and parse a given PNG + * image which is has the size 7 x 8 pixels and contains of the four + * color components RGBA. + * + * The image consists of four horizontal colored stripes each 2 pixels height. + * The first two pixels rows are _pure_ red, the second two are green the + * third two rows are blue colored and the last two rows are pure transparent. + * + * The first three colored stripes are opaque which means that their + * alpha value is 1.0. The last two stripes are transparent which means that + * the alpha values are expected to be 0.0. + */ +BOOST_AUTO_TEST_CASE(CqPngInputFile_readRGBAPixels_test) +{ + CTempBinDataAsFile tmpFile(rgba78_pngData, sizeof(rgba78_pngData)); + Aqsis::CqPngInputFile inFile(tmpFile.getFileName()); + + // Read the whole tiff into a buffer + Aqsis::CqTextureBuffer<TqUint8> buffer; + inFile.readPixels(buffer); + + // Check that the buffer is the right size. + BOOST_CHECK_EQUAL(buffer.width(), 7); + BOOST_CHECK_EQUAL(buffer.height(), 8); + BOOST_CHECK_EQUAL(buffer.numChannels(), 4); + + int x; + + // Check that the buffer contains the right data. + // part of the first two stripes (should be red) + for (x=0; x != buffer.width(); ++x) + { + // 1st row + BOOST_CHECK_CLOSE(buffer(x,0)[0], 1.0f, 1e-5); // red + BOOST_CHECK_CLOSE(buffer(x,0)[1], 0.0f, 1e-5); // green + BOOST_CHECK_CLOSE(buffer(x,0)[2], 0.0f, 1e-5); // blue + BOOST_CHECK_CLOSE(buffer(x,0)[3], 1.0f, 1e-5); // alpha + + // 2nd row + BOOST_CHECK_CLOSE(buffer(x,1)[0], 1.0f, 1e-5); // red + BOOST_CHECK_CLOSE(buffer(x,1)[1], 0.0f, 1e-5); // green + BOOST_CHECK_CLOSE(buffer(x,1)[2], 0.0f, 1e-5); // blue + BOOST_CHECK_CLOSE(buffer(x,1)[3], 1.0f, 1e-5); // alpha + } + + // Check that the buffer contains the right data. + // part of the second two stripes (should be green) + for (x=0; x != buffer.width(); ++x) + { + // 1st row + BOOST_CHECK_CLOSE(buffer(x,2)[0], 0.0f, 1e-5); // red + BOOST_CHECK_CLOSE(buffer(x,2)[1], 1.0f, 1e-5); // green + BOOST_CHECK_CLOSE(buffer(x,2)[2], 0.0f, 1e-5); // blue + BOOST_CHECK_CLOSE(buffer(x,2)[3], 1.0f, 1e-5); // alpha + + // 2nd row + BOOST_CHECK_CLOSE(buffer(x,3)[0], 0.0f, 1e-5); // red + BOOST_CHECK_CLOSE(buffer(x,3)[1], 1.0f, 1e-5); // green + BOOST_CHECK_CLOSE(buffer(x,3)[2], 0.0f, 1e-5); // blue + BOOST_CHECK_CLOSE(buffer(x,3)[3], 1.0f, 1e-5); // alpha + } + + // Check that the buffer contains the right data. + // part of the third two stripes (should be blue) + for (x=0; x != buffer.width(); ++x) + { + // 1st row + BOOST_CHECK_CLOSE(buffer(x,4)[0], 0.0f, 1e-5); // red + BOOST_CHECK_CLOSE(buffer(x,4)[1], 0.0f, 1e-5); // green + BOOST_CHECK_CLOSE(buffer(x,4)[2], 1.0f, 1e-5); // blue + BOOST_CHECK_CLOSE(buffer(x,4)[3], 1.0f, 1e-5); // alpha + + // 2nd row + BOOST_CHECK_CLOSE(buffer(x,5)[0], 0.0f, 1e-5); // red + BOOST_CHECK_CLOSE(buffer(x,5)[1], 0.0f, 1e-5); // green + BOOST_CHECK_CLOSE(buffer(x,5)[2], 1.0f, 1e-5); // blue + BOOST_CHECK_CLOSE(buffer(x,5)[3], 1.0f, 1e-5); // alpha + } + + // Check that the buffer contains the right data. + // part of the forth two stripes (should be transparent (alpha = 0)) + // Note that the actual color values will not be considered here! + for (x=0; x != buffer.width(); ++x) + { + // 1st row + BOOST_CHECK_CLOSE(buffer(x,6)[3], 0.0f, 1e-5); // alpha + + // 2nd row + BOOST_CHECK_CLOSE(buffer(x,7)[3], 0.0f, 1e-5); // alpha + } + +} + +/** This test is supposed to test if a PNG image will be loaded that the resulting image + * buffer contains color components with a premultiplied alpha value. + * This is a requirement of Aqsis because it relies on premultiplied alpha. + * + * The issue here is that PNG does *not* generate color components with premultiplied alpha + * by definition. However the PNG image loader (pnginputfile.cpp) does because it performs a + * multiplication of each color component with the pixels alpha value if a alpha component + * exists. + * + * In order to check if this works this test utilizes the PNG image in order to load and + * parse a given PNG image which is has the size 7 x 8 pixels and contains of the four + * color components RGBA. + * + * The image consists of four horizontal colored stripes each 2 pixels height. + * The first two pixels rows are _pure_ red, the second two are green the + * third two rows are blue colored and the last two rows are pure transparent. + * + * The first three colored stripes are opaque with a value of 70% which + * means that their alpha value is 0.7. + * + * The last two stripes are transparent which means that + * the alpha values are expected to be 0.0. + */ +BOOST_AUTO_TEST_CASE(CqPngInputFile_readRGBAPixels_with_70_percent_opaque_test) +{ + CTempBinDataAsFile tmpFile(rgba78_png_70_percent_opaqueData, sizeof(rgba78_png_70_percent_opaqueData)); + Aqsis::CqPngInputFile inFile(tmpFile.getFileName()); + + // Read the whole tiff into a buffer + Aqsis::CqTextureBuffer<TqUint8> buffer; + inFile.readPixels(buffer); + + // Check that the buffer is the right size. + BOOST_CHECK_EQUAL(buffer.width(), 7); + BOOST_CHECK_EQUAL(buffer.height(), 8); + BOOST_CHECK_EQUAL(buffer.numChannels(), 4); + + int x; + + // Check that the buffer contains the right data. + // part of the first two stripes (should be red) + for (x=0; x != buffer.width(); ++x) + { + // 1st row + BOOST_CHECK_CLOSE(buffer(x,0)[0], 0.7f, 0.3f); // red + BOOST_CHECK_CLOSE(buffer(x,0)[1], 0.0f, 0.3f); // green + BOOST_CHECK_CLOSE(buffer(x,0)[2], 0.0f, 0.3f); // blue + BOOST_CHECK_CLOSE(buffer(x,0)[3], 0.7f, 0.3f); // alpha + + // 2nd row + BOOST_CHECK_CLOSE(buffer(x,1)[0], 0.7f, 0.3f); // red + BOOST_CHECK_CLOSE(buffer(x,1)[1], 0.0f, 0.3f); // green + BOOST_CHECK_CLOSE(buffer(x,1)[2], 0.0f, 0.3f); // blue + BOOST_CHECK_CLOSE(buffer(x,1)[3], 0.7f, 0.3f); // alpha + } + + // Check that the buffer contains the right data. + // part of the second two stripes (should be green) + for (x=0; x != buffer.width(); ++x) + { + // 1st row + BOOST_CHECK_CLOSE(buffer(x,2)[0], 0.0f, 0.3f); // green + BOOST_CHECK_CLOSE(buffer(x,2)[1], 0.7f, 0.3f); // red + BOOST_CHECK_CLOSE(buffer(x,2)[2], 0.0f, 0.3f); // blue + BOOST_CHECK_CLOSE(buffer(x,2)[3], 0.7f, 0.3f); // alpha + + // 2nd row + BOOST_CHECK_CLOSE(buffer(x,3)[0], 0.0f, 0.3f); // green + BOOST_CHECK_CLOSE(buffer(x,3)[1], 0.7f, 0.3f); // red + BOOST_CHECK_CLOSE(buffer(x,3)[2], 0.0f, 0.3f); // blue + BOOST_CHECK_CLOSE(buffer(x,3)[3], 0.7f, 0.3f); // alpha + } + + // Check that the buffer contains the right data. + // part of the third two stripes (should be blue) + for (x=0; x != buffer.width(); ++x) + { + // 1st row + BOOST_CHECK_CLOSE(buffer(x,4)[0], 0.0f, 0.3f); // green + BOOST_CHECK_CLOSE(buffer(x,4)[1], 0.0f, 0.3f); // blue + BOOST_CHECK_CLOSE(buffer(x,4)[2], 0.7f, 0.3f); // red + BOOST_CHECK_CLOSE(buffer(x,4)[3], 0.7f, 0.3f); // alpha + + // 2nd row + BOOST_CHECK_CLOSE(buffer(x,5)[0], 0.0f, 0.3f); // green + BOOST_CHECK_CLOSE(buffer(x,5)[1], 0.0f, 0.3f); // blue + BOOST_CHECK_CLOSE(buffer(x,5)[2], 0.7f, 0.3f); // red + BOOST_CHECK_CLOSE(buffer(x,5)[3], 0.7f, 0.3f); // alpha + } + + // Check that the buffer contains the right data. + // part of the forth two stripes (should be transparent (alpha = 0)) + // Note that the actual color values will not be considered here! + for (x=0; x != buffer.width(); ++x) + { + // 1st row + BOOST_CHECK_CLOSE(buffer(x,6)[3], 0.0f, 1e-5); // alpha + + // 2nd row + BOOST_CHECK_CLOSE(buffer(x,7)[3], 0.0f, 1e-5); // alpha + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/libs/tex/io/project.cmake b/libs/tex/io/project.cmake index 9e90e78..921ed6a 100644 --- a/libs/tex/io/project.cmake +++ b/libs/tex/io/project.cmake @@ -6,6 +6,7 @@ set(io_srcs texfileheader.cpp tiffdirhandle.cpp tiffinputfile.cpp + pnginputfile.cpp tiffoutputfile.cpp tifftest_examples.cpp tiledanyinputfile.cpp @@ -23,6 +24,7 @@ set(io_hdrs tiffdirhandle.h tifffile_test.h tiffinputfile.h + pnginputfile.h tiffoutputfile.h tiledanyinputfile.h tiledtiffinputfile.h @@ -36,11 +38,16 @@ set(io_test_srcs texfileheader_test.cpp tiffdirhandle_test.cpp tiffinputfile_test.cpp + pnginputfile_test.cpp ) make_absolute(io_test_srcs ${io_SOURCE_DIR}) # Setup stuff for linking with external libs include_directories(${AQSIS_TIFF_INCLUDE_DIR}) -set(io_linklibs ${AQSIS_TIFF_LIBRARIES} ${AQSIS_TIFFXX_LIBRARIES}) +set(io_linklibs + ${AQSIS_TIFF_LIBRARIES} + ${AQSIS_TIFFXX_LIBRARIES} + ${AQSIS_PNG_LIBRARIES} +) commit bad56a16720b399c3654bd5315862947efd2f428 Author: Chris Foster <chr...@gm...> Date: Mon Jan 16 06:52:26 2012 +1000 Fix + add features to experimental float4 class The indexing operation is now consistent with the constructors + some arithmetic ops are fixed. Also add some convenience operations like pow and exp by calling standard math functions (no particular claim of efficiency is made for these!) diff --git a/prototypes/newcore/experiments/float4.h b/prototypes/newcore/experiments/float4.h index 89930d4..5d6a10e 100644 --- a/prototypes/newcore/experiments/float4.h +++ b/prototypes/newcore/experiments/float4.h @@ -73,10 +73,10 @@ class float4 STRONG_INLINE float4(float a, float b, float c, float d) { m_vec = _mm_setr_ps(a,b,c,d); } // float4, float4 arithmetic - STRONG_INLINE friend float4 operator+(float4 rhs, float4 lhs) { return float4 (_mm_add_ps (lhs.m_vec, rhs.m_vec)); } - STRONG_INLINE friend float4 operator-(float4 rhs, float4 lhs) { return float4 (_mm_sub_ps (lhs.m_vec, rhs.m_vec)); } - STRONG_INLINE friend float4 operator*(float4 rhs, float4 lhs) { return float4 (_mm_mul_ps (lhs.m_vec, rhs.m_vec)); } - STRONG_INLINE friend float4 operator/(float4 rhs, float4 lhs) { return float4 (_mm_div_ps (lhs.m_vec, rhs.m_vec)); } + STRONG_INLINE friend float4 operator+(float4 lhs, float4 rhs) { return float4 (_mm_add_ps (lhs.m_vec, rhs.m_vec)); } + STRONG_INLINE friend float4 operator-(float4 lhs, float4 rhs) { return float4 (_mm_sub_ps (lhs.m_vec, rhs.m_vec)); } + STRONG_INLINE friend float4 operator*(float4 lhs, float4 rhs) { return float4 (_mm_mul_ps (lhs.m_vec, rhs.m_vec)); } + STRONG_INLINE friend float4 operator/(float4 lhs, float4 rhs) { return float4 (_mm_div_ps (lhs.m_vec, rhs.m_vec)); } // float4, float arithmetic STRONG_INLINE friend float4 operator+(float4 lhs, float rhs) { return float4 (_mm_add_ps (lhs.m_vec, _mm_set1_ps(rhs))); } @@ -104,9 +104,6 @@ class float4 STRONG_INLINE float4& operator*=(float4 rhs) { m_vec = m_vec * rhs.m_vec; return *this; } STRONG_INLINE float4& operator/=(float4 rhs) { m_vec = m_vec / rhs.m_vec; return *this; } - // indexing - STRONG_INLINE float operator[](int i) const { return reinterpret_cast<const float*>(&m_vec)[i]; } - // raw access to underlying data STRONG_INLINE __m128 get() const { return m_vec; } @@ -116,6 +113,46 @@ class float4 STRONG_INLINE static void store(float* f, float4 rhs) { _mm_store_ps(f, rhs.m_vec); } STRONG_INLINE static void storeu(float* f, float4 rhs) { _mm_storeu_ps(f, rhs.m_vec); } + // indexing + STRONG_INLINE float operator[](int i) const + { + float res[4]; + storeu(res, m_vec); + return res[i]; + } + + // powers + STRONG_INLINE friend float4 pow(float4 a, float4 b) + { + float af[4]; + float bf[4]; + storeu(af, a.m_vec); + storeu(bf, b.m_vec); + return float4(pow(af[0], bf[0]), pow(af[1], bf[1]), + pow(af[2], bf[2]), pow(af[3], bf[3])); + } + + STRONG_INLINE friend float4 exp(float4 a) + { + float af[4]; + storeu(af, a.m_vec); + return float4(exp(af[0]), exp(af[1]), exp(af[2]), exp(af[3])); + } + + STRONG_INLINE friend float4 sqrt(float4 a) + { + return float4(_mm_sqrt_ps(a.m_vec)); + } + + STRONG_INLINE friend float4 abs(float4 a) + { + union { + __m128 f; + unsigned int u[4]; // int better be 32 bits wide + } signMask = {{0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF}}; + return float4(_mm_and_ps(signMask.f, a.m_vec)); + } + friend float4 min(float4 a, float4 b) { return float4(_mm_min_ps(a.m_vec, b.m_vec)); } friend float4 max(float4 a, float4 b) { return float4(_mm_max_ps(a.m_vec, b.m_vec)); } }; ----------------------------------------------------------------------- Summary of changes: CMakeLists.txt | 11 +- cmake/modules/FindPNG.cmake | 54 ++++ cmake/modules/FindZLIB.cmake | 6 +- libs/tex/CMakeLists.txt | 4 + libs/tex/io/itexinputfile.cpp | 13 + libs/tex/io/magicnumber.cpp | 8 + libs/tex/io/magicnumber_test.cpp | 26 ++ libs/tex/io/pnginputfile.cpp | 327 +++++++++++++++++++++++ libs/tex/io/pnginputfile.h | 139 ++++++++++ libs/tex/io/pnginputfile_test.cpp | 428 +++++++++++++++++++++++++++++++ libs/tex/io/project.cmake | 15 +- prototypes/newcore/experiments/float4.h | 51 ++++- 12 files changed, 1070 insertions(+), 12 deletions(-) create mode 100644 cmake/modules/FindPNG.cmake create mode 100644 libs/tex/io/pnginputfile.cpp create mode 100644 libs/tex/io/pnginputfile.h create mode 100644 libs/tex/io/pnginputfile_test.cpp hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2012-01-16 05:07:07
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, pointrender has been deleted was eaf740735ffb44ba754bf2dc0f7681bc75725f42 ----------------------------------------------------------------------- eaf740735ffb44ba754bf2dc0f7681bc75725f42 First stab at PBGI tutorial documentation. ----------------------------------------------------------------------- hooks/post-receive -- Aqsis Renderer |
From: Paul G. <pgr...@us...> - 2011-12-03 15:14:39
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via 46870dc8df122d51096bcc771a655210566e8e62 (commit) from 4166429f07b48dba6070903f55a64bce9410aff1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 46870dc8df122d51096bcc771a655210566e8e62 Author: Paul Gregory <pgr...@aq...> Date: Sat Dec 3 15:12:23 2011 +0000 Fix a couple of problems building docs on Windows. * The make.bat file wasn't setup to build PDF. Still not ideal, GNU make must be on the PATH, need to review. * Display Driver Interface had an error in the common include. diff --git a/doc/manual/user/make.bat b/doc/manual/user/make.bat index 2745c46..2b3d9f9 100644 --- a/doc/manual/user/make.bat +++ b/doc/manual/user/make.bat @@ -26,6 +26,8 @@ if "%1" == "help" ( echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. latexpdf to make LaTeX files and run them through pdflatex + echo. (requires GNU Make on the PATH) echo. text to make text files echo. man to make manual pages echo. changes to make an overview over all changed/added/deprecated items @@ -115,6 +117,20 @@ if "%1" == "latex" ( goto end ) +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + echo. Running LaTeX files through pdflatex... + call make.exe -C %BUILDDIR%/latex all-pdf + IF ERRORLEVEL 1 goto error + echo. + echo. pdflatex finished; the PDF files are in %BUILDDIR%/latex. + goto end +:error + echo. + echo. make failed, are you sure make.exe is on the PATH? + goto end +) + if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text echo. diff --git a/doc/manual/user/reference_guide/ddi.rst b/doc/manual/user/reference_guide/ddi.rst index a5ceb35..6ef9191 100644 --- a/doc/manual/user/reference_guide/ddi.rst +++ b/doc/manual/user/reference_guide/ddi.rst @@ -1,4 +1,4 @@ -.. include:: ../../common.rst +.. include:: ../common.rst .. _displays_api: ----------------------------------------------------------------------- Summary of changes: doc/manual/user/make.bat | 16 ++++++++++++++++ doc/manual/user/reference_guide/ddi.rst | 2 +- 2 files changed, 17 insertions(+), 1 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2011-10-26 09:26:50
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via 4166429f07b48dba6070903f55a64bce9410aff1 (commit) from 5ef363912c3d21fa6b756f6d208c06fc25b91ec7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4166429f07b48dba6070903f55a64bce9410aff1 Author: Chris Foster <chr...@gm...> Date: Tue Oct 18 15:40:00 2011 +1000 Remove some obsolete functions + cleanups Various functions for baking and rendering without an acceleration structure were left over from testing the PBGI work. These are now unnecessary so they've been removed. diff --git a/libs/pointrender/microbuffer.cpp b/libs/pointrender/microbuffer.cpp index 0fa4ba1..0a883ce 100644 --- a/libs/pointrender/microbuffer.cpp +++ b/libs/pointrender/microbuffer.cpp @@ -415,27 +415,6 @@ void renderDisk(IntegratorT& integrator, V3f N, V3f p, V3f n, float r, } -template<typename IntegratorT> -void microRasterize(IntegratorT& integrator, V3f P, V3f N, float coneAngle, - const PointArray& points) -{ - float cosConeAngle = cos(coneAngle); - float sinConeAngle = sin(coneAngle); - for(int pIdx = 0, npoints = points.size(); pIdx < npoints; ++pIdx) - { - const float* data = &points.data[pIdx*points.stride]; - // position of current point relative to shading point - V3f p = V3f(data[0], data[1], data[2]) - P; - // normal of current point - V3f n = V3f(data[3], data[4], data[5]); - // radius of point - float r = data[6]; - integrator.setPointData(data+7); - renderDisk(integrator, N, p, n, r, cosConeAngle, sinConeAngle); - } -} - - /// Render point hierarchy into microbuffer. template<typename IntegratorT> static void renderNode(IntegratorT& integrator, V3f P, V3f N, float cosConeAngle, @@ -548,90 +527,6 @@ void microRasterize(IntegratorT& integrator, V3f P, V3f N, float coneAngle, } -void occlWeight(MicroBuf& depthBuf, const V3f& N) -{ - for(int f = MicroBuf::Face_begin; f < MicroBuf::Face_end; ++f) - { - float* face = depthBuf.face(f); - for(int iv = 0; iv < depthBuf.res(); ++iv) - for(int iu = 0; iu < depthBuf.res(); ++iu, face += 2) - { - float d = dot(depthBuf.rayDirection(f, iu, iv), N); - if(d > 0) - face[1] = d*(1.0f - face[1]); - else - face[1] = 0; - } - } -} - - -void bakeOcclusion(PointArray& points, int faceRes) -{ - const float eps = 0.1; - OcclusionIntegrator integrator(faceRes); - for(int pIdx = 0, npoints = points.size(); pIdx < npoints; ++pIdx) - { - if(pIdx % 100 == 0) - std::cout << 100.0f*pIdx/points.size() << "% \r" << std::flush; - float* data = &points.data[pIdx*points.stride]; - // normal of current point - V3f N = V3f(data[3], data[4], data[5]); - // position of current point relative to shading point - V3f P = V3f(data[0], data[1], data[2]); - float r = data[6]; - integrator.clear(); - microRasterize(integrator, P + N*r*eps, N, M_PI_2, points); - data[7] = data[8] = data[9] = 1 - integrator.occlusion(N, M_PI_2); - } -} - - -void bakeOcclusion(PointArray& points, const PointOctree& tree, int faceRes, - float maxSolidAngle) -{ - // FIXME: Code duplication with bakeOcclusion above. - const float eps = 0.1; - OcclusionIntegrator integrator(faceRes); - for(int pIdx = 0, npoints = points.size(); pIdx < npoints; ++pIdx) - { - if(pIdx % 400 == 0) - std::cout << 100.0f*pIdx/points.size() << "% \r" << std::flush; - float* data = &points.data[pIdx*points.stride]; - // normal of current point - V3f N = V3f(data[3], data[4], data[5]); - // position of current point relative to shading point - V3f P = V3f(data[0], data[1], data[2]); - float r = data[6]; - integrator.clear(); - microRasterize(integrator, P + N*r*eps, N, M_PI_2, maxSolidAngle, tree); - data[7] = data[8] = data[9] = 1 - integrator.occlusion(N, M_PI_2); - } -} - - -void bakeRadiosity(PointArray& points, const PointOctree& tree, int faceRes, - float maxSolidAngle) -{ - const float eps = 0.1; - RadiosityIntegrator integrator(faceRes); - for(int pIdx = 0, npoints = points.size(); pIdx < npoints; ++pIdx) - { - if(pIdx % 400 == 0) - std::cout << 100.0f*pIdx/points.size() << "% \r" << std::flush; - float* data = &points.data[pIdx*points.stride]; - // normal of current point - V3f N = V3f(data[3], data[4], data[5]); - // position of current point relative to shading point - V3f P = V3f(data[0], data[1], data[2]); - float r = data[6]; - integrator.clear(); - microRasterize(integrator, P + N*r*eps, N, M_PI_2, maxSolidAngle, tree); - *reinterpret_cast<C3f*>(data+7) = integrator.radiosity(N, M_PI_2); - } -} - - // Explicit instantiations template void microRasterize<OcclusionIntegrator>( OcclusionIntegrator&, V3f, V3f, float, float, const PointOctree&); diff --git a/libs/pointrender/microbuffer.h b/libs/pointrender/microbuffer.h index 053c3bc..0bbb750 100644 --- a/libs/pointrender/microbuffer.h +++ b/libs/pointrender/microbuffer.h @@ -54,8 +54,6 @@ inline float dot(V3f a, V3f b) /// An axis-aligned cube environment buffer. /// -/// Just stores depth (z) for now (TODO) -/// /// Each face has a coordinate system where the centres of the boundary pixels /// lie just _inside_ the boundary. That is, the positions of the pixel point /// samples are at x_i = (1/2 + i/N) for i = 0 to N-1. @@ -608,19 +606,6 @@ class RadiosityIntegrator /// \param N - normal for light probe (should be normalized) /// \param coneAngle - defines cone about N: coneAngle = max angle of interest /// between N and the incoming light. -/// \param points - point cloud to render -template<typename IntegratorT> -void microRasterize(IntegratorT& integrator, V3f P, V3f N, float coneAngle, - const PointArray& points); - - -/// Render points into a micro environment buffer. -/// -/// \param integrator - integrator for incoming geometry/lighting information -/// \param P - position of light probe -/// \param N - normal for light probe (should be normalized) -/// \param coneAngle - defines cone about N: coneAngle = max angle of interest -/// between N and the incoming light. /// \param maxSolidAngle - Maximum solid angle allowed for points in interior /// tree nodes. /// \param points - point cloud to render @@ -629,35 +614,6 @@ void microRasterize(IntegratorT& integrator, V3f P, V3f N, float coneAngle, float maxSolidAngle, const PointOctree& points); -/// Visualize sources of light in occlusion calculation (for debugging) -void occlWeight(MicroBuf& depthBuf, const V3f& N); - - -/// Bake occlusion from point array back into point array. -void bakeOcclusion(PointArray& points, int faceRes); - - -/// Bake occlusion from point hierarchy tree into point cloud. -/// -/// \param points - output array of surfels -/// \param tree - hierarchical point-based representation of scene -/// \param faceRes - resolution of microbuffer to use -/// \param maxSolidAngle - Maximum solid angle allowed for points in interior -/// tree nodes. -void bakeOcclusion(PointArray& points, const PointOctree& tree, int faceRes, - float maxSolidAngle); - -/// Bake radiosity from point hierarchy into point cloud. -/// -/// \param points - output array of surfels -/// \param tree - hierarchical point-based representation of scene -/// \param faceRes - resolution of microbuffer to use -/// \param maxSolidAngle - Maximum solid angle allowed for points in interior -/// tree nodes. -void bakeRadiosity(PointArray& points, const PointOctree& tree, int faceRes, - float maxSolidAngle); - - } // namespace Aqsis #endif // AQSIS_MICROBUFFER_H_INCLUDED ----------------------------------------------------------------------- Summary of changes: libs/pointrender/microbuffer.cpp | 105 -------------------------------------- libs/pointrender/microbuffer.h | 44 ---------------- 2 files changed, 0 insertions(+), 149 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Paul G. <pgr...@us...> - 2011-10-23 20:33:14
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via 5ef363912c3d21fa6b756f6d208c06fc25b91ec7 (commit) from c5ffe1f1dc003cc2acf5c084381ec79268a84d39 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5ef363912c3d21fa6b756f6d208c06fc25b91ec7 Author: Paul Gregory <pgr...@aq...> Date: Sun Oct 23 21:00:01 2011 +0100 Initial documentation layout refactor. * Layout according to agreed structure. * Move some reference material into the new layout. * User guide section is as yet unpopulated, needs to be filled with tutorial style content. * Also fixed a type in the main template layout. diff --git a/doc/manual/user/_templates/layout.html b/doc/manual/user/_templates/layout.html index 4eef091..b2885a3 100644 --- a/doc/manual/user/_templates/layout.html +++ b/doc/manual/user/_templates/layout.html @@ -10,7 +10,7 @@ {% block relbar1 %} <div style="background-color: white; text-align: left; padding: 10px 10px 15px 15px"> -<a href="{{ pathto('index') }}"><span class="title">Aqsis Renederer User Manual</span></a> +<a href="{{ pathto('index') }}"><span class="title">Aqsis Renderer User Manual</span></a> </div> {{ super() }} {% endblock %} diff --git a/doc/manual/user/index.rst b/doc/manual/user/index.rst index b7ccfe6..dac2018 100644 --- a/doc/manual/user/index.rst +++ b/doc/manual/user/index.rst @@ -11,12 +11,13 @@ The Aqsis User Manual Contents: .. toctree:: - :maxdepth: 2 + :maxdepth: 3 welcome user_guide/index - program_guide/index - tutorials/index + reference_guide/index + +.. tutorials/index Indices and tables ================== diff --git a/doc/manual/user/legal.rst b/doc/manual/user/legal.rst index c93ffbc..4e1d2b9 100644 --- a/doc/manual/user/legal.rst +++ b/doc/manual/user/legal.rst @@ -2,9 +2,9 @@ .. _legal: -===== -Legal -===== +============================ +License and Acknowledgements +============================ Software License ---------------- diff --git a/doc/manual/user/reference_guide/attributes.rst b/doc/manual/user/reference_guide/attributes.rst new file mode 100644 index 0000000..2e03f3d --- /dev/null +++ b/doc/manual/user/reference_guide/attributes.rst @@ -0,0 +1,207 @@ +========== +Attributes +========== + +Identifier Attributes +--------------------- + +These values associate information with the primitives they apply to, that +allow various processes to identify the primitive. This information is used +internally to provide meaningful feedback during rendering, and can be accessed +by shaders using the ``attribute`` RSL command. They are grouped under the +"identifier" attribute. + +name + The name applied to primitives in the current attribute block. + + Type: ``"string"`` + + Example: ``Attribute "identifier" "name" [""]`` + + +Displacement Bound Attributes +----------------------------- + +These values control how Aqsis compensates for changes in a primitives surface +due to displacement shading. They are grouped under the "displacementbound" +attribute. + +sphere + Apply the specified amount of extra space in all directions to the bound of + the primitives within the current attribute block to account for surface + changes as a result of displacement shading. + + Type: ``"float"`` + + Example: ``Attribute "displacementbound" "sphere" [0.0]`` + +coordinatesystem + Specifies the coordinate system that the extra displacement offset is specified in. + + Type: ``"string"`` + + Example: ``Attribute "displacementbound" "coordinatesystem" ["object"]`` + +Trimcurve Attributes +-------------------- + +Certain primitive types in Aqsis can have trimcurves, that is a 2D curve in +parameter space that removes a certain portion of the surface, commonly used +with NURBS surfaces. These values allow the user to control how those trim +curves are applied. They only apply to surfaces for which trim curves are +applicable. They are grouped under the "trimcurve" attribute. + +sense + Control the part of trimmed geometry that gets discarded. By default, Aqsis + will discard trimmed geometry that is inside (according to the winding rules) + the trim curves, changing this to "outside" will swap the behaviour. + + Type: ``"string"`` + + Example: ``Attribute "trimcurve" "sense" ["inside"]`` + +Dice Attributes +--------------- + +When Aqsis processes primitives, it has, at various times, to make a decision +regarding whether to dice or split, and if dicing, how finely to dice. These +values allow the user to influence those decisions to achieve a specific +effect. They are grouped under the "dice" attribute. + +binary + Setting this value to anything other than 0 will force Aqsis to dice + primitives so that the number of micropolygons on an edge is a factor of 2. + This can alleviate some cracking problems. + + Type: ``"integer"`` + + Example: ``Attribute "dice" "binary" [0]`` + +Aqsis Internal Attributes +------------------------- + +The "aqsis" attribute is used for enabling internal hacks. + +expandgrids + Setting this to a number greater than zero will cause all grids arising from + the associated primitives to have their boundary micropolygons expanded + outward. This may be used to work around the grid cracking problem - the + appearance of small holes in curved surfaces. The value of the attribute + specifies the amount of expansion as a fraction of a micropolygon. An + expansion amount of 0.01 can be sufficient to prevent cracking for smooth + surfaces, while larger values are necessary for surfaces with a lot of + displacement. Using this option with semitransparent surfaces or the + "midpoint" depth filter for shadow map generation will result in artifacts. + + Type: ``"float"`` + + Example: ``Attribute "aqsis" "expandgrids" [0.01]`` + +Autoshadows Attributes +---------------------- + +When used with the "multipass" render option, these attributes control the generation of automatic shadow depth maps by Aqsis. + +res + Define the resolution of automatically generated shadow maps. The maps are + always square, so only one resolution value is required. + + Type: ``"integer"`` + + Example: ``Attribute "autoshadows" "res" [300]`` + +shadowmapname + The file name of the automatically generated shadow maps. This same name + should then be used in the appropriate argument to the lightsource shader. + + Type: ``"string"`` + + Example: ``Attribute "autoshadows" "shadowmapname" [""]`` + +Matte Attributes +---------------- + +``RiMatte`` is typically used to allow portions of an image to be replaced in +compositing with live action shots or backgrounds ("matte paintings") etc. For +this kind of thing we'd also like to render shadows cast by CG objects so that +they form dark opaque areas which can be composited over the live action. +Unfortunately this isn't possible in a single pass when using the matte objects +defined in the standard, since the colour and opacity of the matte are +interpreted in an unusual way. + +Aqsis adds an additional setting to the ``RiMatte()`` interface call, +``RI_MATTEALPHA`` to support this kind of usage. *Mattes with Alpha* +are a new kind of Matte object which are always opaque from the point of view +of the hider but retain both opacity ("alpha") and colour information from +shaders attached to them. That is, an alpha matte fully occludes all objects +behind it in the scene but the user can at the same time specify a nonzero +alpha value and colour which make their way unmodified into the output image. + +This special attribute is specified via the RiMatte command: + +C API: + ``RiMatte(RI_MATTEALPHA)`` + +RIB Binding: + ``Matte 2`` + +GeometricApproximation Attributes +--------------------------------- + +The ``GeometricApproximation`` attribute allows some control over the +accuracy with which the renderer tesselates geometry into micropolygons for +renderering. Normally, the micropolygon area is constrained to be smaller than +the ``ShadingRate`` attribute. However, when a surface is highly blurred - +either by motion blur or depth of field effects - it is desirable to increase +the shading rate for efficiency. This has the effect of coarsening the +tessellation, but this often doesn't matter since the details are lost to +blurring in any case. + +Defaults for the various types of geometric approximation have been chosen with +the intention of preserving image quality compared to images rendered with the +approximations turned off. + +focusfactor + The "focusfactor" approximation type makes depth of field rendering more + efficient by scaling the effective shading rate with the area of the circle + of confusion. This guarentees that the number of hit tests between samples + and micropolygons stays under control as the amount of blurring increases. + + Example: ``GeometricApproximation "focusfactor" 1.0`` is the default. + +motionfactor + The "motionfactor" approximation type makes motion blur rendering more + efficient by scaling the shading rate proportionally to the distance + travelled by a surface across the screen. This feature is somewhat + experimental in aqsis-1.6. + + Example: ``GeometricApproximation "motionfactor" 0.0`` turns the motionfactor approximation off. + + +Setting Options from the Command Line +===================================== + +Aqsis provides a very flexible and powerful mechanism to override or add to +options in the RIB file being rendered. The **-option** command line argument +allows you to insert arbitrary options - and in fact, arbitrary RIB fragments - +into the command stream just prior to the ``RiWorldBegin`` request. You can +provide multiple fragments via multiple ``-option`` arguments; these will be +processed immediately before ``RiWorldBegin`` in the order that they are +specified on the command line. + +A typical use for this facility is to override the display request to force +output to a different file, or to output to an additional file. For example:: + + aqsis -option="Display \"myname.tif\" \"file\" \"rgba\"" some_file.rib + +allows you to specify not only the type of display, but also the name, and even +the type of data that will be displayed. Note that you must be careful to +*escape the use of double quotes on the command line* so that they get +through to the renderer correctly. Using double quotes within a command line +parameter is likely to confuse the command line processor; mark them with a '\' to +prevent them closing the double quotes surrounding the argument to ``-option``. + +Aqsis has some additional command line arguments which also affect the options +state of the renderer. For example, changing or adding displays may also be +done with the simple command line options ``-type`` and ``-addtype``, though +these offer less flexibility than the ``-option`` mechanism described above. diff --git a/doc/manual/user/reference_guide/capi.rst b/doc/manual/user/reference_guide/capi.rst new file mode 100644 index 0000000..583b0fa --- /dev/null +++ b/doc/manual/user/reference_guide/capi.rst @@ -0,0 +1,4 @@ +***** +C API +***** + diff --git a/doc/manual/user/reference_guide/cli.rst b/doc/manual/user/reference_guide/cli.rst new file mode 100644 index 0000000..385140e --- /dev/null +++ b/doc/manual/user/reference_guide/cli.rst @@ -0,0 +1,4 @@ +************************** +Tools Command Line Options +************************** + diff --git a/doc/manual/user/reference_guide/ddi.rst b/doc/manual/user/reference_guide/ddi.rst new file mode 100644 index 0000000..a5ceb35 --- /dev/null +++ b/doc/manual/user/reference_guide/ddi.rst @@ -0,0 +1,577 @@ +.. include:: ../../common.rst + +.. _displays_api: + +************************ +Display Driver Interface +************************ + +Overview +-------- + +A display driver is a shared library that gets loaded by the renderer at runtime and receives the final rendered image in individual chunks (buckets or scanlines). The display driver is responsible for either displaying the image to the user, storing it on disk, or whatever else is required in the rendering pipeline. + +Displays are connected to the renderer via the **RiDisplay()** interface call or the **Display** RIB request (see the RISpec for details). Although the method for connecting displays is well-defined by the standard, the display interface itself isn't formally described. Nevertheless, the "Dspy" interface used by Pixar's PRMan provides a de-facto standard which is implemented in |Aqsis| and most other RenderMan renderers. Implementing the same interface means that compiled display drivers should be compatible between the various RenderMan renderers. + +|Aqsis| includes some standard display drivers that allow you to save the image in various file formats or display it directly in a framebuffer. However, it is also possible to write your own customized display drivers using the interface described in this section. + + +Display Functions +^^^^^^^^^^^^^^^^^ + +Each display driver following the Dspy standard must implement four mandatory functions: + +* DspyImageOpen_ is the function which sets up the display. It is called before the rendering starts. +* DspyImageQuery_ allows |Aqsis| to ask the display for additional information about an image. +* DspyImageData_ is called to pass the image data from the renderer to the display. +* DspyImageClose_ is called when the entire image has been rendered so that the display driver may free its resources. + +There is one optional function: + +* DspyImageDelayClose_ may be used by interactive display drivers so that they can remain open while the renderer shuts down. + +All functions are explained in detail in the `API Reference`_. + + +Example +------- + +The following is an example display driver that just dumps the functions with their arguments to stdout + +.. code-block:: cpp + + /* + Demo Display Driver that just dumps all the data to stdout. + */ + + #include <ndspy.h> + #include <string.h> + #include <iostream> + + /* ------------------------------------------------------------ + DspyImageOpen + ------------------------------------------------------------ */ + PtDspyError DspyImageOpen(PtDspyImageHandle * image, + const char *drivername, + const char *filename, + int width, + int height, + int paramCount, + const UserParameter *parameters, + int formatCount, + PtDspyDevFormat *format, + PtFlagStuff *flagStuff) + { + std::cout<<"ImageOpen:"<<std::endl; + std::cout<<" Driver name : '"<<drivername<<"'"<<std::endl; + std::cout<<" File name : '"<<filename<<"'"<<std::endl; + std::cout<<" Width x Height : "<<width<<"x"<<height<<std::endl; + std::cout<<" #Parameters : "<<paramCount<<std::endl; + std::cout<<" #Channels : "<<formatCount<<std::endl; + + // Dump the parameters + for(int i=0; i<paramCount; i++) + { + const UserParameter& param = parameters[i]; + std::cout<<" Parameter "<<i+1<<": "<<param.name<<" ("<<param.vtype<<", "<<(int)param.vcount<<") = "; + for (int j=0; j<param.vcount; j++) + { + switch(param.vtype) + { + case 'i': std::cout<<*((int*)param.value+j)<<" "; break; + case 'f': std::cout<<*((float*)param.value+j)<<" "; break; + case 's': std::cout<<*((char**)param.value+j)<<" "; break; + default: std::cout<<"unknown type"; + } + } + std::cout<<std::endl; + } + + // Dump the channels + for(int i=0; i<formatCount; i++) + { + PtDspyDevFormat& f = format[i]; + std::cout<<" Channel '"<<f.name<<"': "; + switch(f.type) + { + case PkDspyNone: std::cout<<"None"; break; + case PkDspyFloat32: std::cout<<"Float32"; break; + case PkDspyUnsigned32: std::cout<<"Unsigned32"; break; + case PkDspySigned32: std::cout<<"Signed32"; break; + case PkDspyUnsigned16: std::cout<<"Unsigned16"; break; + case PkDspySigned16: std::cout<<"Signed16"; break; + case PkDspyUnsigned8: std::cout<<"Unsigned8"; break; + case PkDspySigned8: std::cout<<"Signed8"; break; + default: std::cout<<"Unknown"; + } + std::cout<<std::endl; + } + + flagStuff->flags = 0; + return PkDspyErrorNone; + } + + /* ------------------------------------------------------------ + DspyImageQuery + ------------------------------------------------------------ */ + PtDspyError DspyImageQuery(PtDspyImageHandle image, + PtDspyQueryType type, + int size, + void *data) + { + std::cout<<"ImageQuery()"<<std::endl; + std::cout<<" Type: "; + switch(type) + { + case PkSizeQuery: + { + std::cout<<"SizeQuery"; + PtDspySizeInfo info; + info.width = 320; + info.height = 160; + info.aspectRatio = 1.0f; + if (size>sizeof(info)) + size = sizeof(info); + memcpy(data, &info, size); + break; + } + case PkOverwriteQuery: + { + std::cout<<"OverwriteQuery"; + PtDspyOverwriteInfo info; + info.overwrite = 1; + info.interactive = 0; + if (size>sizeof(info)) + size = sizeof(info); + memcpy(data, &info, size); + break; + } + default: + std::cout<<"Unknown query"; + } + std::cout<<std::endl; + std::cout<<" Size: "<<size<<std::endl; + + return PkDspyErrorNone; + } + + /* ------------------------------------------------------------ + DspyImageData + ------------------------------------------------------------ */ + PtDspyError DspyImageData(PtDspyImageHandle image, + int xmin, + int xmaxplus1, + int ymin, + int ymaxplus1, + int entrysize, + const unsigned char *data) + { + static int count = 0; + count++; + int size = (xmaxplus1-xmin)*(ymaxplus1-ymin)*entrysize; + std::cout<<count<<" - ImageData(image, "<<xmin<<", "<<xmaxplus1<<", "<<ymin<<", "<<ymaxplus1<<", "<<entrysize<<")"; + std::cout<<" - "<<size<<" bytes of pixel data"<<std::endl; + + return PkDspyErrorNone; + } + + /* ------------------------------------------------------------ + DspyImageClose + ------------------------------------------------------------ */ + PtDspyError DspyImageClose(PtDspyImageHandle image) + { + std::cout<<"ImageClose()"<<std::endl; + + return PkDspyErrorNone; + } + +Compiling and using a Display Driver +------------------------------------ + +A display driver must be compiled as a shared object/dynamic link library. Please consult the documentation of your compiler on more information about how this is done. Here are some example command lines: + +Linux + With g++ a display driver may be compiled into a shared object with the command <code>g++ -fPIC -I $install_prefix/include/aqsis -shared displaydriver.cpp -o displaydriver.so</code> The ''-fPIC'' option is probably only needed on 64-bit systems. +OSX + The command is similar to the Linux command: <code>g++ -I /usr/local/include/aqsis -dynamiclib displaydriver.cpp -o displaydriver.dylib</code>(of course, the actual include path depends on where you have installed the |Aqsis| header files) +Windows + Using Visual C++, we have: <code>cl /I%AQSISHOME%\include\aqsis /LD /DWIN32 /EHsc displaydriver.cpp</code> ''/EHsc'' is not required if your display driver is implemented in C. + +Once the driver is compiled, you have to tell |Aqsis| that you want to use your new driver and where it will find the driver. How you do this depends on the modeling/animation package you are using - please consult the documentation of your 3D application. + +If you are using |Aqsis| directly via the RenderMan C API or by creating a RIB file by hand, you can specify the driver in the **RiDisplay()** call:: + + RiDisplay("out.tif", "mydriver", RI_RGB, ...paramlist...); + +or as the RIB request:: + + Display "out.tif" "mydriver" "rgb" ...paramlist... + +|Aqsis| will then look up the name "mydriver" in an internal list that maps display names to display driver libraries. If it cannot find the name, it will output an error. You can add or modify an entry in that list using the **RiOption()** call. Here is a RIB request that associates the display name "mydriver" with the DLL "mydisplaydriver.dll":: + + Option "display" "string mydriver" ["mydisplaydriver.dll"] + +The next problem is that |Aqsis| has to find the library. You could actually provide an entire path in the above call, but the better way is to add the location where you installed the driver to the list of search paths for display drivers:: + + Option "searchpath" "string display" ["&:C:\RenderMan\MyDrivers"] + +The **&** character represents the previously set search paths, so the above option call *adds* another path to the list. If you omit this character the path would replace the previous list and |Aqsis| would not be able to find the standard display drivers anymore (file, framebuffer, etc.). + + +API Reference +------------- + +|Aqsis| expects a display to implement the standard display interface as in PRMan and other renderers. This means implementing the four functions DspyImageOpen_, DspyImageQuery_, DspyImageData_ and DspyImageClose_\. The function prototypes are defined in the header **<ndspy.h>**. + +All functions in the display interface return one of the possible [[#PtDspyError|error codes]], which will normally be *PkDspyErrorNone* when everything is ok. The first parameter to the display interface functions is an image handle of type PtDspyImageHandle_. The handle should be used by the display driver to store internal data associated with the display. Any handle stored here by DspyImageOpen_ will be passed on to the other functions without being modified by the renderer. + +DspyImageOpen +^^^^^^^^^^^^^ +.. c:function:: PtDspyError DspyImageOpen(PtDspayImageHandle* image, const char* drivername, const char* filename, int width, int height, int paramCount, const UserParameter* parameters, int formatCount, PtDspyDevFormat* format, PtFlagStuff* flagstuff) + + DspyImageOpen is called by the renderer to open and initialize a display. Typically this might involve allocating a memory buffer large enough to hold the image, opening a file or initializing a GUI to display the data directly. + + :param image: a pointer to a handle for any internal data structures allocated by the display. This handle should be set by ''DspyImageOpen'' and will be stored by the renderer without modification to be passed on to the other display functions. + :type image: PtDspyImageHandle* + :param drivername: the name of the display driver as it was specified in the **RiDisplay()** call. + :type drivername: const char* + :param filename: the output file name as given in the **RiDisplay()** call. + :type filename: const char* + :param width: the image width in pixels. When the image is cropped this is the cropped size. If 0 is passed the driver must choose an appropriate default value. + :type width: int + :param height: the image height in pixels. When the image is cropped this is the cropped size. If 0 is passed the driver must choose an appropriate default value. + :type height: int + :param paramCount: the number of parameters stored in the array *parameters* + :type paramCount: int + :param parameters: parameters to the **RiDisplay()** interface call are passed on to the display inside this array. For each parameter there is a UserParameter_ struct that contains the name/value pair. These structs are only valid within this function. If you need a value in one of the other functions you must copy the value! + :type parameters: const UserParameter* + :param formatCount: the number of items in the array *format* that is, the number of channels of pixel data in the image. + :type formatCount: int + :param format: for each output channel, there is a PtDspyDevFormat_ struct describing the type of the data that gets passed into the driver. The driver may rearrange this array or change the data type to get the channels delivered in a different order or as a different type or in a different byte order. If you want to remove a channel, set its type to *PkDspyNone'* When you reorder the array you must ensure that the names still point to the original strings that were passed in! Just like the *parameters* array the format structs are only valid inside this call. Do not try to access the values again in one of the other functions. + :type format: PtDspyDevFormat* + :param flagstuff: the display may change the value of these flags to modify aspects of the incoming pixel data, such as to request that the renderer send scanline order. See PtFlagStuff_ for possible values. + :type flagstuff: PtFlagStuff* + :returns: An error code or PkDspyErrorNone + + +In addition to any user parameters passed to the driver, the array ''parameters'' will always contain the following system-defined parameters: + ++--------------------+---------------+-----------------------------------------------------------------------+ +| name | vtype[vcount] | Description | ++====================+===============+=======================================================================+ +| "NP" | f[16] | World to screen space matrix | ++--------------------+---------------+-----------------------------------------------------------------------+ +| "Nl" | f[16] | World to camera space matrix | ++--------------------+---------------+-----------------------------------------------------------------------+ +| "near" | f[1] | Near clipping plane | ++--------------------+---------------+-----------------------------------------------------------------------+ +| "far" | f[1] | Far clipping plane | ++--------------------+---------------+-----------------------------------------------------------------------+ +| "origin" | i[2] | Origin of the crop window within the entire image | ++--------------------+---------------+-----------------------------------------------------------------------+ +| "OriginalSize" | i[2] | Original pixel size of the entire image (not just the cropped window) | ++--------------------+---------------+-----------------------------------------------------------------------+ +| "PixelAspectRatio" | f[1] | The pixel aspect ration | ++--------------------+---------------+-----------------------------------------------------------------------+ +| "Software" | s[1] | The name of the renderer | ++--------------------+---------------+-----------------------------------------------------------------------+ +| "HostComputer" | s[1] | The network name of the computer that the image is rendered on | ++--------------------+---------------+-----------------------------------------------------------------------+ + +Types +""""" +.. _UserParameter: + +UserParameter + +.. code-block:: cpp + + typedef struct + { + RtToken name; + char vtype; + char vcount; + RtPointer value; + int nbytes; + } + UserParameter; + +name + the name of the parameter + +vtype + the type of the parameter value. This can be either ''"i"'' for integers of type ''RtInt'', ''"f"'' for floats of type ''RtFloat'' or ''"s"'' for strings of type ''char*''. + +vcount + this is the array size. If the value is a scalar, ''vcount'' is 1. + +value + this is a pointer that points to the value(s). The display should cast this pointer to the appropriate type to access the contained data. + +nbytes + the total number of bytes used by the entire value + + +.. _PtDspyDevFormat: + +PtDspyDevFormat + +.. code-block:: cpp + + typedef struct + { + char *name; + unsigned type; + } + PtDspyDevFormat; + +name + the name of the output channel. Standard channels include "r", "g", "b", "a", "z", but *name* may take other values when using AOV. + +type + one of the possible `Pixel types`_ describing the channel bitwidth and type. The type can be combined (using the bitwise OR operator) with the following flags to determine the byte order of a single value. Obviously this is only meaningful for types that are longer than a single byte. + + * PkDspyByteOrderHiLo + Force big endian format (most significant bytes first) + * PkDspyByteOrderLoHi + Force little endian format (least significant bytes first) + * PkDspyByteOrderNative + Use whatever format is native on the current machine (this is the default) + + +Pixel types +""""""""""" + +A set of integer constants is defined to specify the output pixel format type. All such constants start with the prefix *Pk* Associated with these is a set of typedefs starting with the prefix *Pt*. Pixel formats are defined both for floating point and signed/unsigned integers of different bit-widths. The value *PkDspyNone* may be set by the display to remove a channel from the data sent to the driver. For example, if the display can only handle rgb images, but the renderer is going to create rgba data, the display should set the type for the "a" field to *PtDspyNone*. + ++------------------+------------------+ +| Format constant | typedef | ++==================+==================+ +| PkDspyNone | *nothing* | ++------------------+------------------+ +| PkDspyFloat32 | PtDspyFloat32 | ++------------------+------------------+ +| PkDspyUnsigned32 | PtDspyUnsigned32 | ++------------------+------------------+ +| PkDspySigned32 | PtDspySigned32 | ++------------------+------------------+ +| PkDspyUnsigned16 | PtDspyUnsigned16 | ++------------------+------------------+ +| PkDspySigned16 | PtDspySigned16 | ++------------------+------------------+ +| PkDspyUnsigned8 | PtDspyUnsigned8 | ++------------------+------------------+ +| PkDspySigned8 | PtDspySigned8 | ++------------------+------------------+ + + +.. _PtFlagStuff: + +PtFlagStuff + +.. code-block:: cpp + + typedef struct + { + int flags; + } + PtFlagStuff; + +flags + is a bitwise or of the following constants: + + * PkDspyFlagsWantsScanLineOrder + Send the data in scanline order rather than as buckets. Scanline order starts from the top-left of the image, working downward line by line. Note that the display shouldn't assume that a whole scanline will arrive at once. + * PkDspyFlagsWantsEmptyBuckets + Send pixel data even for buckets which contain no primitives. + * PkDspyFlagsWantsNullEmptyBuckets + Generate calls to ''DspyImageData'' for empty buckets, but set the associated *data* pointer to null. + + +DspyImageQuery +^^^^^^^^^^^^^^ +.. c:function:: PtDspyError DspyImageQuery(PtDspyImageHandle image, PtDspyQueryType type, size_t size, void* data) + + This function is used by the renderer to obtain further information about the image or the display driver itself. |Aqsis| passes in the image handle that was initialised in the open function (or *NULL* if the query does not relate to a particular image), a query type that determines what kind of information is requested and a data block that has to be filled in by the driver with appropriate values. + + :param image: this is either the image handle that was returned in DspyImageOpen_ or a *NULL* pointer. + :type image: PtDspyImageHandle + :param type: determines the type of information that is requested. The possible types are defined in the enum PtDspyQueryType_. + :type type: PtDspyQueryType + :param size: the size in bytes of the memory that *data* points to. Make sure not to write beyond this size! + :type size: size_t + :param data: an allocated memory buffer of *size* bytes that has to be filled in by the display driver. Depending on the query type this points to an appropriate info struct (see below). + :type data: void* + :returns: An error code or PkDspyErrorNone + + +The following requests may be made by the renderer: + +.. _PkSizeQuery: + +PkSizeQuery + The renderer wants to know the pixel size of an image and the pixel aspect ratio (when *image* is *NULL*, default values have to be returned). The values have to be filled into a PtDspySizeInfo_ structure and copied to *data*. + +.. _PkOverwriteQuery: + +PkOverwriteQuery + This is used to query the driver whether it will overwrite an image file or not. For this query, *data* should receive a PtDspyOverwriteInfo_ struct with the return value. + + +Types +""""" + +.. _PtDspyQueryType: + +PtDspyQueryType + +.. code-block:: cpp + + typedef enum + { + PkSizeQuery, + PkOverwriteQuery + } + PtDspyQueryType; + +These are the query types that may be encountered by the driver in DspyImageQuery_. + +.. note:: PkSupportsCheckpointing and PkRenderingStartQuery are currently not supported by |Aqsis|. + +.. _PtDspySizeInfo: + +PtDspySizeInfo + +.. code-block:: cpp + + typedef struct + { + PtDspyUnsigned32 width; + PtDspyUnsigned32 height; + PtDspyFloat32 aspectRatio; + } + PtDspySizeInfo; + +This struct has to be returned in a query of type PkSizeQuery_. + +width + The image width in pixel + +height + The image height in pixel + +aspectRatio + The pixel aspect ratio + + +.. _PtDspyOverwriteInfo: + +PtDspyOverwriteInfo + +.. code-block:: cpp + + typedef struct + { + PtDspyUnsigned8 overwrite; + PtDspyUnsigned8 interactive; + } + PtDspyOverwriteInfo; + +This struct has to be returned in a query of type ''PkOverwriteQuery''. + +overwrite + A boolean indicating whether the driver will overwrite an image or not + +interactive + Unused (set this to 0). + + + +DspyImageData +^^^^^^^^^^^^^ +.. c:function:: PtDspyError DspyImageData(PtDspyImageHandle image, int xmin, int xmaxplus1, int ymin, int ymaxplus1, int entrysize, const unsigned char* data) + + DspyImageData passes image pixel data from the renderer to the display device. + + :param image: handle to display internal data structures. + :type image: PtDspyImageHandle + :param xmin: minimum x-coordinate for the data. This may be thought of as the left of the bucket. + :type xmin: int + :param ymin: minimum y-coordinate for the data. This may be thought of as the top of the bucket. + :type ymin: int + :param xmaxplus1: maximum x-coordinate for the data, plus one. This means that the chunk width is *xmaxplus1*\ -\ *xmin*. + :type xmaxplus1: int + :param ymaxplus1: maximum y-coordinate for the data, plus one. This means that the chunk height is *ymaxplus1*\ -\ *ymin*. + :type ymaxplus1: int + :param entrysize: the stride between pixel entries in the data array. The pointer *(data+entrysize)* points to the start of the data for the second pixel. + :type entrysize: int + :param data: a pointer to the raw data. The pixel data is stored with scanlines contiguous in memory, such that *data* points to the top-left of the chunk. + :type data: const unsigned char* + :returns: An error code or PkDspyErrorNone + + +DspyImageClose +^^^^^^^^^^^^^^ +.. c:function:: PtDspyError DspyImageClose(PtDspyImageHandle image); + + DspyImageClose closes the display and frees any associated resources such as memory or file handles. + + :param image: handle to display internal data structures. + :type image: PtDspyImageHandle + :returns: An error code or PkDspyErrorNone + + +DspyImageDelayClose +^^^^^^^^^^^^^^^^^^^ +.. c:function:: PtDspyError DspyImageDelayClose(PtDspyImageHandle image); + + This function is similar to DspyImageClose_ but it is executed in a separate process. This is useful for interactive display drivers that want to remain active even though the renderer has finished rendering the image. + + +Additional API Types +-------------------- + +The following additional types are defined by the display API. + +.. _PtDspyError: + +PtDspyError + +.. code-block:: cpp + + typedef enum + { + PkDspyErrorNone, + PkDspyErrorNoMemory, + PkDspyErrorUnsupported, + PkDspyErrorBadParams, + PkDspyErrorNoResource, + PkDspyErrorUndefined + } + PtDspyError; + +All functions from the display driver interface are required to return a value of type ''PtDspyError'' that indicates whether the function ran successfully or not. The meaning of the values is as follows: + + * PkDspyErrorNone + The function ran without errors + * PkDspyErrorNoMemory + The function failed to allocate memory + * PkDspyUnsupported + An unsupported operation was requested + * PkDspyBadParams + The driver received invalid parameters + * PkDspyErrorNoResource + A required resource was not available (such as a file, etc.) + * PkDspyErrorUndefined + No other error code was applicable + + +.. _PtDspyImageHandle: + +PtDspyImageHandle + +.. code-block:: cpp + + typedef void* PtDspyImageHandle; + +The type of an image handle is known only to the display driver which uses it to store state information between display interface function calls. The renderer treats this as an opaque pointer. diff --git a/doc/manual/user/reference_guide/dso.rst b/doc/manual/user/reference_guide/dso.rst new file mode 100644 index 0000000..c0446ce --- /dev/null +++ b/doc/manual/user/reference_guide/dso.rst @@ -0,0 +1,4 @@ +************************* +Dynamic Shader Extensions +************************* + diff --git a/doc/manual/user/reference_guide/index.rst b/doc/manual/user/reference_guide/index.rst new file mode 100644 index 0000000..ffe0a5a --- /dev/null +++ b/doc/manual/user/reference_guide/index.rst @@ -0,0 +1,13 @@ +############### +Reference Guide +############### + +.. toctree:: + + cli + riapi + capi + procedural + ddi + dso + diff --git a/doc/manual/user/reference_guide/options.rst b/doc/manual/user/reference_guide/options.rst new file mode 100644 index 0000000..aed1dd7 --- /dev/null +++ b/doc/manual/user/reference_guide/options.rst @@ -0,0 +1,195 @@ +======= +Options +======= + +Searchpath Options +------------------ + +Aqsis locates the various external assets required during rendering via a +standard Option called "searchpath". The "searchpath" Option has a number of +string values that tell Aqsis where to look for various asset types. The string +value for each of these specifies a list of search paths separated by a colon. + +The special search path character "&" represents the previous value of the +option. This is only available in "searchpath" options. Using this character +you can append or prepend paths to the default path list, i.e:: + + Option "searchpath" "shader" ["/my/shaders:&"] + +Each option value is described below, they are all of type "string", and follow +the same format as the example above. + +archive + Aqsis will search in these folders for external RIB archives. This option is + used by the ``RiReadArchive`` directive. + +display + Aqsis will search for display devices in these folders. This option is used + by the ``RiDisplay`` directive, when it is looking for a display shared + object. + +shader + Aqsis will search for shaders, and shader related assets in these folders. + This option is used by the various shader related directives, such as + ``RiSurface``. In addition, both the shader compiler aqsl and the renderer + itself, will use these folders when searching for DSO shadeops used in + shaders. + +procedural + Aqsis will search these folders for procedural shared objects. This option + is used by the ``RiProcDynamicLoad`` directive to locate DSO's for the + procedural RIB plugin. + +texture + Aqsis will search in these folders for all texture files. This option is + used by the various texture related shading language commands, when searching + for a specified texture file. + +resource + Aqsis will search these folders for any assets not found using the specific + values above. This is a fallback option that specifies a global searchpath + for any and all file types. + + +Hider Options +------------- + +The **hider** specifies the algorithm used to resolve surface visibility (that +is, to decide which surfaces appear "on top" in the final render). Aqsis +supports only one hider type, "hidden", which uses stochastic point sampling +for the visibility computation. + +The "hidden" hider supports several options: + +jitter + This is used to turn random jittering of sample positions on or off. Jitter + is turned on by default in order to turn aliasing artifacts into less + objectionable noise, but should be turned off when rendering shadow maps for + best results. Jitter is necessary for rendering depth of field and motion + blur; turning it off in these cases will result in obvious artifacts. + + Type: ``"integer"`` + + Example: ``Hider "hidden" "jitter" [0]`` + +depthfilter + The depth filter defines the way in which depth samples will be modified + before being passed to the display. Possible values are: "min" (the + default), "midpoint", "max" and "average". The "min" depth filter computes + the depth of the surface closest to the camera, "max" the surface furtherest, + and "average" the average depth of all surfaces between the camera and the + far clipping plane. The "midpoint" depth filter computes the average depth + of the two surfaces closest to the camera, and gives better results than + "min" when used for shadow map generation. + + Type: ``"string"`` + + Example: ``Hider "hidden" "depthfilter" ["min"]`` + +Limits Options +-------------- + +These values control the various settings used during rendering that have an +effect on performance and memory use. They are grouped under the "limits" +option. + +bucketsize + Set the dimensions (in pixels) of a rendering bucket. + + Type: ``"integer[2]"`` + + Example: ``Option "limits" "bucketsize" [16 16]`` + +eyesplits + Set the maximum number of eye splits before the renderer is giving up and + discarding the geometry in which case a "Max eyesplits exceeded" warning is + issued. Note: Always try to push the near clipping plane as much away from + the camera as possible. + + Type: ``"integer"`` + + Example: ``Option "limits" "eyesplits" [10]`` + +gridsize + Set the desired number of micropolygons per grid. + + Type: ``"integer"`` + + Example: ``Option "limits" "gridsize" [256]`` + +texturememory + Set the buffer size (in kB) for texture tiles. Aqsis tries not to exceed the + specified value if possible (by discarding unused tiles whenever new tiles + are required that would overflow the buffer). When a single tile is larger + than the specified buffer Aqsis issues an "Exceeding allocated texture + memory" warning. Note: Not working in aqsis 1.6 and 1.8! + + Type: ``"integer"`` + + Example: ``Option "limits" "texturememory" [8192]`` + +zthreshold + Define the opacity at which a surface is deemed to be opaque for the purposes + of shadow map generation. Any surface with all components of opacity greater + than the components specified by zthreshold will be included in shadow map + generation. The default zthreshold is ``[1 1 1]`` which means that any + partially transparent object will be omitted from shadow maps by default. + + Type: ``"color"`` + + Example: ``Option "limits" "zthreshold" [1 1 1]`` + +Shadow Options +-------------- + +Aqsis supports shadows using depth maps, these values control various settings +that affect the sampling and generation of depth maps, and their use during +rendering. They are grouped under the "shadow" option. + +bias + Specifies a small amount to be added (in "camera" space) to the depth values + stored in the shadow map. This value can be tweaked to overcome self + shadowing artefacts. Self shadowing happens when a surface being lit is + exactly the same as the surface sampled to produce the shadowmap, Aqsis + cannot easily determine if the surface should be in shadow or not, and + inaccuracies in the floating point code cause the check to toggle between + shadow and not, resulting in a noisy pattern on the surface. By shifting the + depth stored in the shadowmap a little, such self shadowing can be avoided. + + Type: ``"float"`` + + Example: ``Option "shadow" "bias" [0.0]`` + +bias0 and bias1 + Specifies a range of bias values, a value is chosen randomly within this + range for the the shadow bias value, explained above. + + Type: ``"float"`` + + Example: ``Option "shadow" "bias0" [0.01] "bias1" [0.05]`` + + +Render Options +-------------- + +Certain features in the rendering pipeline can be controlled and/or enabled +depending on the content being rendered. These values allow the user to control +the renderer at a general level. They are grouped under the "render" option. + +bucketorder + Determines the order in which buckets are processed. Possible values are: + "horizontal", "vertical", "zigzag", "circle" and "random". + + Type: ``"string"`` + + Example: ``Option "render" "bucketorder" ["horizontal"]`` + +multipass + Enables the use of multipass rendering. Used in conjunction with the + "autoshadows" [[doc:options#attributes|Attributes]], this option enables the + generation of automatic shadow maps. + + Type: ``"integer"`` + + Example: ``Option "render" "multipass" [0]`` + diff --git a/doc/manual/user/reference_guide/procedural.rst b/doc/manual/user/reference_guide/procedural.rst new file mode 100644 index 0000000..e2bce35 --- /dev/null +++ b/doc/manual/user/reference_guide/procedural.rst @@ -0,0 +1,4 @@ +****************** +Procedural Plugins +****************** + diff --git a/doc/manual/user/reference_guide/riapi.rst b/doc/manual/user/reference_guide/riapi.rst new file mode 100644 index 0000000..b95e75a --- /dev/null +++ b/doc/manual/user/reference_guide/riapi.rst @@ -0,0 +1,48 @@ +****** +RI API +****** + +.. highlight:: RIB + +The operation of a RenderMan renderer is mostly controlled by the Options and +Attributes mechanisms, both of which associate named values with the various +stages of the rendering pipeline. + +**Options** are associated with the scene as a whole. Once the +``RiWorldBegin`` directive has been reached, the options are fixed, it is then +illegal to call any Ri directives that can modify the options state. +**Attributes** are associated with the attribute stack, and as such are +assigned to light sources and geometric primitives. The value of these +attributes are pushed and popped along with other attribute state by the +``RiAttributeBegin/End`` directives. + +Options and attributes are stored as a named set of name/value pairs. That is, +each option or attribute has a unique name, and can contain any number of +values, each with a unique name and type. The general format of an option or +attribute directive is:: + + Option "<option name>" "<value1 typespec>" [<value1 value(s)>] "<value2 typespec>" [<value2 value(s)>] + +where ``typespec`` is either the name of an already declared value, or an +inline declaration. For example:: + + Declare "string mystringvalue" + Option "myopt" "mystringvalue" ["some string"] "float myfloatvalue" [1.0] + +Note from the second example above that it is perfectly reasonable to specify +multiple name/value pairs in a single Option directive, each will add a new +value to the same containing option or attribute. + +There are a number of predefined options and attributes that Aqsis recognizes +for use internally to configure the operation of the renderer; these are listed +below. In addition, Aqsis fully supports the specification of arbitrary +user-defined name/value pairs for both options and attributes. These may be +queried from the shading language using the standard ``option()`` and +``attribute()`` functions. + + +.. toctree:: + + options + attributes + extensions diff --git a/doc/manual/user/user_guide/aov.rst b/doc/manual/user/user_guide/aov.rst new file mode 100644 index 0000000..0a5645c --- /dev/null +++ b/doc/manual/user/user_guide/aov.rst @@ -0,0 +1,6 @@ +************************** +Arbitrary Output Variables +************************** + +.. toctree:: + diff --git a/doc/manual/user/user_guide/capi.rst b/doc/manual/user/user_guide/capi.rst new file mode 100644 index 0000000..73ce155 --- /dev/null +++ b/doc/manual/user/user_guide/capi.rst @@ -0,0 +1,6 @@ +*************** +Using the C API +*************** + +.. toctree:: + diff --git a/doc/manual/user/user_guide/dof.rst b/doc/manual/user/user_guide/dof.rst new file mode 100644 index 0000000..d7cff53 --- /dev/null +++ b/doc/manual/user/user_guide/dof.rst @@ -0,0 +1,6 @@ +********************** +Depth of Field Effects +********************** + +.. toctree:: + diff --git a/doc/manual/user/user_guide/dra.rst b/doc/manual/user/user_guide/dra.rst new file mode 100644 index 0000000..9e8e010 --- /dev/null +++ b/doc/manual/user/user_guide/dra.rst @@ -0,0 +1,4 @@ +=================== +Dynamic ReadArchive +=================== + diff --git a/doc/manual/user/user_guide/getting_started/index.rst b/doc/manual/user/user_guide/getting_started/index.rst index ff21b83..0f7bfab 100644 --- a/doc/manual/user/user_guide/getting_started/index.rst +++ b/doc/manual/user/user_guide/getting_started/index.rst @@ -1,6 +1,6 @@ -*************** -Getting Started -*************** +****************************** +Installation & Getting Started +****************************** .. index:: support diff --git a/doc/manual/user/user_guide/index.rst b/doc/manual/user/user_guide/index.rst index d618437..705d0cf 100644 --- a/doc/manual/user/user_guide/index.rst +++ b/doc/manual/user/user_guide/index.rst @@ -1,11 +1,22 @@ -############### -The Aqsis Tools -############### +########## +User Guide +########## .. toctree:: - getting_started/index - tools/index + getting_started/index.rst + rib + shaders/index + shadows + reflection + motionblur + dof + procedurals + aov + optimisation + capi + +.. tools/index ri_standard/index pbgi/point_based_gi further_reading/index diff --git a/doc/manual/user/user_guide/lod.rst b/doc/manual/user/user_guide/lod.rst new file mode 100644 index 0000000..cbe8882 --- /dev/null +++ b/doc/manual/user/user_guide/lod.rst @@ -0,0 +1,4 @@ +=============== +Level Of Detail +=============== + diff --git a/doc/manual/user/user_guide/motionblur.rst b/doc/manual/user/user_guide/motionblur.rst new file mode 100644 index 0000000..3e503d1 --- /dev/null +++ b/doc/manual/user/user_guide/motionblur.rst @@ -0,0 +1,6 @@ +***************** +Using Motion Blur +***************** + +.. toctree:: + diff --git a/doc/manual/user/user_guide/optimisation.rst b/doc/manual/user/user_guide/optimisation.rst new file mode 100644 index 0000000..5b50c5d --- /dev/null +++ b/doc/manual/user/user_guide/optimisation.rst @@ -0,0 +1,8 @@ +*********************** +Optimisation Techniques +*********************** + +.. toctree:: + + lod + dra diff --git a/doc/manual/user/user_guide/procedurals.rst b/doc/manual/user/user_guide/procedurals.rst new file mode 100644 index 0000000..be08ee4 --- /dev/null +++ b/doc/manual/user/user_guide/procedurals.rst @@ -0,0 +1,6 @@ +****************** +Procedural Content +****************** + +.. toctree:: + diff --git a/doc/manual/user/user_guide/reflection.rst b/doc/manual/user/user_guide/reflection.rst new file mode 100644 index 0000000..034f661 --- /dev/null +++ b/doc/manual/user/user_guide/reflection.rst @@ -0,0 +1,6 @@ +****************** +Reflection Mapping +****************** + +.. toctree:: + diff --git a/doc/manual/user/user_guide/rib.rst b/doc/manual/user/user_guide/rib.rst new file mode 100644 index 0000000..b7a62a7 --- /dev/null +++ b/doc/manual/user/user_guide/rib.rst @@ -0,0 +1,6 @@ +*************************** +Scene Description Using RIB +*************************** + +.. toctree:: + diff --git a/doc/manual/user/user_guide/shaders/displacement.rst b/doc/manual/user/user_guide/shaders/displacement.rst new file mode 100644 index 0000000..22e6f00 --- /dev/null +++ b/doc/manual/user/user_guide/shaders/displacement.rst @@ -0,0 +1,4 @@ +============ +Displacement +============ + diff --git a/doc/manual/user/user_guide/shaders/index.rst b/doc/manual/user/user_guide/shaders/index.rst new file mode 100644 index 0000000..b53508a --- /dev/null +++ b/doc/manual/user/user_guide/shaders/index.rst @@ -0,0 +1,11 @@ +******* +Shaders +******* + +.. toctree:: + + surface + light + displacement + volume + layered diff --git a/doc/manual/user/user_guide/shaders/layered.rst b/doc/manual/user/user_guide/shaders/layered.rst new file mode 100644 index 0000000..93f3abd --- /dev/null +++ b/doc/manual/user/user_guide/shaders/layered.rst @@ -0,0 +1,4 @@ +=============== +Layered Shaders +=============== + diff --git a/doc/manual/user/user_guide/shaders/light.rst b/doc/manual/user/user_guide/shaders/light.rst new file mode 100644 index 0000000..0020d95 --- /dev/null +++ b/doc/manual/user/user_guide/shaders/light.rst @@ -0,0 +1,4 @@ +===== +Light +===== + diff --git a/doc/manual/user/user_guide/shaders/surface.rst b/doc/manual/user/user_guide/shaders/surface.rst new file mode 100644 index 0000000..c4b7698 --- /dev/null +++ b/doc/manual/user/user_guide/shaders/surface.rst @@ -0,0 +1,4 @@ +======= +Surface +======= + diff --git a/doc/manual/user/user_guide/shaders/volume.rst b/doc/manual/user/user_guide/shaders/volume.rst new file mode 100644 index 0000000..4f993fa --- /dev/null +++ b/doc/manual/user/user_guide/shaders/volume.rst @@ -0,0 +1,4 @@ +====== +Volume +====== + diff --git a/doc/manual/user/user_guide/shadows.rst b/doc/manual/user/user_guide/shadows.rst new file mode 100644 index 0000000..b97dc7f --- /dev/null +++ b/doc/manual/user/user_guide/shadows.rst @@ -0,0 +1,6 @@ +************* +Using Shadows +************* + +.. toctree:: + diff --git a/doc/manual/user/welcome.rst b/doc/manual/user/welcome.rst index a91f092..1f0ca7c 100644 --- a/doc/manual/user/welcome.rst +++ b/doc/manual/user/welcome.rst @@ -13,6 +13,5 @@ Welcome to Aqsis .. toctree:: features - whats_new legal ----------------------------------------------------------------------- Summary of changes: doc/manual/user/_templates/layout.html | 2 +- doc/manual/user/index.rst | 7 +- doc/manual/user/legal.rst | 6 +- doc/manual/user/reference_guide/attributes.rst | 207 ++++++++++++++++++++ doc/manual/user/reference_guide/capi.rst | 4 + doc/manual/user/reference_guide/cli.rst | 4 + .../index.rst => reference_guide/ddi.rst} | 6 +- doc/manual/user/reference_guide/dso.rst | 4 + doc/manual/user/reference_guide/index.rst | 13 ++ doc/manual/user/reference_guide/options.rst | 195 ++++++++++++++++++ doc/manual/user/reference_guide/procedural.rst | 4 + doc/manual/user/reference_guide/riapi.rst | 48 +++++ doc/manual/user/user_guide/aov.rst | 6 + .../{further_reading/index.rst => capi.rst} | 3 +- doc/manual/user/user_guide/dof.rst | 6 + .../{ri_standard/interface.rst => dra.rst} | 3 +- .../user/user_guide/getting_started/index.rst | 6 +- doc/manual/user/user_guide/index.rst | 21 ++- .../examples/index.rst => user_guide/lod.rst} | 3 +- doc/manual/user/user_guide/motionblur.rst | 6 + doc/manual/user/user_guide/optimisation.rst | 8 + doc/manual/user/user_guide/procedurals.rst | 6 + doc/manual/user/user_guide/reflection.rst | 6 + doc/manual/user/user_guide/rib.rst | 6 + .../user/user_guide/shaders/displacement.rst | 4 + doc/manual/user/user_guide/shaders/index.rst | 11 + .../index.rst => user_guide/shaders/layered.rst} | 3 +- .../books.rst => shaders/light.rst} | 3 +- doc/manual/user/user_guide/shaders/surface.rst | 4 + doc/manual/user/user_guide/shaders/volume.rst | 4 + doc/manual/user/user_guide/shadows.rst | 6 + doc/manual/user/welcome.rst | 1 - 32 files changed, 591 insertions(+), 25 deletions(-) create mode 100644 doc/manual/user/reference_guide/attributes.rst create mode 100644 doc/manual/user/reference_guide/capi.rst create mode 100644 doc/manual/user/reference_guide/cli.rst copy doc/manual/user/{program_guide/displays_api/index.rst => reference_guide/ddi.rst} (99%) create mode 100644 doc/manual/user/reference_guide/dso.rst create mode 100644 doc/manual/user/reference_guide/index.rst create mode 100644 doc/manual/user/reference_guide/options.rst create mode 100644 doc/manual/user/reference_guide/procedural.rst create mode 100644 doc/manual/user/reference_guide/riapi.rst create mode 100644 doc/manual/user/user_guide/aov.rst copy doc/manual/user/user_guide/{further_reading/index.rst => capi.rst} (64%) create mode 100644 doc/manual/user/user_guide/dof.rst copy doc/manual/user/user_guide/{ri_standard/interface.rst => dra.rst} (65%) copy doc/manual/user/{tutorials/examples/index.rst => user_guide/lod.rst} (65%) create mode 100644 doc/manual/user/user_guide/motionblur.rst create mode 100644 doc/manual/user/user_guide/optimisation.rst create mode 100644 doc/manual/user/user_guide/procedurals.rst create mode 100644 doc/manual/user/user_guide/reflection.rst create mode 100644 doc/manual/user/user_guide/rib.rst create mode 100644 doc/manual/user/user_guide/shaders/displacement.rst create mode 100644 doc/manual/user/user_guide/shaders/index.rst copy doc/manual/user/{tutorials/examples/index.rst => user_guide/shaders/layered.rst} (65%) copy doc/manual/user/user_guide/{further_reading/books.rst => shaders/light.rst} (63%) create mode 100644 doc/manual/user/user_guide/shaders/surface.rst create mode 100644 doc/manual/user/user_guide/shaders/volume.rst create mode 100644 doc/manual/user/user_guide/shadows.rst hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2011-10-10 11:33:25
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via c5ffe1f1dc003cc2acf5c084381ec79268a84d39 (commit) via 792c123d3b33bfff8b4b219bdb8cab14e7667350 (commit) from 08d8f309aab3075a170394f069a483ebe85e6f3d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c5ffe1f1dc003cc2acf5c084381ec79268a84d39 Author: Chris Foster <chr...@gm...> Date: Mon Oct 10 16:52:16 2011 +1000 Point render optimization: iterative tree traversal This is a minor optimization for point based microbuffer rendering - it gives a few percent speedup over the equivalent recursive traversal. diff --git a/libs/pointrender/microbuffer.cpp b/libs/pointrender/microbuffer.cpp index e6c1a12..0fa4ba1 100644 --- a/libs/pointrender/microbuffer.cpp +++ b/libs/pointrender/microbuffer.cpp @@ -436,94 +436,101 @@ void microRasterize(IntegratorT& integrator, V3f P, V3f N, float coneAngle, } -/// Recursively render point hierarchy into microbuffer. -/// -/// TODO: Check whether making this into an iterative traversal makes it -/// faster. +/// Render point hierarchy into microbuffer. template<typename IntegratorT> static void renderNode(IntegratorT& integrator, V3f P, V3f N, float cosConeAngle, float sinConeAngle, float maxSolidAngle, int dataSize, const PointOctree::Node* node) { - { - // Examine node bound and cull if possible - // TODO: Reinvestigate using (node->aggP - P) with spherical harmonics - V3f c = node->center - P; - if(sphereOutsideCone(c, c.length2(), node->boundRadius, N, - cosConeAngle, sinConeAngle)) - return; - } - float r = node->aggR; - V3f p = node->aggP - P; - float plen2 = p.length2(); - // Examine solid angle of interior node bounding sphere to see whether we - // can render it directly or not. + // This is an iterative traversal of the point hierarchy, since it's + // slightly faster than a recursive traversal. // - // TODO: Would be nice to use dot(node->aggN, p.normalized()) in the solid - // angle estimation. However, we get bad artifacts if we do this naively. - // Perhaps with spherical harmoics it'll be better. - float solidAngle = M_PI*r*r / plen2; - if(solidAngle < maxSolidAngle) - { - integrator.setPointData(reinterpret_cast<const float*>(&node->aggCol)); - renderDisk(integrator, N, p, node->aggN, r, cosConeAngle, sinConeAngle); - } - else + // The max required size for the explicit stack should be < 200, since + // tree depth shouldn't be > 24, and we have a max of 8 children per node. + const PointOctree::Node* nodeStack[200]; + nodeStack[0] = node; + int stackSize = 1; + while(stackSize > 0) { - // If we get here, the solid angle of the current node was too large - // so we must consider the children of the node. - // - // The render order is sorted so that points are rendered front to - // back. This greatly improves the correctness of the hider. + node = nodeStack[--stackSize]; + { + // Examine node bound and cull if possible + // TODO: Reinvestigate using (node->aggP - P) with spherical harmonics + V3f c = node->center - P; + if(sphereOutsideCone(c, c.length2(), node->boundRadius, N, + cosConeAngle, sinConeAngle)) + continue; + } + float r = node->aggR; + V3f p = node->aggP - P; + float plen2 = p.length2(); + // Examine solid angle of interior node bounding sphere to see whether we + // can render it directly or not. // - // FIXME: The sorting procedure gets things wrong sometimes! The - // problem is that points may stick outside the bounds of their octree - // nodes. Probably we need to record all the points, sort, and - // finally render them to get this right. - if(node->npoints != 0) + // TODO: Would be nice to use dot(node->aggN, p.normalized()) in the solid + // angle estimation. However, we get bad artifacts if we do this naively. + // Perhaps with spherical harmoics it'll be better. + float solidAngle = M_PI*r*r / plen2; + if(solidAngle < maxSolidAngle) { - // Leaf node: simply render each child point. - std::pair<float, int> childOrder[8]; - assert(node->npoints <= 8); - for(int i = 0; i < node->npoints; ++i) - { - const float* data = &node->data[i*dataSize]; - V3f p = V3f(data[0], data[1], data[2]) - P; - childOrder[i].first = p.length2(); - childOrder[i].second = i; - } - std::sort(childOrder, childOrder + node->npoints); - for(int i = 0; i < node->npoints; ++i) - { - const float* data = &node->data[childOrder[i].second*dataSize]; - V3f p = V3f(data[0], data[1], data[2]) - P; - V3f n = V3f(data[3], data[4], data[5]); - float r = data[6]; - integrator.setPointData(data+7); - renderDisk(integrator, N, p, n, r, cosConeAngle, sinConeAngle); - } - return; + integrator.setPointData(reinterpret_cast<const float*>(&node->aggCol)); + renderDisk(integrator, N, p, node->aggN, r, cosConeAngle, sinConeAngle); } else { - // Interior node: render children. - std::pair<float, PointOctree::Node*> children[8]; - int nchildren = 0; - for(int i = 0; i < 8; ++i) + // If we get here, the solid angle of the current node was too large + // so we must consider the children of the node. + // + // The render order is sorted so that points are rendered front to + // back. This greatly improves the correctness of the hider. + // + // FIXME: The sorting procedure gets things wrong sometimes! The + // problem is that points may stick outside the bounds of their octree + // nodes. Probably we need to record all the points, sort, and + // finally render them to get this right. + if(node->npoints != 0) { - PointOctree::Node* child = node->children[i]; - if(!child) - continue; - children[nchildren].first = (child->center - P).length2(); - children[nchildren].second = child; - ++nchildren; + // Leaf node: simply render each child point. + std::pair<float, int> childOrder[8]; + assert(node->npoints <= 8); + for(int i = 0; i < node->npoints; ++i) + { + const float* data = &node->data[i*dataSize]; + V3f p = V3f(data[0], data[1], data[2]) - P; + childOrder[i].first = p.length2(); + childOrder[i].second = i; + } + std::sort(childOrder, childOrder + node->npoints); + for(int i = 0; i < node->npoints; ++i) + { + const float* data = &node->data[childOrder[i].second*dataSize]; + V3f p = V3f(data[0], data[1], data[2]) - P; + V3f n = V3f(data[3], data[4], data[5]); + float r = data[6]; + integrator.setPointData(data+7); + renderDisk(integrator, N, p, n, r, cosConeAngle, sinConeAngle); + } + continue; } - std::sort(children, children + nchildren); - // Interior node: render each non-null child. - for(int i = 0; i < nchildren; ++i) + else { - renderNode(integrator, P, N, cosConeAngle, sinConeAngle, - maxSolidAngle, dataSize, children[i].second); + // Interior node: render children. + std::pair<float, const PointOctree::Node*> children[8]; + int nchildren = 0; + for(int i = 0; i < 8; ++i) + { + PointOctree::Node* child = node->children[i]; + if(!child) + continue; + children[nchildren].first = (child->center - P).length2(); + children[nchildren].second = child; + ++nchildren; + } + std::sort(children, children + nchildren); + // Interior node: render each non-null child. Nodes we want to + // render first must go onto the stack last. + for(int i = nchildren-1; i >= 0; --i) + nodeStack[stackSize++] = children[i].second; } } } commit 792c123d3b33bfff8b4b219bdb8cab14e7667350 Author: Chris Foster <chr...@gm...> Date: Mon Oct 10 16:05:47 2011 +1000 Avoid double cull check in point rendering Removing the cull check inside renderDisk() gives a modest performance improvement of a few percent. This is because the disks disks have already gone through a very similar (though not necessarily identical!) cull check inside renderNode(). diff --git a/libs/pointrender/microbuffer.cpp b/libs/pointrender/microbuffer.cpp index 193a545..e6c1a12 100644 --- a/libs/pointrender/microbuffer.cpp +++ b/libs/pointrender/microbuffer.cpp @@ -79,8 +79,8 @@ inline bool sphereOutsideCone(V3f p, float plen2, float r, // cone. if(x < 0) return false; - // Special case - if sphere angle and cone angle add to pi, the sphere and - // cone must intersect. + // Special case - if sphere angle and cone angle add to >= 180 degrees, the + // sphere and cone must intersect. if(cosConeAngle < 0 && x < plen2*cosConeAngle*cosConeAngle) return false; // General case @@ -274,9 +274,6 @@ void renderDisk(IntegratorT& integrator, V3f N, V3f p, V3f n, float r, if(dot_pn > 0) return; float plen2 = p.length2(); - // Cull points which lie outside the cone of interest. - if(sphereOutsideCone(p, plen2, r, N, cosConeAngle, sinConeAngle)) - return; float plen = sqrtf(plen2); // If solid angle of bounding sphere is greater than exactRenderAngle, // resolve the visibility exactly rather than using a cheap approx. @@ -452,7 +449,6 @@ static void renderNode(IntegratorT& integrator, V3f P, V3f N, float cosConeAngle // Examine node bound and cull if possible // TODO: Reinvestigate using (node->aggP - P) with spherical harmonics V3f c = node->center - P; - // TODO: Is this check somewhat redundent with the one inside renderDisk? if(sphereOutsideCone(c, c.length2(), node->boundRadius, N, cosConeAngle, sinConeAngle)) return; ----------------------------------------------------------------------- Summary of changes: libs/pointrender/microbuffer.cpp | 161 +++++++++++++++++++------------------- 1 files changed, 82 insertions(+), 79 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2011-10-05 22:11:19
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via 08d8f309aab3075a170394f069a483ebe85e6f3d (commit) from a60fc421e69527be993c79029e2c25d454534a34 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 08d8f309aab3075a170394f069a483ebe85e6f3d Author: Chris Foster <chr...@gm...> Date: Thu Oct 6 08:07:43 2011 +1000 Update partio for some .ptc file fixes This resolves a problem where normals were occasionally saved incorrectly with length zero inside ptc files. diff --git a/thirdparty/partio/src b/thirdparty/partio/src index 250bf7a..6735343 160000 --- a/thirdparty/partio/src +++ b/thirdparty/partio/src @@ -1 +1 @@ -Subproject commit 250bf7a17dcc7f228c7bd46887310d0deb77e37d +Subproject commit 67353433e60047a6baa6fb6c03ad77669bf4d0fe ----------------------------------------------------------------------- Summary of changes: thirdparty/partio/src | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2011-10-04 06:18:29
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via a60fc421e69527be993c79029e2c25d454534a34 (commit) from be967a333fe3098572d308216918b45240376c79 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a60fc421e69527be993c79029e2c25d454534a34 Author: Chris Foster <chr...@gm...> Date: Fri Sep 30 13:17:30 2011 +1000 Fix ptview bug in disk visualization Rotating the prototype disk normal onto the actual normal doesn't work when the disk normal has length zero. In those cases, disks mysteriously failed to show up in the ptview window. This is fixed by simply drawing such disks as points instead. Also some minor cleanups which were made in the process of tracking down the problem above. diff --git a/libs/pointrender/microbuffer.cpp b/libs/pointrender/microbuffer.cpp index 81be654..193a545 100644 --- a/libs/pointrender/microbuffer.cpp +++ b/libs/pointrender/microbuffer.cpp @@ -256,6 +256,12 @@ static void renderDiskExact(IntegratorT& integrator, V3f p, V3f n, float r) } +/// Rasterize disk into the given integrator +/// +/// N is the normal of the culling cone, with cone angle specified by +/// cosConeAngle and sinConeAngle. The position of the disk with respect to +/// the centre of the microbuffer is p, n is the normal of the disk and r is +/// the disk radius. template<typename IntegratorT> void renderDisk(IntegratorT& integrator, V3f N, V3f p, V3f n, float r, float cosConeAngle, float sinConeAngle) diff --git a/tools/ptview/ptview.cpp b/tools/ptview/ptview.cpp index 9a85d42..c92ed60 100644 --- a/tools/ptview/ptview.cpp +++ b/tools/ptview/ptview.cpp @@ -557,8 +557,10 @@ void PointView::loadPointFiles(const QStringList& fileNames) m_camera.setCenter(exr2qt(m_cloudCenter)); #if 0 // Debug + PointArray a; + loadPointFile(a, fileNames[0].toStdString()); m_pointTree.reset(); // free up memory - m_pointTree = boost::shared_ptr<PointOctree>(new PointOctree(*m_points)); + m_pointTree = boost::shared_ptr<PointOctree>(new PointOctree(a)); #endif updateGL(); } @@ -963,6 +965,16 @@ void PointView::drawPoints(const PointArrayModel& points, VisMode visMode, for(size_t i = 0; i < points.size(); ++i, ++P, ++N, ++r) { glColor(col ? *col++ : C3f(1)); + if(N->length2() == 0) + { + // For zero-length normals, we don't know the disk + // orientation, so draw as a point instead. + glPointSize(1); + glBegin(GL_POINTS); + glVertex(*P); + glEnd(); + continue; + } glPushMatrix(); // Translate disk to point location and scale glTranslate(*P); @@ -970,11 +982,16 @@ void PointView::drawPoints(const PointArrayModel& points, VisMode visMode, // Transform the disk normal (0,0,1) into the correct normal // direction for the current point. The appropriate transform // is a rotation about a direction perpendicular to both - // normals: + // normals, V3f v = diskNormal % *N; - // via the angle given by the dot product: - float angle = rad2deg(acosf(diskNormal^*N)); - glRotatef(angle, v.x, v.y, v.z); + if(v.length2() > 1e-10) + { + // And via the angle given by the dot product. (If the + // length of v is very small we don't do the rotation for + // numerical stability.) + float angle = rad2deg(acosf(diskNormal.dot(*N))); + glRotatef(angle, v.x, v.y, v.z); + } // Instance the disk glCallList(disk); glPopMatrix(); ----------------------------------------------------------------------- Summary of changes: libs/pointrender/microbuffer.cpp | 6 ++++++ tools/ptview/ptview.cpp | 27 ++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2011-09-30 02:34:40
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via be967a333fe3098572d308216918b45240376c79 (commit) from 1d3cf18ceee78fbc4d476d4c61670b624c260d6a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit be967a333fe3098572d308216918b45240376c79 Author: Chris Foster <chr...@gm...> Date: Thu Sep 29 20:58:23 2011 +1000 Speed up microbuffer reinitialization Surprisingly enough, reinitializing the microbuffer for each shading point has a measurable cost of a few percent or so with 20x20 faces. This change makes the reinitialization into a simple memcpy. diff --git a/libs/pointrender/microbuffer.h b/libs/pointrender/microbuffer.h index ce07533..053c3bc 100644 --- a/libs/pointrender/microbuffer.h +++ b/libs/pointrender/microbuffer.h @@ -35,6 +35,7 @@ #include <cfloat> #include <cmath> +#include <cstring> #include <boost/scoped_array.hpp> @@ -103,13 +104,17 @@ class MicroBuf Face_begin = Face_xp }; - MicroBuf(int faceRes, int nchans = 1) + /// faceRes gives face resolution. Faces are square. nchans gives + /// the number of channels in each pixel, and defaultPix gives the + /// values of the channels which will be used when reset() is called. + MicroBuf(int faceRes, int nchans, const float* defaultPix) : m_res(faceRes), m_nchans(nchans), m_faceSize(nchans*faceRes*faceRes), m_pixels() { m_pixels.reset(new float[m_faceSize*Face_end]); + m_defaultPixels.reset(new float[m_faceSize*Face_end]); m_directions.reset(new V3f[Face_end*faceRes*faceRes]); m_pixelSizes.reset(new float[m_faceSize]); // Cache direction vectors @@ -132,20 +137,17 @@ class MicroBuf float v = (0.5f + iv)/faceRes*2.0f - 1.0f; m_pixelSizes[iv*m_res + iu] = 1.0f/V3f(u,v,1).length2(); } + float* pix = m_defaultPixels.get(); + for(int i = 0, iend = size(); i < iend; ++i, pix += m_nchans) + for(int c = 0; c < m_nchans; ++c) + pix[c] = defaultPix[c]; } /// Reset buffer to default (non-rendered) state. - /// - /// \param defaultPix - reset every pixel in the buffer to the channels - /// given in the defaultPix array - void reset(const float* defaultPix) + void reset() { - for(int i = 0, iend = size(); i < iend; ++i) - { - float* pix = &m_pixels[m_nchans*i]; - for(int c = 0; c < m_nchans; ++c) - pix[c] = defaultPix[c]; - } + memcpy(m_pixels.get(), m_defaultPixels.get(), + sizeof(float)*size()*m_nchans); } /// Get raw data store for face @@ -324,6 +326,7 @@ class MicroBuf int m_faceSize; /// Pixel face storage boost::scoped_array<float> m_pixels; + boost::scoped_array<float> m_defaultPixels; /// Storage for pixel ray directions boost::scoped_array<V3f> m_directions; /// Pixels on a unit cube are not all equal in angular size @@ -343,7 +346,7 @@ class OcclusionIntegrator /// Create integrator with given resolution of the environment map /// faces. OcclusionIntegrator(int faceRes) - : m_buf(faceRes, 1), + : m_buf(faceRes, 1, defaultPixel()), m_face(0) { clear(); @@ -370,8 +373,7 @@ class OcclusionIntegrator /// Reset buffer to default state void clear() { - float defaultPixel[1] = {0}; - m_buf.reset(defaultPixel); + m_buf.reset(); }; /// Set extra data (eg, radiosity) associated with the current point @@ -446,6 +448,12 @@ class OcclusionIntegrator } private: + static float* defaultPixel() + { + static float def[1] = {0}; + return def; + } + MicroBuf m_buf; float* m_face; }; @@ -459,7 +467,7 @@ class RadiosityIntegrator /// Create integrator with given resolution of the environment map /// faces. RadiosityIntegrator(int faceRes) - : m_buf(faceRes, 5), + : m_buf(faceRes, 5, defaultPixel()), m_face(0), m_currRadiosity(0) { @@ -487,9 +495,7 @@ class RadiosityIntegrator /// Reset buffer to default state void clear() { - // depth, foreground_coverage, foreground_rgb, background_rgb - float defaultPixel[] = {FLT_MAX, 0, 0, 0, 0, 0, 0, 0}; - m_buf.reset(defaultPixel); + m_buf.reset(); }; /// Set extra data (eg, radiosity) associated with the current point @@ -581,6 +587,13 @@ class RadiosityIntegrator } private: + static float* defaultPixel() + { + // depth, foreground_coverage, foreground_rgb, background_rgb + static float def[] = {FLT_MAX, 0, 0, 0, 0, 0, 0, 0}; + return def; + } + MicroBuf m_buf; float* m_face; C3f m_currRadiosity; ----------------------------------------------------------------------- Summary of changes: libs/pointrender/microbuffer.h | 49 +++++++++++++++++++++++++-------------- 1 files changed, 31 insertions(+), 18 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2011-09-29 09:40:31
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via 1d3cf18ceee78fbc4d476d4c61670b624c260d6a (commit) from ff9536d78f29869c1fb9ba6b40cf5021e7594509 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1d3cf18ceee78fbc4d476d4c61670b624c260d6a Author: Chris Foster <chr...@gm...> Date: Thu Sep 29 19:38:30 2011 +1000 Add forgotten project.cmake This was forgotten from a couple of commits ago (5a703f46) diff --git a/libs/pointrender/project.cmake b/libs/pointrender/project.cmake new file mode 100644 index 0000000..5ac4535 --- /dev/null +++ b/libs/pointrender/project.cmake @@ -0,0 +1,19 @@ +include_subproject(partio) + +set(pointrender_srcs + microbuffer.cpp + pointcontainer.cpp +) +make_absolute(pointrender_srcs ${pointrender_SOURCE_DIR}) +list(APPEND pointrender_srcs ${partio_srcs}) + +set(pointrender_hdrs + microbuffer.h + pointcontainer.h +) +make_absolute(pointrender_hdrs ${pointrender_SOURCE_DIR}) +source_group("Header Files" FILES ${pointrender_hdrs}) + +include_directories(${pointrender_SOURCE_DIR}) + +set(pointrender_libs ${partio_libs}) ----------------------------------------------------------------------- Summary of changes: libs/pointrender/project.cmake | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-) create mode 100644 libs/pointrender/project.cmake hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2011-09-29 07:52:42
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via ff9536d78f29869c1fb9ba6b40cf5021e7594509 (commit) from 68632f55b0fb58b550df0e5e4b9470c359dd5912 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ff9536d78f29869c1fb9ba6b40cf5021e7594509 Author: Chris Foster <chr...@gm...> Date: Thu Sep 29 17:49:04 2011 +1000 Optional "occlusion" output for indirectdiffuse It's sometimes helpful to be able to compute the occlusion at the same time as integrating the indirect lighting. For example, to add in a contribution of indirect lighting coming "from infinity". This patch adds an optional named float parameter (tagged with "occlusion") to indirectdiffuse() to enable this usage. diff --git a/libs/pointrender/microbuffer.h b/libs/pointrender/microbuffer.h index 1ff946e..ce07533 100644 --- a/libs/pointrender/microbuffer.h +++ b/libs/pointrender/microbuffer.h @@ -420,7 +420,7 @@ class OcclusionIntegrator float occlusion(V3f N, float coneAngle) const { // Integrate over face to get occlusion. - float illum = 0; + float occ = 0; float totWeight = 0; float cosConeAngle = std::cos(coneAngle); for(int f = MicroBuf::Face_begin; f < MicroBuf::Face_end; ++f) @@ -435,15 +435,14 @@ class OcclusionIntegrator { d *= m_buf.pixelSize(iu, iv); // Accumulate light coming from infinity. - illum += d*(1.0f - std::min(1.0f, face[0])); + occ += d*std::min(1.0f, face[0]); totWeight += d; } } } - if(totWeight == 0) - return 0; - illum /= totWeight; - return 1 - illum; + if(totWeight != 0) + occ /= totWeight; + return occ; } private: @@ -542,13 +541,17 @@ class RadiosityIntegrator /// radians, the usual cos(theta) weighting is adjusted to /// (cos(theta) - cos(coneAngle)) so that it falls continuously to /// zero when theta == coneAngle - C3f radiosity(V3f N, float coneAngle) const + /// + /// If occlusion is non-null, the amount of occlusion will also be + /// computed and stored. + C3f radiosity(V3f N, float coneAngle, float* occlusion = 0) const { // Integrate incoming light with cosine weighting to get outgoing // radiosity C3f rad(0); float totWeight = 0; float cosConeAngle = std::cos(coneAngle); + float occ = 0; for(int f = MicroBuf::Face_begin; f < MicroBuf::Face_end; ++f) { const float* face = m_buf.face(f); @@ -562,13 +565,19 @@ class RadiosityIntegrator d *= m_buf.pixelSize(iu, iv); C3f& radiosity = *(C3f*)(face + 2); rad += d*radiosity; + occ += d*face[1]; totWeight += d; } } } - if(totWeight == 0) - return C3f(0); - return 1.0f/totWeight * rad; + if(totWeight != 0) + { + occ /= totWeight; + rad = (1.0f/totWeight) * rad; + } + if(occlusion) + *occlusion = occ; + return rad; } private: diff --git a/libs/shadervm/shaderexecenv/shadeops_illum.cpp b/libs/shadervm/shaderexecenv/shadeops_illum.cpp index 33d9657..fc212fb 100644 --- a/libs/shadervm/shaderexecenv/shadeops_illum.cpp +++ b/libs/shadervm/shaderexecenv/shadeops_illum.cpp @@ -1128,6 +1128,7 @@ void CqShaderExecEnv::pointCloudIntegrate(IqShaderData* P, IqShaderData* N, float coneAngle = M_PI_2; float bias = 0; CqString coordSystem = "world"; + IqShaderData* occlusionResult = 0; for(int i = 0; i < cParams; i+=2) { apParams[i]->GetString(paramName, 0); @@ -1170,6 +1171,11 @@ void CqShaderExecEnv::pointCloudIntegrate(IqShaderData* P, IqShaderData* N, if(paramValue->Type() == type_string) paramValue->GetString(coordSystem); } + else if(paramName == "occlusion") + { + if(paramValue->Type() == type_float) + occlusionResult = paramValue; + } // Interesting arguments which could be implemented: // "hitsides" - sidedness culling: "front", "back", "both" // "falloff", "falloffmode" - falloff of occlusion with distance @@ -1269,7 +1275,8 @@ void CqShaderExecEnv::pointCloudIntegrate(IqShaderData* P, IqShaderData* N, integrator.clear(); microRasterize(integrator, Pval2, Nval2, coneAngle, maxSolidAngle, *pointTree); - storeIntegratedResult(integrator, Nval2, coneAngle, result, igrid); + storeIntegratedResult(integrator, Nval2, coneAngle, result, + occlusionResult, igrid); } } } @@ -1293,7 +1300,8 @@ void CqShaderExecEnv::pointCloudIntegrate(IqShaderData* P, IqShaderData* N, //---------------------------------------------------------------------- static void storeIntegratedResult(const OcclusionIntegrator& integrator, const V3f& N, float coneAngle, - IqShaderData* result, int igrid) + IqShaderData* result, + IqShaderData* /*occlusionResult*/, int igrid) { result->SetFloat(integrator.occlusion(N, coneAngle), igrid); } @@ -1310,10 +1318,14 @@ void CqShaderExecEnv::SO_occlusion_rt( IqShaderData* P, IqShaderData* N, IqShade // indirectdiffuse(P, N, samples, ...) static void storeIntegratedResult(const RadiosityIntegrator& integrator, const V3f& N, float coneAngle, - IqShaderData* result, int igrid) + IqShaderData* result, + IqShaderData* occlusionResult, int igrid) { - C3f col = integrator.radiosity(N, coneAngle); + float occ = 0; + C3f col = integrator.radiosity(N, coneAngle, &occ); result->SetColor(CqColor(col.x, col.y, col.z), igrid); + if(occlusionResult) + occlusionResult->SetFloat(occ, igrid); } void CqShaderExecEnv::SO_indirectdiffuse(IqShaderData* P, IqShaderData* N, ----------------------------------------------------------------------- Summary of changes: libs/pointrender/microbuffer.h | 29 +++++++++++++++-------- libs/shadervm/shaderexecenv/shadeops_illum.cpp | 20 +++++++++++++--- 2 files changed, 35 insertions(+), 14 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2011-09-29 03:32:34
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via 68632f55b0fb58b550df0e5e4b9470c359dd5912 (commit) from 5a703f46785686e747022b97d514539e987bc0f8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 68632f55b0fb58b550df0e5e4b9470c359dd5912 Author: Chris Foster <chr...@gm...> Date: Thu Sep 29 13:28:20 2011 +1000 Bugfix: Cached procedurals crash if used > 1 time When caching calls to RiProcedural via inline archives or ObjectBegin/End, we need to avoid deleting the procedural data until the cache object is destructed, because the cached procedural may be used more than once. Deleting the data too soon results in a segfault on the second usage. diff --git a/libs/riutil/ricxx_cache.h b/libs/riutil/ricxx_cache.h index 5582507..d1dcd04 100644 --- a/libs/riutil/ricxx_cache.h +++ b/libs/riutil/ricxx_cache.h @@ -343,6 +343,8 @@ class ${procName} : public CachedRequest } };''' +customImplementations = set(['Procedural']) + memberTypeMap = { 'RtString': 'CachedString', 'RtToken': 'CachedString', @@ -363,6 +365,8 @@ def getMemberType(arg): for proc in riXml.findall('Procedures/Procedure'): if proc.findall('Rib'): procName = proc.findtext('Name') + if procName in customImplementations: + continue argsXml = [a for a in proc.findall('Arguments/Argument') if not a.findall('RibValue')] formals = [formalArg(a) for a in argsXml] @@ -2003,27 +2007,6 @@ class Blobby : public CachedRequest } }; -class Procedural : public CachedRequest -{ - private: - RtPointer m_data; - CachedFloatTuple<6> m_bound; - RtProcSubdivFunc m_refineproc; - RtProcFreeFunc m_freeproc; - public: - Procedural(RtPointer data, RtConstBound bound, RtProcSubdivFunc refineproc, RtProcFreeFunc freeproc) - : m_data(data) - , m_bound(bound) - , m_refineproc(refineproc) - , m_freeproc(freeproc) - { } - - virtual void reCall(Ri::Renderer& context) const - { - context.Procedural(m_data, m_bound, m_refineproc, m_freeproc); - } -}; - class Geometry : public CachedRequest { private: @@ -2334,6 +2317,42 @@ class ArchiveEnd : public CachedRequest }; //[[[end]]] + +// Special case implementation of cached Procedurals. +// +// The reason this is special is the need to carefully manage the lifetime of +// the procedural data. In particular, we need to avoid deleting the data +// until the destructor is called so that reCall() will work multiple times. +class Procedural : public CachedRequest +{ + private: + RtPointer m_data; + CachedFloatTuple<6> m_bound; + RtProcSubdivFunc m_refineproc; + RtProcFreeFunc m_freeproc; + + static void doNothingFreeProc(void* ptr) {} + + public: + Procedural(RtPointer data, RtConstBound bound, RtProcSubdivFunc refineproc, RtProcFreeFunc freeproc) + : m_data(data) + , m_bound(bound) + , m_refineproc(refineproc) + , m_freeproc(freeproc) + { } + + ~Procedural() + { + m_freeproc(m_data); + } + + virtual void reCall(Ri::Renderer& context) const + { + context.Procedural(m_data, m_bound, m_refineproc, &doNothingFreeProc); + } +}; + + } // namespace RiCache } // namespace Aqsis ----------------------------------------------------------------------- Summary of changes: libs/riutil/ricxx_cache.h | 61 +++++++++++++++++++++++++++++--------------- 1 files changed, 40 insertions(+), 21 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2011-09-29 02:19:11
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via 5a703f46785686e747022b97d514539e987bc0f8 (commit) from fc85090a83929a8f89406a9c3807829d0cf6b9c4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5a703f46785686e747022b97d514539e987bc0f8 Author: Chris Foster <chr...@gm...> Date: Thu Sep 29 12:15:30 2011 +1000 Move ptview to tools directory + build cleanups This cleans up the pointrender stuff to export itself using a project.cmake file. Also move the ptview application out of the libs directory and into the proper location inside tools. diff --git a/CMakeLists.txt b/CMakeLists.txt index 95cb188..2ec529b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -265,6 +265,7 @@ include_directories( # Thirdparty libs declare_subproject(thirdparty/tinyxml) declare_subproject(thirdparty/partio) +declare_subproject(libs/pointrender) if(AQSIS_USE_PDIFF) add_subdirectory(thirdparty/pdiff) endif() @@ -281,7 +282,6 @@ add_subdirectory(libs/shadervm) add_subdirectory(libs/slxargs) add_subdirectory(libs/ri2rib) add_subdirectory(libs/core) -add_subdirectory(libs/pointrender) # Build executable tools add_subdirectory(tools/aqsl) @@ -292,6 +292,7 @@ add_subdirectory(tools/teqser) if(AQSIS_USE_QT) add_subdirectory(tools/eqsl) add_subdirectory(tools/piqsl) + add_subdirectory(tools/ptview) endif() # Build displays diff --git a/libs/pointrender/interactivecamera.h b/include/aqsis/util/interactivecamera.h similarity index 100% rename from libs/pointrender/interactivecamera.h rename to include/aqsis/util/interactivecamera.h diff --git a/libs/shadervm/CMakeLists.txt b/libs/shadervm/CMakeLists.txt index f53f30e..2d501cd 100644 --- a/libs/shadervm/CMakeLists.txt +++ b/libs/shadervm/CMakeLists.txt @@ -13,8 +13,6 @@ set(shadervm_srcs shadervm.cpp shadervm1.cpp shadervm2.cpp - ../pointrender/microbuffer.cpp - ../pointrender/pointcontainer.cpp ) set(shadervm_hdrs @@ -29,13 +27,13 @@ set(shadervm_hdrs source_group("Header Files" FILES ${shadervm_hdrs}) add_subproject(shaderexecenv) -include_subproject(partio) +include_subproject(pointrender) aqsis_add_library(aqsis_shadervm ${shadervm_srcs} ${shadervm_hdrs} - ${shaderexecenv_srcs} ${shaderexecenv_hdrs} ${partio_srcs} + ${shaderexecenv_srcs} ${shaderexecenv_hdrs} ${pointrender_srcs} COMPILE_DEFINITIONS AQSIS_SHADERVM_EXPORTS LINK_LIBRARIES aqsis_math aqsis_util aqsis_tex ${Boost_REGEX_LIBRARY} - ${partio_libs} + ${pointrender_libs} ) aqsis_install_targets(aqsis_shadervm) diff --git a/libs/pointrender/CMakeLists.txt b/tools/ptview/CMakeLists.txt similarity index 60% rename from libs/pointrender/CMakeLists.txt rename to tools/ptview/CMakeLists.txt index 85a1489..eae4631 100644 --- a/libs/pointrender/CMakeLists.txt +++ b/tools/ptview/CMakeLists.txt @@ -1,27 +1,27 @@ -project(pointrender) +project(ptview) find_package(OpenGL) -if(AQSIS_USE_OPENEXR AND QT_FOUND AND OPENGL_FOUND) +if(QT_FOUND AND OPENGL_FOUND) include_directories(${AQSIS_OPENEXR_INCLUDE_DIR} "${AQSIS_OPENEXR_INCLUDE_DIR}/OpenEXR" ${QT_INCLUDES} ${OPENGL_INCLUDE_DIR}) - qt4_wrap_cpp(moc_srcs ptview.h interactivecamera.h) - - include_subproject(partio) + include_subproject(pointrender) + qt4_wrap_cpp(moc_srcs + ptview.h + ${aqsis_all_SOURCE_DIR}/include/aqsis/util/interactivecamera.h + ) set(srcs + ${pointrender_srcs} ${moc_srcs} - ${partio_srcs} ptview.cpp - microbuffer.cpp - pointcontainer.cpp ) aqsis_add_executable(ptview ${srcs} GUIAPP LINK_LIBRARIES ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} - ${OPENGL_gl_LIBRARY} ${partio_libs} aqsis_tex) + ${OPENGL_gl_LIBRARY} ${pointrender_libs} aqsis_util) aqsis_install_targets(ptview) endif() diff --git a/libs/pointrender/ptview.cpp b/tools/ptview/ptview.cpp similarity index 100% rename from libs/pointrender/ptview.cpp rename to tools/ptview/ptview.cpp diff --git a/libs/pointrender/ptview.h b/tools/ptview/ptview.h similarity index 99% rename from libs/pointrender/ptview.h rename to tools/ptview/ptview.h index 261cffa..789f7a9 100644 --- a/libs/pointrender/ptview.h +++ b/tools/ptview/ptview.h @@ -44,8 +44,9 @@ #include <Partio.h> +#include <aqsis/util/interactivecamera.h> + #include "pointcontainer.h" -#include "interactivecamera.h" class QActionGroup; class QSignalMapper; ----------------------------------------------------------------------- Summary of changes: CMakeLists.txt | 3 ++- .../aqsis/util}/interactivecamera.h | 0 libs/shadervm/CMakeLists.txt | 8 +++----- {libs/pointrender => tools/ptview}/CMakeLists.txt | 18 +++++++++--------- {libs/pointrender => tools/ptview}/ptview.cpp | 0 {libs/pointrender => tools/ptview}/ptview.h | 3 ++- 6 files changed, 16 insertions(+), 16 deletions(-) rename {libs/pointrender => include/aqsis/util}/interactivecamera.h (100%) rename {libs/pointrender => tools/ptview}/CMakeLists.txt (60%) rename {libs/pointrender => tools/ptview}/ptview.cpp (100%) rename {libs/pointrender => tools/ptview}/ptview.h (99%) hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2011-09-28 13:15:46
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via fc85090a83929a8f89406a9c3807829d0cf6b9c4 (commit) via b6d4ecf39df00b6c71827fd7e9647408ad739107 (commit) from 1963d3a0ae5951133779bec503fec6f24ff218c1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fc85090a83929a8f89406a9c3807829d0cf6b9c4 Author: Chris Foster <chr...@gm...> Date: Wed Sep 28 23:15:04 2011 +1000 Add option to draw axes in ptview diff --git a/libs/pointrender/ptview.cpp b/libs/pointrender/ptview.cpp index 3483c40..9a85d42 100644 --- a/libs/pointrender/ptview.cpp +++ b/libs/pointrender/ptview.cpp @@ -527,6 +527,7 @@ PointView::PointView(QWidget *parent) m_probeMaxSolidAngle(0), m_backgroundColor(0, 0, 0), m_visMode(Vis_Points), + m_drawAxes(false), m_lighting(false), m_points(), m_pointTree(), @@ -590,6 +591,12 @@ void PointView::setVisMode(VisMode mode) } +void PointView::toggleDrawAxes() +{ + m_drawAxes = !m_drawAxes; +} + + void PointView::setColorChannel(QString channel) { for(size_t i = 0; i < m_points.size(); ++i) @@ -640,7 +647,8 @@ void PointView::paintGL() // Draw geometry - //drawAxes(); + if(m_drawAxes) + drawAxes(); for(size_t i = 0; i < m_points.size(); ++i) drawPoints(*m_points[i], m_visMode, m_lighting); // if(m_pointTree) @@ -1009,6 +1017,8 @@ PointViewerMainWindow::PointViewerMainWindow( viewAsDisks->setShortcut(tr("v")); viewAsDisks->setCheckable(true); connect(viewAsDisks, SIGNAL(triggered()), this, SLOT(toggleVisMode())); + QAction* drawAxes = viewMenu->addAction(tr("Draw &Axes")); + drawAxes->setCheckable(true); // Background sub-menu QMenu* backMenu = viewMenu->addMenu(tr("Set &Background")); QSignalMapper* mapper = new QSignalMapper(this); @@ -1047,6 +1057,8 @@ PointViewerMainWindow::PointViewerMainWindow( this, SLOT(setColorChannels(QStringList))); connect(m_colorMenuMapper, SIGNAL(mapped(QString)), m_pointView, SLOT(setColorChannel(QString))); + connect(drawAxes, SIGNAL(triggered()), + m_pointView, SLOT(toggleDrawAxes())); setCentralWidget(m_pointView); if(!initialPointFileNames.empty()) diff --git a/libs/pointrender/ptview.h b/libs/pointrender/ptview.h index 0eade06..261cffa 100644 --- a/libs/pointrender/ptview.h +++ b/libs/pointrender/ptview.h @@ -139,6 +139,7 @@ class PointView : public QGLWidget void setBackground(QColor col); void setVisMode(VisMode mode); void setColorChannel(QString channel); + void toggleDrawAxes(); signals: void colorChannelsChanged(QStringList channels); @@ -174,6 +175,7 @@ class PointView : public QGLWidget QColor m_backgroundColor; /// Type of visualization VisMode m_visMode; + bool m_drawAxes; /// Flag for whether to use OpenGL lighting or not bool m_lighting; /// Point cloud data commit b6d4ecf39df00b6c71827fd7e9647408ad739107 Author: Chris Foster <chr...@gm...> Date: Wed Sep 28 23:00:14 2011 +1000 Make color channel user selectable in ptview This change adds a new menu "View"->"Color Channel" under which all the channels in the point cloud which look color-like are listed. diff --git a/libs/pointrender/ptview.cpp b/libs/pointrender/ptview.cpp index d21be0c..3483c40 100644 --- a/libs/pointrender/ptview.cpp +++ b/libs/pointrender/ptview.cpp @@ -134,6 +134,7 @@ bool PointArrayModel::loadPointFile(const QString& fileName) tr("Couldn't open file \"%1\"").arg(fileName)); return false; } + m_fileName = fileName; // Look for the necessary attributes in the file Pio::ParticleAttribute positionAttr; Pio::ParticleAttribute normalAttr; @@ -163,11 +164,11 @@ bool PointArrayModel::loadPointFile(const QString& fileName) m_r.reset(new float[m_npoints]); // Look for likely color channels & allocate space if necessary m_colorChannelNames = findColorChannels(ptFile.get()); - m_col.reset(); + m_color.reset(); if(!m_colorChannelNames.empty()) { if(ptFile->attributeInfo(m_colorChannelNames[0].toAscii().constData(), colorAttr)) - m_col.reset(new C3f[m_npoints]); + m_color.reset(new C3f[m_npoints]); } // Iterate over all particles & pull in the data. Pio::ParticleAccessor posAcc(positionAttr); @@ -178,24 +179,43 @@ bool PointArrayModel::loadPointFile(const QString& fileName) pt.addAccessor(posAcc); pt.addAccessor(norAcc); pt.addAccessor(radiusAcc); - if(m_col) + if(m_color) pt.addAccessor(colorAcc); V3f* outP = m_P.get(); V3f* outN = m_N.get(); float* outr = m_r.get(); - C3f* outc = m_col.get(); + C3f* outc = m_color.get(); for(; pt != ptFile->end(); ++pt) { *outP++ = posAcc.data<V3f>(pt); *outN++ = norAcc.data<V3f>(pt); *outr++ = radiusAcc.data<float>(pt); - if(m_col) + if(m_color) *outc++ = colorAcc.data<C3f>(pt); } return true; } +void PointArrayModel::setColorChannel(const QString& name) +{ + namespace Pio = Partio; + boost::shared_ptr<Pio::ParticlesData> ptFile( + Pio::read(m_fileName.toAscii().constData()), releasePartioFile); + Pio::ParticleAttribute colorAttr; + if(!ptFile->attributeInfo(name.toAscii().constData(), colorAttr) + || colorAttr.count != 3 || colorAttr.type != Pio::FLOAT) + return; + m_color.reset(new C3f[m_npoints]); + Pio::ParticleAccessor colorAcc(colorAttr); + Pio::ParticlesData::const_iterator pt = ptFile->begin(); + pt.addAccessor(colorAcc); + C3f* outc = m_color.get(); + for(; pt != ptFile->end(); ++pt, ++outc) + *outc = colorAcc.data<C3f>(pt); +} + + V3f PointArrayModel::centroid() const { V3f sum(0); @@ -530,6 +550,7 @@ void PointView::loadPointFiles(const QStringList& fileNames) } if(m_points.empty()) return; + emit colorChannelsChanged(m_points[0]->colorChannels()); m_cloudCenter = m_points[0]->centroid(); m_cursorPos = m_cloudCenter; m_camera.setCenter(exr2qt(m_cloudCenter)); @@ -569,6 +590,14 @@ void PointView::setVisMode(VisMode mode) } +void PointView::setColorChannel(QString channel) +{ + for(size_t i = 0; i < m_points.size(); ++i) + m_points[i]->setColorChannel(channel); + updateGL(); +} + + QSize PointView::sizeHint() const { // Size hint, mainly for getting the initial window size right. @@ -956,6 +985,10 @@ void PointView::drawPoints(const PointArrayModel& points, VisMode visMode, PointViewerMainWindow::PointViewerMainWindow( const QStringList& initialPointFileNames) + : m_pointView(0), + m_colorMenu(0), + m_colorMenuGroup(0), + m_colorMenuMapper(0) { setWindowTitle("Aqsis point cloud viewer"); @@ -997,6 +1030,9 @@ PointViewerMainWindow::PointViewerMainWindow( QAction* backgroundCustom = backMenu->addAction(tr("&Custom")); connect(backgroundCustom, SIGNAL(triggered()), this, SLOT(chooseBackground())); + // Color channel menu + m_colorMenu = viewMenu->addMenu(tr("Color &Channel")); + m_colorMenuMapper = new QSignalMapper(this); // Help menu QMenu* helpMenu = menuBar()->addMenu(tr("&Help")); @@ -1007,6 +1043,11 @@ PointViewerMainWindow::PointViewerMainWindow( connect(aboutAct, SIGNAL(triggered()), this, SLOT(aboutDialog())); m_pointView = new PointView(this); + connect(m_pointView, SIGNAL(colorChannelsChanged(QStringList)), + this, SLOT(setColorChannels(QStringList))); + connect(m_colorMenuMapper, SIGNAL(mapped(QString)), + m_pointView, SLOT(setColorChannel(QString))); + setCentralWidget(m_pointView); if(!initialPointFileNames.empty()) m_pointView->loadPointFiles(initialPointFileNames); @@ -1077,6 +1118,27 @@ void PointViewerMainWindow::toggleVisMode() } +void PointViewerMainWindow::setColorChannels(QStringList channels) +{ + // Remove the old set of color channels from the menu + delete m_colorMenuGroup; + m_colorMenuGroup = new QActionGroup(this); + m_colorMenuGroup->setExclusive(true); + if(channels.empty()) + return; + // Rebuild the color channel menu with a menu item for each channel + for(int i = 0; i < channels.size(); ++i) + { + QAction* act = m_colorMenuGroup->addAction(channels[i]); + act->setCheckable(true); + m_colorMenu->addAction(act); + m_colorMenuMapper->setMapping(act, channels[i]); + connect(act, SIGNAL(triggered()), m_colorMenuMapper, SLOT(map())); + } + m_colorMenuGroup->actions()[0]->setChecked(true); +} + + } // namespace Aqsis diff --git a/libs/pointrender/ptview.h b/libs/pointrender/ptview.h index c296ae7..0eade06 100644 --- a/libs/pointrender/ptview.h +++ b/libs/pointrender/ptview.h @@ -47,6 +47,9 @@ #include "pointcontainer.h" #include "interactivecamera.h" +class QActionGroup; +class QSignalMapper; + namespace Aqsis { using Imath::V3f; @@ -78,13 +81,13 @@ class PointArrayModel : public QObject /// Return point radii const float* r() const { return m_r.get(); } /// Return point color, or NULL if no color channel is present - const C3f* color() const { return m_col.get(); } + const C3f* color() const { return m_color.get(); } /// Get a list of channel names which look like color channels QStringList colorChannels() { return m_colorChannelNames; } /// Set the channel name which the color() function returns data for - void setColorChannel(const QString& name) { } + void setColorChannel(const QString& name); /// Compute the centroid of the P data V3f centroid() const; @@ -99,7 +102,7 @@ class PointArrayModel : public QObject boost::shared_array<V3f> m_P; boost::shared_array<V3f> m_N; boost::shared_array<float> m_r; - boost::shared_array<C3f> m_col; + boost::shared_array<C3f> m_color; }; @@ -135,6 +138,10 @@ class PointView : public QGLWidget /// Set the backgroud color void setBackground(QColor col); void setVisMode(VisMode mode); + void setColorChannel(QString channel); + + signals: + void colorChannelsChanged(QStringList channels); protected: // Qt OpenGL callbacks @@ -198,9 +205,13 @@ class PointViewerMainWindow : public QMainWindow void setBackground(const QString& name); void chooseBackground(); void toggleVisMode(); + void setColorChannels(QStringList channels); private: PointView* m_pointView; + QMenu* m_colorMenu; + QActionGroup* m_colorMenuGroup; + QSignalMapper* m_colorMenuMapper; }; ----------------------------------------------------------------------- Summary of changes: libs/pointrender/ptview.cpp | 86 ++++++++++++++++++++++++++++++++++++++++--- libs/pointrender/ptview.h | 19 ++++++++- 2 files changed, 96 insertions(+), 9 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2011-09-28 12:38:16
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via 1963d3a0ae5951133779bec503fec6f24ff218c1 (commit) from 180de2abf827d28d2d3b9ea42cdb2dbb06414d31 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1963d3a0ae5951133779bec503fec6f24ff218c1 Author: Chris Foster <chr...@gm...> Date: Wed Sep 28 20:53:43 2011 +1000 Revamp ptview point cloud loading for end users There's several changes here which move ptview further from being a debugging tool to something which is more friendly to end users: * ptview now loads any point cloud file which can be generated with bake3d, not just those which have the particular attributes needed for occlusion/indiretdiffuse. * The first color-like channel (3-channel float) data is selected and displayed as the color of the points. * The microbuffer rendering visualization is now disabled. diff --git a/libs/pointrender/pointcontainer.h b/libs/pointrender/pointcontainer.h index 6b1de24..3a4ec27 100644 --- a/libs/pointrender/pointcontainer.h +++ b/libs/pointrender/pointcontainer.h @@ -187,78 +187,6 @@ class PointOctreeCache -//------------------------------------------------------------------------------ -// Musings on abstraction for point array class... not sure what the best -// abstraction is yet. - -#if 0 - -/// Reference to data for a single surface element -class Point -{ - public: - Point(const float* data) : m_data(data) {} - /// Get point position - V3f P() const { return V3f(m_data[0], m_data[1], m_data[2]); } - /// Get normal - V3f N() const { return V3f(m_data[3], m_data[4], m_data[5]); } - /// Get radius - float r() const { return m_data[6]; } - /// Get any additional attached data - const float* userData() const { return &m_data[7]; } - private: - const float* m_data; -}; - - -/// Array of surface elements ("points") -class PointArray -{ - public: - PointArray(int stride) - : m_stride(stride) - { } - - const Point operator[](size_t i) const - { - assert(i < data.size()); - return &data[i*m_stride]; - } - - int stride() const { return m_stride; } - - void addPoint(const float* data) - { - m_data.insert(m_data.end(), data, data + m_stride); - } - - // Get centroid of the point cloud. - V3f centroid() const - { - V3f sum(0); - for(std::vector<float>::const_iterator p = data.begin(); - p < data.end(); p += stride) - { - sum += V3f(p[0], p[1], p[2]); - } - return (1.0f/data.size()*stride) * sum; - } - - private: -// struct Channel -// { -// int index; -// int size; -// std::string name; -// }; - - int m_stride; -// std::vector<Channel> m_channelData; - std::vector<float> m_data; -}; -#endif - - } // namespace Aqsis #endif // AQSIS_POINTCONTAINER_H_INCLUDED diff --git a/libs/pointrender/ptview.cpp b/libs/pointrender/ptview.cpp index 959aab5..d21be0c 100644 --- a/libs/pointrender/ptview.cpp +++ b/libs/pointrender/ptview.cpp @@ -72,6 +72,11 @@ inline void glVertex(const Imath::V2f& v) glVertex2f(v.x, v.y); } +inline void glColor(const Imath::C3f& c) +{ + glColor3f(c.x, c.y, c.z); +} + inline void glLoadMatrix(const Imath::M44f& m) { glLoadMatrixf((GLfloat*)m[0]); @@ -103,6 +108,120 @@ inline Imath::M44f qt2exr(const QMatrix4x4& m) return mOut; } + +//---------------------------------------------------------------------- +// PointViewArray implementation + +static void releasePartioFile(Partio::ParticlesInfo* file) +{ + if(file) file->release(); +} + + +PointArrayModel::PointArrayModel() + : m_npoints(0) +{ } + + +bool PointArrayModel::loadPointFile(const QString& fileName) +{ + namespace Pio = Partio; + boost::shared_ptr<Pio::ParticlesData> ptFile( + Pio::read(fileName.toAscii().constData()), releasePartioFile); + if(!ptFile) + { + QMessageBox::critical(0, tr("Error"), + tr("Couldn't open file \"%1\"").arg(fileName)); + return false; + } + // Look for the necessary attributes in the file + Pio::ParticleAttribute positionAttr; + Pio::ParticleAttribute normalAttr; + Pio::ParticleAttribute radiusAttr; + Pio::ParticleAttribute colorAttr; + if(!ptFile->attributeInfo("position", positionAttr) || + !ptFile->attributeInfo("normal", normalAttr) || + !ptFile->attributeInfo("radius", radiusAttr)) + { + QMessageBox::critical(0, tr("Error"), + tr("Couldn't find required attribute in \"%1\"").arg(fileName)); + return false; + } + // Check types + if(positionAttr.type != Pio::VECTOR || + normalAttr.type != Pio::VECTOR || + radiusAttr.type != Pio::FLOAT || radiusAttr.count != 1) + { + QMessageBox::critical(0, tr("Error"), + tr("Point attribute type or size wrong in \"%1\"").arg(fileName)); + return false; + } + // Allocate required attributes + m_npoints = ptFile->numParticles(); + m_P.reset(new V3f[m_npoints]); + m_N.reset(new V3f[m_npoints]); + m_r.reset(new float[m_npoints]); + // Look for likely color channels & allocate space if necessary + m_colorChannelNames = findColorChannels(ptFile.get()); + m_col.reset(); + if(!m_colorChannelNames.empty()) + { + if(ptFile->attributeInfo(m_colorChannelNames[0].toAscii().constData(), colorAttr)) + m_col.reset(new C3f[m_npoints]); + } + // Iterate over all particles & pull in the data. + Pio::ParticleAccessor posAcc(positionAttr); + Pio::ParticleAccessor norAcc(normalAttr); + Pio::ParticleAccessor radiusAcc(radiusAttr); + Pio::ParticleAccessor colorAcc(colorAttr); + Pio::ParticlesData::const_iterator pt = ptFile->begin(); + pt.addAccessor(posAcc); + pt.addAccessor(norAcc); + pt.addAccessor(radiusAcc); + if(m_col) + pt.addAccessor(colorAcc); + V3f* outP = m_P.get(); + V3f* outN = m_N.get(); + float* outr = m_r.get(); + C3f* outc = m_col.get(); + for(; pt != ptFile->end(); ++pt) + { + *outP++ = posAcc.data<V3f>(pt); + *outN++ = norAcc.data<V3f>(pt); + *outr++ = radiusAcc.data<float>(pt); + if(m_col) + *outc++ = colorAcc.data<C3f>(pt); + } + return true; +} + + +V3f PointArrayModel::centroid() const +{ + V3f sum(0); + const V3f* P = m_P.get(); + for(size_t i = 0; i < m_npoints; ++i, ++P) + sum += *P; + return (1.0f/m_npoints) * sum; +} + + +QStringList PointArrayModel::findColorChannels(const Partio::ParticlesInfo* ptFile) +{ + QStringList colChans; + Partio::ParticleAttribute attr; + for(int i = 0; i < ptFile->numAttributes(); ++i) + { + ptFile->attributeInfo(i, attr); + if(attr.type == Partio::FLOAT && attr.count == 3) + colChans.push_back(QString::fromStdString(attr.name)); + } + // TODO: Sort by some criterion of "most color-like" channels? + return colChans; +} + + +//---------------------------------------------------------------------- /// Get max and min of depth buffer, ignoring any depth > FLT_MAX/2 /// /// \param z - depth array @@ -402,25 +521,23 @@ PointView::PointView(QWidget *parent) void PointView::loadPointFiles(const QStringList& fileNames) { - if(fileNames.empty()) - return; - // free up memory before loading new files. - m_points.reset(new PointArray()); + m_points.clear(); for(int i = 0; i < fileNames.size(); ++i) { - if(!Aqsis::loadPointFile(*m_points, fileNames[i].toStdString())) - { - QMessageBox::critical(this, tr("Error"), - tr("Couldn't open point file \"%1\"").arg(fileNames[i])); - m_points.reset(); - return; - } + boost::shared_ptr<PointArrayModel> points(new PointArrayModel()); + if(points->loadPointFile(fileNames[i]) && !points->empty()) + m_points.push_back(points); } - m_cloudCenter = m_points->centroid(); + if(m_points.empty()) + return; + m_cloudCenter = m_points[0]->centroid(); m_cursorPos = m_cloudCenter; m_camera.setCenter(exr2qt(m_cloudCenter)); +#if 0 + // Debug m_pointTree.reset(); // free up memory m_pointTree = boost::shared_ptr<PointOctree>(new PointOctree(*m_points)); +#endif updateGL(); } @@ -477,22 +594,6 @@ void PointView::resizeGL(int w, int h) void PointView::paintGL() { - RadiosityIntegrator integrator(m_probeRes); - C3f col(1.0f); - if(m_pointTree) - { - // Get a vector toward the probe position from the camera center - QMatrix4x4 viewMatrix = m_camera.viewMatrix(); - V3f d = (qt2exr(viewMatrix.inverted(). - map(viewMatrix.map(exr2qt(m_cursorPos))*1.1)) - - m_cursorPos).normalized(); - float coneAngle = M_PI; - microRasterize(integrator, m_cursorPos, d, - coneAngle, - m_probeMaxSolidAngle, *m_pointTree); - col = integrator.radiosity(d, coneAngle); - } - //-------------------------------------------------- // Draw main scene // Set camera projection @@ -511,42 +612,46 @@ void PointView::paintGL() // Draw geometry //drawAxes(); - if(m_points) - drawPoints(*m_points, m_visMode, m_lighting); + for(size_t i = 0; i < m_points.size(); ++i) + drawPoints(*m_points[i], m_visMode, m_lighting); // if(m_pointTree) // splitNode(m_cursorPos, m_probeMaxSolidAngle, m_pointTree->dataSize(), // m_pointTree->root()); - //-------------------------------------------------- - glPushAttrib(GL_VIEWPORT_BIT | GL_SCISSOR_BIT | GL_ENABLE_BIT); - glPushMatrix(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glMatrixMode(GL_MODELVIEW); - glEnable(GL_SCISSOR_TEST); - - //-------------------------------------------------- - // Draw image of rendered microbuffer - GLuint miniBufWidth = width()/3; - glScissor(width() - miniBufWidth, 0, miniBufWidth, miniBufWidth*3/4); - glViewport(width() - miniBufWidth, 0, miniBufWidth, miniBufWidth*3/4); - - drawMicroBuf(integrator.microBuf()); - -// glColor(col); -// glBegin(GL_QUADS); -// glTexCoord2f(0, 0); glVertex2f(0, 0); -// glTexCoord2f(1, 0); glVertex2f(1, 0); -// glTexCoord2f(1, 1); glVertex2f(1, 1); -// glTexCoord2f(0, 1); glVertex2f(0, 1); -// glEnd(); - - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopAttrib(); + if(m_pointTree) + { + RadiosityIntegrator integrator(m_probeRes); + // Get a vector toward the probe position from the camera center + QMatrix4x4 viewMatrix = m_camera.viewMatrix(); + V3f d = (qt2exr(viewMatrix.inverted(). + map(viewMatrix.map(exr2qt(m_cursorPos))*1.1)) - + m_cursorPos).normalized(); + float coneAngle = M_PI; + microRasterize(integrator, m_cursorPos, d, + coneAngle, + m_probeMaxSolidAngle, *m_pointTree); + // Draw image of rendered microbuffer + glPushAttrib(GL_VIEWPORT_BIT | GL_SCISSOR_BIT | GL_ENABLE_BIT); + glPushMatrix(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glMatrixMode(GL_MODELVIEW); + glEnable(GL_SCISSOR_TEST); + + GLuint microBufWidth = width()/3; + glScissor(width() - microBufWidth, 0, + microBufWidth, microBufWidth*3/4); + glViewport(width() - microBufWidth, 0, + microBufWidth, microBufWidth*3/4); + drawMicroBuf(integrator.microBuf()); + + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopAttrib(); + } // Draw overlay stuff, including cursor position. drawCursor(m_cursorPos); @@ -596,26 +701,26 @@ void PointView::keyPressEvent(QKeyEvent *event) } else if(event->key() == Qt::Key_S) { - if(!m_points) - return; - // Snap probe to position of closest point. - int ptStride = m_points->stride; - int npoints = m_points->data.size()/ptStride; - const float* ptData = &m_points->data[0]; + // Snap probe to position of closest point and center on it V3f newPos(0); float nearestDist = FLT_MAX; - for(int i = 0; i < npoints; ++i) + for(size_t j = 0; j < m_points.size(); ++j) { - const float* data = ptData + i*ptStride; - V3f p(data[0], data[1], data[2]); - float dist = (m_cursorPos - p).length2(); - if(dist < nearestDist) + if(m_points[j]->empty()) + continue; + const V3f* P = m_points[j]->P(); + for(size_t i = 0, iend = m_points[j]->size(); i < iend; ++i, ++P) { - nearestDist = dist; - newPos = p; + float dist = (m_cursorPos - *P).length2(); + if(dist < nearestDist) + { + nearestDist = dist; + newPos = *P; + } } } m_cursorPos = newPos; + m_camera.setCenter(exr2qt(newPos)); updateGL(); } else @@ -720,13 +825,11 @@ void PointView::drawCursor(const V3f& p) const /// Draw point cloud using OpenGL -void PointView::drawPoints(const PointArray& points, VisMode visMode, +void PointView::drawPoints(const PointArrayModel& points, VisMode visMode, bool useLighting) { - int ptStride = points.stride; - int npoints = points.data.size()/ptStride; - const float* ptData = &points.data[0]; - + if(points.empty()) + return; switch(visMode) { case Vis_Points: @@ -744,10 +847,17 @@ void PointView::drawPoints(const PointArray& points, VisMode visMode, glPointParameterf(GL_POINT_SIZE_MAX, 100); // Draw all points at once using vertex arrays. glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glVertexPointer(3, GL_FLOAT, ptStride*sizeof(float), ptData); - glColorPointer(3, GL_FLOAT, ptStride*sizeof(float), ptData+7); - glDrawArrays(GL_POINTS, 0, npoints); + glVertexPointer(3, GL_FLOAT, 3*sizeof(float), + reinterpret_cast<const float*>(points.P())); + const float* col = reinterpret_cast<const float*>(points.color()); + if(col) + { + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(3, GL_FLOAT, 3*sizeof(float), col); + } + glDrawArrays(GL_POINTS, 0, points.size()); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); } break; case Vis_Disks: @@ -809,24 +919,24 @@ void PointView::drawPoints(const PointArray& points, VisMode visMode, // perhaps just compile into a display list? if(useLighting) glEnable(GL_LIGHTING); - for(int i = 0; i < npoints; ++i) + const V3f* P = points.P(); + const V3f* N = points.N(); + const float* r = points.r(); + const C3f* col = points.color(); + for(size_t i = 0; i < points.size(); ++i, ++P, ++N, ++r) { - const float* data = ptData + i*ptStride; - V3f p(data[0], data[1], data[2]); - V3f n(data[3], data[4], data[5]); - float r = M_SQRT2*data[6]; - glColor3f(data[7], data[8], data[9]); + glColor(col ? *col++ : C3f(1)); glPushMatrix(); // Translate disk to point location and scale - glTranslate(p); - glScalef(r,r,r); + glTranslate(*P); + glScalef(*r, *r, *r); // Transform the disk normal (0,0,1) into the correct normal // direction for the current point. The appropriate transform // is a rotation about a direction perpendicular to both // normals: - V3f v = diskNormal % n; + V3f v = diskNormal % *N; // via the angle given by the dot product: - float angle = rad2deg(acosf(diskNormal^n)); + float angle = rad2deg(acosf(diskNormal^*N)); glRotatef(angle, v.x, v.y, v.z); // Instance the disk glCallList(disk); diff --git a/libs/pointrender/ptview.h b/libs/pointrender/ptview.h index 37d0425..c296ae7 100644 --- a/libs/pointrender/ptview.h +++ b/libs/pointrender/ptview.h @@ -31,13 +31,18 @@ #define AQSIS_PTVIEW_H_INCLUDED #include <cmath> +#include <vector> #include <boost/shared_ptr.hpp> +#include <boost/shared_array.hpp> #include <QtGui/QMainWindow> #include <QtOpenGL/QGLWidget> #include <OpenEXR/ImathVec.h> +#include <OpenEXR/ImathColor.h> + +#include <Partio.h> #include "pointcontainer.h" #include "interactivecamera.h" @@ -46,8 +51,56 @@ namespace Aqsis { using Imath::V3f; using Imath::V2f; +using Imath::C3f; + + +//------------------------------------------------------------------------------ +/// Container for points to be displayed in the PointView interface +class PointArrayModel : public QObject +{ + Q_OBJECT + + public: + PointArrayModel(); -inline float deg2rad(float d) { return (M_PI/180) * d; } + /// Load points from a file + bool loadPointFile(const QString& fileName); + + /// Return the number of points + size_t size() const { return m_npoints; } + /// Return true when there are zero points + bool empty() const { return m_npoints == 0; } + + /// Return point position + const V3f* P() const { return m_P.get(); } + /// Return point normals + const V3f* N() const { return m_N.get(); } + /// Return point radii + const float* r() const { return m_r.get(); } + /// Return point color, or NULL if no color channel is present + const C3f* color() const { return m_col.get(); } + + /// Get a list of channel names which look like color channels + QStringList colorChannels() { return m_colorChannelNames; } + + /// Set the channel name which the color() function returns data for + void setColorChannel(const QString& name) { } + + /// Compute the centroid of the P data + V3f centroid() const; + + private: + /// Look through the channels to find all which look like color data + static QStringList findColorChannels(const Partio::ParticlesInfo* ptFile); + + QString m_fileName; + QStringList m_colorChannelNames; + size_t m_npoints; + boost::shared_array<V3f> m_P; + boost::shared_array<V3f> m_N; + boost::shared_array<float> m_r; + boost::shared_array<C3f> m_col; +}; //------------------------------------------------------------------------------ @@ -98,7 +151,7 @@ class PointView : public QGLWidget private: static void drawAxes(); void drawCursor(const V3f& P) const; - static void drawPoints(const PointArray& points, VisMode visMode, + static void drawPoints(const PointArrayModel& points, VisMode visMode, bool useLighting); /// Mouse-based camera positioning @@ -117,7 +170,7 @@ class PointView : public QGLWidget /// Flag for whether to use OpenGL lighting or not bool m_lighting; /// Point cloud data - boost::shared_ptr<PointArray> m_points; + std::vector<boost::shared_ptr<PointArrayModel> > m_points; boost::shared_ptr<const PointOctree> m_pointTree; V3f m_cloudCenter; }; ----------------------------------------------------------------------- Summary of changes: libs/pointrender/pointcontainer.h | 72 --------- libs/pointrender/ptview.cpp | 292 +++++++++++++++++++++++++------------ libs/pointrender/ptview.h | 59 +++++++- 3 files changed, 257 insertions(+), 166 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2011-09-27 13:01:07
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via 180de2abf827d28d2d3b9ea42cdb2dbb06414d31 (commit) from c40ec63b577b232ce91d92b626dc7a6e8a42ccdb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 180de2abf827d28d2d3b9ea42cdb2dbb06414d31 Author: Chris Foster <chr...@gm...> Date: Tue Sep 27 22:50:43 2011 +1000 "coordsystem" option for point cloud shadeops This change causes all point cloud shadeops (bake3d, texture3d, occlusion and indirectdiffuse) to automatically transform points to world space by default. A different space can be chosen by setting the "coordsystem" option to the desired value. The advantage of using world space rather than current space by default is that it's independent of the camera position, which makes point clouds easily reusable between frames with different cameras. diff --git a/include/aqsis/math/matrix.h b/include/aqsis/math/matrix.h index 8e9781e..609648e 100644 --- a/include/aqsis/math/matrix.h +++ b/include/aqsis/math/matrix.h @@ -378,6 +378,18 @@ AQSIS_MATH_SHARE bool isClose(const CqMatrix& m1, const CqMatrix& m2, TqFloat tol = 10*std::numeric_limits<TqFloat>::epsilon()); +/// Get the vector transformation associated with the point transformation, m +/// +/// The vector transform is the point transform without the translation part +/// of m. +CqMatrix vectorTransform(const CqMatrix& m); + +/// Get the normal transformation associated with the point transformation, m +/// +/// The normal transform is the same as the vector transform for orthogonal +/// transformations but more complicated in the general case. +CqMatrix normalTransform(const CqMatrix& m); + //============================================================================== // Implementation details //============================================================================== @@ -965,6 +977,24 @@ inline bool operator!=(const CqMatrix& A, const CqMatrix& B) return !(A==B); } + +inline CqMatrix vectorTransform(const CqMatrix& m) +{ + CqMatrix r = m; + // Remove the transformation and projection parts of the transform. + r[3][0] = r[3][1] = r[3][2] = 0; + r[0][3] = r[1][3] = r[2][3] = 0; + r[3][3] = 1.0; + return r; +} + + +inline CqMatrix normalTransform(const CqMatrix& m) +{ + return vectorTransform(m).Inverse().Transpose(); +} + + } // namespace Aqsis #endif // !MATRIX_H_INCLUDED diff --git a/libs/shadervm/shaderexecenv/shadeops_bake3d.cpp b/libs/shadervm/shaderexecenv/shadeops_bake3d.cpp index e3b0817..207aa53 100644 --- a/libs/shadervm/shaderexecenv/shadeops_bake3d.cpp +++ b/libs/shadervm/shaderexecenv/shadeops_bake3d.cpp @@ -278,6 +278,7 @@ void CqShaderExecEnv::SO_bake3d( IqShaderData* ptc, bool interpolate = false; const IqShaderData* radius = 0; const IqShaderData* radiusScale = 0; + CqString coordSystem = "world"; // P, N and r output attributes are always present Partio::ParticleAttribute positionAttr, normalAttr, radiusAttr; pointFile->attributeInfo("position", positionAttr); @@ -295,24 +296,24 @@ void CqShaderExecEnv::SO_bake3d( IqShaderData* ptc, { apParams[i]->GetString(paramName); IqShaderData* paramValue = apParams[i+1]; + EqVariableType paramType = paramValue->Type(); // Parameters with special meanings may be present in the varargs // list, but shouldn't be saved to the output file, these include: - // - // TODO: also "coordsystem". - if(paramName == "interpolate") + if(paramName == "interpolate" && paramType == type_float) paramValue->GetBool(interpolate); - else if(paramName == "radius") + else if(paramName == "radius" && paramType == type_float) radius = paramValue; - else if(paramName == "radiusscale") + else if(paramName == "radiusscale" && paramType == type_float) radiusScale = paramValue; + else if(paramName == "coordsystem" && paramType == type_string) + paramValue->GetString(coordSystem); else { // If none of the above special cases, we have an output // variable which should be saved to the file. int count = 0; Partio::ParticleAttributeType parType = Partio::FLOAT; - EqVariableType type = paramValue->Type(); - switch(type) + switch(paramType) { case type_float: count = 1; parType = Partio::FLOAT; break; case type_point: count = 3; parType = Partio::VECTOR; break; @@ -326,7 +327,7 @@ void CqShaderExecEnv::SO_bake3d( IqShaderData* ptc, << paramName << "\"\n"; continue; } - bakeVars.push_back(UserVar(paramValue, type)); + bakeVars.push_back(UserVar(paramValue, paramType)); // Find the named attribute in the point file, or create it if // it doesn't exist. UserVar& var = bakeVars.back(); @@ -350,6 +351,14 @@ void CqShaderExecEnv::SO_bake3d( IqShaderData* ptc, Aqsis::log() << "unexpected non-string for parameter name " "in bake3d()\n"; } + + /// Compute transformations + CqMatrix positionTrans; + getRenderContext()->matSpaceToSpace("current", coordSystem.c_str(), + pShader->getTransform(), + pTransform().get(), 0, positionTrans); + CqMatrix normalTrans = normalTransform(positionTrans); + CqAutoBuffer<TqFloat, 100> allData(interpolate ? 2*nOutFloats : nOutFloats); @@ -455,8 +464,10 @@ void CqShaderExecEnv::SO_bake3d( IqShaderData* ptc, float* P = pointFile->dataWrite<float>(positionAttr, ptIdx); float* N = pointFile->dataWrite<float>(normalAttr, ptIdx); float* r = pointFile->dataWrite<float>(radiusAttr, ptIdx); - P[0] = *d++; P[1] = *d++; P[2] = *d++; - N[0] = *d++; N[1] = *d++; N[2] = *d++; + CqVector3D cqP = positionTrans * CqVector3D(d[0], d[1], d[2]); d += 3; + P[0] = cqP.x(); P[1] = cqP.y(); P[2] = cqP.z(); + CqVector3D cqN = normalTrans * CqVector3D(d[0], d[1], d[2]); d += 3; + N[0] = cqN.x(); N[1] = cqN.y(); N[2] = cqN.z(); r[0] = radiusVal; // Save out user-defined attributes for(int i = 0, iend = bakeVars.size(); i < iend; ++i) @@ -496,9 +507,10 @@ static bool parseTexture3dVarargs(int nargs, IqShaderData** args, } args[i]->GetString(paramName); IqShaderData* paramValue = args[i+1]; + EqVariableType paramType = paramValue->Type(); // Parameters with special meanings may be present in the varargs // list, and shouldn't be looked up in the file: - if(paramName == "coordsystem") + if(paramName == "coordsystem" && paramType == type_string) paramValue->GetString(coordSystem); else if(paramName == "filterradius") ; // For brick maps; ignored for now @@ -511,7 +523,6 @@ static bool parseTexture3dVarargs(int nargs, IqShaderData** args, // If none of the above special cases, we have a user-defined // variable. Look it up in the point file, and check whether the // type corresponds with the provided shader variable. - EqVariableType type = paramValue->Type(); Partio::ParticleAttribute attr; pointFile->attributeInfo(paramName.c_str(), attr); if(attr.type != Partio::FLOAT && attr.type != Partio::VECTOR) @@ -522,7 +533,7 @@ static bool parseTexture3dVarargs(int nargs, IqShaderData** args, continue; } int desiredCount = 0; - switch(type) + switch(paramType) { case type_float: desiredCount = 1; break; case type_point: desiredCount = 3; break; @@ -543,7 +554,7 @@ static bool parseTexture3dVarargs(int nargs, IqShaderData** args, << "\" mismatched in point file\n"; continue; } - userVars.push_back(UserVar(paramValue, type, attr)); + userVars.push_back(UserVar(paramValue, paramType, attr)); } } return userVars.size() > 0; @@ -590,6 +601,13 @@ void CqShaderExecEnv::SO_texture3d(IqShaderData* ptc, return; } + /// Compute transformations + CqMatrix positionTrans; + getRenderContext()->matSpaceToSpace("current", coordSystem.c_str(), + pShader->getTransform(), + pTransform().get(), 0, positionTrans); + CqMatrix normalTrans = normalTransform(positionTrans); + // Grab the standard attributes for computing filter weights Partio::ParticleAttribute positionAttr, normalAttr, radiusAttr; pointFile->attributeInfo("position", positionAttr); @@ -602,7 +620,9 @@ void CqShaderExecEnv::SO_texture3d(IqShaderData* ptc, continue; CqVector3D cqP, cqN; position->GetPoint(cqP, igrid); + cqP = positionTrans*cqP; normal->GetNormal(cqN, igrid); + cqN = normalTrans*cqN; // Using the four nearest neighbours for filtering is roughly the // minimum we can get away with for a surface made out of @@ -693,20 +713,19 @@ void CqShaderExecEnv::SO_texture3d(IqShaderData* ptc, break; case type_color: var->value->SetColor(CqColor(accum[0], accum[1], - accum[2]), igrid); + accum[2]), igrid); break; case type_point: - // TODO: Transformations! var->value->SetPoint(CqVector3D(accum[0], accum[1], accum[2]), igrid); break; case type_normal: var->value->SetNormal(CqVector3D(accum[0], accum[1], - accum[2]), igrid); + accum[2]), igrid); break; case type_vector: var->value->SetVector(CqVector3D(accum[0], accum[1], - accum[2]), igrid); + accum[2]), igrid); break; case type_matrix: var->value->SetMatrix(CqMatrix(accum), igrid); diff --git a/libs/shadervm/shaderexecenv/shadeops_illum.cpp b/libs/shadervm/shaderexecenv/shadeops_illum.cpp index 882eef8..33d9657 100644 --- a/libs/shadervm/shaderexecenv/shadeops_illum.cpp +++ b/libs/shadervm/shaderexecenv/shadeops_illum.cpp @@ -1114,7 +1114,8 @@ void storeZeroResult<RadiosityIntegrator>(IqShaderData* result, int igrid) template<typename IntegratorT> void CqShaderExecEnv::pointCloudIntegrate(IqShaderData* P, IqShaderData* N, IqShaderData* result, int cParams, - IqShaderData** apParams) + IqShaderData** apParams, + IqShader* pShader) { if(!getRenderContext()) return; @@ -1126,6 +1127,7 @@ void CqShaderExecEnv::pointCloudIntegrate(IqShaderData* P, IqShaderData* N, float maxSolidAngle = 0.03; float coneAngle = M_PI_2; float bias = 0; + CqString coordSystem = "world"; for(int i = 0; i < cParams; i+=2) { apParams[i]->GetString(paramName, 0); @@ -1163,9 +1165,13 @@ void CqShaderExecEnv::pointCloudIntegrate(IqShaderData* P, IqShaderData* N, faceRes = std::max(1, static_cast<int>(res)); } } + else if(paramName == "coordsystem") + { + if(paramValue->Type() == type_string) + paramValue->GetString(coordSystem); + } // Interesting arguments which could be implemented: // "hitsides" - sidedness culling: "front", "back", "both" - // "coordsystem" - coordinate system of points, default "world" // "falloff", "falloffmode" - falloff of occlusion with distance // ... more! // @@ -1173,6 +1179,13 @@ void CqShaderExecEnv::pointCloudIntegrate(IqShaderData* P, IqShaderData* N, // "pointbased" - we don't support any other method... } + // Compute transform from current to appropriate space. + CqMatrix positionTrans; + getRenderContext()->matSpaceToSpace("current", coordSystem.c_str(), + pShader->getTransform(), + pTransform().get(), 0, positionTrans); + CqMatrix normalTrans = normalTransform(positionTrans); + // TODO: interpolation. 3delight uses Attribute "irradiance" // "shadingrate" to control interpolation; PRMan uses the "maxvariation" // parameter. @@ -1244,6 +1257,8 @@ void CqShaderExecEnv::pointCloudIntegrate(IqShaderData* P, IqShaderData* N, else P->GetVector(Pval, igrid); CqVector3D Nval; N->GetVector(Nval, igrid); + Pval = positionTrans * Pval; + Nval = normalTrans * Nval; V3f Pval2(Pval.x(), Pval.y(), Pval.z()); V3f Nval2(Nval.x(), Nval.y(), Nval.z()); // TODO: It may make more sense to scale bias by the current @@ -1286,7 +1301,8 @@ static void storeIntegratedResult(const OcclusionIntegrator& integrator, // occlusion(P,N,samples) void CqShaderExecEnv::SO_occlusion_rt( IqShaderData* P, IqShaderData* N, IqShaderData* samples, IqShaderData* Result, IqShader* pShader, int cParams, IqShaderData** apParams ) { - pointCloudIntegrate<OcclusionIntegrator>(P, N, Result, cParams, apParams); + pointCloudIntegrate<OcclusionIntegrator>(P, N, Result, cParams, apParams, + pShader); } @@ -1306,7 +1322,8 @@ void CqShaderExecEnv::SO_indirectdiffuse(IqShaderData* P, IqShaderData* N, IqShader* pShader, int cParams, IqShaderData** apParams) { - pointCloudIntegrate<RadiosityIntegrator>(P, N, Result, cParams, apParams); + pointCloudIntegrate<RadiosityIntegrator>(P, N, Result, cParams, apParams, + pShader); } diff --git a/libs/shadervm/shaderexecenv/shaderexecenv.h b/libs/shadervm/shaderexecenv/shaderexecenv.h index 143b3c2..dca6219 100644 --- a/libs/shadervm/shaderexecenv/shaderexecenv.h +++ b/libs/shadervm/shaderexecenv/shaderexecenv.h @@ -381,7 +381,7 @@ class AQSIS_SHADERVM_SHARE CqShaderExecEnv : public IqShaderExecEnv, boost::nonc template<typename IntegratorT> void pointCloudIntegrate(IqShaderData* P, IqShaderData* N, IqShaderData* result, int cParams, - IqShaderData** apParams); + IqShaderData** apParams, IqShader* pShader); /// Turn 1D iteration into 2D grid indices /// ----------------------------------------------------------------------- Summary of changes: include/aqsis/math/matrix.h | 30 ++++++++++++ libs/shadervm/shaderexecenv/shadeops_bake3d.cpp | 55 +++++++++++++++------- libs/shadervm/shaderexecenv/shadeops_illum.cpp | 25 +++++++++-- libs/shadervm/shaderexecenv/shaderexecenv.h | 2 +- 4 files changed, 89 insertions(+), 23 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2011-09-27 04:52:26
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via c40ec63b577b232ce91d92b626dc7a6e8a42ccdb (commit) from 718258e20f158f031e7440c8e60a02e755946e85 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c40ec63b577b232ce91d92b626dc7a6e8a42ccdb Author: Chris Foster <chr...@gm...> Date: Mon Sep 26 23:15:23 2011 +1000 Implement texture3d with partio's kdtree lookup This replaces the old texture3d implementation with a proper lookup scheme based on a kdtree and filtering of nearest four points. Since the lookups happen without prefiltering, no effort is made to avoid aliasing by using a filter radius based on the size of the current shading element. The implementation is mostly complete but still does all lookups in "current" space whereas they should happen in world space by default and be configurable. diff --git a/libs/shadervm/shaderexecenv/shadeops_bake3d.cpp b/libs/shadervm/shaderexecenv/shadeops_bake3d.cpp index a459220..e3b0817 100644 --- a/libs/shadervm/shaderexecenv/shadeops_bake3d.cpp +++ b/libs/shadervm/shaderexecenv/shadeops_bake3d.cpp @@ -18,12 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -/** \file - \brief Implements the basic shader operations. (bake3d related) - \author Michel Joron jo...@sy... -*/ - - #ifdef AQSIS_SYSTEM_WIN32 #include <io.h> #endif @@ -37,18 +31,25 @@ #include <aqsis/util/autobuffer.h> #include <aqsis/util/logging.h> +#include <OpenEXR/ImathVec.h> + namespace Aqsis { +using Imath::V3f; + // Utils for bake3d() shadeop. namespace { -struct BakeVar +struct UserVar { - const IqShaderData* value; + IqShaderData* value; EqVariableType type; Partio::ParticleAttribute attr; - BakeVar(const IqShaderData* value, EqVariableType type) + UserVar(IqShaderData* value, EqVariableType type, + const Partio::ParticleAttribute& attr) + : value(value), type(type), attr(attr) {} + UserVar(IqShaderData* value, EqVariableType type) : value(value), type(type) {} }; } @@ -62,8 +63,8 @@ struct BakeVar /// \param normal - normal array /// \param bakeVars - array of shader data and associated types /// \param nBakeVars - length of bakeVars array. -static void extractBakeVars(float* out, int igrid, IqShaderData* position, - IqShaderData* normal, BakeVar* bakeVars, +static void extractUserVars(float* out, int igrid, IqShaderData* position, + IqShaderData* normal, UserVar* bakeVars, int nBakeVars) { // Temp vars for extracting data from IqShaderData @@ -82,7 +83,7 @@ static void extractBakeVars(float* out, int igrid, IqShaderData* position, // of floats to pass to Ptc API. for(int i = 0; i < nBakeVars; ++i) { - const BakeVar& var = bakeVars[i]; + const UserVar& var = bakeVars[i]; switch(var.type) { case type_float: @@ -176,12 +177,62 @@ class Bake3dCache }; } + +namespace { +/// A cache for open point cloud bake files for texture3d(). +class Texture3dCache +{ + public: + /// Find a point cloud with the given name, or open it from file. + Partio::ParticlesData* find(const std::string& fileName) + { + Partio::ParticlesDataMutable* pointFile = 0; + FileMap::iterator ptcIter = m_files.find(fileName); + if(ptcIter == m_files.end()) + { + // Create new bake file & insert into map. + pointFile = Partio::read(fileName.c_str()); + m_files[fileName].reset(pointFile, releasePartioFile); + if(pointFile) + { + // Sort file so that it can be looked up efficiently. + pointFile->sort(); + // TODO: Ensure that radius, position & normal attributes + // are present. + } + else + { + Aqsis::log() << error + << "texture3d: Could not open point cloud \"" << fileName + << "\" for reading\n"; + } + } + else + pointFile = ptcIter->second.get(); + return pointFile; + } + + /// Flush all files from the cache. + void clear() + { + m_files.clear(); + } + + private: + typedef std::map<std::string, boost::shared_ptr<Partio::ParticlesDataMutable> > FileMap; + FileMap m_files; +}; +} + + // TODO: Make non-global static Bake3dCache g_bakeCloudCache; +static Texture3dCache g_texture3dCloudCache; void flushBake3dCache() { g_bakeCloudCache.flush(); + g_texture3dCloudCache.clear(); } //------------------------------------------------------------------------------ @@ -233,7 +284,7 @@ void CqShaderExecEnv::SO_bake3d( IqShaderData* ptc, pointFile->attributeInfo("normal", normalAttr); pointFile->attributeInfo("radius", radiusAttr); // Extract list of user-specified output vars from arguments - std::vector<BakeVar> bakeVars; + std::vector<UserVar> bakeVars; bakeVars.reserve(cParams/2); CqString paramName; // Number of output floats. Start with space for position and normal data. @@ -243,7 +294,7 @@ void CqShaderExecEnv::SO_bake3d( IqShaderData* ptc, if(apParams[i]->Type() == type_string) { apParams[i]->GetString(paramName); - const IqShaderData* paramValue = apParams[i+1]; + IqShaderData* paramValue = apParams[i+1]; // Parameters with special meanings may be present in the varargs // list, but shouldn't be saved to the output file, these include: // @@ -275,10 +326,10 @@ void CqShaderExecEnv::SO_bake3d( IqShaderData* ptc, << paramName << "\"\n"; continue; } - bakeVars.push_back(BakeVar(paramValue, type)); + bakeVars.push_back(UserVar(paramValue, type)); // Find the named attribute in the point file, or create it if // it doesn't exist. - BakeVar& var = bakeVars.back(); + UserVar& var = bakeVars.back(); if(pointFile->attributeInfo(paramName.c_str(), var.attr)) { if(var.attr.count != count) @@ -315,6 +366,7 @@ void CqShaderExecEnv::SO_bake3d( IqShaderData* ptc, if(interpolate) { // Get micropoly position on 2D grid. + // TODO: What if the grid is 1D or 0D? iv = igrid / uSize; iu = igrid - iv*uSize; // Check whether we're off the edge (number of polys in each @@ -324,7 +376,7 @@ void CqShaderExecEnv::SO_bake3d( IqShaderData* ptc, } // Extract all baking variables into allData. - extractBakeVars(allData.get(), igrid, position, normal, + extractUserVars(allData.get(), igrid, position, normal, &bakeVars[0], bakeVars.size()); // Get radius if it's avaliable, otherwise compute automatically @@ -348,7 +400,7 @@ void CqShaderExecEnv::SO_bake3d( IqShaderData* ptc, // micropolygon & merge into outData. for(int i = 0; i < 3; ++i) { - extractBakeVars(tmpData, interpIndices[i], position, normal, + extractUserVars(tmpData, interpIndices[i], position, normal, &bakeVars[0], bakeVars.size()); for(int j = 0; j < nOutFloats; ++j) outData[j] += tmpData[j]; @@ -409,7 +461,7 @@ void CqShaderExecEnv::SO_bake3d( IqShaderData* ptc, // Save out user-defined attributes for(int i = 0, iend = bakeVars.size(); i < iend; ++i) { - BakeVar& var = bakeVars[i]; + UserVar& var = bakeVars[i]; float* out = pointFile->dataWrite<float>(var.attr, ptIdx); for(int j = 0; j < var.attr.count; ++j) out[j] = *d++; @@ -422,216 +474,249 @@ void CqShaderExecEnv::SO_bake3d( IqShaderData* ptc, //------------------------------------------------------------------------------ +// Texture3d stuff + +// Parse and validate the varargs part of the texture3d argument list. +// +// nargs and args specify the varargs list. +static bool parseTexture3dVarargs(int nargs, IqShaderData** args, + const Partio::ParticlesData* pointFile, + CqString& coordSystem, + std::vector<UserVar>& userVars) +{ + userVars.reserve(nargs/2); + CqString paramName; + for(int i = 0; i+1 < nargs; i+=2) + { + if(args[i]->Type() != type_string) + { + Aqsis::log() << error + << "unexpected non-string for parameter name in texture3d()\n"; + return false; + } + args[i]->GetString(paramName); + IqShaderData* paramValue = args[i+1]; + // Parameters with special meanings may be present in the varargs + // list, and shouldn't be looked up in the file: + if(paramName == "coordsystem") + paramValue->GetString(coordSystem); + else if(paramName == "filterradius") + ; // For brick maps; ignored for now + else if(paramName == "filterscale") + ; // For brick maps; ignored for now + else if(paramName == "maxdepth") + ; // For brick maps; ignored for now + else + { + // If none of the above special cases, we have a user-defined + // variable. Look it up in the point file, and check whether the + // type corresponds with the provided shader variable. + EqVariableType type = paramValue->Type(); + Partio::ParticleAttribute attr; + pointFile->attributeInfo(paramName.c_str(), attr); + if(attr.type != Partio::FLOAT && attr.type != Partio::VECTOR) + { + Aqsis::log() << warning + << "texture3d: Can't load non-float data \"" + << paramName << "\"\n"; + continue; + } + int desiredCount = 0; + switch(type) + { + case type_float: desiredCount = 1; break; + case type_point: desiredCount = 3; break; + case type_color: desiredCount = 3; break; + case type_normal: desiredCount = 3; break; + case type_vector: desiredCount = 3; break; + case type_matrix: desiredCount = 16; break; + default: + Aqsis::log() << warning + << "texture3d: Can't load non float-based argument \"" + << paramName << "\"\n"; + continue; + } + if(desiredCount != attr.count) + { + Aqsis::log() << warning + << "texture3d: variable \"" << paramName + << "\" mismatched in point file\n"; + continue; + } + userVars.push_back(UserVar(paramValue, type, attr)); + } + } + return userVars.size() > 0; +} + + /** \brief Shadeops "texture3d" to restore any parameter from one pointcloud file refer. * \param ptc the name of the pointcloud file - * \param point the P - * \param normat its normal + * \param position + * \param normal * \result result 0 or 1 * \param pShader shaderexecenv * \param cParams number of remaining user parameters. * \param aqParams list of user parameters (to save to ptc) */ -void CqShaderExecEnv::SO_texture3d(IqShaderData* ptc, - IqShaderData* point, +void CqShaderExecEnv::SO_texture3d(IqShaderData* ptc, + IqShaderData* position, IqShaderData* normal, IqShaderData* Result, IqShader* pShader, TqInt cParams, IqShaderData** apParams ) { - // FIXME! - -#if 0 - bool __fVarying; - TqUint __iGrid; - - __fVarying=(point)->Class()==class_varying; - __fVarying=(normal)->Class()==class_varying||__fVarying; - __fVarying=(Result)->Class()==class_varying||__fVarying; - - __iGrid = 0; const CqBitVector& RS = RunningState(); - CqString _aq_ptc; - (ptc)->GetString(_aq_ptc,__iGrid); - TqUshort VarStarts[CqBake3DOptionsMaxParams] = {0}; - PtcPointCloud MyCloudRead = PtcManager.FindCloudRead(_aq_ptc.c_str(), VarStarts); - CqBake3DOptions sampleOpts; - CqBake3DOptionsExtractor optExtractor(apParams, cParams, sampleOpts); - - - if (!MyCloudRead) - { - const char *varnames[CqBake3DOptionsMaxParams]; - const char *vartypes[CqBake3DOptionsMaxParams]; - TqInt varnumber = 0; - MyCloudRead = PtcOpenPointCloudFile(_aq_ptc.c_str(), &varnumber, vartypes, varnames); + CqString ptcName; + ptc->GetString(ptcName); - TqInt i, j; + Partio::ParticlesData* pointFile = g_texture3dCloudCache.find(ptcName); + bool varying = position->Class() == class_varying || + normal->Class() == class_varying || + Result->Class() == class_varying; + int npoints = varying ? shadingPointCount() : 1; - TqInt okay = 0; + CqString coordSystem = "world"; + std::vector<UserVar> userVars; - // Double check if this variable exist in this PTC... + if(!pointFile || !parseTexture3dVarargs(cParams, apParams, + pointFile, coordSystem, userVars)) + { + // Error - no point file or no arguments to look up: set result to 0 + // and return. + for(int igrid = 0; igrid < npoints; ++igrid) + if(!varying || RS.Value(igrid)) + Result->SetFloat(0, igrid); + return; + } - TqInt found = 0; - for (j=0; j < sampleOpts.m_Count; j++) - { - for (i=0; i < varnumber; i ++) - { - if (strcmp(sampleOpts.m_VarNames[j], varnames[i]) == 0) - { - found ++; - break; - } - } - } - okay = (found == sampleOpts.m_Count); + // Grab the standard attributes for computing filter weights + Partio::ParticleAttribute positionAttr, normalAttr, radiusAttr; + pointFile->attributeInfo("position", positionAttr); + pointFile->attributeInfo("normal", normalAttr); + pointFile->attributeInfo("radius", radiusAttr); - if (!okay) + for(int igrid = 0; igrid < npoints; ++igrid) + { + if(varying && !RS.Value(igrid)) + continue; + CqVector3D cqP, cqN; + position->GetPoint(cqP, igrid); + normal->GetNormal(cqN, igrid); + + // Using the four nearest neighbours for filtering is roughly the + // minimum we can get away with for a surface made out of + // quadrilaterals. This isn't exactly perfect near edges but it seems + // to be good enough. + // + // Since the lookups happen without prefiltering, no effort is made to + // avoid aliasing by using a filter radius based on the size of the + // current shading element. + const int nfilter = 4; + Partio::ParticleIndex indices[nfilter]; + float distSquared[nfilter]; + float maxRadius2 = 0; + V3f P(cqP.x(), cqP.y(), cqP.z()); + // The reinterpret_casts are ugly here of course, but V3f is basically + // a POD type, so they work ok. + int pointsFound = pointFile->findNPoints(reinterpret_cast<float*>(&P), + nfilter, FLT_MAX, indices, + distSquared, &maxRadius2); + if(pointsFound < nfilter) { - PtcClosePointCloudFile(MyCloudRead); - MyCloudRead = 0; + Result->SetFloat(0.0f, igrid); + Aqsis::log() << error << "Not enough points found to filter!"; } - else + // Read position, normal and radius + V3f foundP[nfilter]; + pointFile->dataAsFloat(positionAttr, nfilter, indices, false, + reinterpret_cast<float*>(foundP)); + V3f foundN[nfilter]; + pointFile->dataAsFloat(normalAttr, nfilter, indices, false, + reinterpret_cast<float*>(foundN)); + float foundRadius[nfilter]; + pointFile->dataAsFloat(radiusAttr, nfilter, indices, false, foundRadius); + + // Compute filter weights for nearby points. inverseWidthSquared + // decides the blurryness of the gaussian filter. The value was chosen + // by eyeballing the results of various widths. As usual it's a trade + // off: Too small a value will be too blurry, (and artifacty if nfilter + // is 4); too large a value and it ends up looking like nearest + // neighbour filtering. + const float inverseWidthSquared = 1.3f; + float weights[nfilter]; + float totWeight = 0; + V3f N(cqN.x(), cqN.y(), cqN.z()); + for(int i = 0; i < nfilter; ++i) { - - for (i=0; i< sampleOpts.m_Count; i++) - { - // First we need to find where shader' variable with the userdata - TqInt found = -1; - for (j=0; j < varnumber && found == -1; j++) - { - if (strcmp(varnames[j], sampleOpts.m_VarNames[i]) == 0) - found = j; - } - - TqInt where = 0; - // If it is existing find its location within the userdata block - if (found >= 0) - { - - for (j=0; j < found; j++) - { - if ( strcmp(vartypes[j], "float") == 0 || - strcmp(vartypes[j], "integer") == 0 || - strcmp(vartypes[j], "bool") == 0 ) - where ++; - else if ( strcmp(vartypes[j], "matrix") == 0 ) - where += 16; - else - where += 3; - } - VarStarts[i] = where; - } - } - PtcManager.SaveCloudRead(_aq_ptc.c_str(), MyCloudRead, VarStarts); + // The weights depend on how well the normals are aligned, and the + // distance between the current shading point and the points found + // in the point cloud. + float wN = std::max(0.0f, N.dot(foundN[i])); + // TODO: Speed this up using a lookup table for exp? + float wP = std::exp(-inverseWidthSquared * distSquared[i] + / (foundRadius[i]*foundRadius[i])); + // Clamping to a minimum of 1e-7 means the weights don't quite + // become zero as distSquared becomes large, so texture lookups + // even far from any point in the cloud return something nonzero. + // + // Not sure if this is a good idea or not, so commented out for now + // wP = std::max(1e-7f, wP); + float w = wN*wP; + weights[i] = w; + totWeight += w; } - } - + // Normalize the weights + float renorm = totWeight != 0 ? 1/totWeight : 0; + for(int i = 0; i < nfilter; ++i) + weights[i] *= renorm; - - TqFloat *userdata = NULL; - - do - { - if(RS.Value( __iGrid ) ) + for(std::vector<UserVar>::const_iterator var = userVars.begin(); + var != userVars.end(); ++var) { - TqInt okay = 1; - - if (MyCloudRead != 0) + // Read and filter each piece of user-defined data + float varData[16*nfilter]; + pointFile->dataAsFloat(var->attr, nfilter, indices, false, varData); + int varSize = var->attr.count; + float accum[16]; + for(int c = 0; c < varSize; ++c) + accum[c] = 0; + for(int i = 0; i < nfilter; ++i) + for(int c = 0; c < varSize; ++c) + accum[c] += weights[i] * varData[i*varSize + c]; + // Ah, if only we could get at the raw floats stored by + // IqShaderData, we wouldn't need this switch + switch(var->type) { - TqFloat radius; - if (userdata == NULL) - { - TqInt size = 0; - PtcGetPointCloudInfo(MyCloudRead, "datasize", &size); - - userdata = new TqFloat[size]; - } - - /* - it could to do a simple find using qsort/bsearch based on point - okay = PtcFindDataPoint(MyCloudRead, pointf, normalf, &radius, userdata); - */ - // Take all the information and call PtcReadDataPoint() - TqFloat pointf[3]; - TqFloat normalf[3]; - okay = PtcReadDataPoint(MyCloudRead, pointf, normalf, &radius, userdata); - - CqVector3D _aq_point; - (point)->GetPoint(_aq_point,__iGrid); - CqVector3D _aq_normal; - (normal)->GetPoint(_aq_normal,__iGrid); - TqFloat fRes = 0.0f; - - // Convert all the information from userdata and save the data into the user parameters - for (TqInt i=0; i< sampleOpts.m_Count; i++) - { - // First we need to find where shader' variable with the userdata - TqInt where = VarStarts[i]; - if ( strcmp(sampleOpts.m_VarTypes[i], "float") == 0 || - strcmp(sampleOpts.m_VarTypes[i], "integer") == 0 || - strcmp(sampleOpts.m_VarTypes[i], "bool") == 0 ) - { - TqFloat f; - - f = userdata[where]; - sampleOpts.m_UserData[ i ]->SetFloat( f, __iGrid); - } else if ( strcmp(sampleOpts.m_VarTypes[i], "vector") == 0) - { - CqVector3D v; - - for (TqInt j=0; i < 3; i++) - { - v[j] = userdata[where + j]; - } - sampleOpts.m_UserData[ i ]->SetVector( v, __iGrid); - } else if ( strcmp(sampleOpts.m_VarTypes[i], "color") == 0) - { - CqColor c; - - for (TqInt j=0; j < 3; j++) - { - c[j] = userdata[where + j]; - } - sampleOpts.m_UserData[ i ]->SetColor( c, __iGrid); - } else if ( strcmp(sampleOpts.m_VarTypes[i], "point") == 0) - { - CqVector3D p; - - for (TqInt j=0; j < 3; j++) - { - p[j] = userdata[where + j]; - } - sampleOpts.m_UserData[ i ]->SetPoint( p, __iGrid); - } else if ( strcmp(sampleOpts.m_VarTypes[i], "normal") == 0) - { - CqVector3D n; - - for (TqInt j=0; j < 3; j++) - { - n[j] = userdata[where + j]; - } - sampleOpts.m_UserData[ i ]->SetNormal( n, __iGrid); - } else if ( strcmp(sampleOpts.m_VarTypes[i], "matrix") == 0) - { - CqMatrix m; - - for (TqInt j=0; j < 16; j++) - { - m.pElements()[j] = userdata[where + j]; - } - sampleOpts.m_UserData[ i ]->SetMatrix( m, __iGrid); - } - } - fRes = okay; - (Result)->SetFloat(fRes,__iGrid); + case type_float: + var->value->SetFloat(accum[0], igrid); + break; + case type_color: + var->value->SetColor(CqColor(accum[0], accum[1], + accum[2]), igrid); + break; + case type_point: + // TODO: Transformations! + var->value->SetPoint(CqVector3D(accum[0], accum[1], + accum[2]), igrid); + break; + case type_normal: + var->value->SetNormal(CqVector3D(accum[0], accum[1], + accum[2]), igrid); + break; + case type_vector: + var->value->SetVector(CqVector3D(accum[0], accum[1], + accum[2]), igrid); + break; + case type_matrix: + var->value->SetMatrix(CqMatrix(accum), igrid); + break; + default: assert(0 && "unknown type"); } } - } while( ( ++__iGrid < shadingPointCount() ) && __fVarying); - if (userdata != NULL) - { - delete [] userdata; + // Return success for this point + Result->SetFloat(1.0f, igrid); } -#endif } //--------------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: libs/shadervm/shaderexecenv/shadeops_bake3d.cpp | 487 +++++++++++++---------- 1 files changed, 286 insertions(+), 201 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2011-09-17 12:53:09
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via 718258e20f158f031e7440c8e60a02e755946e85 (commit) from fbdcf5259cd27e29c364ceef0f9f8bfa98c9d8fd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 718258e20f158f031e7440c8e60a02e755946e85 Author: Chris Foster <chr...@gm...> Date: Fri Sep 16 11:07:52 2011 +1000 Avoid calling Partio::write in static destructor Partio::write uses a static std::map internally, so calls from a static destructor can result in weird behaviour or crashes because the map may have already been destroyed. In addition, make sure any references to baked point data are removed at the end of frame for efficiency. This also means that the next frame won't append additional data to a bake file which seems like the right thing to do. diff --git a/libs/shadervm/shaderexecenv/shadeops_bake3d.cpp b/libs/shadervm/shaderexecenv/shadeops_bake3d.cpp index f65f4ee..a459220 100644 --- a/libs/shadervm/shaderexecenv/shadeops_bake3d.cpp +++ b/libs/shadervm/shaderexecenv/shadeops_bake3d.cpp @@ -130,14 +130,6 @@ namespace { class Bake3dCache { public: - Bake3dCache() - { } - - ~Bake3dCache() - { - flush(); - } - /// Find or create a point cloud with the given name. /// /// The standard attributes; position, normal, and radius are added on @@ -170,11 +162,12 @@ class Bake3dCache return pointFile; } - /// Flush all files to disk. + /// Flush all files to disk and clear the cache void flush() { for(FileMap::iterator i = m_files.begin(); i != m_files.end(); ++i) Partio::write(i->first.c_str(), *i->second); + m_files.clear(); } private: diff --git a/libs/shadervm/shaderexecenv/shaderexecenv.h b/libs/shadervm/shaderexecenv/shaderexecenv.h index 528eeb2..143b3c2 100644 --- a/libs/shadervm/shaderexecenv/shaderexecenv.h +++ b/libs/shadervm/shaderexecenv/shaderexecenv.h @@ -654,7 +654,7 @@ class AQSIS_SHADERVM_SHARE CqShaderExecEnv : public IqShaderExecEnv, boost::nonc }; -/// Flush any caches of bake3d() data to disk. +/// Flush any caches of bake3d() data to disk and clear the cache. void flushBake3dCache(); /// Clear static caches of point cloud data ready for next frame ----------------------------------------------------------------------- Summary of changes: libs/shadervm/shaderexecenv/shadeops_bake3d.cpp | 11 ++--------- libs/shadervm/shaderexecenv/shaderexecenv.h | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: <gi...@aq...> - 2011-09-16 18:15:28
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "RIBMosaic Experimental". The branch, master has been updated via f6f500c7d5855a723862024417622fcf3e635e63 (commit) via f22caa43bc2f56210e0867f3c7327fe83f1ad0d7 (commit) from 04160dc6cdf6aeeafd0de3923c8e4582a46f5398 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f6f500c7d5855a723862024417622fcf3e635e63 Author: Jeff Doyle (nfz) <she...@ea...> Date: Fri Sep 16 15:15:08 2011 -0300 Bug Fix: A previous pass render dimensions could effect the next pass if that pass didn't have the render dimensions set. A passes render dimensions now default to the scene render dimensions if not set. diff --git a/render_ribmosaic/rm_export.py b/render_ribmosaic/rm_export.py index 56c48be..c7926b2 100644 --- a/render_ribmosaic/rm_export.py +++ b/render_ribmosaic/rm_export.py @@ -841,13 +841,14 @@ class ExporterManager(): ec.pointer_render = render_object ec.current_pass = i + 1 ec.current_frame = f + # default to using the render dimension settings + ec.dims_resx = x + ec.dims_resy = y if p.pass_type != 'BEAUTY': if p.pass_res_x > 0: - x = p.pass_res_x + ec.dims_resx = p.pass_res_x if p.pass_res_y > 0: - y = p.pass_res_y - ec.dims_resx = x - ec.dims_resy = y + ec.dims_resy = p.pass_res_y target_name = ec._resolve_links("P@[EVAL:.current_pass:#####]@" "_F@[EVAL:.current_frame:#####]@.rib") commit f22caa43bc2f56210e0867f3c7327fe83f1ad0d7 Author: Jeff Doyle (nfz) <she...@ea...> Date: Fri Sep 16 15:12:08 2011 -0300 Needed extra line feed so MakeShadow doesn't screw up rib formatting. Use .tx as extension for shadow file. diff --git a/render_ribmosaic/pipelines/aqsis_core.rmp b/render_ribmosaic/pipelines/aqsis_core.rmp index d3a3a2a..0f26dc6 100644 --- a/render_ribmosaic/pipelines/aqsis_core.rmp +++ b/render_ribmosaic/pipelines/aqsis_core.rmp @@ -70,7 +70,8 @@ Hider "hidden" "jitter" [ 0 ] </begin> <end target=""> -MakeShadow "@[EVAL:.pass_output:]@" "@[EVAL:.pass_output:]@.shad" +MakeShadow "@[EVAL:.pass_output:]@" "@[EVAL:.pass_output:]@.tx" + </end> <regexes target=""> </regexes> @@ -243,4 +244,4 @@ echo "Info complete" </layout> </Info> </command_panels> -</Aqsis_Core> \ No newline at end of file +</Aqsis_Core> diff --git a/render_ribmosaic/pipelines/pixie_core.rmp b/render_ribmosaic/pipelines/pixie_core.rmp index d5b5f0c..b396195 100644 --- a/render_ribmosaic/pipelines/pixie_core.rmp +++ b/render_ribmosaic/pipelines/pixie_core.rmp @@ -71,6 +71,7 @@ Hider "hidden" "jitter" [ 0 ] </begin> <end target=""> MakeShadow "@[EVAL:.pass_output:]@" "@[EVAL:.pass_output:]@.tx" + </end> <regexes target=""> </regexes> ----------------------------------------------------------------------- Summary of changes: render_ribmosaic/pipelines/aqsis_core.rmp | 5 +++-- render_ribmosaic/pipelines/pixie_core.rmp | 1 + render_ribmosaic/rm_export.py | 9 +++++---- 3 files changed, 9 insertions(+), 6 deletions(-) hooks/post-receive -- RIBMosaic Experimental |
From: Chris F. <c4...@us...> - 2011-09-15 04:08:16
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via fbdcf5259cd27e29c364ceef0f9f8bfa98c9d8fd (commit) from cd3167f2e0055550e4af9634830ed2c27b76cb8f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fbdcf5259cd27e29c364ceef0f9f8bfa98c9d8fd Author: Chris Foster <chr...@gm...> Date: Thu Sep 15 14:01:34 2011 +1000 Update newcore for some ParamListBuilder changes These changes were accidentally omitted when in a recent refactor of ParamListBuilder. diff --git a/prototypes/newcore/interactive.h b/prototypes/newcore/interactive.h index 45a4081..0e38f41 100644 --- a/prototypes/newcore/interactive.h +++ b/prototypes/newcore/interactive.h @@ -121,9 +121,8 @@ class InteractiveRender : public QWidget Ri::Renderer& ri = renderer.firstFilter(); // Set up the display - Aqsis::Display* disp = &m_display; ri.Display("Ci.tif", "__Display_instance__", "rgb", - ParamListBuilder()("pointer instance", &disp)); + ParamListBuilder()("instance", static_cast<void*>(&m_display))); m_frameTimer = new QTimer(this); m_frameTimer->setInterval(40); connect(m_frameTimer, SIGNAL(timeout()), this, SLOT(nextFrame())); @@ -243,9 +242,8 @@ class InteractiveRender : public QWidget ri.Format(m_imageSize.x, m_imageSize.y, 1); // Viewing transformation - float fov = 90; ri.Projection("perspective", - ParamListBuilder()("float fov", &fov)); + ParamListBuilder()("fov", 90)); ri.Translate(0, 0, m_dist); ri.Rotate(m_theta, 1, 0, 0); ri.Rotate(m_phi, 0, 1, 0); ----------------------------------------------------------------------- Summary of changes: prototypes/newcore/interactive.h | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Paul G. <pgr...@us...> - 2011-09-04 13:53:28
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via cd3167f2e0055550e4af9634830ed2c27b76cb8f (commit) via 18468fbf1ab98707a857539e46463a9b72db866e (commit) from 3c01f899f210f2884334649be5bf08557cad45dc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit cd3167f2e0055550e4af9634830ed2c27b76cb8f Author: Paul Gregory <pgr...@aq...> Date: Sun Sep 4 14:51:05 2011 +0100 Fixes to the inclusion pattern for OpenEXR. * Seems the OpenEXR header files themselves require that both the location of the OpenEXR folder and the OpenEXR folder itself need to be specified in the build options. So all CMake configurations do that, and all our inclusions of the headers follow the pattern #include <OpenEXR/...> diff --git a/include/aqsis/tex/buffers/channelinfo.h b/include/aqsis/tex/buffers/channelinfo.h index 5fdb384..140f6e7 100644 --- a/include/aqsis/tex/buffers/channelinfo.h +++ b/include/aqsis/tex/buffers/channelinfo.h @@ -44,7 +44,7 @@ #include <string> #ifdef USE_OPENEXR -#include <half.h> +#include <OpenEXR/half.h> #endif #include <aqsis/util/enum.h> diff --git a/libs/pointrender/CMakeLists.txt b/libs/pointrender/CMakeLists.txt index 14e9a4e..85a1489 100644 --- a/libs/pointrender/CMakeLists.txt +++ b/libs/pointrender/CMakeLists.txt @@ -3,7 +3,7 @@ project(pointrender) find_package(OpenGL) if(AQSIS_USE_OPENEXR AND QT_FOUND AND OPENGL_FOUND) - include_directories(${AQSIS_OPENEXR_INCLUDE_DIR} ${QT_INCLUDES} + include_directories(${AQSIS_OPENEXR_INCLUDE_DIR} "${AQSIS_OPENEXR_INCLUDE_DIR}/OpenEXR" ${QT_INCLUDES} ${OPENGL_INCLUDE_DIR}) qt4_wrap_cpp(moc_srcs ptview.h interactivecamera.h) diff --git a/libs/shadervm/CMakeLists.txt b/libs/shadervm/CMakeLists.txt index 002de1a..f53f30e 100644 --- a/libs/shadervm/CMakeLists.txt +++ b/libs/shadervm/CMakeLists.txt @@ -1,10 +1,12 @@ project(shadervm) # Check for boost regex. -if(NOT Boost_REGEX_FOUND) - message(FATAL_ERROR "Aqsis shadervm requires boost regex to build") +if(NOT Boost_REGEX_FOUND OR NOT AQSIS_USE_OPENEXR) + message(FATAL_ERROR "Aqsis shadervm requires boost regex and OpenEXR to build") endif() +include_directories(${AQSIS_OPENEXR_INCLUDE_DIR} "${AQSIS_OPENEXR_INCLUDE_DIR}/OpenEXR") + set(shadervm_srcs dsoshadeops.cpp shaderstack.cpp diff --git a/libs/tex/CMakeLists.txt b/libs/tex/CMakeLists.txt index b565dcb..0341e0f 100644 --- a/libs/tex/CMakeLists.txt +++ b/libs/tex/CMakeLists.txt @@ -20,7 +20,7 @@ source_group("Header files" FILES ${tex_hdrs}) set(linklibs ${io_linklibs}) if(AQSIS_USE_OPENEXR) - include_directories(${AQSIS_OPENEXR_INCLUDE_DIR}) + include_directories(${AQSIS_OPENEXR_INCLUDE_DIR} "${AQSIS_OPENEXR_INCLUDE_DIR}/OpenEXR") add_definitions(-DUSE_OPENEXR) list(APPEND linklibs ${AQSIS_OPENEXR_LIBRARIES}) endif() diff --git a/libs/tex/buffers/mixedimagebuffer.cpp b/libs/tex/buffers/mixedimagebuffer.cpp index 8fa275c..dff0199 100644 --- a/libs/tex/buffers/mixedimagebuffer.cpp +++ b/libs/tex/buffers/mixedimagebuffer.cpp @@ -40,7 +40,7 @@ #include <aqsis/tex/buffers/mixedimagebuffer.h> #ifdef USE_OPENEXR -#include <half.h> +#include <OpenEXR/half.h> #endif #include <aqsis/util/exception.h> diff --git a/libs/tex/filtering/itexturesampler.cpp b/libs/tex/filtering/itexturesampler.cpp index be1b152..48b3267 100644 --- a/libs/tex/filtering/itexturesampler.cpp +++ b/libs/tex/filtering/itexturesampler.cpp @@ -38,7 +38,7 @@ #include <aqsis/tex/filtering/itexturesampler.h> #ifdef USE_OPENEXR -# include <half.h> +# include <OpenEXR/half.h> #endif #include "dummytexturesampler.h" diff --git a/libs/tex/io/exrinputfile.cpp b/libs/tex/io/exrinputfile.cpp index 6716352..8c3302d 100644 --- a/libs/tex/io/exrinputfile.cpp +++ b/libs/tex/io/exrinputfile.cpp @@ -41,10 +41,10 @@ #include <algorithm> #include <cctype> -#include <ImfInputFile.h> -#include <ImfChannelList.h> -#include <ImfFrameBuffer.h> -#include <Iex.h> +#include <OpenEXR/ImfInputFile.h> +#include <OpenEXR/ImfChannelList.h> +#include <OpenEXR/ImfFrameBuffer.h> +#include <OpenEXR/Iex.h> #include <aqsis/util/logging.h> #include <aqsis/tex/texexception.h> diff --git a/tools/displays/exr/CMakeLists.txt b/tools/displays/exr/CMakeLists.txt index 3416adb..f1701fc 100644 --- a/tools/displays/exr/CMakeLists.txt +++ b/tools/displays/exr/CMakeLists.txt @@ -1,6 +1,6 @@ include_subproject(dspyutil) -include_directories(${AQSIS_OPENEXR_INCLUDE_DIR}) +include_directories(${AQSIS_OPENEXR_INCLUDE_DIR} "${AQSIS_OPENEXR_INCLUDE_DIR}/OpenEXR") aqsis_add_display(exr d_exr.cpp ${dspyutil_srcs} LINK_LIBRARIES ${AQSIS_OPENEXR_LIBRARIES} ${AQSIS_ZLIB_LIBRARIES}) diff --git a/tools/displays/exr/d_exr.cpp b/tools/displays/exr/d_exr.cpp index 0a2abde..508d100 100644 --- a/tools/displays/exr/d_exr.cpp +++ b/tools/displays/exr/d_exr.cpp @@ -104,21 +104,21 @@ #if AQSIS_SYSTEM_WIN32 && (defined(AQSIS_COMPILER_MSVC6) || defined(AQSIS_COMPILER_MSVC7)) # pragma warning(push,1) #endif -#include <ImfOutputFile.h> -#include <ImfChannelList.h> -#include <ImfIntAttribute.h> -#include <ImfFloatAttribute.h> -#include <ImfMatrixAttribute.h> -#include <ImfStringAttribute.h> -#include <ImfChromaticitiesAttribute.h> -#include <ImfStandardAttributes.h> -#include <ImfCompressionAttribute.h> -#include <ImfLut.h> -#include <ImfArray.h> -#include <ImathFun.h> -#include <Iex.h> -#include <half.h> -#include <halfFunction.h> +#include <OpenEXR/ImfOutputFile.h> +#include <OpenEXR/ImfChannelList.h> +#include <OpenEXR/ImfIntAttribute.h> +#include <OpenEXR/ImfFloatAttribute.h> +#include <OpenEXR/ImfMatrixAttribute.h> +#include <OpenEXR/ImfStringAttribute.h> +#include <OpenEXR/ImfChromaticitiesAttribute.h> +#include <OpenEXR/ImfStandardAttributes.h> +#include <OpenEXR/ImfCompressionAttribute.h> +#include <OpenEXR/ImfLut.h> +#include <OpenEXR/ImfArray.h> +#include <OpenEXR/ImathFun.h> +#include <OpenEXR/Iex.h> +#include <OpenEXR/half.h> +#include <OpenEXR/halfFunction.h> #if AQSIS_SYSTEM_WIN32 && (defined(AQSIS_COMPILER_MSVC6) || defined(AQSIS_COMPILER_MSVC7)) # pragma warning(pop) #endif commit 18468fbf1ab98707a857539e46463a9b72db866e Author: Paul Gregory <pgr...@aq...> Date: Sat Aug 20 21:53:18 2011 +0100 Implement a fix for part of bug #3288739. * When using the normal 'rgbaz' style channel specification, the requested format type wasn't being honored, defaulting to HALF. diff --git a/tools/displays/exr/d_exr.cpp b/tools/displays/exr/d_exr.cpp index 4be02c7..0a2abde 100644 --- a/tools/displays/exr/d_exr.cpp +++ b/tools/displays/exr/d_exr.cpp @@ -676,7 +676,7 @@ extern "C" { SqImageLayerChannel chan; chan.dataOffset = pixelSize; - chan.channel = Channel(HALF); + chan.channel = Channel(pixelType); chan.bufferOffset = 0; // This is filled in by the image when the layer is added. if(!chanName.empty()) chan.channelName = chanName; ----------------------------------------------------------------------- Summary of changes: include/aqsis/tex/buffers/channelinfo.h | 2 +- libs/pointrender/CMakeLists.txt | 2 +- libs/shadervm/CMakeLists.txt | 6 +++- libs/tex/CMakeLists.txt | 2 +- libs/tex/buffers/mixedimagebuffer.cpp | 2 +- libs/tex/filtering/itexturesampler.cpp | 2 +- libs/tex/io/exrinputfile.cpp | 8 +++--- tools/displays/exr/CMakeLists.txt | 2 +- tools/displays/exr/d_exr.cpp | 32 +++++++++++++++--------------- 9 files changed, 30 insertions(+), 28 deletions(-) hooks/post-receive -- Aqsis Renderer |
From: Chris F. <c4...@us...> - 2011-09-01 07:27:26
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Aqsis Renderer". The branch, master has been updated via 3c01f899f210f2884334649be5bf08557cad45dc (commit) from 3c74c1913915ffe831f0c3a7d0e27fa041c9114c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3c01f899f210f2884334649be5bf08557cad45dc Author: Chris Foster <chr...@gm...> Date: Thu Sep 1 17:19:00 2011 +1000 Flush point cloud caches at end of frame This ensures that a frame baking point cloud data may be rendered, followed by a frame which uses that data. The implementation is a bit of a hack, since it relies on the caches being global. However, it's a simple solution for now and the same problem is present in many other areas of the core renderer in any case. Also improve the behaviour when a point cloud file cannot be found: don't crash + do provide a helpful error message! diff --git a/include/aqsis/shadervm/ishaderexecenv.h b/include/aqsis/shadervm/ishaderexecenv.h index 61c65e9..4ac3940 100644 --- a/include/aqsis/shadervm/ishaderexecenv.h +++ b/include/aqsis/shadervm/ishaderexecenv.h @@ -128,6 +128,18 @@ AQSIS_SHADERVM_SHARE extern TqInt gDefLightUses; #define DEFVOIDPARAMVAR DEFVOIDPARAM, int cParams=0, IqShaderData** apParams=0 +/// Clear any global caches held by the shading system. +/// +/// This clears caches such as the cache of open files used by bake3d(), to be +/// ready for the next frame. +/// +/// Note that this is a bit of an awful hack: it assumes that the caches are +/// global, but this doesn't make sense if there's more than one renderer +/// instance active. It should therefore be migrated to a +/// per-renderer-instance ShaderSystem object at some stage. +AQSIS_SHADERVM_SHARE +void clearShaderSystemCaches(); + //---------------------------------------------------------------------- /** \struct IqShaderExecEnv * Interface to shader execution environment. diff --git a/libs/core/api/ri.cpp b/libs/core/api/ri.cpp index 58c3f15..eef0a4a 100644 --- a/libs/core/api/ri.cpp +++ b/libs/core/api/ri.cpp @@ -697,6 +697,9 @@ RtVoid RiCxxCore::WorldEnd() // Remove all cached textures. QGetRenderContext()->textureCache().flush(); + // Clear out point cloud caches, etc. + clearShaderSystemCaches(); + // Delete the world context QGetRenderContext() ->EndWorldModeBlock(); diff --git a/libs/pointrender/pointcontainer.cpp b/libs/pointrender/pointcontainer.cpp index d1431b9..d029b29 100644 --- a/libs/pointrender/pointcontainer.cpp +++ b/libs/pointrender/pointcontainer.cpp @@ -288,8 +288,11 @@ const PointOctree* PointOctreeCache::find(const std::string& fileName) PointArray points; // Convert to octree boost::shared_ptr<PointOctree> tree; - if(loadPointFile(points, fileName)); + if(loadPointFile(points, fileName)) tree.reset(new PointOctree(points)); + else + Aqsis::log() << error << "Point cloud file \"" << fileName + << "\" not found\n"; // Insert into map. If we couldn't load the file, we insert // a null pointer to record the failure. m_cache.insert(MapType::value_type(fileName, tree)); diff --git a/libs/shadervm/shaderexecenv/shadeops_bake3d.cpp b/libs/shadervm/shaderexecenv/shadeops_bake3d.cpp index 252a506..f65f4ee 100644 --- a/libs/shadervm/shaderexecenv/shadeops_bake3d.cpp +++ b/libs/shadervm/shaderexecenv/shadeops_bake3d.cpp @@ -135,8 +135,7 @@ class Bake3dCache ~Bake3dCache() { - for(FileMap::iterator i = m_files.begin(); i != m_files.end(); ++i) - Partio::write(i->first.c_str(), *i->second); + flush(); } /// Find or create a point cloud with the given name. @@ -171,6 +170,13 @@ class Bake3dCache return pointFile; } + /// Flush all files to disk. + void flush() + { + for(FileMap::iterator i = m_files.begin(); i != m_files.end(); ++i) + Partio::write(i->first.c_str(), *i->second); + } + private: typedef std::map<std::string, boost::shared_ptr<Partio::ParticlesDataMutable> > FileMap; FileMap m_files; @@ -180,6 +186,11 @@ class Bake3dCache // TODO: Make non-global static Bake3dCache g_bakeCloudCache; +void flushBake3dCache() +{ + g_bakeCloudCache.flush(); +} + //------------------------------------------------------------------------------ /// Shadeop to bake vertices to point cloud /// diff --git a/libs/shadervm/shaderexecenv/shadeops_illum.cpp b/libs/shadervm/shaderexecenv/shadeops_illum.cpp index 370db34..882eef8 100644 --- a/libs/shadervm/shaderexecenv/shadeops_illum.cpp +++ b/libs/shadervm/shaderexecenv/shadeops_illum.cpp @@ -1085,10 +1085,31 @@ void CqShaderExecEnv::SO_calculatenormal( IqShaderData* p, IqShaderData* Result, // FIXME: It's pretty ugly to have a global cache here! // // Missing cache features: -// * Clear at end of frame // * Ri search paths static PointOctreeCache g_pointOctreeCache; +void clearPointCloudCache() +{ + g_pointOctreeCache.clear(); +} + + +namespace { +/// Store zeros in shader variable, depending on integrator type: +/// OcclusionIntegrator has result type float, whereas RadiosityIntegrator has +/// result type Color. +template<typename T> +void storeZeroResult(IqShaderData* result, int igrid) +{ + result->SetFloat(0.0f,igrid); +} +template<> +void storeZeroResult<RadiosityIntegrator>(IqShaderData* result, int igrid) +{ + result->SetColor(CqColor(0.0f),igrid); +} +} + template<typename IntegratorT> void CqShaderExecEnv::pointCloudIntegrate(IqShaderData* P, IqShaderData* N, @@ -1246,7 +1267,7 @@ void CqShaderExecEnv::pointCloudIntegrate(IqShaderData* P, IqShaderData* N, { if(!varying || RS.Value(igrid)) { - result->SetFloat(0.0f,igrid); + storeZeroResult<IntegratorT>(result, igrid); } } while( ( ++igrid < shadingPointCount() ) && varying); @@ -1254,7 +1275,6 @@ void CqShaderExecEnv::pointCloudIntegrate(IqShaderData* P, IqShaderData* N, } - //---------------------------------------------------------------------- static void storeIntegratedResult(const OcclusionIntegrator& integrator, const V3f& N, float coneAngle, diff --git a/libs/shadervm/shaderexecenv/shaderexecenv.cpp b/libs/shadervm/shaderexecenv/shaderexecenv.cpp index 68ba6f3..9c0e11a 100644 --- a/libs/shadervm/shaderexecenv/shaderexecenv.cpp +++ b/libs/shadervm/shaderexecenv/shaderexecenv.cpp @@ -99,6 +99,12 @@ TqUlong gVariableTokens[ EnvVars_Last ] = CqString::hash( gVariableNames[ 24 ] ), }; +void clearShaderSystemCaches() +{ + flushBake3dCache(); + clearPointCloudCache(); +} + /** \brief Set default shader variables which the renderer needs internally. * diff --git a/libs/shadervm/shaderexecenv/shaderexecenv.h b/libs/shadervm/shaderexecenv/shaderexecenv.h index d1c3337..528eeb2 100644 --- a/libs/shadervm/shaderexecenv/shaderexecenv.h +++ b/libs/shadervm/shaderexecenv/shaderexecenv.h @@ -654,6 +654,14 @@ class AQSIS_SHADERVM_SHARE CqShaderExecEnv : public IqShaderExecEnv, boost::nonc }; +/// Flush any caches of bake3d() data to disk. +void flushBake3dCache(); + +/// Clear static caches of point cloud data ready for next frame +/// +/// TODO: Remove this - it's a bit of a hack! +void clearPointCloudCache(); + //============================================================================== // Implementation details //============================================================================== ----------------------------------------------------------------------- Summary of changes: include/aqsis/shadervm/ishaderexecenv.h | 12 ++++++++++ libs/core/api/ri.cpp | 3 ++ libs/pointrender/pointcontainer.cpp | 5 +++- libs/shadervm/shaderexecenv/shadeops_bake3d.cpp | 15 +++++++++++- libs/shadervm/shaderexecenv/shadeops_illum.cpp | 26 ++++++++++++++++++++-- libs/shadervm/shaderexecenv/shaderexecenv.cpp | 6 +++++ libs/shadervm/shaderexecenv/shaderexecenv.h | 8 +++++++ 7 files changed, 69 insertions(+), 6 deletions(-) hooks/post-receive -- Aqsis Renderer |