How would you implement this?

Started by
7 comments, last by Kringlehaafer 18 years, 10 months ago
Hi all, perhaps someone can give me some ideas on my problem: I have a radar display implemented in opengl, as for now the whole thing is implemented through textures, the beam data is copied with texSubImage to existing textures. Now I would like to implement the afterglow effect. That means that old pixels have to "shine" through a defined transparent color (I do that with alpha blending and not clearing the screen) and clipped to the half of their original luminance value (this isn't implemented yet). The problem is obvious, if I don't clear the color buffer, dynamic elements (like range rigns, SHF line or VRM lines) rest in place and are copied as well through the keyed color. I've tried a different approach in rendering the beam echoes (pixels) as vertexes, the problem there is that I get zillions of vertexes and that slows down everything to unreasonable levels, so it's unuseable. Another problem is that with my current method (copy to textures) the system is at a 100% load (on a 1.8 Gigahertz proc), wich is unacceptable. I've seen other radar programs (I don't know if they use OpenGL) where the system load is about 12% on a PII 500 Mhz. Perhaps a fundamental question, is OpenGL the right thing to do this? I'm using a linux system. Thank you in advance for your thoughts and ideas.
Advertisement
please use Enter after ending th line "if you don't mind"
what i get that you want to make a glowing effect for your radar "if i am wrong just tell me :)"

1)draw your radar and animate it.
2)use glReadPixel() and select you radar region and save it in unsigned char array (you can use glCopyTexImage2d() short way) and clear the scene.
3)draw two quad and apply the texture (that you get it from glReadPixel()) onto them .
4)enable GL_BLEND before the second quad and use glBlendFunc(GL_ONE,GL_ONE) you'll get simple glowing effect.

that's all

bye
Sorry, I use enter, but it doesn't takes it (at least it seems it doesn't). readPixels is slow (I've tried that) and slows down the rendering to unreasonable levels (below 1 FPS, the resolution is 1280 x 1024).

the code I would use in plain C++ to do what I mean:

while(newPixel--){	if(*pixel > 127)		*pixel = 127;	*pixel |= *newPixel;	*pixel++;	*newPixel++;}


both pixel and newPixel are pointers to unsigned chars. If you have direct access to the framebuffer's address space the code is quite easy.

The effect of the whole thing is to see the trail whenever an object on the radar screen moves, so you can see where it was and into which direction it is moving.

Thank you for your fast response.
you want to make the moving objects glowing if this right what is the problem?
Quote:Original post by ff8
you want to make the moving objects glowing if this right what is the problem?


There are many problems, the issue of overwriting the old frame with an OR logic operation is quite a problem in OpenGL (without erasing the old frame). Operations like readPixels, copyTexSubImage, etc... are horribly slow. There are no layers in OpenGL (dynamic objects mix with the actual echo data rendering, so I'm forced to clear the color buffer).



I don't want to make some fancy "glow" effect, it's just that old pixels (their brightness) have to be clipped to a predefined value and shine through the keyed color of the new frame.



It seems that the issue isn't trivial...

can you post the code ?
Quote:Original post by ff8
can you post the code ?


can you post the code ?

Here's were the echoes are rendered (the color buffer is cleared at the parent function):


	void render() 	{		if(trihead == tritail) 			return;					glDisable(GL_BLEND);		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);		int t0 = texhead / 128;		int t1 = (texhead + texcount) / 128;		int y0 = texhead % 128;		int y1 = (texhead + texcount) % 128;		for(int i = t0; i <= t1; i++) 		{			int from = (i == t0) ? y0 : 0;			int to = (i == t1) ? y1 : 128;			int n = i % TCOUNT;			glBindTexture(GL_TEXTURE_2D, texture[n]);						glTexSubImage2D(GL_TEXTURE_2D, 0,0,from,2048,to - from,GL_RED,GL_UNSIGNED_BYTE,tex + (n * MAX_TEX_SIZE + from) * 128);		}		glVertexPointer(2, sizeof(GLreal) == sizeof(GL_FLOAT) ? GL_FLOAT : GL_DOUBLE, sizeof(GLreal) * 4, vtx);		glTexCoordPointer(2, sizeof(GLreal) == sizeof(GL_FLOAT) ? GL_FLOAT : GL_DOUBLE, sizeof(GLreal) * 4, vtx + 1);		glEnableClientState(GL_VERTEX_ARRAY);		glEnableClientState(GL_TEXTURE_COORD_ARRAY);		glEnable(GL_TEXTURE_2D);		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);		glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, getColor("color"));		glColor4fv(getColor("bgColor"));		t0 = trihead / 128;		t1 = (trihead + tricount) / 128;		y0 = trihead % 128;		y1 = (trihead + tricount) % 128;		for(int i = t0; i <= t1; i++) 		{			int from = (i == t0) ? y0 : 0;			int to = (i == t1) ? y1 : 128;			int n = i % TCOUNT;			glBindTexture(GL_TEXTURE_2D, _texture[n]);			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);			glDrawArrays(GL_QUADS, (n * 128 + from) * 4, (to - from) * 4);		}		glDisable(GL_TEXTURE_2D);		glEnable(GL_BLEND);			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);			texhead = tex_tail;			texcount = 0;			int tail = (tritail + MAXBEAMS - 1) % MAXBEAMS;					glColor4fv(getColor("color"));			glLineWidth(getFloat("beamT"));					glBegin(GL_LINES);				glVertex2f(vtx[tail * 8 + 4].x, vtx[tail * 8 + 4].y);				glVertex2f(vtx[tail * 8 + 6].x, vtx[tail * 8 + 6].y);			glEnd();		glDisable(GL_BLEND);	}


The texture data is hold in a circular buffer.
Instead of trying to save/reuse the pixels in the radar, why not just save/reuse the objects that showed up on the radar, then animate them dying out over subsequent frames? On top of that, you could animate the actual radar beam fade with a single texture that you rotate each frame (using the texture matrix).

This seems like an efficient solution, am I missing something that would make this not work, and did I explain my approach alright?
It sounds like the effect your trying to achieve is residual "phosphor burn."

What about using a multiple texture approach? For each new frame, you would
draw only those new items you wish to see. You would then draw your new
radar view over top of the old as a texture blend. The end result would have
each "new" frame be at maximum intensity while the "old" burned in images
slowly fade out.

I don't remember the OpenGL details and I don't have time to look them up right
now, but it should be a fairly simple blend. How big is this radar?

*

This topic is closed to new replies.

Advertisement