There is a spinning box. In the animator, each time it turns on 1/16 on each of the coordinate axes. Plus, the user can use the keyboard to turn the model by 1.0 per click.

Taking advantage of the advice in the topic " Determining visible and invisible faces ", he included the property GL_DEPTH_TEST . Now only the necessary edges are visible. But the edge on which there are images flickers wildly. How to get rid of it?

Added.

I seem to understand what the problem is. Several primitives are drawn on the front face on the same plane (and it doesn’t matter if it is a picture or a rectangle). But I still do not know how to get rid of it.

drawSquareFace method:

  private void drawSquareFace(GL2 gl, int width, int height, int depth) { gl.glBegin(GL2.GL_QUADS); gl.glTexCoord2f(0, 0); gl.glVertex3f(-width / 2, -height / 2, depth / 2); gl.glTexCoord2f(0, 1); gl.glVertex3f(-width / 2, height / 2, depth / 2); gl.glTexCoord2f(1, 1); gl.glVertex3f(width / 2, height / 2, depth / 2); gl.glTexCoord2f(1, 0); gl.glVertex3f(width / 2, -height / 2, depth / 2); gl.glEnd(); } 

ForegroundUtil class:

 import javax.media.opengl.GL2; public class ForegroundUtil { private static int myX; private static int myY; private static int myZ; public static void paint(GL2 gl, int x, int y, int z) { myX = x; myY = y; myZ = z; paintPhone(gl); paintDisplayOff(gl); ImageFromFile logoImage = new ImageFromFile("samsung1.jpg"); logoImage.paint(gl, SizeUtil.getLogoWidth(), SizeUtil.getLogoHeight(), SizeUtil.getLogoLeft(), SizeUtil.getLogoTop()); ImageFromFile buttonsImage = new ImageFromFile("buttons.jpg"); buttonsImage.paint(gl, SizeUtil.getButtonsWidth(), SizeUtil.getButtonsHeight(), SizeUtil.getButtonsLeft(), SizeUtil.getButtonsTop()); } public static void paintPoly(GL2 gl, float w, float h, float left, float top) { gl.glBegin (GL2.GL_POLYGON); gl.glTexCoord2d (0, 0); vertexHack(gl, left, top, 0); gl.glTexCoord2d(1, 0); vertexHack(gl, left + w, top, 0); gl.glTexCoord2d(1, 1); vertexHack(gl, left + w, top - h, 0); gl.glTexCoord2d(0, 1); vertexHack(gl, left, top - h, 0); gl.glEnd (); } private static void paintRectangle(GL2 gl, float w, float h, float left, float top, float r, float g, float b) { gl.glBegin(GL2.GL_QUADS); gl.glColor3f(r, g, b); vertexHack(gl, left, top, 0); vertexHack(gl, left + w, top, 0); vertexHack(gl, left + w, top + h, 0); vertexHack(gl, left, top + h, 0); gl.glEnd(); } private static void vertexHack(GL2 gl, float x, float y, float z) { // почему-то просто так не работало (этот хак меняет местами х и у) // когда всё заработает, постараюсь избавиться этого. // скорее всего неверный угол или ширину с высотой попутал. gl.glVertex3f(y + myX, x + myY, z + myZ); } public static void paintPhone(GL2 gl) { float phoneWidth = SizeUtil.getWidth(); float phoneHeight = SizeUtil.getHeight(); paintRectangle(gl, phoneWidth, phoneHeight, -SizeUtil.getShiftX(), -SizeUtil.getShiftY(), 0.09f, 0.095f, 0.095f); } private static void paintDisplayOff(GL2 gl) { float displayWidth = SizeUtil.getDisplayWidth(); float displayHeight = SizeUtil.getDisplayHeight(); float left = SizeUtil.getDisplayLeft(); float top = SizeUtil.getDisplayTop(); paintRectangle(gl, displayWidth, displayHeight, left, top, 0.17f, 0.17f, 0.21f); } } 

Class displaying images:

 import javax.imageio.ImageIO; import javax.media.opengl.GL; import javax.media.opengl.GL2; import java.awt.*; import java.awt.color.ColorSpace; import java.awt.image.*; import java.io.IOException; import java.nio.ByteBuffer; public class ImageFromFile { private float myWidth; private float myHeight; private ByteBuffer myByteBuffer; public ImageFromFile(String fileName) { BufferedImage bufferedImage = null; try { bufferedImage = ImageIO.read(this.getClass().getResource(fileName)); myWidth = bufferedImage.getWidth(); myHeight = bufferedImage.getHeight(); } catch (IOException e) { e.printStackTrace(); } WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, (int) myWidth, (int) myHeight, 4, null); ComponentColorModel colorModel= new ComponentColorModel (ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] {8, 8, 8, 8}, true, false, ComponentColorModel.TRANSLUCENT, DataBuffer.TYPE_BYTE); BufferedImage dukeImg = new BufferedImage (colorModel, raster, false, null); Graphics2D g = dukeImg.createGraphics(); g.drawImage(bufferedImage, null, null); DataBufferByte dukeBuf = (DataBufferByte)raster.getDataBuffer(); byte[] dukeRGBA = dukeBuf.getData(); myByteBuffer = ByteBuffer.wrap(dukeRGBA); myByteBuffer.position(0); myByteBuffer.mark(); } public void paint(GL2 gl, double width, double height, double left, double top) { gl.glBindTexture(GL.GL_TEXTURE_2D, 13); gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); gl.glTexImage2D (GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, (int) myWidth, (int) myHeight, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, myByteBuffer); gl.glEnable(GL.GL_TEXTURE_2D); gl.glBindTexture (GL.GL_TEXTURE_2D, 13); ForegroundUtil.paintPoly(gl, (float) width, (float) height, (float) left, (float) top); gl.glDisable(GL.GL_TEXTURE_2D); } } 

When you try to take a screenshot, the following image is saved:

alt text

    1 answer 1

    First, you reload textures from a file on each drawing and load it into video memory. This does not lead to flicker, but still not good.

    Secondly, you are not using glGenTextures , but using your own constants as the glBindTexture parameter. This is not criminal, does not lead to flicker, but also not the best practice, as well as any magic numbers.

    Thirdly, the flickering is most likely due to the fact that you draw the front panel polygon, screen, keyboard and logo in the same plane, which leads to uncertainty: a fragment of the texture and a fragment of the polygon claim the same pixel. Try to make a common texture for the entire front panel and display one textured polygon - it should not flicker. Another option is to move the planes of the screen, the logo and the keyboard to a minimum distance from the case.

    • Thanks for the feedback. I've tried this: first draw a panel, then increase myZ ( myZ++ ). And then we draw the rest. Just for the task, I will need to display an animation ... - angry
    • Yes, this is the way out. Although, if you draw animations on the screen, then you probably need to render in texture. And in this case, it will be possible to completely combine the texture of the front panel with the current frame on the screen and draw it with one polygon. Shl. You have too much procedural code. Try it OOPizirovat) - Nofate