Hi,

In order to use modern shaders (without built-in OpenGL
uniforms/attributes) it is necessary
call State::setUseModelViewAndProjectionUniforms and
State::setUseVertexAttributeAliasing. This provides a bridge to the old
fixed-function approach, using a well defined set of names for sending the
respective values to the shaders. Therefore, it is possible to seamlessly
use existing OSG classes (Transformations, Geometries etc.).

However, my question is the following: Does
State::setUseVertexAttributeAliasing also require to enable VBOs via
Geometry::setUseVertexBufferObjects? In my attached example, failing to do
so produces a warning and the object is not drawn:

Warning: detected OpenGL error 'invalid framebuffer operation' at After
Renderer::compile

Is it really necessary to manually enable VBOs for each geometry that is
rendered using such a shader? In particular, what about 3d models that are
imported with osgDB? What would be an elegant way to enable VBOs for all
geometries?

Cheers,
Peter
#if defined(_DEBUG)
#pragma comment(linker, "/SUBSYSTEM:\"console\"")
#else
#pragma comment(linker, "/SUBSYSTEM:\"windows\" /ENTRY:\"mainCRTStartup\"")
#endif

#if defined(_DEBUG)
#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgGAd.lib")
#pragma comment(lib, "osgViewerd.lib")
#else
#pragma comment(lib, "osg.lib")
#pragma comment(lib, "osgGA.lib")
#pragma comment(lib, "osgViewer.lib")
#endif

#pragma warning(push)
#pragma warning(disable: 4250)

#include <osg/Node>
#include <osg/Program>
#include <osgGA/TrackballManipulator>
#include <osgViewer/Viewer>

#pragma warning(pop)

// Rawish string literals (Hack until MSVC gets better C++11 support...)
// Consecutive whitespace characters will be replaced by single space.
#define R(...) #__VA_ARGS__

const int windowWidth = 800, windowHeight = 600;

const std::string vertSource = R(
#version 400\n

uniform mat4 osg_ModelViewProjectionMatrix;
uniform mat3 osg_NormalMatrix;

in vec3 osg_Vertex;
in vec3 osg_Normal;
in vec4 osg_MultiTexCoord0;

out vec2 texCoord;

void main()
{
	gl_Position = osg_ModelViewProjectionMatrix * vec4(osg_Vertex, 1.0);

	texCoord = osg_MultiTexCoord0.st;
});

const std::string fragSource = R(
#version 400\n

in vec2 texCoord;

out vec4 fragData;

void main()
{
	fragData = vec4(texCoord.s, texCoord.t, 0.0, 1.0);
});

osg::Geometry* createQuad(const osg::Vec2& size)
{
	osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;

	const float w = size.x()/2.0f;
	const float h = size.y()/2.0f;

	osg::Vec3Array* vertices = new osg::Vec3Array;
	vertices->push_back(osg::Vec3(-w, -h, 0.0f));
	vertices->push_back(osg::Vec3(+w, -h, 0.0f));
	vertices->push_back(osg::Vec3(-w, +h, 0.0f));
	vertices->push_back(osg::Vec3(+w, +h, 0.0f));
	
	osg::Vec3Array* normals = new osg::Vec3Array;
	normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
	normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
	normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
	normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));

	osg::Vec4Array* texCoords = new osg::Vec4Array;
	texCoords->push_back(osg::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
	texCoords->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 0.0f));
	texCoords->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 0.0f));
	texCoords->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 0.0f));

	geometry->setVertexArray(vertices);

	geometry->setNormalArray(normals);
	geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);

	geometry->setTexCoordArray(0, texCoords);

	geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, 0, vertices->size()));
	//geometry->setUseDisplayList(false);
	geometry->setUseVertexBufferObjects(true);

	return geometry.release();
}

int main(int argc, char** argv)
{
	//osg::setNotifyLevel(osg::DEBUG_INFO);

	unsigned int screenWidth = 0, screenHeight = 0;

	auto wsi = osg::GraphicsContext::getWindowingSystemInterface(); 
	wsi->getScreenResolution(0, screenWidth, screenHeight);

	osg::ref_ptr<osg::Group> root = new osg::Group;

	osg::ref_ptr<osg::Geode> geode =  new osg::Geode;
	geode->addDrawable(createQuad(osg::Vec2(1.0f, 1.0f)));

	root->addChild(geode.get());

	osg::ref_ptr<osg::Program> program = new osg::Program;
	program->addShader(new osg::Shader(osg::Shader::VERTEX, vertSource));
	program->addShader(new osg::Shader(osg::Shader::FRAGMENT, fragSource));

	osg::StateSet* stateSet = geode->getOrCreateStateSet();
	stateSet->setAttributeAndModes(program.get(), osg::StateAttribute::ON);

	osgViewer::Viewer viewer;
	viewer.setCameraManipulator(new osgGA::TrackballManipulator);
	viewer.setSceneData(root.get());
	viewer.setUpViewInWindow((screenWidth-windowWidth)/2, (screenHeight-windowHeight)/2, windowWidth, windowHeight);
	viewer.realize();

	osg::State* state = viewer.getCamera()->getGraphicsContext()->getState();
	state->setUseModelViewAndProjectionUniforms(true);
	state->setUseVertexAttributeAliasing(true);

	return viewer.run();
}
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to