"Layer blending" with OpenGL - java

Adobe has this blending effect in some of their products called "Layer" and it basically achieves what is on the left of this image:
When overlapping two transparent images drawn in the same batch, what I get is shown on the right, I'm trying to go for the result on the left.
I've never been good with the source/destination blending functions and I'm not even sure if they're the solution to this problem, but if they are, what combination would I need to achieve this effect?
For example:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Related

Emulating gouraud shading in JavaFX

I'm currently trying to mimic Gouraud shading in JavaFX.
Specifically, I want to be able to apply vertex colors to textured polygons.
The problem is, I'd rather not have to generate unique textures for all of the used vertex color / texture combinations, due to resource limitations.
My solution is to setup the model without vertex coloring, then overlay faces on top, with (relatively) small transparent textures which overlay on top to create the intended look.
However, my problem is that, I cannot seem to find any information or techniques to procedurally make the texture which when overlayed will create the intended effect.
Generating the "colored texture" uses the original texture, and multiplies the rgb values by brightness values which are unique for each pixel. My problem is, I need to figure out how to mimic this process, by just overlaying one face upon another.
I have tried changing the BlendMode, however no matter what I set it to, the MeshViews both completely disappear when I do this. I do not know why this happens.

Transparency when using ‘drawPixel’ on Pixmap?

Background
I am creating an application where I manually lay out a texture atlas. The whole point is that the image itself isn’t supposed to be transparent—it has a consistent background color that is then supposed to be removed in the code.
The problem I’m having is that I can’t seem to be able to remove pixels—make them transparent—from the Pixmap I’m working on. I’ve made sure to use RGBA_8888 for my Pixmap’s Format, which is sure to support transparency.
Problem
Here’s the piece of code I’m having trouble with:
pixmap.drawPixel(x, y, 0x00000000);
Quite obviously, 0x00000000 would be zero—even if converted from hex to base ten—seriously, it’s the same number!
From my observations, I’ve noticed that the drawPixel method draws a pixel onto the current one. What I want is for it to become transparent. Using the aforementioned piece of code, it draws transparency onto something that isn’t transparent—ending up changing nothing. As if you add nothing to something, the something remains.
Research
As usual, I’ve done some research on my own. Here on Stackoverflow I haven’t managed to find anything of use. The only things I know is the things mentioned above that I’ve managed to find out by observing the Pixmap and its drawPixel method.
Moreover
Perhaps someone can point me in the right direction as to how you’d make a pixel of a Pixmap transparent?
As you already discovered, you can't draw a blended transparent pixel over the existing pixel, because you can't see anything. So first you need to disable Pixmap blending.
Pixmap.setBlending(Pixmap.Blending.None); // before you start drawing pixels.
pixmap.drawPixel(x, y, 0x00000000);
// And all pixels you want to draw
Pixmap.setBlending(Pixmap.Blending.SourceOver); // if you want to go back to blending
If you want to maintain the RGB of the existing pixel, you have to get the current pixel color and manually black out the alpha component only:
pixmap.drawPixel(x, y, pixmap.getPixel(x, y) & 0xffffff00);

Using a semi transparent texture to "mask" out a part of the background

I am attempting to create a "hole in the fog" effect. I have a background grid image, overlapped onto that I have a "fog" texture that I use to show that certain areas are not in view. I am attempting to cut a chunk out of "fog" that will show the area that is currently in view. I am trying to "mask" a part of the fog off the screen.
I made some images to help explain what I am after:
Background:
"Mask Image" (The full transparency has to be on the inside and not the outer rim for what I am going to use it for):
Fog (Sorry, hard to see.. Mostly Transparent):
What I want as a final Product:
I have tried:
Stencil-Buffer: I got this fully working except for one fact... I wasn't able to figure out how to retain the fading transparency of the "mask" image.
glBlendFunc: I have tried many different version of the parameters and many other methods with it (glColorMask, glBlendEquation, glBlendFuncSeparate) I started by using some parameter that I found on this website: here. I used the "glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);" as this seemed to be what I was looking for but... This is what ended up happening as a result: (Its hard to tell what is happening here but... There is fog covering the grid in the background. Though, the mask is just ending up as an fully opaque black blob when its supposed to be a transparent part in the fog.
Some previous code:
glEnable(GL_BLEND); // This is not really called here... It is called on the init function of the program as it is needed all the way through the rendering cycle.
renderFogTexture(delta, 0.55f); // This renders the fog texture over the background the 0.55f is the transparency of the image.
glBlendFunc(GL_ZERO, GL11.GL_ONE_MINUS_SRC_ALPHA); // This is the one I tried from one of the many website I have been to today.
renderFogCircles(delta); // This just draws one (or more) of the mask images to remove the fog in key places.
(I would have posted more code but after I tried many things I started removing some old code as it was getting very cluttered (I "backed them up" in block comments))
This is doable, provided that you're not doing anything with the alpha of the framebuffer currently.
Step 1: Make sure that the alpha of the framebuffer is cleared to zero. So your glClearColor call needs to set the alpha to zero. Then call glClear as normal.
Step 2: Draw the mask image before you draw the "fog". As Tim said, once you blend with your fog, you can't undo that. So you need the mask data there first.
However, you also need to render the mask specially. You only want the mask to modify the framebuffer's alpha. You don't want it to mess with the RGB color. To do that, use this function: glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE). This turns off writes to the RGB part of the color; thus, only the alpha will be modified.
Your mask texture seems to have zero where it is visible and one where it isn't. However, the algorithm needs the opposite, so you should either fix your texture or use a glTexEnv mode that will effectively flip the alpha.
After this step, your framebuffer should have an alpha of 0 where we want to see the fog, and an alpha of 1 where we don't.
Also, don't forget to undo the glColorMask call after rendering the mask. You need to get those colors back.
Step 3: Render the fog. That's easy enough; to make the masking work, you need a special blend mode. Like this one:
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, GL_ZERO, GL_ONE);
The separation between the RGB and A blend portions is important. You don't want to change the framebuffer's alpha (just in case you want to render more than one layer of fog).
And you're done.
The approach you're currently taking will not work, as once you draw the fog over the whole screen, there's no way to 'erase' it.
If you're using fixed pipeline:
You can use multitexturing (glTexEnv) with fixed pipeline to combine the fog and circle textures in a single pass. This function is probably kind of confusing if you haven't used it before, you'll probably have to spend some time studying the man page. You'll do something like bind fog to glActiveTexture 0, and mask to glActiveTexture 1, enable multitexturing, and then combine them with glTexEnv. I don't remember exactly the right parameters for this.
If you're using shaders:
Use a multitexturing shader where you multiply the fog alpha with the circle texture (to zero out the alpha in the circle region), and then blend this combined texture into the background in a single pass. This is probably a more conceptually easy approach, but not sure if you're using shaders.
I'm not sure there's a way you can do this where you draw the fog and the mask in separate passes, as they both have their own alpha values, it will be difficult to combine them to get the right color result.

AndEngine - artifacts while scrolling map (TextureOptions related)

I'm developing 2D Side Scroll Android Game, using AndEngine.
I have problem with tiles quality.
If I will use DEFAULT texture option, for my texture congaing tiles, it doesn't look perfect, contours ARE NOT smooth, etc:
DEFAULT Texture options, uses such OPEN GL parameters:
new TextureOptions(GL10.GL_NEAREST, GL10.GL_NEAREST, GL10.GL_CLAMP_TO_EDGE, GL10.GL_CLAMP_TO_EDGE, GL10.GL_MODULATE, true);
But lately I realized, that if I will use such parameters (similar to BILINEAR parameters, except last one)
new TextureOptions(GL10.GL_LINEAR, GL10.GL_LINEAR, GL10.GL_CLAMP_TO_EDGE, GL10.GL_CLAMP_TO_EDGE, GL10.GL_MODULATE, true)
graphic looks smooth (i would say perfect, check image below)
Everything would be perfect, but while moving camera (Camera is chasing player) there are visible contours of those sprites, like for example on this screen:
I have been trying to use different OPEN GL parameters, but with no luck. I would be grateful for some help. With DEFAULT texture option, such problem doesn't exist, but quality is bad. Thanks.
Ps: I have been trying to cast integer on my setCenter method inside camera, but with no luck, some people were saying it should help, but it didn't.
This occurs because the function that is used for smoothing out the textures uses pixels that are outside of the pictures on the Texture Atlas. These are black by default so the pixels on the edges are poisoned by the black area outside.
I have temporarily fixed the issue by extending the picture an all sides by 1px and putting there a copy of the adjacent 1px line from the picture. Then I set my TextureRegion to contain only the middle of the picture with the padding being outside. The results are probably not perfect but the lines are no longer noticeable.
I have seen someone on the AndEngine forums say that in the newest version the problem is fixed, so you may try updating.

OpenGL: Create a sky box?

I'm new to OpenGL. I'm using JOGL.
I would like to create a sky for my world that I can texture with clouds or stars. I'm not sure what the best way to do this is. My first instinct is to make a really big sphere with quadric orientation GLU_INSIDE, and texture that. Is there a better way?
A skybox is a pretty good way to go. You'll want to use a cube map for this. Basically, you render a cube around the camera and map a texture onto the inside of each face of the cube. I believe OpenGL may include this in its fixed function pipeline, but in case you're taking the shader approach (fixed function is deprecated anyway), you'll want to use cube map samplers (samplerCUBE in Cg, not sure about GLSL). When drawing the cube map, you also want to remove translation from the modelview matrix but keep the rotation (this causes the skybox to "follow" the camera but allows you to look around at different parts of the sky).
The best thing to do is actually draw the cube map after drawing all opaque objects. This may seem strange because by default the sky will block other objects, but you use the following trick (if using shaders) to avoid this: when writing the final output position in the vertex shader, instead of writing out .xyzw, write .xyww. This will force the sky to the far plane which causes it to be behind everything. The advantage to this is that there is absolutely 0 overdraw!
Yes.
Making a really big sphere has two major problems. First, you may encounter problems with clipping. The sky may disappear if it is outside of your far clipping distance. Additionally, objects that enter your sky box from a distance will visually pass through a very solid wall. Second, you are wasting a lot of polygons(and a lot of pain) for a very simple effect.
Most people actually use a small cube(Hence the name "Sky box"). You need to render the cube in the pre-pass with depth testing turned off. Thus, all objects will render on top of the cube regardless of their actual distance to you. Just make sure that the length of a side is greater than twice your near clipping distance, and you should be fine.
Spheres are nice to handle as they easily avoid distortions, corners etc. , which may be visible in some situations. Another possibility is a cylinder.
For a really high quality sky you can make a sky lighting simulation, setting the sphere colors depending on the time (=> sun position!) and direction, and add some clouds as 3D objects between the sky sphere and the view position.

Categories

Resources