Re: [osg-users] Drawing lines using OpenGL ES 2.0
Hi, you are outputting the position as color, that's why you see black (because these have negative coordinate values) and the three values. Just set an arbitrary fixed color value in the frag-shader to see anything. But if you need to see colors, then you need to define your own vertex attribute for passing in colors. But my advice is that you should first get used to writing very basic shaders in opengl 3.0 core profile mode. OpenGL ES 2.0 is similar in the sense they do not support fixed function pipeline. You need to learn the basics first. -deniz -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=57108#57108 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Drawing lines using OpenGL ES 2.0
Actually I solved it... one of the problems was that the number I was using for the attribute was too big (or reserved). I am forced to use OpenGL ES 2.0 because I develop on iOS platform! Thank you anyway for your advice. Cheers, John This is the working code Code: #define BARYCENTRIC_ATTR_UNIT 11 void OSGGraphicsUtils::setBarycentricCoordinates(osg::Node * object, osg::Program *shaderProgram) { GeodeFinder myGeodeFinder; std::vector osg::Geode * listOfGeodes; object-accept(myGeodeFinder); listOfGeodes = myGeodeFinder.getNodeList(); std::cout there are listOfGeodes.size() geodes std::endl; for (int j = 0; j listOfGeodes.size() ; j++) { //play with the Geode here std::cout Geode number j std::endl; //get the current geode osg::Geode* currentGeode = listOfGeodes.at(j); if (currentGeode != NULL) { std::cout number of drawables in geode is currentGeode-getNumDrawables() std::endl; for (int i = 0; i currentGeode-getNumDrawables(); i++) { std::cout current geode class is currentGeode-getDrawable(i)-className() std::endl; std::cout inside cycle i std::endl; osg::Geometry *cubeGeometry = currentGeode-getDrawable(i)-asGeometry(); if (!cubeGeometry) continue; int numAttribs = cubeGeometry-getVertexArray()-getNumElements(); std::cout number of vertices is numAttribsstd::endl; osg::ref_ptr osg::Vec3Array cubeVertexVector; if (! strcmp (cubeGeometry-getVertexArray()-className(), Vec3Array)) { cubeVertexVector = (osg::Vec3Array *) cubeGeometry-getVertexArray(); } else { //handle the error however you want -- here all I do is print a warning and bail out. std::cerr Unexpected VertexArray className.\n std::endl; return; } osg::ref_ptrosg::Vec3Array array = new osg::Vec3Array; //add this to declaration section: std::map int, int vertexMap; osg::ref_ptr osg::PrimitiveSet nextPrimitiveSet; // ... // int k = 0; for (i = 0; i cubeGeometry-getNumPrimitiveSets(); i++) { nextPrimitiveSet = cubeGeometry-getPrimitiveSet(i); //cout PrimitiveSet # i has Mode: nextPrimitiveSet-getMode() endl; //cout \tVertex Indices: endl; for (j = 0; j nextPrimitiveSet-getNumIndices(); j++) { if(vertexMap.find(nextPrimitiveSet-index(j)) == vertexMap.end()) { if (k==3) k = 0; //cout \t nextPrimitiveSet-index(j) endl; vertexMap[nextPrimitiveSet-index(j)] = k; k++; } else { k = vertexMap[nextPrimitiveSet-index(j)] + 1; } } } for (int i = 0; i numAttribs; i++) { int j = vertexMap[i]; if (j==0) { array-push_back(osg::Vec3f(1.0f,0.0f,0.0f)); } else if (j==1) { array-push_back(osg::Vec3f(0.0f,1.0f,0.0f)); } else if (j==2) { array-push_back(osg::Vec3f(0.0f,0.0f,1.0f)); } //std::cout Vertex # i : ( cubeVertexVector-getName()): ( nextVertex[0] , nextVertex[1] , nextVertex[2] )\n; } std::cout Array size is array-getNumElements() std::endl; if( !cubeGeometry-getVertexAttribArray( BARYCENTRIC_ATTR_UNIT ) ) { //cubeGeometry-setVertexAttribData(31, osg::Geometry::ArrayData(array,osg::Geometry::BIND_PER_VERTEX, GL_FALSE ) ); std::cout setting barycentric attr unit array of size array-getNumElements() std::endl; cubeGeometry-setVertexAttribArray(BARYCENTRIC_ATTR_UNIT, array.get());
Re: [osg-users] Drawing lines using OpenGL ES 2.0
I want to add that this is the fragment shader I used for drawing the wireframe model Code: precision highp float; varying vec3 vBC; #extension GL_OES_standard_derivatives : enable float edgeFactor(){ vec3 d = fwidth(vBC); vec3 a3 = smoothstep(vec3(0.0), d*1.0, vBC); return min(min(a3.x, a3.y), a3.z); } void main (void) { gl_FragColor = vec4(0.0, 0.0, 0.0, (1.0-edgeFactor())*1.0); } Special thanks to this blog for the fragment shader and the idea of using barycentric coordinates! http://codeflow.org/entries/2012/aug/02/easy-wireframe-display-with-barycentric-coordinates/ -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=57117#57117 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Drawing lines using OpenGL ES 2.0
Hi, for learning basic shader programming you do not have to constrain yourself to opengl es 2.0. It is sufficient to do the same basic stuff with OGL 3.0 in order at least to understand the difference between assigning a coordinate value and a color value as the final fragment value. I wanted to help you with that. This was my point. For your app you have to work wherever you need to work in, of course, there you are right. But I am glad you have been able to solve your problem on your own. best, -deniz -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=57118#57118 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Drawing lines using OpenGL ES 2.0
I found a solution which involves computing the barycentric coordinates. However it seems that is not working properly. To compute the barycentric coordinates I need to associate to the vertices of the triangles a coordinate among (1,0,0) (0,1,0) (0,0,1) for doing that I use the following function, which is based on the assumption I load the 3d model using the option noTriStripPolygons so that each polygon is a triangle (and not a strip of triangles). Code: void OSGGraphicsUtils::setBarycentricCoordinates(osg::Node * object, osg::Program *shaderProgram) { GeodeFinder myGeodeFinder; std::vector osg::Geode * listOfGeodes; object-accept(myGeodeFinder); listOfGeodes = myGeodeFinder.getNodeList(); std::cout there are listOfGeodes.size() geodes std::endl; for (int j = 0; j listOfGeodes.size() ; j++) { //get the current geode osg::Geode* currentGeode = listOfGeodes.at(j); if (currentGeode != NULL) { for (int i = 0; i currentGeode-getNumDrawables(); i++) { osg::Geometry *cubeGeometry = currentGeode-getDrawable(i)-asGeometry(); if (!cubeGeometry) continue; int numAttribs = cubeGeometry-getVertexArray()-getNumElements(); std::cout number of vertices is numAttribsstd::endl; osg::ref_ptr osg::Vec3Array cubeVertexVector; if (! strcmp (cubeGeometry-getVertexArray()-className(), Vec3Array)) { cubeVertexVector = (osg::Vec3Array *) cubeGeometry-getVertexArray(); } else { //handle the error however you want -- here all I do is print a warning and bail out. std::cerr Unexpected VertexArray className.\n std::endl; return; } osg::Vec3Array *array = new osg::Vec3Array(cubeVertexVector-size()); std::map osg::Vec3, int vertexMap; osg::Vec3 nextVertex; int j = 0; for (int i = 0; i cubeVertexVector-size(); i++) { nextVertex = cubeVertexVector-at(i); if (j == 3) j = 0; if(vertexMap.find(nextVertex) == vertexMap.end()) {//check if it is the first, the second o the third vertex of the triangle and associate appropriate attribute if (j==0) { array-at(i) = (osg::Vec3(1.0,0.0,0.0)); vertexMap[nextVertex] = i; } else if (j==1) { array-at(i) = (osg::Vec3(0.0,1.0,0.0)); vertexMap[nextVertex] = i; } else if (j==2) { array-at(i) = (osg::Vec3(0.0,0.0,1.0)); vertexMap[nextVertex] = i; } } else { //std::cout Vertex already present in the map at index vertexMap[nextVertex] std::endl; array-at(i) = osg::Vec3(array-at(vertexMap[nextVertex])); } j++; } if( !cubeGeometry-getVertexAttribArray( 31 ) ) { //cubeGeometry-setVertexAttribData(31, osg::Geometry::ArrayData(array,osg::Geometry::BIND_PER_VERTEX, GL_FALSE ) ); std::cout setting barycentric attr unit array of size array-getNumElements() std::endl; cubeGeometry-setVertexAttribArray(31, array); cubeGeometry-setVertexAttribBinding(BARYCENTRIC_ATTR_UNIT, osg::Geometry::BIND_PER_VERTEX); } } } } } The attribute is binded to the program with the line of code Code: void OSGGraphicsUtils::loadShaders(osg::ref_ptrosg::StateSet objectStateSet, const char *vsSource, const char *fsSource, osg::ref_ptrosg::Node object, const char *shaderName) { // set shader for mammoth osg::ref_ptrosg::Program shaderProgram = new osg::Program; shaderProgram-setName(shaderName); shaderProgram-addShader( new osg::Shader( osg::Shader::VERTEX, vsSource ) ); shaderProgram-addShader( new osg::Shader( osg::Shader::FRAGMENT, fsSource ) ); objectStateSet = object-getOrCreateStateSet(); objectStateSet-setAttributeAndModes(shaderProgram, osg::StateAttribute::ON ); if (strcmp(shaderName,ShaderWireframe)==0) { std::cout adding