I'm programming my first project with libGDX and I'm currently trying to draw a transparent circle with an opaque border on top of the background.
It's working as desired in the android an the desktop project. The html project, however, doesn't render the border of the circle.
The circle is a texture which is created with a pixmap. As there is no possibility to set the strokewidth for the drawCircle method (why isn't there any?; see http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/Pixmap.html#drawCircle-int-int-int-), I'm drawing the border as a filledCircle with another circle on top of it:
creating the texture
Pixmap pixmap = new Pixmap(radius * 2 + 1, radius * 2 + 1, Format.RGBA8888);
Pixmap.setBlending(Blending.None);
pixmap.setColor(new Color(1,1,1,1));
pixmap.fillCircle(radius, radius, radius);
pixmap.setColor(new Color(0, 0, 0, 0.6f);
pixmap.fillCircle(radius, radius, radius - borderWidth);
texture = new Texture(pixmap);
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
pixmap.dispose();
drawing
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT (Gdx.graphics.getBufferFormat().coverageSampling ? GL20.GL_COVERAGE_BUFFER_BIT_NV : 0));
// tell the camera to update its matrices.
camera.update();
game.spriteBatch.setProjectionMatrix(camera.combined);
// begin the drawing process
game.spriteBatch.begin();
drawBackground();
//circle gets drawn here
game.spriteBatch.draw(texture, 50, 50);
//end drawing process
game.spriteBatch.end();
Any ideas?
Edit: Tested on Chrome (35.0.1916.153) and Firefox (30.0) on Ubuntu 14.04. Can anybody reproduce this problem?
You need to disable blending before drawing a circle:
pixmap.setBlending(Pixmap.Blending.None);
pixmap.fillCircle(radius, radius, radius);
Related
I use the following to draw the texture quads
tex.bind();
glTranslatef(x, y, 0);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2f(0, 0);
glTexCoord2f(1, 0);
glVertex2f(width, 0);
glTexCoord2f(1, 1);
glVertex2f(width, height);
glTexCoord2f(0, 1);
glVertex2f(0, height);
glEnd();
glLoadIdentity();
with these configurations:
try {
Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, WIDTH, HEIGHT, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
GL11.glEnable(GL11.GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL11.glClearDepth(1);
however now i want to add a menu to the game by drawing a rect over the screen but when i do so, everything turns red (if i set red as color)
case MENU:
GL11.glColor3f(1.0f, 0.0f, 0.0f);
glRectf(50, 50, 50, 50);
Two things:
Whenever you draw using color instead of textures, make sure to disable GL_TEXTURE_2D by calling glDisable(GL_TEXTURE_2D); before the rendering call (in your case before case MENU:). But don't forget to enable it again as soon as you're finished and ready to draw the texture once again (in your case, call glEnable(GL_TEXTURE_2D); after glRectf()). This might not be the reason for the problem that you're experiencing, but it will become a problem later.
The reason as to why everything turns red, is because whenever you render a texture, the currently bound color affects what color components are rendered from the texture. Every pixel in the texture that you're drawing is composed of 3 or 4 values. Red, Green, Blue and possibly an Alpha channel. Since you bind the color to red, and you do not change it before you draw the texture, OpenGL only draws the red component of each pixel within your texture. Thus, the Red component will be ranging from 0-1 in your texture, and the Green and Blue values will be staying at a constant 0.
To fix this, simply call glColor3f(1, 1, 1); After rendering the red rectangle. This will set the rendering color back to white (default) and therefore OpenGL will successfully draw all 3 color components of your texture pixels.
I hope that I've been clear and that this helps.
Good luck! :)
//SK
I have made a simple application in lwjgl and created simple gui. For now I have frame and panel. But there is a problem.
Because (Display 800x600) when I make panel on Panel(x,y,w,h) (0,0,64,64) everything works fine, but when I create it on other position (x,y where point 0,0 is in left upeper corner) it render moved panel.
The white space is my panel which should change color when I drag mouse on it. It is created on (417,417,64,64), but it's rendered on somethink like (90,90).
I have rendered fonts to show all of itss positions. The blue box I draw on this image is where it should be and it looks like there the panel is, because the white space is changing color when I drag mouse there, but this white space should be there.
My code looks like that:
I am adding all components to HashMap like Panels.
glColor3f(backgroundColor.getRed(), backgroundColor.getGreen(),
backgroundColor.getBlue());
if (hasFocus()) {
glColor3f(1f, 0f, 0f);
}
glPushMatrix();
glRecti(getX(), getY(), getWidth(), getHeight());
glPopMatrix();
And initGL method:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glScalef(1.0f, 1.0f, 1.0f);
glOrtho(0, 800, 600, 0, 1, -1);
glFrustum(-1, 1, -1, 1, 0.0, 40.0);
glViewport(0, 0, Display.getWidth(), Display.getHeight());
glMatrixMode(GL_MODELVIEW);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glShadeModel(GL_SMOOTH);
glRecti doesn't work that way it expects the coordinates of the corners
so instead you should do:
glRecti(getX(), getY(), getX()+getWidth(), getY()+getHeight());
First happy new year to all here!
I have a question about drawing background in code. I have a code for simple Android game and all assests is in png format, expect background. I`m not a programmer (but newbie in this and I learn with live examples).
I think this code draw background clouds on the screen:
//draw cloud layer 1
background_shader.setColor(getResources().getColor(R.color.blue_dark));
int radius = DrawBackgroundCloud(canvas, (ScreenHeight() / 2), 7);
canvas.drawRect(0, (float) ((ScreenHeight() / 2.2) + radius * 1.5), ScreenWidth(), ScreenHeight(), background_shader);
//draw cloud layer 2
background_shader.setColor(getResources().getColor(R.color.blue_darkest));
radius = DrawBackgroundCloud(canvas, (int) (ScreenHeight() / 1.5), 4);
canvas.drawRect(0, (float) ((ScreenHeight() / 1.7) + radius * 1.5), ScreenWidth(), ScreenHeight(), background_shader);
This draw some random circles as clouds but I want to change this to draw something like hills or mountains. Here is a picture of current background and what I`m looking for.
http://prntscr.com/5nqa25
Can anyone help me with this? I will be really thankfuly
Responding to the further question in the comment:
you cant really do that with canvas.drawColor, but you can use a proper Paint object and use canvas.drawPaint (or other canvas method that uses Paint object - if you want to for example draw shape with gradient).
The key part of creating your gradient Paint object is calling its setShader(...) method. For example like so:
mGradientPaint = new Paint();
mGradientPaint.setStyle(Paint.Style.FILL);
mGradientPaint.setShader(new LinearGradient(0, 0, 0, getHeight(), Color.TRANSPARENT, Color.GREEN, Shader.TileMode.MIRROR));
I'm currently using ShapeRenderer to draw polygons.
Code:
shapeRenderer.begin(ShapeType.Line);
shapeRenderer.setColor(255 / 255.0f, 109 / 255.0f, 120 / 255.0f, 0.0f);
Gdx.gl.glEnable(GL20.GL_BLEND);
//drawing a sample rectangle to test transparency(it worked)
shapeRenderer.rect(getRect().x, getRect().y,
getRect().width, getRect().height);
//drawing polygon
shapeRenderer.polygon(getPoly().getTransformedVertices());
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glDisable(GL20.GL_BLEND);
shapeRenderer.end();
I'm getting the rectangle as a transparent one but polygon is still opaque as ever.
How to do this correctly?
Or is this even possible?
The actual "drawing" probably isn't happening until the shapeRenderer.end() call. Try moving that up:
//drawing polygon
shapeRenderer.polygon(getPoly().getTransformedVertices());
shapeRenderer.end();
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glDisable(GL20.GL_BLEND);
I wrote some code to get a plain 2d box to face the mouse. It rotated just fine around its center, and everything was working great, but when i put a texture on the box, it did not rotate around the center anymore.
The code:
float imgWidth = texture.getImageWidth()*scale;
float imgHeight = texture.getImageHeight()*scale;
glLoadIdentity();
texture.bind();
glTranslatef(x, y, 0);
glRotated(rotation - 90, 0, 0, 360);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2f(-imgWidth, -imgHeight);
glTexCoord2f(1, 0);
glVertex2f(imgWidth, -imgHeight);
glTexCoord2f(1,1);
glVertex2f(imgWidth, imgHeight);
glTexCoord2f(0, 1);
glVertex2f(-imgWidth, imgHeight);
glEnd();
The answer is simple but with a complicated background that has to be understood.
OpenGL always rotate something not around its center but takes as center the point (0;0).
This can be an issue because if you translate your object somewhere and then your rotate it, it will rotate not on its center but around the (0;0) point (origin) creating a big rotation, I will say as a planet around the Sun.
Also OpenGL works with matrix, that with very barbaric simplification means that the operation are executed bottom to top.
// store the current model matrix
GL11.glPushMatrix();
// bind to the appropriate texture for this image
this.texture.bind();
// translate to the right location and prepare to draw
GL11.glColor3f(1, 1, 1);
GL11.glTranslated(x + (this.texture.getImageWidth() / 2), y + (this.texture.getImageHeight() / 2), 0);
GL11.glRotated(this.angle, 0, 0, 1);
GL11.glTranslated(-this.texture.getImageWidth() / 2, -this.texture.getImageHeight() / 2, 0);
// draw a quad textured to match the sprite
GL11.glBegin(GL11.GL_QUADS);
{
GL11.glTexCoord2f(0, 0);
GL11.glVertex2f(0, 0);
GL11.glTexCoord2f(0, this.texture.getHeight());
GL11.glVertex2f(0, this.texture.getImageHeight());
GL11.glTexCoord2f(this.texture.getWidth(), this.texture.getHeight());
GL11.glVertex2f(this.texture.getImageWidth(), this.texture.getImageHeight());
GL11.glTexCoord2f(this.texture.getWidth(), 0);
GL11.glVertex2f(this.texture.getImageWidth(), 0);
}
GL11.glEnd();
// restore the model view matrix to prevent contamination
GL11.glPopMatrix();
This means that first I am moving the texture to have its center positioned at (0;0) that means translating it backward half the dimensions.
Then I rotate it, and this is the crucial point, because you are using a strange way to rotate it, maybe the problem it's here, take a look to the javadoc:
SPECIFICATION
void glRotated( GLdouble angle,<br>
GLdouble x,<br>
GLdouble y,<br>
GLdouble z )<br>
void glRotatef( GLfloat angle,<br>
GLfloat x,<br>
GLfloat y,<br>
GLfloat z )<br>
PARAMETERS<br>
angle Specifies the angle of rotation, in degrees.
x, y, z<br>
Specify the x, y, and z coordinates of a vector, respectively.
DESCRIPTION<br>
glRotate produces a rotation of angle degrees around the<br>
vector (x,y,z).
First of all all x,y,z values should be between 0 and 1, if you want to rotate a 2d image then you should use the z axis, so the third param will be 1 that mean that you are rotating your image around the unit vector z.
The angle should be in degree and can be either positive or negative.
Try to change your code according to the documentation and you will have your problem solved.
Also with your quad you are drawing a 2x scaled quad, you are starting from -imageWidth to +imageWidth that means 2 times the width...