drawing a bunch of 2D points on screen

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
yjlchina
Posts: 9
Joined: Tue Nov 23, 2004 7:29 am
Location: China. west lake

drawing a bunch of 2D points on screen

Post by yjlchina »

hi, everybody.

I want to draw pixel point on irrlicht game screen using 2D APIs. the data source is a vector<Point> contains corrdinates which should be present on screen(800x600).So each time there is a event, i would scan the vector and draw the points.

However, I find in tutorial that APIs supporting 2D line and receangle like driver->draw2DRectangle() is called between beginScene() and endScene(). So when i using the code showing below, no effect...

Code: Select all

else if(event.EventType == EET_USER_EVENT) 
	{
		s32 a = event.UserEvent.UserData1;
		//s32 b = event.UserEvent.UserData2;
		f32 f = event.UserEvent.UserData3;

		// transform int handle into a vector pointer
		pactivePoints = static_cast<vector<Point>*>((void*)a);

vector<Point>::iterator i;
	
	if(pactivePoints != NULL)
		for(i = pactivePoints->begin(); i != pactivePoints->end(); i++)
		{
			int x = (*i).x;
			int y = (*i).y;

			position2d<int> start(x, y);
			position2d<int> end(x+1,y+1);
			SColor whitecolor(255,255,255,255);

			driver->draw2DLine(start, end, whitecolor);
			
		}


if i change the structure to:

Code: Select all

driver->beginScene(true, true, video::SColor(0,200,200,200));
for(...)
     driver->draw2DLine(start, end, whitecolor);
driver->endScene();
still no effects...

So, can I call 2D rendering APIs in other part of my program like OnEvent()? You know, if i add a mesh to smgr in other part of the program, it works since i call smgr->drawall() in the main loop.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Maybe it's not a good idea to split up your render process into many different places. Render state confusions may likely occur.
anyway, you should probably change to ParticleSystems or simply use the Point drawing provided by the engine. For the latter you can either draw by using the drawVertexPrimitiveList with primitive EPT_POINTS or EPT_POINT_SPRITES, or you draw usual triangles with the material flag pointcloud being enabled. The latter can be used with normal scene nodes, but does not render much faster than the usual mesh, while EPT_POINTS uses far less indices and should render faster. You can use a custom scene node, though.
TomiZ
Posts: 40
Joined: Wed Aug 29, 2007 6:02 am
Location: Poland
Contact:

Post by TomiZ »

If you will use

driver->beginScene(true, true, video::SColor(0,200,200,200));
// render points/lines
driver->endScene();

and then you will draw everything else in main loop
driver->beginScene(true, true, video::SColor(0,200,200,200));
smgr->drawAll();
env->drawAll();
driver->endScene();

you will replace previous image (and screen will blinking).

So if you want to draw lines/points you have to do this in you main rendering loop after smgr and gui;
yjlchina
Posts: 9
Joined: Tue Nov 23, 2004 7:29 am
Location: China. west lake

Post by yjlchina »

thank you two guys.

i did a little experiment, and find that if i call my drawpoints function in the main loop, it works just fine. codes are like this:

Code: Select all

while(device->run())
{
               driver->beginScene(true, true, video::SColor(0,200,200,200));
		now = device->getTimer()->getTime();
		if (now - sceneStartTime > 5000)
		{
			//do something here
			drawpoints();
			sceneStartTime = now;
		}

		//smgr->drawAll();
		driver->endScene();
}
so, in my simple conclusion, i can call 2D APIs actively in the main render loop and it work fine. but if i want to do some 2D animation passively, such as response to a event, i still can't find a proper place to draw them.

------------------------------------------------------------------------------------
another test. i didn't do a thing in main loop, the main loop look some what like this:

Code: Select all

while(device->run())
	if (device->isWindowActive())
	{}
and i put begine and end scene function into OnEvent() which is a callback. in this way render function appears once in my program. code segement is below:

Code: Select all

 // inside of  OnEvent function
vector<Point>::iterator i;
	
	// test codes
	static ti = 0;
	ti++;
	
	// render points
	driver->beginScene(true, true, video::SColor(0,200,200,200));
	if(pactivePoints != NULL)
		for(i = pactivePoints->begin(); i != pactivePoints->end(); i++)
		{
			int x = (*i).x;
			int y = (*i).y;

			position2d<int> start(x, y);
			position2d<int> end(x+ti,y+ti);
			SColor whitecolor(255,255,255,255);

			driver->draw2DLine(start, end, whitecolor);
		}
	driver->endScene();
as you can see, i put a counter inside. and in my test program, the counter increases ever time it is called. Still i see no points on screen...

I don't know why.
greenya
Posts: 1012
Joined: Sun Jan 21, 2007 1:46 pm
Location: Ukraine
Contact:

Post by greenya »

yjlchina wrote: so, in my simple conclusion, i can call 2D APIs actively in the main render loop and it work fine. but if i want to do some 2D animation passively, such as response to a event, i still can't find a proper place to draw them.
The proper place to drawing is between driver-beginScene() and driver->endScene().

In any other places you can call anytime something like smgr->addXXXNode(), gui->addXXX() and so on -- this all will be handled by smgr->drawAll(), gui->drawAll() and so on -- which is executed between driver->BeginScene() and driver->endScene().

OnEvent() and other your functions should be logical -- they should decide what to draw but don't draw it -- just set some data structures, which will be handled later between beginScene() and endScene() with proper code (also created by yourself).

This is how I see this (as simple as possible). The abstract example of some button animation:

somewhere in globals:

Code: Select all

int myExitButtonStateCount = 16;
int myExitButtonState = -1;
somewhere in OnEvent():

Code: Select all

if (-proper-event-checking-)
{
      myExitButtonState = myExitButtonStateCount-1;
}
somewhere between driver->beginScene() and endScene():

Code: Select all

if (myExitButtonState>=0)
{
      driver->draw2D... // <-- here some drawing of myExitButtonState
      myExitButtonState--;
}
yjlchina
Posts: 9
Joined: Tue Nov 23, 2004 7:29 am
Location: China. west lake

Post by yjlchina »

thanks, greenya.

you show me the right way to think about the problem. It seems my simple conclusion is a little bit 'straight-forward'.

Yes, i should refer to GUI->drawAll() mechanism.
Post Reply