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

Reply via email to