Skip to content

Instantly share code, notes, and snippets.

@jeremyfromearth
Created April 22, 2011 05:34
Show Gist options
  • Save jeremyfromearth/936110 to your computer and use it in GitHub Desktop.
Save jeremyfromearth/936110 to your computer and use it in GitHub Desktop.
Generate pixel bounds for Cinder Texture #pixelbounds #cinder #opengl #texture #collision-detection
//
// PixelBounds.cpp
// Demonstrates calculating the actual pixel bounds ( non-transparent bounds ) for a texture in Cinder
// More information here: http://wp.me/pPFvc-42
//
#include <cinder/app/AppBasic.h>
#include <cinder/Font.h>
#include <cinder/Text.h>
#include "cinder/gl/Texture.h"
#include "cinder/Surface.h"
#include "cinder/Area.h"
#include "Resources.h"
using namespace ci;
using namespace ci::app;
using namespace ci::gl;
class PixelBounds : public AppBasic
{
public:
void prepareSettings( Settings *settings );
void setup();
void draw();
Font font;
TextLayout layout;
Texture texture;
Surface8u surface;
Area pixelBounds;
};
void PixelBounds::prepareSettings( Settings *settings )
{
settings->setWindowSize( 620, 150 );
settings->setFrameRate( 60.0f );
settings->setResizable( true );
settings->setFullScreen( false );
}
void PixelBounds::setup()
{
// -- create the font and set up the TextLayout
font = Font( loadResource( RES_FONT_METROPOLIS ), 118 );
layout.setFont( font );
layout.setColor( ColorA( 1.0f, 1.0f, 1.0f, 1.0f ) );
layout.addLine( "Pixel Bounds" );
surface = layout.render( true, false );
texture = Texture( surface );
// -- using surface.getBounds() causes problems
// -- so use texture.getCleanBounds();
Area bounds = texture.getCleanBounds();
Surface::Iter iter = surface.getIter( bounds );
// -- begin by inverting a bounding box
// -- set the corners of the area to the max and min pixels possible
pixelBounds.x1 = bounds.x2;
pixelBounds.y1 = bounds.y2;
pixelBounds.y2 = bounds.y1;
pixelBounds.x2 = bounds.x1;
while( iter.line() )
{
while( iter.pixel() )
{
int x = 0;
int y = 0;
// -- if the alpha channel of the current pixel is greater than zero
if (iter.a() > 0 )
{
// -- iter.getPos() does not traverse the pixels as you might expect
// -- it's possible that the x and y points will start near the middle of the texture
x = iter.getPos().x;
y = iter.getPos().y;
// -- if the non-transparent pixel is out of the bounds of the respective area x,y
// -- set the area to the current pixel's x,y coords
pixelBounds.x1 = std::min( x, pixelBounds.x1 );
pixelBounds.y1 = std::min( y, pixelBounds.y1 );
pixelBounds.x2 = std::max( x, pixelBounds.x2 );
pixelBounds.y2 = std::max( y, pixelBounds.y2 );
}
}
}
}
void PixelBounds::draw()
{
gl::clear( Color( 0.1f, 0.1f, 0.1f ) );
gl::enableAlphaBlending();
gl::pushMatrices();
gl::translate( Vec2i( 10, 10 ) );
// -- draw the texture bounds
gl::color( ColorA( 1.0f, 1.0f, 1.0f, 1.0f ) );
gl::drawSolidRect( texture.getBounds() );
// -- draw pixel bounds
gl::color( ColorA( 0.0f, 0.80f, 1.0f, 1.0f ) );
gl::drawSolidRect( pixelBounds );
// -- draw the texture
gl::color( ColorA( 0.97f, 0.14f, 0.4f, 1.0f ) );
gl::draw( texture );
gl::popMatrices();
gl::disableAlphaBlending();
}
CINDER_APP_BASIC( PixelBounds, RendererGl )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment