opengl don't call glClear() in render - opengl

I draw GLUT primitives each render, more and more. To make things faster, I decided not to clear every time, just put new primitives. Is that just wrong?
When I did this, I got blinking. Putting sleep() showed that one frame is ok and second is empty and so on.
EDIT:
Brief code in render(display) that is executed once(I use Java's JOGL):
gl.glPushMatrix();
gl.glColor3f(1, 1, 0);
gl.glTranslatef(0, 0, 0);
glut.glutSolidCube(10);
gl.glPopMatrix();
drawable.swapBuffers();

Sure it is empty.When you clear, you clear the front buffer frame.Then , when swapBuffers() called the back-buffer frame becomes front , and in the meanwhile your stuff is being drawn to the front buffer frame ,which just has become back-buffer frame.Then ,when the backbuffer frame is finished the buffer swap is done(triggered by the call to swapBuffers().That is how double buffering works.If you don't clear the frame color you will get your drawings accumulated in the front buffer over time ,which I am not sure is desired result.
Clearing the front buffer once in the beginning of every render loop is not a big performance hit.The problem appears when you call glClear() frequently ,like calling it before each object drawing which also doesn't make sense as in such a case you will see only the last drawn object.
For the flickering - you should be more descriptive on how you do it all.From your example it is unclear why it happens.

gl.glDisable(GL_DEPTH_TEST);
?
It's hard to say without seeing more of your code.
When ever I get unexpected results in openGL code, I mentally go through the list of state possibilities and set them either enabled or disabled:
Depth Test
Texturing
Lighting
Blending
Culling
Framebuffers
Shaders

Swapbuffers(HDC) doesn't actually copy the contents of the buffer but merely swaps the front and back buffer, that is why you see every odd frame, but not the even ones.

Related

Is it better to glClear() before drawing to a buffer or after?

I currently have code that does the following:
sleep until next frame
glClear(GL_COLOR_BUFFER_BIT | GL_DPETH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
perform all drawing for the frame
flush and display drawing to screen
sleep until next frame (again)
My question is: should the clear (2) be moved to happen after step 4?
This order is nice because it's easier to prep a render buffer for rendering conceptually, like putting primer on a canvas, as opposed to cleaning the render buffer up afterwards. But I'm worried the GPU might get stuck on each clear and delay the drawing commands immediately after it, meaning it should be used when the GPU has nothing to do yet, like right before waiting for the next frame to begin.
Best case scenario: This order is fine and I'm being paranoid, glClear() doesn't delay other opengl drawing commands in any meaningful way.
Worst case scenario: glClear() is best called after a frame is rendered, where there's downtime for it to work since no other opengl commands are queued up yet.

Displaying a framebuffer in OpenGL

I've been learning a bit of OpenGL lately, and I just got to the Framebuffers.
So by my current understanding, if you have a framebuffer of your own, and you want to draw the color buffer onto the window, you'll need to first draw a quad, and then wrap the texture over it? Is that right? Or is there something like glDrawArrays(), glDrawElements() version for framebuffers?
It seems a bit... Odd (clunky? Hackish?) to me that you have to wrap a texture over a quad in order to draw the framebuffer. This doesn't have to be done with the default framebuffer. Or is that done behind your back?
Well. The main point of framebuffer objects is to render scenes to buffers that will not get displayed but rather reused somewhere, as a source of data for some other operation (shadow maps, High dynamic range processing, reflections, portals...).
If you want to display it, why do you use a custom framebuffer in the first place?
Now, as #CoffeeandCode comments, there is indeed a glBlitFramebuffer call to allow transfering pixels from one framebuffer to another. But before you go ahead and use that call, ask yourself why you need that extra step. It's not a free operation...

How to redraw only an invalidated part of OpenGL context? (for 2D GUI rendering)

I'm using OpenGL to optimize GUI rendering. When rendering the whole scene it works fine, but that's not optimal, since often only a small part is changed. So I tried this:
glReadBuffer (GL_FRONT);
glDrawBuffer (GL_BACK);
glCopyPixels (0, 0, sz.X, sz.Y, GL_COLOR);
glFlush();
This should copy front buffer to back buffer, so that afterwards I can change just a portion limited using glViewport. Unfortunately when a scene is changed, it looks like the glCopyPixels command is performed after the actual rendering, so that the original content sort of alphablends with the new graphics.
What is wrong? Or is there a better way to do this?
(for the record, when I do nothing, the front buffer starts blinking with back buffer and stuff like that...)
but that's not optimal
What makes you think that? OpenGL and modern GPUs are designed on the grounds, that in the worst case you have to redraw the whole thing anyway and things should perform well in that situation, too.
Or is there a better way to do this?
Yes: Redraw the whole scene. (Or what I suggest below)
To a modern low-end GPU which easily capable of throwing tens of millions of triangles to the screen per second, the few hundred to a thousand triangles of a 2D GUI are neglectible.
In fact your copying-stuff-around will probably a worse performance hit, than redrawing everything, because copying from the front to the back buffer is not a very performant operation and causes serious synchronization issues.
If you want to cache things you might split your GUI into separate widgets of content, which you draw to individually using FBOs into textures – design it in a way that widgets may overlap. You redraw a widget if its contents change. For drawing the whole window you just redraw the full window contents from the textures into the main framebuffer.
Ok so it seems this solves the problem:
glDisable( GL_BLEND );
I don't know why, but it looks like before it was blending the data, despite I didn't find anything about it in docs and "glCopyPixels" doesn't seem it should do that.

How to make a step by step display animation in openGL?

How to make a step by step display animation in openGL??
I'M doing a reprap printer project to read a GCode file and interpret it into graphic.
now i have difficulty make a step by step animation of drawing the whole object.
i need to draw many short lines to make up a whole object.
for example:
|-----|
| |
| |
|-----|
the square is made up of many short lines, and each line is generated by code like:
glPushMatrix();
.....
for(int i=0; i< instruction[i].size(),i++)
{ ....
glBegin(GL_LINES);
glVertex3f(oldx, oldy, oldz);
glVertex3f(x, y, z);
glEnd();
}
glPopMatrix();
now i want to make a step animation to display how this square is made. I tried to refresh the screen each time a new line is drawn, but it doesn't work, the whole square just come out at once. anyone know how to make this?
Typical OpenGL implementations will queue up large number of calls to batch them together into bursts of activity to make optimal use of available communication bandwidth and GPU time resources.
What you want to do is basically the opposite of double buffered rendering, i.e. rendering where each drawing step is immediately visible. One way to do this is by rendering to a single buffered window and call glFinish() after each step. Major drawback: It's likely to not work well on modern systems, which use compositing window managers and similar.
Another approach, which I recommend, is using a separate buffer for incremental drawing, and constantly refreshing the main framebuffer from this one. The key subjects are Frame Buffer Object and Render To Texture.
First you create a FBO (tons of tutorials out there and as answers on StackOverflow). A FBO is basically an abstraction to which you can connect target buffers, like textures or renderbuffers, and which can be bound as the destination of drawing calls.
So how to solve your problem with them? First you should not do the animation by delaying a drawing loop. This has several reasons, but the main issue is, that you loose program interactivity by this. Instead you maintain a (global) counter at which step in your animation you are. Let's call it step:
int step = 0;
Then in your drawing function you have to phases: 1) Texture update 2) Screen refresh
Phase one consists of binding your framebuffer object as render target. For this to work the target texture must be unbound
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, animFBO);
glViewport(0, 0, fbo.width, fbo.height);
set_animFBO_projection();
the trick now is, that you clear the animFBO only once, namely after creation, and then never again. Now you draw your lines according to the animation step
draw_lines_for_step(step);
and increment the step counter (could do this as a compound statement, but this is more explicit)
step++;
After updating the animation FBO it's time to update the screen. First unbind the animFBO
glBindFramebuffer(GL_FRAMEBUFFER, 0);
We're now on the main, on-screen framebuffer
glViewport(0, 0, window.width, window.height);
set_window_projection(); //most likely a glMatrixMode(GL_PROJECTION); glOrtho(0, 1, 0, 1, -1, 1);
Now bind the FBO attached texture and draw it to a full viewport quad
glBindTexture(GL_TEXTURE_2D, animFBOTexture);
draw_full_viewport_textured_quad();
Finally do the buffer swap to show the animation step iteration
SwapBuffers();
You should have the SwapBuffer method called after each draw call.
Be sure you don't screw the matrix stack and you'll probably need something to "pause" the rendering like a breakpoint.
If you only want the Lines to appear one after another and you dont have to be nit-picking about efficiency or good programming style try something like:
(in your drawing routine)
if (timer > 100)
{
//draw the next line
timer = 0;
}
else
timer++;
//draw all the other lines (you have to remember wich one already appeared)
//for example using a boolean array "lineDrawn[10]"
The timer is an integer that tells you, how often you have drawn the scene. If you make it larger, stuff happens more slowly on the screen when you run your program.
Of course this only works if you have a draw routine. If not, I strongly suggest using one.
->plenty tutorials pretty everywhere, e.g.
http://nehe.gamedev.net/tutorial/creating_an_opengl_window_%28win32%29/13001/
Goor luck to you!
PS: I think you have done nearly the same, but without a timer. thats why everything was drawn so fast that you thought it appeared all at the same time.

Erase parts of drawings in OpenGL

I would like to know if it is possible to erase parts of any drawing in OpenGL? Lets say I have drawn two lines with my mouse and those lines are overlapping at some points.
Is it possible to erase just one line? Is there a more or less simple approach?
OpenGL does not store what you draw. If you draw a line in OpenGL, then OpenGL will take that line, perform various math operations on it, and write pixels into a framebuffer that makes the shape of a line. OpenGL does not remember that you drew a line; all OpenGL can do is write pixels to the framebuffer.
The general idea is that it is up to the user of OpenGL to remember what they drew. So if you draw two lines, you should remember the coordinates you gave for those two lines. Therefore, if you want to "erase" a line, what you do is clear the screen and redraw everything except that line.
This isn't as silly as it may sound. Many OpenGL applications are constantly redrawing the screen. They show a frame, draw a new frame, then show that frame, etc. This provides the possibility for animation: changing what gets drawn and where it gets drawn from frame to frame. This creates the illusion of movement.
You can use glLogicOp with GL_XOR, then repaint the line to erase it. It's not a general solution, but it is a good fit for marquee selection or mouse tool overlays, where it was traditionally used. Note that you'll need to either use single-buffering, or copy between the back and the front buffer rather than swapping them.
There are two aproaches if I understood you correctly.
Repaint only the elements you need, each element must have a boolean indicating if it will be painted or not.
In case you need to erase exactly one part of the window, use glScissor.
Info:
Now for something new. A wonderful GL command called glScissor(x,y,w,h). What this command does is creates almost what you would call a window. When GL_SCISSOR_TEST is enabled, the only portion of the screen that you can alter is the portion inside the scissor window.
You need to clear the buffer and redraw the lines you want. For that you probably need to store the line data in some structure.
You can try stencil buffer techniques. See J. Carmack technique on shadow volumes (inverse stencil or something).