I use Framework Cocos2D to make my little game.
I used 3 object:
CCTMXTiledMap at background at layer -1
CCRenderTexture to render some line with texture at layer 0
CCSpriteBatchNode to render game object at layer 1
I use CCRenderTexture at z-oder 0. When i try to render some Texture on this, its working perfect, but when use Clear function to clear the Texture in viewport to redraw another texture, it's clear Map too.
[target clear:0.0f g:0.0f b:0.0f a:1.0f];
How can i so this problem?
Thanks you ! –
//For removing all textures
[[CCTextureCache sharedTextureCache] removeAllTextures];
//For removing un used textures
[[CCTextureCache sharedTextureCache] removeUnusedTextures];
I had this problem, but my solution was to just use [target clear:0.0f g:0.0f b:0.0f a:0.0];.... see the difference there. The alpha is zero. We're clearing the screen with the colour black though we are putting the alpha to zero. That will DEFINATELY work if I think you are trying to sort out what I think you are.
Related
I am trying to draw brush strokes made of quads with a rough texture into framebuffers that are then composited together. The problem is that the framebuffer texture initial color is 0,0,0,0 and it blends in creating a dark glow around the edges. here is an example image
im using
gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );
gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.SRC_ALPHA, gl.ONE );
I think Iv tried every possible combination of blending settings and none work the way I want.
here is a demo of the problem
This looks like a pre-multiplication issue to me. Either your brush stroke textures aren't pre-multiplied and they should be, or they are pre-multiplied and they shouldn't be - I forget which.
For compositing you most likely want to use pre-multiplied alpha to get the effect you want. Either pre-multiply the texture when you upload the data
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
or pre-multiply in the shader
gl_FragColor = vec4(color.rgb * color.a, color.a);
And blend with
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
A quick google of "pre-multiplied alpha blending" brought up this great explanation of the issue
I can't get my head around what's going on here and I know I'm being stupid, but here's whats going on:
I have two images, one is 1024x768, one is 2048x1536. They are "background" textures. I'm trying to switch from one texture to the other:
CCSprite *bg = [CCSprite spriteWithFile:#"one.jpg"];
bg.scale = 0.5;
[self addChild:bg];
...
CCTexture2D* tex = [[CCTextureCache sharedTextureCache] addImage:two.jpg];
[bg setTexture: tex];
OK this is totally normal, the 2nd image fits perfectly into the same exact space and dimensions of the first, despite being a different resolution. Now i'm adding a 2nd image so i can have the first one fade into the second one
CCSprite *newBG = [CCSprite spriteWithFile:#"two.jpg"];
newBG.scale = bg.scale;
[self addChild: newBG];
This however doesn't work, the image is twice as big as it should be.
So what exactly is happening here? As best I can guess when a sprite is created from an image, the size of the sprite is set, and then any texture applied automatically scales to fit the space, and the 2nd doesn't work because the newly created sprite is using a different sized image?
When you set a texture, you should also call
-(void) setTextureRect:(CGRect) rect;
to set its size. This is automatically called in initWithTexture, but not when you simply call setTexture. So, you assumption is right: the texture size is set when you init the sprite and not changes thereafter; but you can change it when you want to use a new texture.
I'm making a 2D game using OpenGL. I recently tried implementing Framebuffer-objects, and I am having some problems regarding blending.
I'm creating an FBO (using GL_RGBA as format).
When I render to the FBO, I first clear it to fully transparent black, and disable GL_BLEND. I then draw my textures and then I enable GL_BLEND again.
When I'm drawing the FBO-texture, I use GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA as source and destination pixels respectively, as the blending-function. I am rendering it as a textured quad.
This does not work properly, as white pixels appear transparent. I have tried experimenting with different blend-function values, but all that I have tried have had issues. I do not fully understand how blending works, so it's hard for me to wrap my head around this. Maybe I'm missing something obvious here?
Here's an image of how it looks right now. There is supposed to be a glow around the button when it is being highlighted, but instead the pixels around it appear transparent: http://i.snag.gy/RnV4s.jpg
You can also see two boxes of text in the image. The top one is drawn normally, without an FBO. The textures are also rendered normally without an FBO, so I know that the problem lies within my framebuffer-code somewhere.
I have pasted my "RenderTarget" class to pastebin (I'm used to calling it a rendertarget instead of FBO): http://pastebin.com/dBXgjrUX
This is how I use it:
RT->Begin();
// draw stuff
RT->End();
RT->Draw();
Can someone help me? Let me know if you need any more info about my issue.
Edit:
Here are the properties of OpenGL that I set on startup:
// Initialize shaders
shaderManager.InitializeStockShaders();
// Set some OpenGL properties
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glShadeModel(GL_SMOOTH);
glAlphaFunc(GL_GREATER, 0.0f);
// Enables/disables
glEnable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDisable(GL_DITHER);
glDisable(GL_LIGHTING);
I'ts a bit difficult to tell what your problem is exactly, because you didn't provide source code. Alas, I see several potential troublemakers:
First you told that you want to draw a glow around the button. I presume, that all the buttons are drawn into the FBO, merging them into a UI overlay. Glow sounds to me, like you want to blend something, so you probably also want to have blending enabled, drawing to the FBO.
Next be aware of depth buffer issues. Blending and Depth Buffering have peculiar interactions. In your case I suggest disabling depth testing and depth writes to the FBO (or not using a depth buffer attachment to the FBO at all). Draw the glowing button last, so that it won't block the other buttons from being drawn. Also you must make sure, that your glow comes out with a nonzero alpha value, otherwise it will blend transparent. This is something you control in your shaders, or texture environment (depending on what you use).
Update 1:
Your FBO class doesn't propperly ensure, that textures attached to a bound framebuffer must not be bound themself. It's easy to fix though, by moving attachment code into bind, where the textures are also unbound apropriately. See my edited pastebin http://pastebin.com/1uVT7VkR (I probably missed a few things).
Following problem: I have two textures and I want to combine these two into a new texture. Thus, one texture is used as background, the other will be overlaid. The overlay texture is getting initialized with glClearColor(1.0, 1.0, 1.0, 0.0). Objects are draw onto the texture, these objects do have alpha values.
Now blending between the two textures leaves a white border around the objects. The border comes from the fact that the background color in the second texture is white, isn't it?
How can I use alpha blending where I do not have to think about the background color of the overlaying texture?
I solved the problem myself, but thanks a lot to all of you guys!
The problem was following: to combine both textures I used glblend(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) which does not work due to the fact that OpenGL uses pre-multiplied alpha values. Blending with glblend(GL_ONE, GL_ONE_MINUS_SRC_ALPHA), works as the source term now will be:
1*src_alpha*src_color!
How can i use alpha blending where i do not have to think about the background color of the overlaying texture?
You can't; your blend function incorporates the background color into it, because it may not actually be the "background". You render multiple objects to the texture, so the "background" color may in fact be a previously rendered object.
Your best bet is to minimize the impact. There's no particular need for the background color to be white. Just make it black. This won't make the artifacts go away; it will hopefully just make it less noticeable.
The simple fact is that blending in graphics cards simply isn't designed to be able to do the kinds of compositing you're doing. It works best when what you're blending with is opaque. Even if there are layers of transparency between the opaque surface and what you're rendering, it still works.
But if the background is actually transparent, with no fully opaque color, the math simply stops working. You will get artifacts; the question is how noticeable they will be.
If you have access to more advanced hardware, you could use some shader-based programmatic blending techniques. But these will have a performance impact.
Although I think you probably get better results with a black background, as Nicol Bolas pointed out. But you should double check your blending functions, because as you point out, it SHOULD not matter...
1.0 * 0.0 + 0.734 * 1.0 = 0.734
What I don't really get is why your base texture is fully transparent? Is that intended? Unless you blend the textures and then use them somewhere else initializing to Alpha = 1.0 is a batter idea.
Make sure you disable depth writing before you draw the transparent texture (so one transparent texture can't "block" another, preventing part of it from being drawn). To do so just call glDepthMask(false). Once you are done drawing transparent objects, call glDepthMask(true) to set depth writing back to normal.
I'm learning about how to use JOGL and OpenGL to render texture-mapped quads. I have a test program and a test quad, and I figured out how to enable GL_BLEND so that I can specify the alpha value of a vertex to make a quad with a sort of gradient... but now I want this to show through to another textured quad at the same position.
Drawing two quads with the same vertex locations didn't work, it only renders the first quad. Is this possible then, or will I need to basically construct a custom texture on-the-fly based on what I want and then draw one quad with this texture? I was really hoping to take advantage of blending in this case...
Have a look at which glDepthFunc you're using, perhaps you're using GL_LESS/GL_GREATER and it could work if you're using GL_LEQUAL/GL_GEQUAL.
Its difficult to make out of the question what exactly you're trying to achieve but here's a try
For transparency to work correctly in OpenGL you need to draw the polygons from the furthest to the nearest to the camera. If you're scene is static this is definitely something you can do. But if it's rotating and moving then this is usually not feasible since you'll have to sort the polygons for each and every frame.
More on this can be found in this FAQ page:
http://www.opengl.org/resources/faq/technical/transparency.htm
For alpha blending, the renderer blends all colors behind the current transparent object (from the camera's point of view) at the time the transparent object is rendered. If the transparent object is rendered first, there is nothing behind it to blend with. If it's rendered second, it will have something to blend it with.
Try rendering your opaque quad first, then rendering your transparent quad second. Plus, make sure your opaque quad is slightly behind your transparent quad (relative to the camera) so you don't get z-buffer striping.