2D Filling Polygon problem.

Post your questions, suggestions and experiences regarding to Image manipulation, 3d modeling and level editing for the Irrlicht engine here.
Post Reply
Ulf
Posts: 281
Joined: Mon Jun 15, 2009 8:53 am
Location: Australia

2D Filling Polygon problem.

Post by Ulf »

I have made my own fill algorithm for filling my polygons, which can be regular, non-regular convex, or concave.
At the moment it just fills with a color, but I'm extending it to fill with textures as well. I just need to get my rotateTexture function working (nearly done).

When I fill the polygons, it works perfectly.
When I draw the border it works perfectly.
But if I draw the border and fill the polygon then I get some white pixels near some edges.
There are never any holes when the edge is axis aligned.
But for polygons with sloping edges, some pixels are missing. Approximately 1 pixel away from the edge, and always on the right side.
I draw lines from left to right after working out the intersection points using a version of pointInPolygon test for each Y value (row) of the height of the polygon.

Damn. Where can I get a URL for free to upload some images? Then I could show them.

I can show the fill code, but do I need to? It works.

This is the boundary drawing code:

Code: Select all

//! Now draw the border.
irr::core::array<SVertex2d<irr::f32>> const & vertices = this->getVertices();

//! each vertex must be offset by the destination minus the upperleft position of bounds box.
irr::core::vector2di drawOffset(ptDest - sBoundsBox.UpperLeftCorner);

irr::core::vector2di startPoint, endPoint;
irr::u32 startIndex = this->getVertexCount() - 1; // start with the line from last vertex to first vertex
startPoint.X = irr::core::round32(vertices[startIndex].Vertex.X) + drawOffset.X;
startPoint.Y = irr::core::round32(vertices[startIndex].Vertex.Y) + drawOffset.Y;
for (irr::u32 index = 0; index < this->getVertexCount(); ++index)
{
	//! Note: if only 2 vertices, it draws the line twice.
	//! If only 1 vertex, does not get drawn.
	endPoint.X = irr::core::round32(vertices[index].Vertex.X) + drawOffset.X;
	endPoint.Y = irr::core::round32(vertices[index].Vertex.Y) + drawOffset.Y;

	pVideoDriver->draw2DLine(startPoint, endPoint, this->getColor());
	
	//! end point becomes the start point
	startPoint = endPoint;
}

//! fill the polygon with it's color.
this->fill(pVideoDriver, ptDest, this->getColor(), clipRect);
The fill function draws in the same fashion.
It draws horizontal lines between internal edges of the polygon.

If my 2 drawing routines are correct, is there something I am not considering?
I can hear birds chirping
:twisted:

I live in the Eye of Insanity.
Ulf
Posts: 281
Joined: Mon Jun 15, 2009 8:53 am
Location: Australia

Post by Ulf »

Reply to myself ;-)

It's not a problem with the drawing. I was thinking too much.. thinking maybe I was drawing over the same place twice and it was producing XOR result.
But it's not that.

It could be one of a few things:

1. Rounding errors.
Using a float coordinate system, but having to convert to integer when drawing pixels and lines.
I ironed out these problems, but some calculations (pixels) may still round off incorrectly. Difficult to debug.

2. Bug in my polygonFill algorithm. (pointInPolyTest)
I already had a few bugs that were simply to do with using an irr::u32 variable in a calculation that produced an irr::s32 result.

3. A God is playing games with me.

4. My insanity.
I can hear birds chirping
:twisted:

I live in the Eye of Insanity.
Ulf
Posts: 281
Joined: Mon Jun 15, 2009 8:53 am
Location: Australia

A thread for just me

Post by Ulf »

I discovered the answer.
Most of my problems in life are due to this.

It was a bit of 3 and a lot of 4.
Usually I listen to Metal, but late at night I get funky! :wink:
I stay awake for 48 hours straight on occasion.
I might program for 12 hours .. all day.
I sometimes don't move on from a very small problem until it's fixed. And that's when I get creative and trick myself into mucking it all up, trying anything I can think of!
I'm sick and I need help. :twisted:

So I'm not a genius. Sometimes I feel like I am walking on a fine line. lol.

I'll present my algorithm later for all to see.

Maybe we could implement it into Irrlicht for filling the vertex primitive list?

And also take advantage of HWA in the DirectX and OpenGL implementations?
I can hear birds chirping
:twisted:

I live in the Eye of Insanity.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Teh vertexprimitive2d should already draw filled poylgons. Otherwise you do something wrong, maybe you have Wireframe enabled?
Ulf
Posts: 281
Joined: Mon Jun 15, 2009 8:53 am
Location: Australia

Post by Ulf »

hybrid wrote:vertexprimitive2d should already draw filled poylgons. Otherwise you do something wrong, maybe you have Wireframe enabled?
Are you sure?
I actually haven't tried.
But I see that there is no color variable in the function. How can it fill?

Code: Select all

virtual void draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount,
	const void* indexList, u32 primCount,
	E_VERTEX_TYPE vType=EVT_STANDARD,
	scene::E_PRIMITIVE_TYPE pType=scene::EPT_TRIANGLES,
	E_INDEX_TYPE iType=EIT_16BIT) =0;
Do you mean in the latest SVN version?

**EDIT**
Special Note: I intend to be able to fill my polygons with textures.
In other words, clipping to a non-rect. I don't know how useful that is, but my insanity isn't always concerned about usefulness. So I'm doing it.

At the moment I have implemented a fill with texture. It compiles but it's not tested. But I believe it shouldn't be too much effort to debug, since I already can fill with a color and I can accurately rotate a texture, and vertex points.
I can hear birds chirping
:twisted:

I live in the Eye of Insanity.
Post Reply