Draw EXACTLY in half frequency as frame rate

Hello,
my monitor is set to 80 Hz and I want to draw EXACTLY in 40 Hz, I use a gen lock to be sure that the frequency has no variation.

Its kind of important that after 24 hours still each frame will be draw in the right time.

At the Moment I use a Timer-Member and use the

event EventHandler Tick
to switch to the next Picture every 25ms. But the function draw() is still running uninterrupted.

I’m sure there is a better way :wink:

Any ideas?

you have to make a timer that calcylates the time it takes to render each frame, then just before you swap the buffers you use sleep() to pause it for a moment so the whole thing takes just less than 25ms, that should do it

wglSwapInterval(2)

Edit : well this assumes that each rendering frame takes less than 1/80th of second.

zeoverlord method with wglSwapInterval(1) allow for frames as slow as 1/40th of second. Using glFlush() or glFinish() may be useful to avoid too much buffering on the video card.

Thx, and what happend if I’m not fast enough?

Then you unfortunately will drop one screen frame :slight_smile:
The swap interval value means “how many retrace event to wait before swapping back buffer to front buffer”.
0 -> no wait, display asap, means tearing
1 -> also called vsync, no tearing. but for a 80Hz display, if the rendering is at 79fps, then it will end up with only 40 fps.
2 -> wait 2 retrace. say if your rendering is still at 79fps, you will end up with 3/80 = 26.667 fps

What application is this ? Some kind of alternate frame stereographics ? Will you have complex graphics ?
You say you already have a genlock, where is it plugged ?

Basicaly it is very hard to have real real-time guarantees, unless some dedicated hardware.
Having a very powerful system can help, to be sure no frame will always be above 40fps.

First I my must correct meself, the Display (SXGA-R3) must run in 40Hz and I must draw in 40Hz.

I want to expose a hologram film, I have a system which drives the Display (atched to a laser) row after row.
During this, I expose each Pixel with a 1bpp Bitmap in nearly 1kHz, but the Display want one Bitmap with 24bpp in 40Hz. Because the Display self take each Bitlayer apart.

Now I have a Gen Lock to run constantly and in phase at 40Hz.

But my Problems are

[ul][li] Draw in frequency and in phase[*] I must be able to draw 200 Pictures (100x100 24bpp-> 800x800 24bpp) per line[/ul][/li]I think the first point is solved with vsync (thx to ZbuffeR) and I tried to solve the second point with UV-Mapping (see my post). At the moment I create a 4000x4000 texture and draw one element out of this for example 100x100. So I get down only 40 Pictures but I need a lot of more.

Any suggestion?

I still can not understand what do you need to draw exactly, even after reading that other thread.

I must be able to draw 200 Pictures (100x100 24bpp-> 800x800 24bpp) per line

I don’t get it.
What is the resolution for each picture ? What is the total resolution of 40hz display ?
To sum up, how many 24bits pixels do you have to draw per second ?

sorry, I try again.

You have something like a photo film (1m x 1m), now you want to expose each Pixel separate.
This film has a resolution of 5000 x 5000 Pixel and each Pixel must be expose with one 1bpp Bitmap (100x100 to 800x800).
Now you have a PLC (Programmable Logic Controller), so you can drive along each linie (5000 times until each line is passed).
I send to the Display not 1bpp but 24bpp pics, because the Display will make of one 24bpp 24 1bpp pics.

So I send the Display in 40Hz 24bpp but actually the Display show in neraly 1kHz 1bpp Pictures. And each Picture should be on the right place (Pixel).

I need to draw in 40Hz my pictures and during a line feed a have about 1s-2s to load pictures for the next line.

Please have bear with me :wink:

An hologram can hold a lot of information.

to sum up, please correct if this is wrong :
A for each line up to 5000:

  • B for each frame up to 5000, at 40 fps :
    • C draw textured quad (varying size, from 100x100 up to 800x800)
  • D load next textures during line feed (1s 2s available)

Step B takes 125 seconds. During which you have to transfer at at a rate = 800x800x3 x 40 = 76800000 bytes/sec = 73.3 MB/sec : that means all textures should be kept in memory for performance.

Total texture memory = 9155 MB, that’s way too much for step D. Even with smaller 100x100 texture, it looks already very big.
Using a pool of textures, some being used for rendering, some being uploaded with new data with PBO (pixel buffer object), will help. But anyway such throughput seem hard to achieve…
What are the specs of computer and video card ?

After reading all this, it is still not clear to me… :slight_smile:
What is actually the problem after frame rate synchronisation? You are experiencing problems to load all the picture data in time to then be displayed by your SXGA-R3 microdisplay?

This is the thing about “drawing pictures per line” I don’t find the answer in your last post. A line is one dimensional, how do you “expose a pixel in a bitmap” ??

EDIT:

Ok, reading last Zbuffer’s post, this must be due to my complete ignorance about holograms. So forget me :slight_smile: .

73.3 MB/sec should work, a 16x pci express bus can transfer 4GB/sec and sata drives usually preform at around 133MB/sec.
The trick is to continually load data as ZbuffeR said, at 40 FPS it’s gonna take a big chunk out of the time you have for rendering.

Here’s my understanding, if textures will be loaded during line-feed:


GLuint RowTextures[5000];


void Version1(){ // loads textures during line-feed
	//----[ display black, to protect film ]----[
	DrawFullscreenBlack();
	SwapBuffers(hdc);
	//------------------------------------------/

	for(int row=0;row<5000;row++){
		
		_SetMotorPosition(row,0); // async linefeed
		//FreeTextures(RowTextures);
		LoadTextures(RowTextures,row); // load all 5000 textures for this row
		
		
		
		for(int column=0;column<5000;column++){
			if(column!=0)_SetMotorPosition(row,column); // move to current "pixel"
			DrawFullscreenQuad(RowTextures[column]);
			_WaitMotors();
			//-----[ during this time, film is exposed, motors don't move the platform/display ]-------[
			SwapBuffers(hdc);		
			//-----------------------------------------------------------------------------------------/
			DrawFullscreenBlack();
			SwapBuffers(hdc);
#ifdef MONITOR_DOES_BUFFERING // thus delays frames a bit
			DrawFullscreenBlack();
			SwapBuffers(hdc);
#endif
		}
	}
}





void _SetMotorPosition(int row,int column){ // async
	// .... sends output command via LPT or whatever, to start moving motors to given row and column. 
	// Returns immediately after sending command
}

void _WaitMotors(){ // blocking
	//.... waits till motor reaches previous given position
}

// Nota Benes: move motors only while screen is black

5000 textures * 800x800 * 1/8 = 381.5MB (1bpp. Such bit-depth must be emulated via integer-handling instructions for shaders on a GF8800, and possibly bindable uniforms). A RAID array of HDDs is necessary, plus async reading of files directly onto memory-mapped buffers.
5000 textures * 100x100 * 1/8 = 6MB.

Another approach is to continue streaming texture-data after line-feed. This gives 0.02525000 = 250s time (minimum) per row.

The above code requires you’ve already set the monitor’s refresh-rate to 40Hz (actually the gpu’s refresh-rate) and enabled opengl vsync.

Yes, but 1bpp Bitmaps

5000/24 = 208 frames at 40 fps.
Because I give the Display one Bitmap with 24bpp, and the Display extract this one Bitmaps to 24 Bitmaps with each 1 bpp, this is a internal operation.

Each Pixel will be expose with one 1bpp Bitmaps in around 1kHz, but Input must be a 24bpp Bitmap which will be extract by the display.

24bpp / 40 Hz => 1bpp / 960 Hz

@Ilian Dinev
Not 5000 textures only 5000/24 = 208 textures.
Because, see my last post, this Display will extract 24 Bitmaps out of one Bitmap with 24bpp.

But your Code would be work with 208@24bpp too, or?

(The value 5000 is choosed because this is biggest size of the film material, one pixel is 0.2mm)

Sorry to raise a disturbance by mention this 5000.

My code is just pseudo-code, that expects 1bpp textures. Made to simplify and make clear the thing you want - while trying to cover for the “gotchas” (like moving motors only when screen is black).

Of course, in your real code, you will be using 32bpp (not 24bpp) textures, or even better: uniform buffers. (filtering in any case will have to be done manually in the shader-code)

To Draw the pictures, would you use UV-Mapping or this SwapBuffer?
And why?

Both. With UV-mapping and texturing, and a quad (or 2 triangles) you draw that small texture stretched onto the 1280x1024 back-buffer.
With SwapBuffers(HDC hdc) you wait for vsync and flip back-buffer and front-buffer. [only then the monitor shows what you’ve drawn with opengl into the back-buffer]

So I can draw seperatly to back-buffer and front-buffer and then switch between them?

Drawing to front-buffer is never recommended. Just draw to back-buffer, and flip, draw to back-buffer and flip,…