Hi,
I'm trying to port my opengl code to the osg tessellation shader
implementation. Sadly I can't get it to work.
It is basicly a quad grid that should be tessellated dynamicaly as a base for a
heightfeld. So far I can't see anything at all. (the cube isn't affekted by the
shader) . So I broke the shader down to the most basic think but sill nothing.
My gues is something is going wrong with the per vertex attribute binding or
the uniform binding.
cpp file
Code:
#include <iostream>
#include <osg/PolygonMode>
#include <osg/Image>
#include <osg/Node>
#include <osg/Group>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Program>
#include <osg/ShapeDrawable>
#include <osg/Shader>
#include <osg/Texture2D>
#include <osg/Texture2DArray>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/PositionAttitudeTransform>
#include <osgGA/TrackballManipulator>
#include "MyKeyboardEventHandler.h"
osg::Program* createShader()
{
osg::Program* prog = new osg::Program;
prog->setName("heightMapShader");
// VERTEX SHADER
osg::Shader* vertShader =
osgDB::readShaderFile("./src/shaders/height_map.vert");
if (!vertShader){
osg::notify(osg::FATAL) << " can't read vertex shader!" <<
std::endl;
std::exit(-1);
} else {
vertShader->setType(osg::Shader::VERTEX);
prog->addShader( vertShader );
}
//TESSELLATION CONTROL SHADER
osg::Shader* tessControlShader =
osgDB::readShaderFile("./src/shaders/height_map.tesscon");
if (!tessControlShader){
osg::notify(osg::FATAL) << " can't read tessellation control
shader!" << std::endl;
std::exit(-1);
} else {
tessControlShader->setType(osg::Shader::TESSCONTROL);
prog->addShader( tessControlShader );
}
// TESSELLATION EVALUATION SHADER
osg::Shader* tessEvalShader =
osgDB::readShaderFile("./src/shaders/height_map.tesseva");
if (!tessEvalShader){
osg::notify(osg::FATAL) << " can't read tessellation evaluation
shader!" << std::endl;
std::exit(-1);
} else {
tessEvalShader->setType(osg::Shader::TESSEVALUATION);
prog->addShader( tessEvalShader );
}
prog->setParameter( GL_PATCH_VERTICES, 4);
// GEOMETRY SHADER
osg::Shader* geomShader =
osgDB::readShaderFile("./src/shaders/height_map.geom");
if (!geomShader){
osg::notify(osg::FATAL) << " can't read geometry shader!" <<
std::endl;
std::exit(-1);
} else {
geomShader->setType(osg::Shader::GEOMETRY);
prog->addShader( geomShader );
}
prog->setParameter( GL_GEOMETRY_VERTICES_OUT_EXT, 3 );
prog->setParameter( GL_GEOMETRY_INPUT_TYPE_EXT, GL_TRIANGLES );
prog->setParameter( GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_TRIANGLE_STRIP );
// FRAGMENT SHADER
osg::Shader* fragShader =
osgDB::readShaderFile("./src/shaders/height_map.frag");
if (!fragShader){
osg::notify(osg::FATAL) << " can't read fragment shader!" <<
std::endl;
std::exit(-1);
} else {
fragShader->setType(osg::Shader::FRAGMENT);
prog->addShader( fragShader );
}
return prog;
}
osg::Geometry* createHeightField(int quadsInX = 10, int quadsInZ = 10,float
quadSize = 1.0)
{
int positionAttributeID = 1, texCoordsAttributeID = 4;
osg::Geometry* heightFieldGeometry = new osg::Geometry();
//Create verticies from left to right and front to back.
osg::Vec3Array* heightFieldPositions = new osg::Vec3Array;
osg::Vec2Array* heightFieldTexCords = new osg::Vec2Array;
// create positions
int index = 0;
for (int z = 0; z <= quadsInZ; z++){
float vCord = z / quadsInZ;
for (int x = 0; x <= quadsInX; x ++){
float uCord = x / quadsInX;
heightFieldPositions->push_back( osg::Vec3( quadSize * x,
quadSize * z, 0) );
// osg::notify() << "heightFieldTexCords->push_back(" << xCord <<
"," << yCord << ")" << std::endl;
heightFieldTexCords->push_back( osg::Vec2f( uCord, vCord ) );
index++;
}
}
//Associate this set of vertices with the geometry associated with the
//geode we added to the scene.
heightFieldGeometry->setVertexArray(heightFieldPositions);
heightFieldGeometry->setVertexAttribArray(positionAttributeID,
heightFieldPositions);
heightFieldGeometry->setVertexAttribArray(texCoordsAttributeID,
heightFieldTexCords);
int textureUnit = 0;
heightFieldGeometry->setTexCoordArray(textureUnit, heightFieldTexCords);
osg::DrawElementsUInt* hightField = new
osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
// create height field grid from left to right and front to back.
for (int z = 0; z < quadsInZ; z++){
for (int x = 0; x< quadsInX; x ++){
int width = quadsInX + 1;
int vertexIndex = (z*width) + x;
hightField->push_back(vertexIndex); // ancer point
hightField->push_back(vertexIndex+1); //right neighbor
hightField->push_back(vertexIndex+width+1); //top
neighbor
hightField->push_back(vertexIndex+width); //top right
neighbor
}
}
heightFieldGeometry->addPrimitiveSet(new osg::DrawArrays( GL_PATCHES, 0,
heightFieldPositions->size()));
osg::StateSet* ss = heightFieldGeometry->getOrCreateStateSet();
osg::Program* program = createShader();
program->addBindAttribLocation("Position", positionAttributeID);
program->addBindAttribLocation("TexCoord", texCoordsAttributeID);
ss->setAttribute(program, osg::StateAttribute::ON);
return heightFieldGeometry;
}
int main()
{
osg::setNotifyLevel(osg::INFO);
// setting up viewer
osgViewer::Viewer viewer;
viewer.setUpViewInWindow(0,0,1600,1000,0);
// defining the scene
osg::Group* root = new osg::Group();
osg::Box* unitCube = new osg::Box( osg::Vec3(0,0,0), 1.0f);
osg::ShapeDrawable* unitCubeDrawable = new osg::ShapeDrawable(unitCube);
osg::Geode* basicShapesGeode = new osg::Geode();
basicShapesGeode->addDrawable(unitCubeDrawable);
osg::Geode* heightFieldGeode = new osg::Geode();
osg::Drawable * heightField = createHeightField(10, 10);
heightFieldGeode->addDrawable(heightField);
osg::StateSet* sset = heightField->getOrCreateStateSet();
root->addChild(heightFieldGeode);
osg::Matrixd worldMatrix = heightField->getWorldMatrices().front();
osg::Matrixd projectionMatrix =
viewer.getCamera()->getProjectionMatrix();
sset->addUniform( new osg::Uniform( "Modelview", worldMatrix) );
sset->addUniform( new osg::Uniform( "Projection", projectionMatrix) );
// Add the goede to the scene:
root->addChild(basicShapesGeode);
viewer.setSceneData( root );
// input handling
MyKeyboardEventHandler* kbeh = new MyKeyboardEventHandler();
kbeh->setStateSetForWireframeing(root->getOrCreateStateSet());
viewer.addEventHandler(kbeh);
viewer.setCameraManipulator(new osgGA::TrackballManipulator());
viewer.realize();
while( !viewer.done() )
{
viewer.frame();
}
return 0;
}
shaders
Code:
#version 400
in vec4 Position;
in vec2 TexCoord;
out vec2 vTexCoord;
out vec3 vPosition;
void main()
{
vPosition = Position.xyz;
vTexCoord = TexCoord;
}
#version 400
#tesselation control
layout(vertices = 4) out;
in vec3 vPosition[];
in vec2 vTexCoord[];
out vec3 tcPosition[];
out vec2 tcTexCoord[];
#define ID gl_InvocationID
void main()
{
tcPosition[ID] = vPosition[ID];
tcTexCoord[ID] = vTexCoord[ID];
if(ID == 0) {
float TessLevel = 2;
//tcTessFactor[ID] = TessLevel/MaxTessLevel;
//TessLevel = min(MaxTessLevel, TessLevel); // don't get to
extreme
//TessLevel = max(TessLevel, 1);
// needs to be at least 1
gl_TessLevelInner[0] = TessLevel;
gl_TessLevelInner[1] = TessLevel;
gl_TessLevelOuter[0] = TessLevel;
gl_TessLevelOuter[1] = TessLevel;
gl_TessLevelOuter[2] = TessLevel;
gl_TessLevelOuter[3] = TessLevel;
}
}
#version 400
#tessellation evaluation
layout(quads) in;
in vec3 tcPosition[];
out vec3 tePosition;
uniform mat4 Projection;
uniform mat4 Modelview;
void main()
{
// linear interpolation of the coordinates
float u = gl_TessCoord.x, v = gl_TessCoord.y;
vec3 XDirection = ( tcPosition[1] - tcPosition[0] );
vec3 YDirection = ( tcPosition[3] - tcPosition[0] );
vec3 a = XDirection * u;
vec3 b = YDirection * v;
tePosition = tcPosition[0] + a + b;
gl_Position = Projection * Modelview * vec4(tePosition, 1);
}
#version 400
#geometry
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
in vec3 tePosition[3];
void main()
{
vec3 A = tePosition[2] - tePosition[0];
vec3 B = tePosition[1] - tePosition[0];
gl_Position = gl_in[0].gl_Position;
EmitVertex();
gl_Position = gl_in[1].gl_Position;
EmitVertex();
gl_Position = gl_in[2].gl_Position;
EmitVertex();
EndPrimitive();
}
#version 400
#fragment
out vec4 FragColor;
void main()
{
FragColor = vec4(1);
}
Thank you!
Cheers,
Waldemar
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=34095#34095
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org