diff --git a/doc/best-practices.dox b/doc/best-practices.dox
index 7517541ca..6dba060be 100644
--- a/doc/best-practices.dox
+++ b/doc/best-practices.dox
@@ -57,11 +57,14 @@ information.
As noted in the above link, buffers in NaCl implementation need to be bound
only to one unique target, i.e., Buffer bound to @ref Buffer::Target "Target::Array"
-cannot be later rebound to @ref Buffer::Target "Target::Element". However,
+cannot be later rebound to @ref Buffer::Target "Target::ElementArray". However,
%Magnum by default uses any sufficient target when binding the buffer
internally (e.g. for setting data or copying). To avoid this, set target hint
to desired target, either in constructor or using Buffer::setTargetHint().
+To ease up the development, @ref Mesh checks proper target hint when adding
+vertex and index buffers.
+
@subsection best-practices-powervr PowerVR hardware
- [PowerVR Performance Recommendations](http://www.imgtec.com/powervr/insider/docs/PowerVR.Performance%20Recommendations.1.0.28.External.pdf) [PDF]
diff --git a/src/AbstractShaderProgram.h b/src/AbstractShaderProgram.h
index 05fc4ef07..f2b486ee7 100644
--- a/src/AbstractShaderProgram.h
+++ b/src/AbstractShaderProgram.h
@@ -282,6 +282,9 @@ setUniform() documentation for more information.
To achieve least state changes, set all uniforms in one run -- method chaining
comes in handy.
+
+@todo Compiling and linking more than one shader in parallel, then checking
+ status, should be faster -- https://twitter.com/g_truc/status/352778836657700866
*/
class MAGNUM_EXPORT AbstractShaderProgram {
friend class Context;
diff --git a/src/Mesh.cpp b/src/Mesh.cpp
index 6ab0159d8..04f9b88d6 100644
--- a/src/Mesh.cpp
+++ b/src/Mesh.cpp
@@ -118,6 +118,11 @@ Mesh& Mesh::operator=(Mesh&& other) {
}
Mesh* Mesh::setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type, UnsignedInt start, UnsignedInt end) {
+ #ifdef CORRADE_TARGET_NACL
+ CORRADE_ASSERT(buffer->targetHint() == Buffer::Target::ElementArray,
+ "Mesh::setIndexBuffer(): the buffer has unexpected target hint, expected" << Buffer::Target::ElementArray << "but got" << buffer->targetHint(), this);
+ #endif
+
indexOffset = offset;
indexType = type;
#ifndef MAGNUM_TARGET_GLES2
@@ -235,10 +240,20 @@ void Mesh::destroyImplementationVAO() {
}
void Mesh::attributePointerImplementationDefault(const Attribute& attribute) {
+ #ifdef CORRADE_TARGET_NACL
+ CORRADE_ASSERT(attribute.buffer->targetHint() == Buffer::Target::Array,
+ "Mesh::addVertexBuffer(): the buffer has unexpected target hint, expected" << Buffer::Target::Array << "but got" << attribute.buffer->targetHint(), );
+ #endif
+
attributes.push_back(attribute);
}
void Mesh::attributePointerImplementationVAO(const Attribute& attribute) {
+ #ifdef CORRADE_TARGET_NACL
+ CORRADE_ASSERT(attribute.buffer->targetHint() == Buffer::Target::Array,
+ "Mesh::addVertexBuffer(): the buffer has unexpected target hint, expected" << Buffer::Target::Array << "but got" << attribute.buffer->targetHint(), );
+ #endif
+
bindVAO(vao);
vertexAttribPointer(attribute);
}
diff --git a/src/Platform/CMakeLists.txt b/src/Platform/CMakeLists.txt
index 634197a4a..5ff61f660 100644
--- a/src/Platform/CMakeLists.txt
+++ b/src/Platform/CMakeLists.txt
@@ -84,6 +84,11 @@ if(WITH_WINDOWLESSNACLAPPLICATION)
install(TARGETS MagnumWindowlessNaClApplication DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR})
endif()
+# JavaScript stuff for NaCl
+if(WITH_NACLAPPLICATION OR WITH_WINDOWLESSNACLAPPLICATION)
+ install(FILES NaClApplication.js DESTINATION ${MAGNUM_DATA_INSTALL_DIR})
+endif()
+
# GLX application
if(WITH_GLXAPPLICATION)
set(NEED_ABSTRACTXAPPLICATION 1)
@@ -162,10 +167,11 @@ if(WITH_MAGNUMINFO)
add_executable(magnum-info magnum-info.cpp)
if(UNIX AND NOT CORRADE_TARGET_NACL)
- target_link_libraries(magnum-info Magnum MagnumWindowlessGlxApplication ${X11_LIBRARIES})
+ target_link_libraries(magnum-info MagnumWindowlessGlxApplication ${X11_LIBRARIES})
elseif(CORRADE_TARGET_NACL)
- target_link_libraries(magnum-info Magnum MagnumWindowlessNaClApplication ppapi_cpp ppapi)
+ target_link_libraries(magnum-info MagnumWindowlessNaClApplication ppapi_cpp ppapi)
endif()
+ target_link_libraries(magnum-info Magnum)
install(TARGETS magnum-info DESTINATION ${MAGNUM_BINARY_INSTALL_DIR})
if(CORRADE_TARGET_NACL)
diff --git a/src/Platform/NaClApplication.css b/src/Platform/NaClApplication.css
new file mode 100644
index 000000000..a2abf2c85
--- /dev/null
+++ b/src/Platform/NaClApplication.css
@@ -0,0 +1,51 @@
+body {
+ margin: 0px;
+ padding: 0px;
+ font-family: sans-serif;
+ background-color: #111111;
+ color: #aaaaaa;
+}
+
+h1 {
+ text-align: center;
+ font-size: 20px;
+}
+
+#listener {
+ border-style: solid;
+ border-color: #333333;
+ border-width: 1px;
+ padding: 1px;
+ width: 640px;
+ height: 480px;
+ margin-left: auto;
+ margin-right: auto;
+ margin-top: 20px;
+ margin-bottom: 20px;
+ position: relative;
+}
+
+#module {
+ width: 640px;
+ height: 480px;
+ z-index: 10;
+}
+
+#status {
+ position: absolute;
+ width: 640px;
+ text-align: center;
+ top: 200px;
+ font-size: 30px;
+ font-weight: bold;
+ z-index: 9;
+}
+
+#statusDescription {
+ position: absolute;
+ width: 640px;
+ text-align: center;
+ top: 250px;
+ font-size: 15px;
+ z-index: 9;
+}
diff --git a/src/Platform/NaClApplication.h b/src/Platform/NaClApplication.h
index e1a04d654..75b65d68c 100644
--- a/src/Platform/NaClApplication.h
+++ b/src/Platform/NaClApplication.h
@@ -73,12 +73,53 @@ to simplify porting.
@section NaClApplication-html HTML markup and NMF file
-You need to provide HTML markup containing `<embed>` pointing to `*.nmf`
-file describing the application.
+You need to provide HTML markup for your application. Template one is below,
+you can modify it to your liking. The markup references two files,
+`NaClApplication.js` and `NaClApplication.css`, both are in `Platform/`
+directory in the source tree and are also installed into `share/magnum/` inside
+your NaCl toolchain.
+@code
+
+
+
+Magnum NaCl Application
+
+
+
+
Magnum NaCl Application
+
+
+
+
Initialization...
+
+
+
+
+@endcode
+
+You can modify all the files to your liking, but the HTML file must contain at
+least the `<embed>` enclosed in listener `<div>`. The JavaScript
+file contains event listeners which print loading status on the page. The
+status displayed in the remaining two `<div>`s, if they are available.
+The CSS file contains rudimentary style to avoid eye bleeding.
+
+The `<embed>` file references NMF file which you need to provide too. If
+you target @ref CORRADE_TARGET_NACL_NEWLIB_ "newlib", the file is pretty
+simple, for example:
+@code
+{
+ "program": {
+ "x86-32": {"url": "application-x86-32.nexe"},
+ "x86-64": {"url": "application-x86-64.nexe"}
+ }
+}
+@endcode
-@todoc Document this better, add "bootstrap" examples
+If you target @ref CORRADE_TARGET_NACL_GLIBC_ "glibc", you need to specify also
+all additional dependencies. See [Native Client](https://developers.google.com/native-client/)
+documentation for more information.
-@subsection NaClApplication-html-console Redirecting output to Chrome's JavaScript console
+@section NaClApplication-console Redirecting output to Chrome's JavaScript console
The application redirects @ref Corrade::Utility::Debug "Debug",
@ref Corrade::Utility::Warning "Warning" and @ref Corrade::Utility::Error "Error"
diff --git a/src/Platform/NaClApplication.js b/src/Platform/NaClApplication.js
new file mode 100644
index 000000000..50bbe023a
--- /dev/null
+++ b/src/Platform/NaClApplication.js
@@ -0,0 +1,43 @@
+function setStatus(message) {
+ var status = document.getElementById('status');
+ if(status) status.innerHTML = message;
+}
+
+function setStatusDescription(message) {
+ var statusDescription = document.getElementById('statusDescription');
+ if(statusDescription) statusDescription.innerHTML = message;
+}
+
+var listener = document.getElementById('listener');
+
+listener.addEventListener('loadstart', function() {
+ setStatus('Loading...');
+}, true);
+
+listener.addEventListener('progress', function(event) {
+ setStatus('Downloading...');
+
+ /* Show progress */
+ if(event.lengthComputable && event.total > 0)
+ setStatusDescription(Math.round(event.loaded*100/event.total) + '% of '
+ + Math.round(event.total/1024) + ' kB');
+
+ /* Unknown total size */
+ else setStatusDescription(Math.round(event.loaded/1024) + ' kB');
+
+}, true);
+
+listener.addEventListener('error', function() {
+ setStatus('Loading failed');
+ setStatusDescription(document.getElementById('module').lastError + ' Check JavaScript console for more information.');
+}, true);
+
+listener.addEventListener('abort', function() {
+ setStatus('Loading aborted');
+ setStatusDescription('');
+}, true);
+
+listener.addEventListener('load', function() {
+ setStatus('');
+ setStatusDescription('');
+}, true);
diff --git a/src/Platform/WindowlessNaClApplication.h b/src/Platform/WindowlessNaClApplication.h
index d0f4ebb19..54de3ea05 100644
--- a/src/Platform/WindowlessNaClApplication.h
+++ b/src/Platform/WindowlessNaClApplication.h
@@ -71,11 +71,12 @@ If no other application header is included this class is also aliased to
@section WindowlessNaClApplication-html HTML markup and NMF file
You need to provide HTML markup containing `<embed>` pointing to `*.nmf`
-file describing the application.
+file describing the application. See @ref NaClApplication for more information.
+You may want to hide the `<embed>` (for example using CSS
+`visibility: hidden;`), as it probably won't display anything to default
+framebuffer.
-@todoc Document this better, add "bootstrap" examples
-
-@subsection WindowlessNaClApplication-html-console Redirecting output to Chrome's JavaScript console
+@section WindowlessNaClApplication-console Redirecting output to Chrome's JavaScript console
The application redirects @ref Corrade::Utility::Debug "Debug",
@ref Corrade::Utility::Warning "Warning" and @ref Corrade::Utility::Error "Error"
diff --git a/src/Platform/magnum-info-nacl.html b/src/Platform/magnum-info-nacl.html
index f12bcf996..4a3af2251 100644
--- a/src/Platform/magnum-info-nacl.html
+++ b/src/Platform/magnum-info-nacl.html
@@ -2,37 +2,10 @@
Magnum Info
+
-
+
Magnum Info
+
Initialization...
+
diff --git a/src/SceneGraph/AbstractFeature.h b/src/SceneGraph/AbstractFeature.h
index 3cd00f42b..343b9b6bc 100644
--- a/src/SceneGraph/AbstractFeature.h
+++ b/src/SceneGraph/AbstractFeature.h
@@ -143,8 +143,8 @@ class TransformingFeature: public SceneGraph::AbstractFeature3D {
If we take for example @ref Object "Object", it is
derived from @ref AbstractBasicObject "AbstractObject3D" and
@ref BasicMatrixTransformation3D "MatrixTransformation3D", which is derived
-from @ref BasicAbstractTranslationRotationScaling3D "AbstractTranslationRotationScaling3D",
-which is derived from @ref BasicAbstractTranslationRotation3D "AbstractTranslationRotation3D",
+from @ref AbstractBasicTranslationRotationScaling3D "AbstractTranslationRotationScaling3D",
+which is derived from @ref AbstractBasicTranslationRotation3D "AbstractTranslationRotation3D",
which is automatically extracted from the pointer in our constructor.
@section AbstractFeature-explicit-specializations Explicit template specializations
diff --git a/src/SceneGraph/MatrixTransformation2D.h b/src/SceneGraph/MatrixTransformation2D.h
index 72f266811..0eaaff628 100644
--- a/src/SceneGraph/MatrixTransformation2D.h
+++ b/src/SceneGraph/MatrixTransformation2D.h
@@ -38,7 +38,7 @@ namespace Magnum { namespace SceneGraph {
@brief Two-dimensional transformation implemented using matrices
Uses Math::Matrix3 as underlying type.
-@see @ref MatrixTransformation2D, @ref scenegraph, @ref RigidBasicMatrixTransformation2D, @ref BasicMatrixTransformation3D
+@see @ref MatrixTransformation2D, @ref scenegraph, @ref BasicRigidMatrixTransformation2D, @ref BasicMatrixTransformation3D
*/
template class BasicMatrixTransformation2D: public AbstractBasicTranslationRotationScaling2D {
public:
diff --git a/src/SceneGraph/Object.h b/src/SceneGraph/Object.h
index 51c6c0658..362e31d8f 100644
--- a/src/SceneGraph/Object.h
+++ b/src/SceneGraph/Object.h
@@ -129,7 +129,7 @@ template class MAGNUM_SCENEGRAPH_EXPORT Object: public Abs
* See @ref scenegraph-hierarchy for more information.
*/
- /** @copydoc AbstractObject::scene() */
+ /** @copydoc AbstractBasicObject::scene() */
Scene* scene();
const Scene* scene() const; /**< @overload */
@@ -271,13 +271,13 @@ template class MAGNUM_SCENEGRAPH_EXPORT Object: public Abs
/* `objects` passed by copy intentionally (to avoid copy internally) */
static void setClean(std::vector