OpenSceneGraph - Texture on each face of model - visual-c++

I've got another question.
Here is my code:
#include <iostream>
#include <osg/Light>
#include <osg/LightSource>
#include <osg/PositionAttitudeTransform>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
int main(int argc, char** argv)
{
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile("cube.3ds"); //importing object
osg::ref_ptr<osg::StateSet> ss = loadedModel->getOrCreateStateSet();
osg::ref_ptr<osg::Image> image = osgDB::readImageFile("box_1.png"); //loading texture from file
osg::ref_ptr<osg::Texture2D> tex(new osg::Texture2D()); /creating texture for model from image
tex->setImage(image);
ss->setTextureAttributeAndModes(0, tex);
osg::ref_ptr<osg::TexGen> texGen(new osg::TexGen());
texGen->setPlane(osg::TexGen::S, osg::Plane(0.075, 0.0, 0.0, 0.5));
texGen->setPlane(osg::TexGen::T, osg::Plane(0.0, 0.035, 0.0, 0.3));
ss->setTextureAttributeAndModes(0, texGen);
osgViewer::Viewer viewer; //Creating viewer
viewer.setSceneData(loadedModel);
viewer.setUpViewOnSingleScreen(0);
return viewer.run();
}
So what this code is doing: It takes model from file (i.e. "cube.3s") and adding texture (image from file "box_1.png" to it. You can change texture on object by switching one image to another. But here is a question: He stretching image on whole model. How it can be done just by placing all image on each face of model (they are platonic solid (like pyramid, cube and etc.)).

This all boils down to the texture coordinates that were assigned to the model's vertices when it was built. If you convert cube.3ds to .OSG or .OSGT text format you can see the UV coordinates that the texture mapper uses to determine where in the texture map to look for each corner of each face. This is how textures are "pinned" to faces.
Just load and edit that cube or pyramid in a 3d modeling tool and fix up the UV coordinates to what you want.
Alternately, you could edit the .osgt file to change the UV coordinates assigned to each vertex.

Related

Color points on CGAL Triangulation_3

I am trying to give a color to the points into a triangulation_3 on CGAL. I just take the example from CGAL describe here
I made a simple modification on this example to be able to draw the triangulation:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_3.h>
#include <CGAL/Delaunay_triangulation_cell_base_3.h>
#include <CGAL/Triangulation_vertex_base_with_info_3.h>
#include <CGAL/IO/Color.h>
#include <CGAL/draw_triangulation_3.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_vertex_base_with_info_3<CGAL::Color, K> Vb;
typedef CGAL::Delaunay_triangulation_cell_base_3<K> Cb;
typedef CGAL::Triangulation_data_structure_3<Vb, Cb> Tds;
typedef CGAL::Delaunay_triangulation_3<K, Tds> Delaunay;
typedef Delaunay::Point Point;
int main()
{
Delaunay T;
T.insert(Point(0,0,0));
T.insert(Point(1,0,0));
T.insert(Point(0,1,0));
T.insert(Point(0,0,1));
T.insert(Point(2,2,2));
T.insert(Point(-1,0,1));
// Set the color of finite vertices of degree 6 to red.
Delaunay::Finite_vertices_iterator vit;
for (Delaunay::Vertex_handle v : T.finite_vertex_handles())
if (T.degree(v) == 6)
v->info() = CGAL::Color(0,255,0);
CGAL::draw(T);
return 0;
}
But no matter which color I put on v->info() = CGAL::Color(0,255,0); the method draw always give the same red points in the window displayed:
I understand that the code is constructing a data structure that contains color information but this could be independent of the draw method, so i think that the window doesn't show me green points because this is not the way to color the points. If so, what is the way to get a triangulation with green points using the draw method?'.
In its current form, the viewer is not able to change the color of vertices nor edges.
But it is easy to change the code.
Copy the file draw_triangulation_3.h in your project
edit the method void compute_vertex(Vertex_const_handle vh), (line 92 in this file) to use the add_point method with a color as parameter: add_point(vh->point(), vh->info());

Transparency on one face of cube OpenScreenGraph

I have imported object (Cube) from 3dsMax in my OSG project in VisualStudio. But I can't find out how to make transparent only one face of this imported cube. this is my code:
#include <osgViewer/Viewer>
#include <iostream>
#include <osg/Group>
#include <osg/Node>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osg/Notify>
#include <osg/MatrixTransform>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/StateSet>
#include <osg/StateAttribute>
#include <osg/CullFace>
#include <osg/Point>
#include <osg/Light>
#include <osg/LightSource>
#include <osg/BlendFunc>
#include <osg/Material>
#include <osg/PolygonMode>
int main(int argc, char** argv)
{
osg::ref_ptr<osg::Group> root = new osg::Group;
osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("cube.3ds"); //Importing model
osg::StateSet* state2 = model->getOrCreateStateSet(); //Creating material
osg::ref_ptr<osg::Material> mat2 = new osg::Material;
mat2->setAlpha(osg::Material::FRONT_AND_BACK, 0.1); //Making alpha channel
state2->setAttributeAndModes( mat2.get() ,
osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
osg::BlendFunc* bf = new //Blending
osg::BlendFunc(osg::BlendFunc::SRC_ALPHA,
osg::BlendFunc::ONE_MINUS_DST_COLOR );
state2->setAttributeAndModes(bf);
root->addChild(model.get());
osgViewer::Viewer viewer;
viewer.setSceneData(root.get());
viewer.setUpViewOnSingleScreen(0);
return viewer.run();
}
This is my source with just imported file. I've tried implement transparency with multiple passes but have no success.
Is there any method how could i make it ?
The code in the question does make the model transparent. For example, with the cessna model from the OSG data package:
Adding two more models, a box and a sphere, where the box also has blending:
We see that blending is working. If you add another model but it isn't displayed, then probably the plane is being rendered before the other models. If the plane happens to be in front of the other models, even if the plane is transparent, you won't see them; as they don't pass the depth test.
Adding
cessna->getStateSet()->setMode( GL_BLEND, osg::StateAttribute::ON );
cessna->getStateSet()->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
forces the cessna to be rendered after the opaque models.
Also, note that if you provide a blending function, then you don't need to call
cessna->getStateSet()->setMode( GL_BLEND, osg::StateAttribute::ON );
Let's see another scene, where the box is behind the plane and we haven't set the rendering hint:
And now with the rendering hint active:

Blended lines do not look as expected

I use the following fragment shader, which uses the fog effect, to draw my scene:
precision mediump float;
uniform int EnableFog;
uniform float FogMinDist;
uniform float FogMaxDist;
varying lowp vec4 DestinationColor;
varying float EyeToVertexDist;
float computeFogFactor()
{
float fogFactor = 1.0;
if (EnableFog != 0)
{
//Use a bit lower vlaue of FogMaxDist to get a better fog effect - it will make the far end disappear quicker.
float fogMaxDistABitCloser = FogMaxDist * 0.98;
fogFactor = (fogMaxDistABitCloser - EyeToVertexDist) / (fogMaxDistABitCloser - FogMinDist);
fogFactor = clamp(fogFactor, 0.0, 1.0);
}
return fogFactor;
}
void main(void)
{
float fogFactor = computeFogFactor();
gl_FragColor = DestinationColor * fogFactor;
}
And i enable alpha blending:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
The result is the following scene:
My problem is with the places in which the lines overlap - the result is that the color seems darker than the color of both lines:
How i can fix it?
As already described in the comment you are blending the newly drawn line with the background which may already contain colours from another object at certain pixels, in your case where lines overlap. To solve this you will either have to draw your lines without overlapping or make your drawing independent from the current buffer state.
In your specific case you may pass the background colour to your fragment shader via some uniform or even a texture and then do your blending manually in the fragment shader.
In general you might want to draw the grid to some frame buffer object (FBO) with attached texture and then draw the whole texture in a single draw call using your fog shader and blending. The drawing to FBO should then be with disabled blending.
There are other ways such as drawing the grid to a stencil buffer first and then redraw a full-screen rect applying a colour with your shader and blending.

VTK: Intersection between a plane and a polydata

Is there a simple way to compute whether a plane and a polydata-object intersect?
I want to know on which sides my polydata-object protude my bounding box.
I want to use VTK for this task.
Will the vtkIntersectionPolyDataFilter work for you? http://www.vtk.org/Wiki/VTK/Examples/Cxx/PolyData/IntersectionPolyDataFilter
I solved this using a vtkBoundingBox, which has the plane position and a second vtkBoundingBox which got the the bounds from my vtkPolyData.
You can use vtkCutter, like below:
#include <vtkSmartPointer.h>
#include <vtkCubeSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkPlane.h>
#include <vtkCutter.h>
#include <vtkProperty.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
int main(int, char *[])
{
vtkSmartPointer<vtkCubeSource> cube =
vtkSmartPointer<vtkCubeSource>::New();
cube->SetXLength(40);
cube->SetYLength(30);
cube->SetZLength(20);
vtkSmartPointer<vtkPolyDataMapper> cubeMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
cubeMapper->SetInputConnection(cube->GetOutputPort());
// Create a plane to cut,here it cuts in the XZ direction (xz normal=(1,0,0);XY =(0,0,1),YZ =(0,1,0)
vtkSmartPointer<vtkPlane> plane =
vtkSmartPointer<vtkPlane>::New();
plane->SetOrigin(10,0,0);
plane->SetNormal(1,0,0);
// Create cutter
vtkSmartPointer<vtkCutter> cutter =
vtkSmartPointer<vtkCutter>::New();
cutter->SetCutFunction(plane);
cutter->SetInputConnection(cube->GetOutputPort());
cutter->Update();
vtkSmartPointer<vtkPolyDataMapper> cutterMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
cutterMapper->SetInputConnection( cutter->GetOutputPort());
// Create plane actor
vtkSmartPointer<vtkActor> planeActor =
vtkSmartPointer<vtkActor>::New();
planeActor->GetProperty()->SetColor(1.0,1,0);
planeActor->GetProperty()->SetLineWidth(2);
planeActor->SetMapper(cutterMapper);
// Create cube actor
vtkSmartPointer<vtkActor> cubeActor =
vtkSmartPointer<vtkActor>::New();
cubeActor->GetProperty()->SetColor(0.5,1,0.5);
cubeActor->GetProperty()->SetOpacity(0.5);
cubeActor->SetMapper(cubeMapper);
// Create renderers and add actors of plane and cube
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(planeActor); //display the rectangle resulting from the cut
renderer->AddActor(cubeActor); //display the cube
// Add renderer to renderwindow and render
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
renderWindow->SetSize(600, 600);
vtkSmartPointer<vtkRenderWindowInteractor> interactor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(renderWindow);
renderer->SetBackground(0,0,0);
renderWindow->Render();
interactor->Start();
return EXIT_SUCCESS;
}

A Question on OpenGL ES 2.0 and Alpha / Stencil Tests

I have a quad covering the area between -0.5, 0.5 and 0.5, -0.5 on a cleared viewport with a stencil and alpha buffer. In the fragment shader I apply a texture which happens to have a shape -- in this case a circle -- outside of which it is fully transparent.
I am trying to figure out how I can essentially "cut" that non-alpha textured shape out of the next draw of the shape, such that I draw the first quad, offset to some degree (say between -0.3, 0.5 and 0.8, -0.5) and draw again, and only the non-overlap of the non-alpha texture is drawn of the second quad's texture.
It is easy enough doing this with a stencil buffer, such that it applies to the quad and is blind to the texture, however I would like to apply it to the texture.
So as an example of the function what I want actually rendered of the conceptual circle texture would be a crescent in that case. I am not sure what tests I should be using for this.
I think you want to stick with the stencil buffer, but the alpha test isn't available in ES 2.0 per the philosophy that anything that can be done in a shader isn't supplied as fixed functionality.
Instead, you can insert one of your own choosing inside the fragment shader, thanks to the discard keyword. Supposing you had the most trivial textured fragment shader:
varying mediump vec2 texCoordVarying;
uniform sampler2D tex2D;
void main()
{
gl_FragColor = texture2D(tex2D, texCoordVarying);
}
You could throw in an alpha test so that pixels with an alpha of less than 0.1 don't proceed down the pipeline, and hence don't affect the stencil buffer with:
varying mediump vec2 texCoordVarying;
uniform sampler2D tex2D;
void main()
{
vec4 colour = texture2D(tex2D, texCoordVarying);
if(colour.a > 0.1)
gl_FragColor = colour;
else
discard;
}

Resources