How to set background Image for OpenGL in Android? - android

I am new to OpenGL. How to set background image for OpenGL. Actually when I am rendering the square texture and normal square (means which is including with colors). Texture also change its color...

I don't completely understand your question, but there is no background image in OpenGL. If you want to have an image as background of your rendering, just draw a textured square covering the whole screen before drawing everything else.
In case you have depth buffering enabled, you should also make sure your background image doesn't write to the depth buffer, so that the other things you render after it are actually rendered on top of the background. This can either be done by rendering it at the far plane so it gets the maximum depth of 1 or by just disabling depht writes using
glDepthMask(GL_FALSE);
and of course enabling it again (using glDepthMask(GL_TRUE)) after it is drawn.
But of course OpenGL is no scene or image management system and has no notion of any persistent scene or images and forgets about anything after it has been drawn. This means, like everything else you have to draw this background image each frame before the other scene objects are drawn.

Related

Background image working with SurfaceView

Working with a SurfaceView to make a 2d game i do not know who to put a background image in it efficiently.
I want to avoid drawing it each frame because it is an static image, any help?
The SurfaceView's Surface is a single layer. You can specify a dirty rect to reduce your draw area when you lock the Canvas, but you have to draw everything in the rect every frame -- background and all.
You could use a pair of SurfaceViews, one at the default Z-ordering, one at "media" depth. Use SurfaceView.setZOrderMediaOverlay() to do that. The layers will be composited by the system before being rendered.
If you were using OpenGL ES rather than Canvas, it'd generally be more efficient to just redraw the background from a texture each time. (If HWC runs out of overlays, that's essentially what SurfaceFlinger is doing anyway.)
See the "multi-surface test" in Grafika for an example of using multiple overlapping surfaces.

OpenGL: Create a "transparent window-like object"

I am developing an augmented reality app, that should render a 3D model. So far so good. I am using Vuforia for AR, libgdx for graphics, everything is on Android, works like charm...
Problem is, that I need to create a "window - like" effect. I literally need to make the model look like a window you can look through and see behind it. That means I have some kind of wall-object, which has a hole in it(a window). Through this hole, you can see another 3D model behind the wall.
Problem is, I need to also render the video background. And this background is also behind the wall. I can't just turn of blending when rendering the wall, because that would corrupt the video image.
So I need to make the wall and everything directly behind it transparent, but not the video background.
Is such marvel even possible using only OpenGL?
I have been thinking about some combination of front-to-end and back-to-front rendering: render background first, then render the wall, but blend it only into the alpha channel (making video visible only on pixels that are not covered by wall), then render the actual content, but blend it only into the visible pixels (that are not behind the wall) and then "render" the wall once more, but this time make everything behind it visible. Would such thing work?
I can't just turn of blending when rendering the wall
What makes you think that? OpenGL is not a scene graph. It's a drawing API and everything happens in the order and as you call it.
So order of operations would be
Draw video background with blending turned off.
The the objects between video and the wall (turn blending on or off as needed)
Draw the wall, with blending or alpha test enabled, so that you can create the window.
Is such marvel even possible using only OpenGL?
The key in understanding OpenGL is, that you don't think of using it to setup a 3D world scene, but instead use it to draw a 2D picture of a 3D world (because that's what OpenGL actually does). In the end OpenGL is just a bit smarter brush to draw onto a flat canvas. Think about how you'd paint a picture on paper, how you'd mask different parts. And then you do that with OpenGL.
Update
Ohkay, now I see what you want to achieve. The wall is not really visible, but a depth dependent mask. Easy enough to achieve: Use alpha testing instead of blending to produce the window in the depth buffer. Or, instead of alpha testing you could just draw 4 quads, which form a window between them.
The trick is, that you draw it into just the depth buffer, but not into the color buffer.
glDepthMask(1);
glColorMask(0,0,0,0);
draw_wall();
Blending will not work in this case, since even fully transparent fragments will end up in the depth buffer. Hence alpha test. In fixed function OpenGL glEnable(GL_ALPHA_TEST) and glAlphaFunc(…). However on OpenGL-ES2 you've to implement it through a shader.
Say you've got a single channel texture, in the fragment shader do
float opacity = texture(sampler, uv).r;
if( opacity < threshold ) discard;

Seamlessly layering transparent sprites in OpenGL ES

I am working on an Android app, based on the LibGDX framework (Though I don't think that should affect this problem too much), and I am having trouble finding a way to get the results I want when drawing using transparent sprites. The problem is that the sprites visibly layer on top of each other where they overlap, similar to what is displayed in this image :
This is pretty unsightly for some of what I want to do, and even completely breaks other parts. What I would like them to do is merge together seamlessly, like so:
The only success I have had thus far is to draw the entire sequence of sprites on a separate texture at full opacity, and then draw that texture back with the desired opacity. I had this working moderately well, and I could likely make it work for most of what I need it to, but the large problem right now is that these things are dynamically drawn onto the screen, and the process of modifying a fairly large texture and sending it back are pretty taxing on mobile devices, and causes an unacceptable level of performance.
I've spent a good chunk of time looking for more ideal solutions, including experimenting with blend modes and coming up with quirky formulas that balanced out alpha and color values in ways to even things out, but nothing was particularly successful. My guess is that the only viable route for this is the previously mentioned way of creating a texture and applying the alpha difference to that, but I am unsure of the best way to make that work with lower powered mobile devices.
There might be a few other ways to do this: The most straight forward would be to attach a stencil buffer and draw circles to stencil first and then draw a full screen rect with desired color+alpha with the stencil, this should be much faster then some FBO with a separate texture.
Another thing might work is drawing those circles first with disabled blend and then your whole scene over it with inverted "blendFunc" but do note it might be impossible if other elements also need blending.
3rd instead of using stencil you could just use the alpha channel of your render buffer. Just use a color mask to draw only to alpha and draw the circles, then reenable RGB on color mask and draw the fullscreen rect using appropriate "blendFunc" also note here that if previous shapes have used blend you will need to clear the alpha to 1.0 before doing this (color mask to alpha only, disabled blend, draw full screen rect with color that has alpha set to 1.0)

Producing eraser effects using libgdx and OpenGL ES

Please consider the following images for the illustration:
Initially I fill the whole screen/stage with individual Images until the screen turns pink. Each blob of pink colour is an individual Image actor that I add to the stage.
Now I want to implement the touchDown method in such a way that each time the user touches the screen, it erases a part of that Image where the touch event took place. However, that touch event should not effect other Images/actors/TextureRegions that are behind or above the pink blob actors. How am I supposed to achieve this in libgdx using OpenGL ES? Please help me in this regard.
I found this link which explains how to modify a TextureRegion but I don't know how I am going to achieve solution for my problem using the technique explained in this blog. Here is the link
Could you use FBO's and a stencil buffer?
Setup an FBO for your "pink" layer and a stencil buffer for it. On touch down, draw your touch as a mask to the pink FBO's stencil buffer. Now when you draw the pink FBO, the areas you touched wont be rendered so you'll be able to see the background FBO behind it.
This link http://www.opengl.org/archives/resources/faq/technical/rasterization.htm, section 14.050 tells you how to setup a stencil buffer:
You can set up OpenGL state as follows:
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 0x1, 0x1);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
Subsequent rendering will set a 1 bit in the stencil buffer for every
pixel rendered.
You may have to fiddle with things so your masking comes out the right way (masks where you did touch, not where you didn't.)

How to put a semi-opaque layer on a frame?

Usually when clearing the frame for a new draw, one uses the glClear() or glClearColor(). But each of those completely removes the previous frame.
I'd like to make the frames disappear gradually, i.e. with each new frame put a semi-transparent overlay on what's already on the canvas. I tried to use the glClearColor()'s alpha parameter, but it doesn't seem to have any effect.
What should I do to achieve this gradual disappearing effect?
If you just want to draw the clear color over the last frame without getting rid of it entirely, draw a screen-size quad over the viewport with the same color as what you'd pass to glClearColor, and skip calling glClear(GL_COLOR_BUFFER_BIT) (you should probably still clear the depth/stencil buffers if you're using either of them). So, if you're using a depth buffer, first clear the depth buffer if need be, disable depth testing (this is important mainly to make sure that your quad does not update the depth buffer), draw your screen-size quad, and then re-enable depth testing. Draw anything else afterward if you need to.
What follows assumes you're using OpenGL ES 2.0
If you need to blend two different frames together and you realistically never actually see the clear color, you should probably render the last frame to a texture and draw that over the new frame. For that, you can either read the current framebuffer and copy it to a texture, or create a new framebuffer and attach a texture to it (see glFramebufferTexture2D). Once the framebuffer is set up, you can happily draw into that. After you've drawn the frame into the texture, you can go ahead and bind the texture and draw a quad over the screen (remembering of course to switch the framebuffer back to your regular framebuffer).
If you're using OpenGL ES 1.1, you will instead want to use glCopyTexImage2D (or glCopyTexSubImage2D) to copy the color buffer to a texture.

Categories

Resources