I need to change the transparency of a texture/sprite and I really have no idea how to do it. Any help?
I see two solutions here - one is to change transparency directly in sprite:
Sprite sprite = new Sprite( yourTexture );
Sprite otherSprite = new Sprite( yourOtherTexture );
sprite.setAlpha(0.1f); // 0f is full transparent when 1f is full visible
...
batch.begin();
sprite.draw( batch ); //this one will be almost transparent
otherSprite.draw( batch ); //this one will be normal
batch.end();
you can always manipulate with Sprite color directly:
sprite.setColor( sprite.getColor.r, sprite.getColor.g, sprite.getColor.b, 0.1f);
but it seems to be a silly way for me.
The second one which I recommend is to wrap your Sprite into Scene2d Actor class like for example Image. Then you can still change aplha directly but you are also able to use Scene2d Actions mechanism, manipulating actor's alpha smoothly (like alpha changing animation step by step).
Both Scene2d and Actions are to wide to describe it here but I encourage you to read about it here:
Scene2d
Scene2d Actions
I added this to my GameRenderer.java:
private void drawTapTapChuggy() {
batcher.setColor(1, 1, 1, 0.5f);
batcher.draw(AssetLoader.tapTapChuggy, 28, 89, (83 * 0.9f), (52 * 0.9f));
batcher.setColor(1, 1, 1, 1.0f);
}
Related
I can not to set alpha parameter for my GlSurfaceView. XML-attribute android:alpha= not working, call of method from code mView.setAlpha() too not working. I read about a similar problem, for example, - how to make a transparent background on this View, but unfortunately solution did not help to solve my problem - to set alpha channel the contains of GlSurfaceView. I tried to move GlSurfaceView inside FrameLayout and yet to set alpha of FrameLayout, but this solution did not help.
Now i am still see only a one variant - to move a sample View above GlSurfaceView and to set a transparent of a sample View. This solution to be last case for me!
I want to ask - Is there any way to solve this problem differently?
The problem is solved!
Only one variant is correct - to set parametr 'alpha' in 'gl_FragColor' of your shader! For example: gl_FragColor.a=0.5;
That to have acces to your shader from code - need to make parameter alpha in shader as global ('uniform' type), and to link him across methods 'glGetUniformLocation', 'glUniform1f'. For example:
// View-code
int mAlpha;
float alpha = 0.5f;
mAlpha = GLES20.glGetUniformLocation(mProgrammerHandle, "u_alpha");
GLES20.glUniform1f(mAlpha, alpha);
// Shader-code
...
uniform float u_alpha;
...
gl_FragColor = vec4(rgb,u_alpha);
But that is not all!
Need to set parameters GlSurfaceView and Render. After initialization GlSurfaceView should be allowed a transparent Drawing:
setEGLConfigChooser(8, 8, 8, 8, 16, 0);
getHolder().setFormat(PixelFormat.RGBA_8888);
In render object too must to set a transparent color cleaning and correct color mixing.
GLES20.glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
GLES20.glEnable(GL_BLEND);
Color mixing can be different. Default - colors mix i.e. GLES20.glBlendEquation(GL_FUNC_ADD); - not necessary write.
But there are other options of mixing:
GL_FUNC_SUBTRACT
GL_FUNC_REVERSE_SUBTRACT
I was not write 'glBlendEquation' in my code.
Next important moment - alpha mixing. Method 'glBlendFunc' or 'glBlendFuncSeparate'. More information you can read in OpenGL tutorial. For correct alpha mixing i took advantage of more detailed setup:
GLES20.glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
The last thing to do - overriding methods 'setAlpa' and 'getAlpa' in your GlSurfaceView.
P.S. If in your View a transparent artifact appear, then you may tried to set parameters setZOrderOnTop(true); and/or android:windowIsTranslucent="true" inside XML. But for me it was not required - everything works fine!
when i am trying to publish ios game into android setColor(Color3B::GREEN) is not working,color of font not coming properly
l_answer = Label::createWithTTF(label_config,str_numberStr );
l_answer->setColor(Color3B::GREEN);
l_answer->enableOutline(Color4B(0,0,0,255),255);
l_answer->enableGlow(Color4B(0,0,0,225));
l_answer->setScale(0.0f);
Color of font not coming properly.
You can’t set more than one effect on the label. Effects defined in enum class LabelEffect in ccTypes.h and they cancel each other. Now you can see only Glow effect, but if you swap enableOutline() and enableGlow(), you will see only Outline effect.
For example, for code
Label* lbSomeText = Label::createWithTTF("sometext", "fonts/junegull_rg.ttf", 100);
lbSomeText->setPosition(Vec2(winSize.width * 0.5f, winSize.height * 0.5f));
lbSomeText->setColor(230,110,180); // I set for more contrast with green
lbSomeText->enableGlow(Color4B(0,0,0,255));
lbSomeText->enableOutline(Color4B(0,255,0,255), 15);
this->addChild(lbSomeText);
result is:
For code
...
lbSomeText->enableOutline(Color4B(0,255,0,255), 15);
lbSomeText->enableGlow(Color4B(0,0,0,255));
...
result is:
Next, if you want to see GREEN effect, you need set Color4B(r, g, b, alpha) to Color4B(0, 255, 0, 255). Now you have (0, 0, 0, 255) and result is BLACK color. For example, here is result for lbSomeText->enableGlow(Color4B(0,255,0,255));
As you can see, there is little difference between green and black glowing, because you can’t to set width of glowing. So, if you need more glow, better way is make the sprite from label text in designer program like Photoshop and add more glow manually in this program.
I hope, I answered your question. Now you can choose which option suits you best.
I try to render using GLSurfaceView, and by docs I set format:
getHolder().setFormat(PixelFormat.TRANSLUCENT);
The I use GLSurfaceView.Renderer, which draws in onDrawFrame:
GLES20.glClearColor(0, 0, 1, .5f);
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
However, the GL rendering in GLSurfaceView is not translucent, and is fully blue. If I omit glClear call, then it's fully black.
How do I make GL rendering to have transparent background, so that it is blended with views drawn behind it?
EDIT: here is my GLSurfaceView:
class GLView extends GLSurfaceView{
MyRenderer r;
public GLView(Context ctx){
super(ctx);
setEGLContextClientVersion(2);
getHolder().setFormat(PixelFormat.TRANSLUCENT);
setEGLConfigChooser(8, 8, 8, 8, 16, 0);
r = new MyRenderer(getContext());
setRenderer(r);
}
}
OK, after some research I can answer this myself.
I finally made it to be drawn with transparency using SurfaceView.setZOrderOnTop(true). But then I lost possibility to place other views on top of my GLSurfaceView.
I ended with two possible results:
On left is standard GL surface below all other views, which can't be drawn with transparency, because GL surface is drawn before application's window surface, and GLSurfaceView just punches hole in its location so that GL surface is seen through.
On right is transparent GL surface drawn with setZOrderOnTop(true), thus its surface is drawn on top of application window. Now it's transparent, but is drawn on top of other views placed on it in view hierarchy.
So it seems that application has one window with surface for its view hierarchy, and SurfaceView has own surface for GL, which may be on top or below of app window. Unfortunately, transparent GL view can't be ordered correctly inside view hierarchy with other views on top of it.
You need RGBA 8888 pixel format for translucency:
private void init( boolean translucent, int depth, int stencil )
{
/* By default, GLSurfaceView() creates a RGB_565 opaque surface.
* If we want a translucent one, we should change the surface's
* format here, using PixelFormat.TRANSLUCENT for GL Surfaces
* is interpreted as any 32-bit surface with alpha by SurfaceFlinger.
*/
this.getHolder().setFormat( PixelFormat.RGB_565 );
if ( translucent )
{
this.getHolder().setFormat( PixelFormat.TRANSLUCENT );
}
setEGLContextFactory( new ContextFactory() );
/* We need to choose an EGLConfig that matches the format of
* our surface exactly. This is going to be done in our
* custom config chooser. See ConfigChooser class definition
* below.
*/
setEGLConfigChooser( translucent ?
new ConfigChooser( 8, 8, 8, 8, depth, stencil ) :
new ConfigChooser( 5, 6, 5, 0, depth, stencil ) );
setRenderer( new Renderer() );
}
Have you thought about using a LayerDrawable with setAlpha? Here's an example i have of two images... one is transparent (by the setAlpha) and the other is not. The 'calendar_cell' is solid and is on the back, then comes the box which is transparent to show the calendar cell behind it. This way you can stack as many images as you want giving them all a different transparency.
Drawable []layers = new Drawable [2];
int imageResource1 = mContext.getResources().getIdentifier("drawable/calendar_cell", null, mContext.getPackageName());
Drawable background = v.getResources().getDrawable(imageResource1);
layers [0]= background;
int imageResource = mContext.getResources().getIdentifier("drawable/box_" + box, null, mContext.getPackageName());
Drawable boxImg = v.getResources().getDrawable(imageResource);
boxImg.setAlpha(100);
layers [1]= boxImg;
LayerDrawable layerDrawable = new LayerDrawable (layers);
v.setBackground(layerDrawable)
I'm not sure what the problem is exactly but an alternative could be covering the screen with a translucent colored rectangle and just clearing the depth buffer bit.
Is there any alternative for GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)?
Otherwise make sure your depth buffer bit is 1
I'll be back later to try and recreate the problem on my phone in a bit when I can.
Edit: I just realized that the reason it appears blue may be that you set it to .5f so it only takes 2 calls for it to get to full 1f opacity. meaning that it takes at 30fps 1/15th of a second to go fully blue.
Try lowering the alpha transparency value to 0.01f or 0.05f
try using setZOrderMediaOverlay(true) for the GLSurfaceView with Hardware Acceleration for the Activity set to false. That makes the GLSurfaceView background Transparent. But I am not sure how the hardware acceleration impacts it. Overlaying a GLSurface on top of a MapView without using SetZOrderTop.
I had posted a question recently still looking for a better solution
I am new to opengl and have no idea how to deal with opacity. I have two layers that are overlapped i am drawing both the layers on to the screen. I want to fade out the one in the foreground to transtition to the background image. Is there any way to do this?? Here's my draw method.
public void draw(GL10 gl10) {
gl10.glDisable(GL10.GL_BLEND);
gl10.glEnable(GL10.GL_BLEND);
gl10.glBlendFunc(GL10.GL_TRUE, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl10.glClearColor(0F, 0F, 0F, 0);
gl10.glBindTexture(GL10.GL_TEXTURE_2D, this.mTextureId);
this.layer1.draw(gl10); // i want to transition from this layer
this.layer2.draw(gl10); // to this layer by changing opacity
}
I dont know even i framed my question correctly. Hope you get it :)
Well it depends on the method you're using for this transition. I have a similar situation with an animation view. About your opacity problem, can't you use
View v;
int i = 0; /*Values from 0 to 1, float cast might be needed for intermediate values*/
v.setAlpha(i);
this.layer2.setAlpha(i);
Or something like that, isn't this applicable in your case?
How do you create an animated dashed or dotted border of an arbitrary shape in Android? In XML (preferred) or programmatically.
See picture below for an example.
Have you seen the PathEffects API demo?
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/PathEffects.html
It produces precisely an animated line and you can just adjust the path to the edge of your view to create a border. For example:
Define a path by your view parameters / arbitrary shape:
Path path = new Path();
path.addRect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom(), Path.Direction.CW);
Then create a dashed PathEffect with:
PathEffect pe = new DashPathEffect(new float[] {10, 5, 5, 5}, phase);
Then set the associate it with a Paint object and draw:
mPaint.setPathEffect(pe);
canvas.drawPath(path, mPaint);
EDIT: The animated effect comes from continuously changing the phase and redrawing. In the API demo it calls invalidate() in the onDraw() method (which triggers onDraw()...)
XML... I guess not possible. But you can use a custom view or a SurfaceView and handle the drawing by yourself. Have fun with that :)
Could you use some form of two 9patch images as a background frame around the image file you want to present, one in each of two layouts. The images would differ in terms of the placement of the dashed elements. Interchange the views rapidly (might need a delay) and you might get the effect you want. Don't really know how effective that would be though in terms of being able to let the user continue using the app and chewing battery...