When I draw a texture with transparency(in file) over ShapeRenderer any shape isn't being updating. When I set batch.setColor(1f, 1f, 1f, 0.5f) result is almost the same: I see stuck shapes with 50% transparency and also see the same animated shapes underneath.
I've tried to use Gdx.gl.glEnable(GL20.GL_BLEND) but it didn't help.
shape.begin(ShapeRenderer.ShapeType.Filled);
shape.setColor(0f / 255f, 7f / 255f, 32f / 255f, 1f);
shape.rect(0,0, width, height);
for(Star star : stars) {
star.render(shape);
star.update(dx, dy, delta);
}
shape.end();
batch.begin();
batch.draw(overlay, 0, 0, width, height);
app.batch.end();
render method inside the Star class:
public void render(ShapeRenderer shape) {
r = (position.z / max_depth);
g = (position.z / max_depth);
b = (position.z / max_depth);
a = 1.f;
if(r < 0) r = 0;
if(g < 7f / 255f) g = 7f / 255f;
if (b < 32f / 255f) b = 32f / 255f
float radius = (position.z / max_depth) * maxRadius;
if(radius < 1) radius = 1;
shape.setColor(r, g, b, a);
shape.circle(position.x, position.y, radius);
}
You need to set BlendFunction to batch according to your desired blend output. By default it is enabled with GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA
so try to change to :
batch.setBlendFunction(GL20.GL_SRC_ALPHA,GL20.GL_DST_COLOR);
May be this not fit your requirement so choose appropriate one, according to your requirement.
Related
I am learning opengl but having problem rendering sphere. I can draw and bind the texture of polygon normally but when I try to use the same method to the sphere drew by triangle strip, it just didn't went well. Part of the texture is broken. (Pic on below)
May I know what did I do wrongly? Sorry if this is an obvious question.
Here are the code of sphere :
(before adding the texture part, the sphere can be displayed normally)
private void drawSphere(GL gl) {
Position spherePosition = state.getSpherePosition();
final float PI = 3.141592f;
gl.glPushMatrix();
if(spheretexture == null){
setSphereTexture();
}
gl.glTranslated(spherePosition.getX(), spherePosition.getY(), spherePosition.getZ());
float[] ambientDiffuse = new float[] {255.0f, 255.0f, 255.0f, 1.0f};
gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT_AND_DIFFUSE, ambientDiffuse, 0);
gl.glEnable(GL_BLEND);
gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
float x, y, z, alpha, beta; // Storage for coordinates and angles
float radius = 25f;
int gradation = 10;
for (alpha = 0.0f; alpha < PI; alpha += PI / gradation) {
spheretexture.enable();
spheretexture.bind();
gl.glBegin(GL_TRIANGLE_STRIP);
for (beta = 0.0f; beta < 2.01 * PI; beta += PI / gradation) {
x = (float) (radius * Math.cos(beta) * Math.sin(alpha));
y = (float) (radius * Math.sin(beta) * Math.sin(alpha));
z = (float) (radius * Math.cos(alpha));
gl.glTexCoord2f(beta / (2.0f * PI), alpha / PI);
gl.glVertex3f(x, y, z);
x = (float) (radius * Math.cos(beta) * Math.sin(alpha + PI / gradation));
y = (float) (radius * Math.sin(beta) * Math.sin(alpha + PI / gradation));
z = (float) (radius * Math.cos(alpha + PI / gradation));
gl.glTexCoord2f(beta / (2.0f * PI), alpha / PI + 1.0f / gradation);
gl.glVertex3f(x, y, z);
}
gl.glEnd();
spheretexture.disable();
gl.glDisable(GL_BLEND);
gl.glPopMatrix();
}
}
Output picture:
The major issue is that the top cap of the sphere is drawn twice. That causes Z-fighting. Note, first it is drawn buy the strip between PI-PI/gradation and PI and then it is drawn by the strip between PI and PI+PI/gradation. That is caused, because the outer loop does one an extra pass. Change it to:
for (alpha = 0.0f; alpha < PI-PI/gradation; alpha += PI / gradation) {
// [...]
}
or even better
for (int i = 0; i < gradation; ++ i ) {
float alpha = PI * (float)i / (float)(gradation);
// [...]
}
I`m using Vertex Buffers in JOGL. I have a few hundred thousand triangles. Each triangle contains :
9 floats for the vertices - 3 for each edge
3 floats for the surface normal
3 floats for the colors.
I can`t seem to display the triangles or the colors. I know the normals are being calculated correctly.
This doesn`t work.
gl.glDrawArrays(GL2.GL_TRIANGLES, 0, vertxcnt);
But, the below snippet works - however I don`t see the colors. So, I know the points that are making up the triangles are correct.
gl.glDrawArrays(GL2.GL_POINTS, 0, vertxcnt);
So, if the points and the normals are correctly being calculated, I thinking is I`m going wrong in the render(gl) function. The code for that is below. What am I doing wrong? I cant post SSCCE now due to the complexity, but would like to know if anything is glaringly wrong.
private void render(GL2 gl) {
// VBO
// Enable Pointers
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, VBOVertices[0]); // Set Pointers To Our Data
gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); // Enable Vertex Arrays
gl.glVertexPointer(3, GL.GL_FLOAT, BufferUtil.SIZEOF_FLOAT * 15, 0); //15 = 9 vertices of triangles + 3 normal + 3 colors
gl.glEnableClientState(GL2.GL_NORMAL_ARRAY);
gl.glNormalPointer(GL.GL_FLOAT, BufferUtil.SIZEOF_FLOAT * 15, BufferUtil.SIZEOF_FLOAT * 9);
gl.glEnableClientState(GL2.GL_COLOR_ARRAY);
gl.glColorPointer(3, GL.GL_FLOAT, BufferUtil.SIZEOF_FLOAT * 15, BufferUtil.SIZEOF_FLOAT * 12);
// Render
// Draw All Of The Triangles At Once
gl.glPointSize(4);
gl.glDrawArrays(GL2.GL_POINTS, 0, vertxcnt);
// Disable Pointers
// Disable Vertex, Normals and Color Arrays
gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL2.GL_NORMAL_ARRAY);
gl.glDisableClientState(GL2.GL_COLOR_ARRAY);
}
Here is the init and display functions.
#Override
public void init(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
gl.glClearColor(0.0f, 0.0f, 6.0f, 0.5f);
gl.glClearDepth(1.0f); // Depth Buffer Setup
gl.glDepthFunc(GL.GL_LEQUAL); // The Type Of Depth Testing (Less Or
// Equal)
gl.glEnable(GL.GL_DEPTH_TEST); // Enable Depth Testing
gl.glDepthFunc(GL2.GL_LESS);
gl.glEnable(GL2.GL_LIGHTING);
gl.glEnable(GL2.GL_LIGHT0);
gl.glEnable(GL2.GL_AUTO_NORMAL);
gl.glEnable(GL2.GL_NORMALIZE);
gl.glEnable(GL2.GL_CULL_FACE);
gl.glFrontFace(GL2.GL_CCW);
gl.glCullFace(GL2.GL_BACK);
gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
gl.glShadeModel(GL2.GL_SMOOTH);
buildVBOs(gl);
}
#Override
public void display(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
gl.glClearColor(.0f, .0f, .2f, 0.9f);
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
glu.gluLookAt(45, 0, 0, 0, 0, 0, 0.0, 1.0, 0.0);
float ma_x = (float) getMax(fx0);
float mi_x = (float) getMin(fx0);
float tr_x = (ma_x + mi_x) / 2;
float ma_y = (float) getMax(fy0);
float mi_y = (float) getMin(fy0);
float tr_y = (ma_y + mi_y) / 2;
float ma_z = (float) getMax(fz0);
float mi_z = (float) getMin(fz0);
float tr_z = (ma_z + mi_z) / 2;
gl.glScalef(scaleFac, scaleFac, scaleFac);
gl.glRotatef(rotFac, 0, 1, 0);
gl.glTranslatef(-tr_x, -tr_y, -tr_z);
for (int i = 0; i < 30; i++) {
render(gl);
gl.glRotatef(12, 0, 0, 1);
}
}
*/
private void createVects(double ang) {
int cnt = fx0.size();
for (int i = 0; i < cnt - 1; i++) {
// Triangle 1 and 2 [Top]
float x0 = (float) (fx0.get(i) * Math.cos(ang) - fy0.get(i) * Math.sin(ang));
float y0 = (float) (fx0.get(i) * Math.sin(ang) + fy0.get(i) * Math.cos(ang));
float z0 = fz0.get(i).floatValue();
Vect3D v0 = new Vect3D(x0, y0, z0);
fvert.add(v0); // 0
float x1 = (float) (fx0.get(i + 1) * Math.cos(ang) - fy0.get(i + 1) * Math.sin(ang));
float y1 = (float) (fx0.get(i + 1) * Math.sin(ang) + fy0.get(i + 1) * Math.cos(ang));
float z1 = fz0.get(i + 1).floatValue();
Vect3D v1 = new Vect3D(x1, y1, z1);
fvert.add(v1);// 1
float x2 = (float) (fx1.get(i + 1) * Math.cos(ang) - fy1.get(i + 1) * Math.sin(ang));
float y2 = (float) (fx1.get(i + 1) * Math.sin(ang) + fy1.get(i + 1) * Math.cos(ang));
float z2 = fz1.get(i + 1).floatValue();
Vect3D v2 = new Vect3D(x2, y2, z2);
fvert.add(v2);// 2
Vect3D n0 = calcNormal(v0, v1, v2);
fnorm.add(n0);
// VBO
vertices.put(x0); //vertices of the triangle
vertices.put(y0);
vertices.put(z0);
vertices.put(x1);
vertices.put(y1);
vertices.put(z1);
vertices.put(x2);
vertices.put(y2);
vertices.put(z2);
vertices.put(n0.x); // normals
vertices.put(n0.y);
vertices.put(n0.z);
vertices.put(0.5f); // colors // for now
vertices.put(0.0f);
vertices.put(0.0f);
}
}
I am making a brick breaker game in Java for fun. In this game the bat is a curved arc that goes around the circumference of a circle. I am struggling to make the bat behave properly.
I am drawing an arc that comes from 2 points on the circle:
public void update(){
if(dir == 1){
angle += 0.05;
}else if(dir == 0){
angle -= 0.05;
}
x0 = a + r * Math.cos(angle);
y0 = b + r * Math.sin(angle);
x1 = a + r * Math.cos(angle - 0.1);
y1 = b + r * Math.sin(angle - 0.1);
}
public void draw(Graphics2D g){
g.setColor(Color.black);
g.fillRect(0, 0, GamePanel.WIDTH, GamePanel.HEIGHT);
int tr = (int)Math.sqrt((x0-a)*(x0-a) + (y0-b)*(y0-b));
int x = (int) (a - tr);
int y = (int) (a - tr);
int width = 2*tr;
int height = 2*tr;
int startAngle = (int) (180/Math.PI*Math.atan2(y0-b, x0-a));
int endAngle = (int) (180/Math.PI*Math.atan2(y1-b, x1-a));
g.setColor(Color.white);
g.drawArc(x, y, width, height, startAngle, endAngle);
}
In theory this should work, the second points being generated from the angle going slightly further, but the length of the arc keeps varying in size...? That is where the problem lies.
This here statement breaks the pattern:
int y = (int) (a - tr);
It would make more sense to use
int y = (int) (b - tr);
And then there is the way g.drawArc is being called:
g.drawArc(x, y, width, height, startAngle, endAngle);
The last parameter is the angle of the arc, so I think you want
g.drawArc(x, y, width, height, startAngle, endAngle - startAngle );
possibly even
g.drawArc(x, y, width, height, startAngle, Math.abs(endAngle - startAngle) );
Hey i implement code to rotate AND flip image.
Left, Right, Upsidedown rotation works.
Fliping Horizontal, Vertical works.
But they dont work together
When i flip image and then i rotate, it disappears.
BUT
When i flip and flip image (so it is as it was before flip) i can rotate normally.
I try to understand what is wrong and i think the problem is with transform or scale.
Do you have any idea how to fix this code ?
/**
* Paint the icons of this compound icon at the specified location
*
* #param c
* The component on which the icon is painted
* #param g
* the graphics context
* #param x
* the X coordinate of the icon's top-left corner
* #param y
* the Y coordinate of the icon's top-left corner
*/
#Override
public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D) g.create();
AffineTransform af = g2.getTransform();
int cWidth = icon.getIconWidth() / 2;
int cHeight = icon.getIconHeight() / 2;
int xAdjustment = (icon.getIconWidth() % 2) == 0 ? 0 : -1;
int yAdjustment = (icon.getIconHeight() % 2) == 0 ? 0 : -1;
if (rotate == Rotate.DOWN) {
g2.translate(x + cHeight, y + cWidth);
g2.rotate(Math.toRadians(90));
icon.paintIcon(c, g2, -cWidth, yAdjustment - cHeight);
} else if (rotate == Rotate.UP) {
g2.translate(x + cHeight, y + cWidth);
g2.rotate(Math.toRadians(-90));
icon.paintIcon(c, g2, xAdjustment - cWidth, -cHeight);
} else if (rotate == Rotate.UPSIDE_DOWN) {
g2.translate(x + cWidth, y + cHeight);
g2.rotate(Math.toRadians(180));
icon.paintIcon(c, g2, xAdjustment - cWidth, yAdjustment - cHeight);
} else if (rotate == Rotate.VERTICAL) {
g2.translate(0, getIconHeight());
g2.scale(1, -1);
icon.paintIcon(c, g2, x, y);
vert = !vert; //boolean flag
} else if (rotate == Rotate.HORIZONTAL) {
g2.translate(getIconWidth(), 0);
g2.scale(-1, 1);
icon.paintIcon(c, g2, x, y);
hor = !hor; //boolean flag
} else if (rotate == Rotate.VERTICALLY_HORIZONTAL) {
g2.translate(getIconWidth(), getIconHeight());
g2.scale(-1, -1);
icon.paintIcon(c, g2, x, y);
hor = !hor;
vert = !vert;
} else if (rotate == Rotate.CENTER) {
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
AffineTransform original = g2.getTransform();
AffineTransform at = new AffineTransform();
at.concatenate(original);
at.translate((getIconWidth() - icon.getIconWidth()) / 2,
(getIconHeight() - icon.getIconHeight()) / 2);
at.rotate(Math.toRadians(angle), x + cWidth, y + cHeight);
g2.setTransform(at);
icon.paintIcon(c, g2, x, y);
g2.setTransform(original);
}
}
If you want them to work together you've got to save the image you've made with your transform. Here is an example
Image orig = ...;
Image transformedCopy = ...;
AffineTransformation at = ...;
transformedCopy.getGraphics().setTransform(at).drawImage(orig);
//transformedCopy will now have a copy of the transformed image
I am painting a curve arrow using java,
but I can't place to arrow head in the right location .
can you help me please
This is what I done so far,
icon should be dynamic size, so all should be painted according to the
m_size variable
Thank you.
public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D) g;
Object hintOriginal = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int strokeSize = m_size / 6;
Stroke strokeOriginal = g2.getStroke();
g2.setStroke(new BasicStroke(strokeSize, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER));
g2.drawArc(x + (strokeSize / 2), y + (strokeSize / 2), m_size - (strokeSize * 2), m_size - (strokeSize * 2), 45, 180);
g2.setStroke(strokeOriginal);
int arrSize = (m_size / 4) + strokeSize;
int[] xArr = new int[3];
int[] yArr = new int[3];
xArr[0] = x;
xArr[1] = x + arrSize;
xArr[2] = x + (arrSize / 2);
yArr[0] = y;
yArr[1] = y;
yArr[2] = y - (arrSize / 2);
AffineTransform origXform = g2.getTransform();
AffineTransform newXform = (AffineTransform) (origXform.clone());
newXform.rotate(Math.toRadians(135), x + m_size / 2, y + m_size / 2);
g2.setTransform(newXform);
g2.fillPolygon(xArr, yArr, 3);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, hintOriginal);
}