Opened 5 years ago

Last modified 3 years ago

#3191 new bug

glut programs with single buffer display a black window

Reported by: mysticmike Owned by: phoudoin
Priority: normal Milestone: R1
Component: Kits/OpenGL Kit Version: R1/pre-alpha1
Keywords: Cc:
Blocked By: Blocking:
Has a Patch: no Platform: All

Description

glut programs with single buffer display a black window

I have compiled some of the programs from the OpenGL
red book. they use glut. When you run the programs
you get an empty black window. The only program that
i can get to run is double.c which uses a double buffer
screen.

I have attached cube.c a program that demonstrates this bug.

it can be made to run by adding glutSwapBuffers to the end of
the display function but this should not be nessesary.

I have also attached font.c which also shows the bug.

tested on svn revision 28754 on emulation (qemu) and on
real hardware (eeepc 900)

Attachments (4)

cube.c (3.3 KB) - added by mysticmike 5 years ago.
font.c (6.2 KB) - added by mysticmike 5 years ago.
glut3191.diff (1.5 KB) - added by mysticmike 5 years ago.
SpaceDuel3D.1.0b.zip (313.2 KB) - added by michaelvoliveira 4 years ago.
test game. type 'make'

Download all attachments as: .zip

Change History (14)

Changed 5 years ago by mysticmike

Changed 5 years ago by mysticmike

comment:1 Changed 5 years ago by korli

Is it like #2843 ?

comment:2 Changed 5 years ago by mysticmike

yes this is #2843

comment:3 Changed 5 years ago by phoudoin

Current GLUT implementation we designed for the BeOS R4.5+ targets.
At this time, BGLView didn't support single buffer mode, enforcing silently BGL_DOUBLE flag.

GLUT implementation knows that, and I guess that why GLUT_SINGLE flag is ignored and never passed to the BGLView below: see src/kits/opengl/glut/glutWindow.cpp, glutConvertDisplayMode().
Being silently working in double buffer mode means that, indeed, calling glutSwapBuffers() is mandatory to see something/anything.

I see two solutions here:

1) A short-term fix :
When GLUT_SINGLE were set - a good hint code wont call glutSwapBuffers() - we could automagically call glutSwapBuffers() after each call to the registered display callback.

2) A longer-term solution :
Honor GLUT_SINGLE and pass it to BGLView (BGL_SINGLE flag). This solution needs to have actual support of single buffer mode in GLRenderer(s).


Anyway, I'm not for honoring actual single buffer mode: in OpenGL lingua single buffer is supposed to be the mode where every drawning primitive is visible on screen ASAP, so one after one (flickering !). The single buffer is supposed to be (part of) the screen frame buffer.

To support such mode under BeOS, that can be only accomplished by calling BView's methods to draw single (ouch!) or span of pixels. When BDirectWindow mode is enabled, that can be done by clipping every primitives draws (ouch!) before applying to the screen frame buffer. While it's obvious performance will suffers a lot compared to a one-shot bitmap draw (clipping done only once), I fail to see what kind of benefit an actual single buffer mode give us (flickering? Who wants that!?), except for the lower memory footprint - an issue far more worrying 15 years ago than now.

BTW, our current Mesa Software Renderer don't do actual single buffer mode. Primitives are drawn in a BBitmap first, and this bitmap is made visible at SwapBuffers() time, either by calling DrawBitmap() or by clipping & blitting when BDirectWindow mode is enabled. That's the double buffer mode as defined in OpenGL lingua...

Let's try simply fix GLUT, aka 1).

And, yes, Axel, GLUT is a mess ;-)

comment:4 Changed 5 years ago by mysticmike

My comments on the above proposed solutions

1) the short-term fix:
Sounds like it can be made to work.

The problem with just fixing glut is then this bug will crop up again in any lib that can manage an openGL window, ie SDL or similar (is there an SDL that works on Haiku ??).

2) the longer-term solution:

if understand this right both the front and back buffers are bitmaps stored in main memory, ie not the actual framebuffer, so what would happens if thay were just made to point to the same actual memory and then swap buffers could just do nothing (or maybe just glFlush or glFinish) ??

When rendering in single buffer mode I don't think there is any need to update the framebuffer until the application issues a glFlush() or glFinish(). That shouldn't effect the performance much even with the software renderer, and it need not be to flicky.

Changed 5 years ago by mysticmike

comment:5 follow-up: Changed 5 years ago by mysticmike

1) A short-term fix : When GLUT_SINGLE were set - a good hint code wont call glutSwapBuffers() - we could automagically call glutSwapBuffers() after each call to the registered display callback.

attached is glut3191.diff a patch that does just that.

problems:

black screen comes back when window is moved - must find a way to force it to redraw.

mouse pointer leaves mouse droppings on the window.

I also made it so glutSwapBuffers() does nothing if the app calls it in single buffer mode.
.

comment:6 in reply to: ↑ 5 Changed 5 years ago by phoudoin

  • Owner changed from korli to phoudoin

Replying to mysticmike:

1) A short-term fix : When GLUT_SINGLE were set - a good hint code wont call glutSwapBuffers() - we could automagically call glutSwapBuffers() after each call to the registered display callback.

attached is glut3191.diff a patch that does just that.


Thanks.

I've reviewed it, and it needs some modifications before being applied.

  1. the displayFunc variable should'nt be a global variable but per-window one. Must be moved into gState.currentWindow struct.
  1. Instead of calling window's SwapBuffers() directly when in single buffer mode *but* at the same time disabling all explicit call via glutSwapBuffers(), I'll prefer doing the reverse: in single buffer mode we simply call glutSwapBuffers() after the display callback, period. glutSwapBuffers() should always call the window's SwapBuffers() which in turn will ends in renderer's SwapBuffers(). He's the one who know actually if it does double or single *actual* buffering, so he should be in control of the decision to do something, nothing or whatever. While GLUT calling always SwapBuffers() could be tolerated, tweaking GLUT to work around of one renderer weakness is not. It should be transparent for GLUT.

problems:

black screen comes back when window is moved - must find a way to force it to redraw.

Just by moving it goes to black?! Or when some region were invalidated (moved partially out of screen, or overlapped by other window?).
In first case, it's a bug. In second, well, in single buffer mode that the expected behavior and limitation, and unfortunatly our current software renderer don't do real double buffering, which give you the black holes.

mouse pointer leaves mouse droppings on the window.

That's the same issue as above : our renderer don't have two buffers, but only one. It's bug #2843. Really not a GLUT issue.

I also made it so glutSwapBuffers() does nothing if the app calls it in single buffer mode.
.

As I said above, I'm against it as GLUT should not try to work around renderer limitation. While faking a single buffer mode make all old' GLUT-based programs works even if they assume wrongly single buffer mode is always available, I'm against making GLUT more dependent on our renderer issues & limitations...

These issues should be fixed in software renderer side. That's the point of #2843.

comment:7 Changed 5 years ago by mysticmike

These issues should be fixed in software renderer side. That's the point of #2843

Yes, patching glut is bad idea the renderer should be fixed, even just calling a swapbuffers at the end of the display function could potentially break some other renderer.

comment:8 Changed 5 years ago by korli

Applied in hrev28806 a fix to handle drawing in single buffer mode.
Still there is a problem with window moves and mouse moves.

comment:9 Changed 4 years ago by michaelvoliveira

maybe it could be related with

http://ports.haiku-files.org/ticket/268 ?

Changed 4 years ago by michaelvoliveira

test game. type 'make'

comment:10 Changed 3 years ago by michaelvoliveira

This one could be closed and set as fixed

Note: See TracTickets for help on using tickets.