• Advertisement
Sign in to follow this  

[C++/SFML] Problems texturing a GL_POLYGON

This topic is 2997 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

... I'm at a loss for words:
What you're looking at is my attempt at "carving" out a hole in the foreground -- i.e. the background is rendered first, then a polygon is rendered on top in such a way that it appears to have been cut out. At the moment I'm using a simple convex polygon, textured using its coordinates. Note that these are in world-coordinates. (The screen is 40 by 20 units, with the center of the screen being the origin.) Here's some relevant code: Note, the code is messy, as this is just a prototype until I figure out how to get this to work.
void Lobby::RenderMenuState( RenderFrame& frame ) {
	sf::RenderWindow& rw = frame.vp.GetRenderWindow(); // vp == Viewport
	rw.Clear();

	frame.vp.WorldView(); // Prepares for drawing in world-space
	// rc == ResourceCache
	frame.rc.GetForegroundTexture().Bind(); // Checkered image

	sf::FloatRect const& window = frame.vp.GetCurrentView().GetRect();
	float const scale = 0.125f, playScale = scale * 1.33f; // Texture scaling factors

	// Texture coordinates
	sf::FloatRect tex = sf::ext::toRect( Vector2f( window.Left, window.Bottom ) * scale, Vector2f( window.Right, window.Top ) * scale );

	// The "hole" extents
	Vector2f playAreaMin = Vector2f( -10, -10 );
	Vector2f playAreaMax = Vector2f( 10, 10 );

	// The "hole" polygon
	std::vector<Vector2f> outline;
	outline.push_back( playAreaMin );
	outline.push_back( Vector2f( playAreaMin.x, playAreaMax.y ) );
	outline.push_back( playAreaMax );
	outline.push_back( Vector2f( playAreaMax.x + 5, playAreaMin.y + 10 ) );
	// This vertex circles around a point, used to test my embossing algorithm
	outline.push_back( Vector2f( playAreaMax.x + 5.f * std::sin( mTestScroll ) , playAreaMin.y + 5.f * std::cos( mTestScroll ) ) ); 

	// Drawing the foreground:
	sf::FloatRect playArea = sf::ext::toRect( playAreaMin, playAreaMax );
	Vector2f offset = Vector2f( 1, 1 ).Normalize() * (mTestScroll);
	sf::FloatRect playAreaTex = sf::ext::toRect( playAreaMin * playScale + offset * playScale, playAreaMax * playScale + offset * playScale );
	glBegin( GL_QUADS ); {
		glColor4ub( 255, 255, 255, 255 );
		sf::ext::glEmit( window, glVertex2f, tex, glTexCoord2f );
	} glEnd();

	// Drawing the "hole":
	glBegin( GL_POLYGON ); {
		for ( std::vector<Vector2f>::const_iterator it = outline.begin(), end = outline.end(); it != end; ++it ) {
			sf::ext::glEmit( *it, glVertex2f ); // calls glVertex2f( it->x, it->y );
			sf::ext::glEmit( *it, glTexCoord2f );
		}
	} glEnd();


	// Darkening the "hole":
	glDisable( GL_TEXTURE_2D );
	glBegin( GL_POLYGON ); {
		glColor4ub( 0, 0, 0, 210 );
		for ( std::vector<Vector2f>::const_iterator it = outline.begin(), end = outline.end(); it != end; ++it )
			sf::ext::glEmit( *it, glVertex2f );
	} glEnd();

	// "emboss" adds some highlights/shadow effects, disabled for now:
	// sf::ext::emboss( outline, 1.f );

	// Give the "hole" with a magenta outline:
	glBegin( GL_LINE_LOOP ); {
		glColor4ub( 255, 0, 255, 255 );
		for ( std::vector<Vector2f>::const_iterator it = outline.begin(), end = outline.end(); it != end; ++it ) {
			sf::ext::glEmit( *it, glVertex2f );
			// sf::ext::glEmit( *it, glTexCoord2f );
		}
	} glEnd();
}

And the sf::ext namespace:
namespace sf { namespace ext {
	template<typename T, typename F>
	void glEmit( ::Vector2t<T> const& vec, F const& func ) {
		func( vec.x, vec.y );
	}

	template<typename T, typename F>
	void glEmit( sf::Rect<T> const& rect, F const& func ) {
		func( rect.Left, rect.Top );
		func( rect.Right, rect.Top );
		func( rect.Right, rect.Bottom );
		func( rect.Left, rect.Bottom );
	}

	template<typename T, typename F1, typename F2>
	void glEmit( sf::Rect<T> const& rect, const F1& vertFunc, sf::Rect<T> const& tex, F2 const& texFunc ) {
		texFunc( tex.Left, tex.Top );		vertFunc( rect.Left, rect.Top );
		texFunc( tex.Right, tex.Top );		vertFunc( rect.Right, rect.Top );
		texFunc( tex.Right, tex.Bottom );	vertFunc( rect.Right, rect.Bottom );
		texFunc( tex.Left, tex.Bottom );	vertFunc( rect.Left, rect.Bottom );
	}

	template<typename T>
	sf::Rect<T> toRect( Vector2t<T> const& bl, Vector2t<T> const& tr ) {
		return sf::Rect<T>( bl.x, tr.y, tr.x, bl.y );
	}
} }

Any help will be greatly appreciated! EDIT: The question is: How to apply a square-UV map onto a polygon? [Edited by - _fastcall on December 6, 2009 7:17:28 PM]

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by _fastcall
The question is: How to apply a square-UV map onto a polygon?
Very, very carefully. One problem you may encounter is that the order in which the driver triangulates your polygon is not particularly well defined - make sure that you aren't depending on the interpolation of specific edges.

Share this post


Link to post
Share on other sites
Facepalm! Thanks for your post, swiftcoder; it made me take a closer look at how I was drawing my polygon:


// Drawing the "hole":
glBegin( GL_POLYGON ); {
for ( std::vector<Vector2f>::const_iterator it = outline.begin(), end = outline.end(); it != end; ++it ) {
sf::ext::glEmit( *it, glVertex2f );
sf::ext::glEmit( *it, glTexCoord2f ); // This should probably be called before the vertex is sent
// ;______________;
}
} glEnd();





I originally draw the polygon without a texture, but when I added the glTextCoord2f function there, I must have carelessly misplaced it. :P



Thar, I fixd it. Thanks again!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement