Skip to content

Instantly share code, notes, and snippets.

@vicrucann
Created December 13, 2016 15:28
Show Gist options
  • Save vicrucann/c8163ff18f5699182995d7254fb8ede4 to your computer and use it in GitHub Desktop.
Save vicrucann/c8163ff18f5699182995d7254fb8ede4 to your computer and use it in GitHub Desktop.
OpenSceneGraph Photo class: photo flips, move and rotation
cmake_minimum_required(VERSION 2.8.11)
project(osg-photo)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(OpenSceneGraph REQUIRED COMPONENTS osgDB osgGA osgUtil osgViewer)
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS})
set(SOURCES
osg-photo.cpp
Photo.h
Photo.cpp
)
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME}
${OPENSCENEGRAPH_LIBRARIES}
)
#include <iostream>
#include <osg/ref_ptr>
#include <osg/Geode>
#include <osgViewer/Viewer>
#include <osgGA/GUIEventHandler>
#include "Photo.h"
# define M_PI 3.14159265358979323846
class EventHandler : public osgGA::GUIEventHandler
{
public:
EventHandler(entity::Photo* photo)
: osgGA::GUIEventHandler()
, m_photo(photo)
{}
virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
switch (ea.getEventType()){
case (osgGA::GUIEventAdapter::KEYDOWN):
switch (ea.getKey()){
case 'm':
std::cout << "move photo" << std::endl;
m_photo->move(0.2, 0.2);
break;
case 'h':
std::cout << "flip photo horizontally" << std::endl;
m_photo->flipH();
break;
case 'v':
std::cout << "flip photo vertically" << std::endl;
m_photo->flipV();
break;
case 's':
std::cout << "scale photo" << std::endl;
m_photo->scale(1.1);
break;
case 'x':
std::cout << "scale photo in X direction" << std::endl;
m_photo->scaleX(1.1);
break;
case 'y':
std::cout << "scale photo in Y direction" << std::endl;
m_photo->scaleY(1.1);
break;
case 'r':
std::cout << "rotate photo" << std::endl;
m_photo->rotate(M_PI / 4);
break;
default:
return false;
}
default:
return false;
}
}
private:
osg::observer_ptr<entity::Photo> m_photo;
};
int main(int argc, char** argv){
entity::Photo* photo = new entity::Photo;
photo->loadImage("../Images/sample.bmp");
EventHandler* EH = new EventHandler(photo);
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(photo);
geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, photo->getTextureAsAttribute());
/* set up viewer */
osgViewer::Viewer viewer;
viewer.setSceneData(geode.get());
viewer.addEventHandler(EH);
/* clear the backgroup color */
osg::Camera* cam = viewer.getCamera();
cam->setClearColor(osg::Vec4(1.0f, 1.0f, 1.0f, 0.f));
cam->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* set up lightning settings */
osg::StateSet* stateset = geode->getOrCreateStateSet();
stateset->setMode(GL_LINE_SMOOTH, osg::StateAttribute::ON);
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
return viewer.run();
}
#include "Photo.h"
#include <iostream>
#include <math.h>
#include <osg/Image>
#include <osgDB/ReadFile>
entity::Photo::Photo()
: osg::Geometry()
, m_texture(new osg::Texture2D)
, m_center(osg::Vec3(0,0,0))
, m_width(0)
, m_height(0)
, m_angle(0)
{
this->setName("Photo");
}
void entity::Photo::loadImage(const std::string &fname)
{
osg::Image* image = osgDB::readImageFile(fname);
m_texture->setImage(image);
float aspectRatio = static_cast<float>(image->s()) / static_cast<float>(image->t());
m_width = 1;
m_height = m_width / aspectRatio;
osg::Vec3Array* vertices = new osg::Vec3Array(4);
this->setVertexArray(vertices);
this->updateVertices();
this->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
osg::Vec3Array* normals = new osg::Vec3Array;
normals->push_back(osg::Vec3(0,-1,0));
this->setNormalArray(normals);
this->setNormalBinding(osg::Geometry::BIND_OVERALL);
osg::Vec2Array* texcoords = new osg::Vec2Array(4);
this->setTexCoordArray(0, texcoords);
double x = m_width;
(*texcoords)[0] = osg::Vec2(0, 0);
(*texcoords)[1] = osg::Vec2(x, 0);
(*texcoords)[2] = osg::Vec2(x, x);
(*texcoords)[3] = osg::Vec2(0, x);
}
osg::StateAttribute *entity::Photo::getTextureAsAttribute() const
{
return dynamic_cast<osg::StateAttribute*>(m_texture.get());
}
void entity::Photo::move(double u, double v)
{
m_center = m_center + osg::Vec3f(u,0,v);
this->updateVertices();
}
void entity::Photo::rotate(double angle)
{
m_angle += angle;
this->updateVertices();
}
void entity::Photo::flipH()
{
double x = m_width;
osg::Vec2Array* texcoords = static_cast<osg::Vec2Array*>(this->getTexCoordArray(0));
if (!texcoords)
return;
std::swap((*texcoords)[0], (*texcoords)[1]);
std::swap((*texcoords)[2], (*texcoords)[3]);
this->dirtyDisplayList();
this->dirtyBound();
}
void entity::Photo::flipV()
{
double x = m_width;
osg::Vec2Array* texcoords = static_cast<osg::Vec2Array*>(this->getTexCoordArray(0));
if (!texcoords)
return;
std::swap((*texcoords)[0], (*texcoords)[3]);
std::swap((*texcoords)[1], (*texcoords)[2]);
this->dirtyDisplayList();
this->dirtyBound();
}
void entity::Photo::scale(double times)
{
m_width *= times;
m_height *= times;
this->updateVertices();
}
void entity::Photo::scaleX(double times)
{
m_width *= times;
this->updateVertices();
}
void entity::Photo::scaleY(double times)
{
m_height *= times;
this->updateVertices();
}
void entity::Photo::updateVertices()
{
osg::Vec3Array* verts = static_cast<osg::Vec3Array*>(this->getVertexArray());
if (!verts)
return;
(*verts)[0] = m_center + osg::Vec3(-m_width * std::cos(m_angle) + m_height * std::sin(m_angle), 0,
-m_width * std::sin(m_angle) - m_height * std::cos(m_angle));
(*verts)[1] = m_center + osg::Vec3(m_width * std::cos(m_angle) + m_height * std::sin(m_angle), 0,
m_width * std::sin(m_angle) - m_height * std::cos(m_angle));
(*verts)[2] = m_center + osg::Vec3(m_width * std::cos(m_angle) - m_height * std::sin(m_angle), 0,
m_width * std::sin(m_angle) + m_height * std::cos(m_angle));
(*verts)[3] = m_center + osg::Vec3(-m_width * std::cos(m_angle) - m_height * std::sin(m_angle), 0,
-m_width * std::sin(m_angle) + m_height * std::cos(m_angle));
this->dirtyDisplayList();
this->dirtyBound();
}
#ifndef PHOTO_H
#define PHOTO_H
#include <string>
#include <osg/Geometry>
#include <osg/Texture2D>
namespace entity{
class Photo : public osg::Geometry
{
public:
Photo();
void loadImage(const std::string& fname);
osg::StateAttribute* getTextureAsAttribute() const;
void move(double u, double v);
void rotate(double angle);
void flipH();
void flipV();
void scale(double times);
void scaleX(double times);
void scaleY(double times);
protected:
void updateVertices();
void updateTexCoords();
private:
osg::ref_ptr<osg::Texture2D> m_texture;
osg::Vec3 m_center;
float m_width, m_height;
float m_angle;
};
}
#endif // PHOTO_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment