|
|
|
|
@ -31,6 +31,7 @@
|
|
|
|
|
#include "Magnum/Mesh.h" |
|
|
|
|
#include "Magnum/PrimitiveQuery.h" |
|
|
|
|
#include "Magnum/Shader.h" |
|
|
|
|
#include "Magnum/TransformFeedback.h" |
|
|
|
|
#include "Magnum/Math/Vector2.h" |
|
|
|
|
#include "Magnum/Test/AbstractOpenGLTester.h" |
|
|
|
|
|
|
|
|
|
@ -40,41 +41,45 @@ class PrimitiveQueryGLTest: public AbstractOpenGLTester {
|
|
|
|
|
public: |
|
|
|
|
explicit PrimitiveQueryGLTest(); |
|
|
|
|
|
|
|
|
|
void query(); |
|
|
|
|
#ifndef MAGNUM_TARGET_GLES |
|
|
|
|
void primitivesGenerated(); |
|
|
|
|
#endif |
|
|
|
|
void transformFeedbackPrimitivesWritten(); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
PrimitiveQueryGLTest::PrimitiveQueryGLTest() { |
|
|
|
|
addTests({&PrimitiveQueryGLTest::query}); |
|
|
|
|
addTests({ |
|
|
|
|
#ifndef MAGNUM_TARGET_GLES |
|
|
|
|
&PrimitiveQueryGLTest::primitivesGenerated, |
|
|
|
|
#endif |
|
|
|
|
&PrimitiveQueryGLTest::transformFeedbackPrimitivesWritten}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void PrimitiveQueryGLTest::query() { |
|
|
|
|
#ifndef MAGNUM_TARGET_GLES |
|
|
|
|
#ifndef MAGNUM_TARGET_GLES |
|
|
|
|
void PrimitiveQueryGLTest::primitivesGenerated() { |
|
|
|
|
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::transform_feedback>()) |
|
|
|
|
CORRADE_SKIP(Extensions::GL::EXT::transform_feedback::string() + std::string(" is not available.")); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES |
|
|
|
|
class MyShader: public AbstractShaderProgram { |
|
|
|
|
public: |
|
|
|
|
typedef Attribute<0, Vector2> Position; |
|
|
|
|
|
|
|
|
|
explicit MyShader() { |
|
|
|
|
Shader vert(Version::GL210, Shader::Type::Vertex); |
|
|
|
|
|
|
|
|
|
CORRADE_INTERNAL_ASSERT_OUTPUT(vert.addSource( |
|
|
|
|
"attribute lowp vec4 position;\n" |
|
|
|
|
"void main() {\n" |
|
|
|
|
" gl_Position = position;\n" |
|
|
|
|
"}\n").compile()); |
|
|
|
|
|
|
|
|
|
attachShader(vert); |
|
|
|
|
CORRADE_INTERNAL_ASSERT_OUTPUT(link()); |
|
|
|
|
} |
|
|
|
|
struct MyShader: AbstractShaderProgram { |
|
|
|
|
typedef Attribute<0, Vector2> Position; |
|
|
|
|
|
|
|
|
|
explicit MyShader() { |
|
|
|
|
Shader vert(Version::GL210, Shader::Type::Vertex); |
|
|
|
|
|
|
|
|
|
CORRADE_INTERNAL_ASSERT_OUTPUT(vert.addSource( |
|
|
|
|
"attribute lowp vec4 position;\n" |
|
|
|
|
"void main() {\n" |
|
|
|
|
" gl_Position = position;\n" |
|
|
|
|
"}\n").compile()); |
|
|
|
|
|
|
|
|
|
attachShader(vert); |
|
|
|
|
bindAttributeLocation(Position::Location, "position"); |
|
|
|
|
CORRADE_INTERNAL_ASSERT_OUTPUT(link()); |
|
|
|
|
} |
|
|
|
|
} shader; |
|
|
|
|
|
|
|
|
|
constexpr Vector2 data[9]; |
|
|
|
|
Buffer vertices; |
|
|
|
|
vertices.setData(data, BufferUsage::StaticDraw); |
|
|
|
|
vertices.setData({nullptr, 9*sizeof(Vector2)}, BufferUsage::StaticDraw); |
|
|
|
|
|
|
|
|
|
Mesh mesh; |
|
|
|
|
mesh.setPrimitive(MeshPrimitive::Triangles) |
|
|
|
|
@ -98,9 +103,69 @@ void PrimitiveQueryGLTest::query() {
|
|
|
|
|
CORRADE_VERIFY(!availableBefore); |
|
|
|
|
CORRADE_VERIFY(availableAfter); |
|
|
|
|
CORRADE_COMPARE(count, 3); |
|
|
|
|
#else |
|
|
|
|
CORRADE_SKIP("Not implemented in OpenGL ES 3.0 yet."); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
void PrimitiveQueryGLTest::transformFeedbackPrimitivesWritten() { |
|
|
|
|
#ifndef MAGNUM_TARGET_GLES |
|
|
|
|
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::transform_feedback2>()) |
|
|
|
|
CORRADE_SKIP(Extensions::GL::ARB::transform_feedback2::string() + std::string(" is not available.")); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
struct MyShader: AbstractShaderProgram { |
|
|
|
|
explicit MyShader() { |
|
|
|
|
#ifndef MAGNUM_TARGET_GLES |
|
|
|
|
Shader vert(Version::GL300, Shader::Type::Vertex); |
|
|
|
|
#else |
|
|
|
|
Shader vert(Version::GLES300, Shader::Type::Vertex); |
|
|
|
|
Shader frag(Version::GLES300, Shader::Type::Fragment); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
CORRADE_INTERNAL_ASSERT_OUTPUT(vert.addSource( |
|
|
|
|
"out mediump vec2 outputData;\n" |
|
|
|
|
"void main() {\n" |
|
|
|
|
" outputData = vec2(1.0, -1.0);\n" |
|
|
|
|
"}\n").compile()); |
|
|
|
|
#ifndef MAGNUM_TARGET_GLES |
|
|
|
|
attachShader(vert); |
|
|
|
|
#else |
|
|
|
|
/* ES for some reason needs both vertex and fragment shader */ |
|
|
|
|
CORRADE_INTERNAL_ASSERT_OUTPUT(frag.addSource("void main() {}\n").compile()); |
|
|
|
|
attachShaders({vert, frag}); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
setTransformFeedbackOutputs({"outputData"}, TransformFeedbackBufferMode::SeparateAttributes); |
|
|
|
|
CORRADE_INTERNAL_ASSERT_OUTPUT(link()); |
|
|
|
|
} |
|
|
|
|
} shader; |
|
|
|
|
|
|
|
|
|
Buffer output; |
|
|
|
|
output.setData({nullptr, 18*sizeof(Vector2)}, BufferUsage::StaticDraw); |
|
|
|
|
|
|
|
|
|
Mesh mesh; |
|
|
|
|
mesh.setPrimitive(MeshPrimitive::Triangles) |
|
|
|
|
.setCount(9); |
|
|
|
|
|
|
|
|
|
MAGNUM_VERIFY_NO_ERROR(); |
|
|
|
|
|
|
|
|
|
TransformFeedback feedback; |
|
|
|
|
feedback.attachBuffer(0, output); |
|
|
|
|
|
|
|
|
|
PrimitiveQuery q{PrimitiveQuery::Target::TransformFeedbackPrimitivesWritten}; |
|
|
|
|
q.begin(); |
|
|
|
|
|
|
|
|
|
Renderer::enable(Renderer::Feature::RasterizerDiscard); |
|
|
|
|
|
|
|
|
|
mesh.draw(shader); /* Draw once without XFB (shouldn't be counted) */ |
|
|
|
|
feedback.begin(shader, TransformFeedback::PrimitiveMode::Triangles); |
|
|
|
|
mesh.draw(shader); |
|
|
|
|
feedback.end(); |
|
|
|
|
|
|
|
|
|
q.end(); |
|
|
|
|
const UnsignedInt count = q.result<UnsignedInt>(); |
|
|
|
|
|
|
|
|
|
MAGNUM_VERIFY_NO_ERROR(); |
|
|
|
|
CORRADE_COMPARE(count, 3); /* Three triangles (9 vertices) */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
}} |
|
|
|
|
|