Drawing a stationary background - c++

In my program, I am trying to use an image and draw it as a stationary background. The foreground does have some models loaded inside a camera and runnig fine.
However, when I apply a background image, the whole model and other objects don't appear and I can only see the background image appearing over the screen.
I did the disable the Depth_Test before drawing the background and then re-enabled it before drawing the model.
glDisbale(GL_DEPTH_TEST);
bgImage.draw(0,0); //draw the background image. Width and height parameters previously while initializing image
glEnable(GL_DEPTH_TEST);
cam.begin();
//stuff drawn inside
cam.end();
Also tried clearing the Depth Buffer/Depth Color bit after the bgImage.draw but nothing changes.

You need to disable depth writes so that the background doesn't hogs the depth buffer.
glDepthMask(GL_FALSE);
background();
glDepthMask(GL_TRUE);
Or you simply clear only the depth buffer after drawing the background:
glDisable(GL_DEPTH_TEST);
background(); // instead of clearing the color
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);

Related

OpenGL: Draw color with mask on a background image

I need to draw a color with some shape onto an image. My thought was to supply a mask with the given shape (say, hearts), then fill the rectangular area with the color and use the mask to render it over the final image.
Masked by:
PLUS
EQUALS:
The rectangle color is decided at runtime - that's why I don't draw the colored heart on my own.
The black heart image is transparent (alpha is 0) anywhere except for the heart (alpha is 255).
I tried using:
glBlendFunc(GL_DST_ALPHA, GL_ZERO)
where the source is the solid color, and the destination is the alpha channel image.
I used https://www.andersriggelsen.dk/glblendfunc.php for help.
However the bottom image (tree) is being used as the DST image...
Seems like I need an intermediate buffer to first render the blue heart, then do a second render onto the tree.
What is the way to do it?
If the tree is drawn before, it will appear in the dest Color and change your final result.
You are right, you need an intermediate buffer to store which part of the quand should be rendered, with the shape of your heart.
OpenGL provide a perfect tool for this, it's called stencil buffer.
In your case i will render my scene like usual (the tree)
Then i will enable the stencil buffer glEnable(GL_STENCIL_TEST);
Disable the write to the colorBuffer glColorMask(false, false, false, false);,
Draw only the heart with the appropriate mask. glStencilMask(0xFF);
Then you draw your colored quad with stencil test enable with glStencilFunc(GL_EQUAL, 1, 0xFF)
Don't forget to clear your stencil buffer each frame glClear(GL_STENCIL_BUFFER_BIT);
You can find some good tutorials online: https://learnopengl.com/Advanced-OpenGL/Stencil-testing
Here's a very simple way to do this in legacy OpenGL (which I assume you're using) that does not require a stencil buffer:
public void render() {
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glOrtho(0, 1, 1, 0, 1, -1);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
// Regular blending
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_ALPHA_TEST);
// Discard transparent pixels. Not strictly necessary but good for performance in this case.
glAlphaFunc(GL_GREATER, 0.01f);
glColor3f(1,1,1);
glBindTexture(GL_TEXTURE_2D, treeTexture);
drawQuad();
glColor3f(1,0,1); // Your color goes here
glBindTexture(GL_TEXTURE_2D, maskTexture);
drawQuad();
}
private void drawQuad() {
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex2f(0,0);
glTexCoord2f(0,1);
glVertex2f(0,1);
glTexCoord2f(1,1);
glVertex2f(1,1);
glTexCoord2f(1,0);
glVertex2f(1,0);
glEnd();
}
Here, treeTexture is the tree texture, and maskTexture is the white-on-transparent heart shape.
Result:
The principle is that in the legacy OpenGL pipeline, you can use glColor* before glVertex* to specify a color that the texture color (in this case white or transparent) is multiplied by component-wise.
Note that with this method you can easily render multiple colored shapes in multiple different colors without needing any (relatively expensive) clears of the stencil buffer. I suggest cropping the mask texture to the boundaries of the actual mask shape, to save the GPU the small effort of discarding all the transparent fragments.

Wireframe not drawing with glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);

my renderer works fine if I use
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
but as soon I switch to
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
Nothing is drawn on screen. For some camera config I can sort of see some dots on the border of the screen, but nothing sensical. I am doing some postprocessing on the framebuffer where the image is drawn. What can it be?

Set background color to a texture

So in openGL when I call glClearColor() is there a way to set the background color to a texture instead of setting it just to a static color? Or is there another method which can do that besides glClearColor()?
You cannot clear the screen to a texture. You can:
Draw a textured quad the size of the screen.
Blit a texture from an FBO onto the screen.
Either one will work.

Color coded picking problem in OpenGL

I am making a game, actually a very basic replica of Minecraft, for a class project of mine. I'm stuck in the picking process right now, which would enable me to destroy and create blocks in the game environment.
I've been trying to use OpenGL's own picking mode without any success, and building my own ray picker using math libraries seems to large a work for a project of this size. So, I've decided to use the color coded picking method, which consists of rendering every pickable object in a different color, then getting the color at the mouse position and using it to identify the picked object.
My current interface is just a 3D rendering of many boxes stacked, creating a terrain-like structure. Since I've done no texture mapping yet, all the boxes are shades of grey (lighting enabled).
Now, time for some actual code:
This is the initialization part, enabling texturing, lighting etc.
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
When a mouse button is clicked, I try to get the color at the mouse cursor's position (always the middle of the window, actually) by:
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_DITHER);
glDisable(GL_LIGHT0);
glDisable(GL_LIGHT1);
renderColors();
GLubyte pixels[3];
glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, (void *)pixels);
glEnable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glEnable(GL_DITHER);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
Problem is, the disables do not work and I always get the RGB values of different shades of grey in my pixels array.
What could be the problem?
Perhaps you forget to clear the color buffer and disable depth buffer and all your rendered colors are causing Z-Fighting or not rendered at all (if z-test is "less"). Try to add swapbuffers code and see what gets rendered after your ColorRender code.

OpenGL AntiAliasing and Background Quad

I'm drawing a background behind my 3D scene which works as expected (code below). I'm also anti-aliasing the scene using the accumulation buffer (chapter 10 of the red book).
...loop several times (say, n) through code that jitters and draws the image (jittering is moving the image to a slightly different position), accumulating the data with
glAccum(GL_ACCUM, 1.0/n)
and finally calling
glAccum(GL_RETURN, 1.0)
However, I do not want to anti-alias the background. The problem is that calling glAccum with GL_RETURN copies (overwrites) the values in the color buffer (rather than using the depth test and blend functions, etc) to mask the values being written to the color buffer.
How can I draw the background before or after anti-aliasing the 3D scene so that the background looks just like it does when I draw the 3D scene without anti-aliasing?
// Draw the background.
glMatrixMode GL.GL_PROJECTION
glLoadIdentity
glMatrixMode GL.GL_MODELVIEW
glLoadIdentity
glPolygonMode GL_FRONT_AND_BACK, GL_FILL
glDisable glcDepthTest
glBegin bmQuads
// Call glColor and glVertex here.
glEnd
glEnable glcDepthTest
If you're just after the appearance, and not looking for a rendering acceleration, don't jitter the background. Your loop would draw the background, apply the jitter, then draw the foreground. Since the background never moves, the accumulated background would be aliased.