Hot questions for Using Lightweight Java Game Library in opengl compat

Question:

I am doing a project on OpenGL 3D. I have several figures, and when I rotate the camera (scene), the figures seem to go beyond it (or beyond Viewport)

Normal condition:

Cropped figure:

How can I increase the viewing area? Or what can be done in this situation?

Now I am trying:

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glDepthFunc(GL_LEQUAL);
        glfwPollEvents();
        glPushMatrix();
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        GL11.glViewport(0, 0, width, height);
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        glLoadIdentity();

But it does not bring results.


Answer:

It seems that the object is clipped by the near plane of then orthographic projection. Change the near plane to solve the issue. The orthographic projection matrix is set by glOrtho.

By default the projection matrix is the Identity matrix. That is the same as you would do

GL11.glOrtho(-1, 1, -1, 1, 1, -1);

Increase the distance to the near and far plane to solve the issue. e.g:

GL11.glMatrixMode(GL11.GL_PROJECTION);
glLoadIdentity();
GL11.glOrtho(-1, 1, -1, 1, 10, -10);

Question:

This is my first time working with textures in OpenGL, although I've been studying it for 4 months now. And when I try to load a texture (Just an image with a square) I get just a black square.\

My texture load code:

  byte[] pixelData = new byte[0];
        try {
            BufferedImage bi = ImageIO.read(getClass().getResource(TEXTURE_FILES));
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(bi, "png", baos);
            baos.flush();
            pixelData = baos.toByteArray();
            baos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        ByteBuffer byteBuffer = ByteBuffer.wrap(pixelData);
        int texId = glGenTextures();
        glBindTexture(GL_TEXTURE_2D, texId);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 500, 500, 0,
                GL_RGB, GL_UNSIGNED_BYTE, byteBuffer);

        return texId;

I tried loading the texture with a simpler method, but it did not work. Also I tried another image or to place the texture not in my jar file

Texture show code:

                glEnable(GL_TEXTURE_2D);
                glColor4f(1f, 1f, 1f, 1f);
                glBindTexture(GL_TEXTURE_2D, texId);
                glBegin(GL_QUADS);
                glTexCoord2f(0, 0);
                glVertex2f(-1, -1);
                glTexCoord2f(1, 0);
                glVertex2f(1, -1);
                glTexCoord2f(1, 1);
                glVertex2f(1, 1);
                glTexCoord2f(0, 1);
                glVertex2f(-1, 1);
                glEnd();
                glDisable(GL_TEXTURE_2D);

My opengl paramters:

        glEnable(GL_ALPHA_TEST);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_COLOR_MATERIAL);
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
        glEnable(GL_NORMALIZE);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glShadeModel(GL_SMOOTH);
        glColorMask (true, true, true, true);
        glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);

I also read many other tips from this forum, but they are useless for me too

My result:

I tried also to run it on another computer with a different video card, but the result remains the same


Answer:

Possibly th issue is reading the png file:

BufferedImage bi = ImageIO.read(getClass().getResource(TEXTURE_FILES));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bi, "png", baos);
baos.flush();
pixelData = baos.toByteArray();
baos.close();

I've found a cde snippet (LWJGL3 Texture) where the file is read in a loop:

InputStream is = getClass().getResourceAsStream(TEXTURE_FILES);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int read1 = is.read();
while (read1 != -1) { 
    baos.write(read1);
    read1 = is.read();
}
byte[] pixelData= baos.toByteArray();
baos.close();
ByteBuffer byteBuffer = ByteBuffer.wrap(pixelData);

Alternatively a PNGDecoder is used: (See also Load a PNG file with pure OpenGL and Loading PNG images with TWL's PNGDecoder)

InputStream in = getClass().getResourceAsStream(TEXTURE_FILES);
PNGDecoder decoder = new PNGDecoder(in);
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(3*decoder.getWidth()*decoder.getHeight());
decoder.decode(byteBuffer, decoder.getWidth()*3, PNGDecoder.Format.RGB);
byteBuffer.flip();

Question:

I'm trying to create some code for loading and drawing 2D textures in LWJGL. Here is my code for drawing:

glfwShowWindow(window);
GL.createCapabilities();
loadTextures();
glClearColor(1f, 1f, 1f, 1f);

while (!glfwWindowShouldClose(window))
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //draw

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glPushMatrix();
    glTranslatef(100, 100, 0);
    glBindTexture(GL_TEXTURE_2D, testTexture);
    glBegin(GL_QUADS);
    {
        glTexCoord2f(0, 0);
        glVertex2f(0, 0);

        glTexCoord2f(1, 0);
        glVertex2f(TEXTURE_WIDTH, 0);

        glTexCoord2f(1, 1);
        glVertex2f(TEXTURE_WIDTH, TEXTURE_HEIGHT);

        glTexCoord2f(0, 1);
        glVertex2f(0, TEXTURE_HEIGHT);
     }

     glEnd();
     glPopMatrix();

    //end draw

    glfwSwapBuffers(window);
    glfwPollEvents();
}

glfwFreeCallbacks(window);
glfwDestroyWindow(window);
glfwTerminate();
glfwSetErrorCallback(null).free();

And this is my texture loading code:

try
{
    BufferedImage image = ImageIO.read(file);
    /*
    if (image.getType() != BufferedImage.TYPE_INT_ARGB)
    {
        throw new TextureException("Invalid image!");
    }
    */
    int[] pixels = new int[image.getWidth() * image.getHeight()];
    image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
    ByteBuffer byteBuffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4);

    for (int x = 0; x < image.getWidth(); x++)
    {
        for (int y = 0; y < image.getHeight(); y++)
        {
            int pixel = pixels[y * image.getWidth() + x];
            byteBuffer.put((byte)((pixel >> 16) & 0xFF));
            byteBuffer.put((byte)((pixel >> 8) & 0xFF));
            byteBuffer.put((byte)(pixel & 0xFF));
            byteBuffer.put((byte)((pixel >> 24) & 0xFF));
        }
    }

    byteBuffer.flip();
    int textureID = glGenTextures();
    glBindTexture(GL_TEXTURE_2D, textureID);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, byteBuffer);
    return textureID;
}
catch (Exception e)
{
    e.printStackTrace();
    throw new TextureException("Failed to load image!");
}

However, when I run this code all I get is a white screen. I checked the value of testTexture and it was set to 1, so I assume that's the texture's ID which makes me believe that worked, but I think there's something going wrong when drawing.


Answer:

Two-dimensional texturing has to be enabled by glEnable and can be disabled by glDisable:

glEnable(GL_TEXTURE_2D);

If texturing is enables then the texture wich is currently bound is applied, when the geometry is drawn by the glBegin/glEnd sequences.


If you want to draw the geometry in window (pixel) coordinates, then you've to set an orthographic projection with. The orthographic projection can be set by glOrtho. If you dont set the orthographic projection, the vertex coordinates would have to be in normalized device space in range [-1.0, 1.0].

In the following windowWidth an windowHeight is assumed to be the width and height of the window:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, windowWidth, windowHeight, 0.0, -1.0, 1.0);

glMatrixMode(GL_MODELVIEW);

while (!glfwWindowShouldClose(window))
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


    // [...]
}

Question:

I am programming a GUI framework in lwjgl (opengl for java). I've recently implemented rounded rectangles by rendering a couple of normal rectangles surrounded by circles. To render the circles I used GL11.GL_POINTS. I now reached the point, where I am trying to implement animations and for a window open animation, I decided to GL11.glScaled() it from small to normal. That works fine, but unfortunately my circles don't get resized.

I tried changing my GL_POINTS circle render method against a method that uses TRIANGLE_FANs and that worked fine. My problem there was, that the circles didn't look smooth and round at all and if I increase the rendered triangles it starts to lag very quick. Even though my computer isn't bad at all.

This is the code I've used to render circles with GL_POINTS.

        GL11.glEnable(GL11.GL_POINT_SMOOTH);
        GL11.glHint(GL11.GL_POINT_SMOOTH_HINT, GL11.GL_NICEST);
        GL11.glPointSize(radius);
        GL11.glBegin(GL11.GL_POINTS);
        GL11.glVertex2d(x, y);
        GL11.glEnd();
        GL11.glDisable(GL11.GL_POINT_SMOOTH);

This is the code I've used to scale the circles

        GL11.glPushMatrix();
        GL11.glTranslated(x, y, 0);
        GL11.glScaled(2.0f, 2.0f, 1);
        GL11.glTranslated(-x, -y, 0);
        render circles
        GL11.glPopMatrix();

I expect the circles to scale accordingly to the number I've put into glScaled()

Currently they aren't rescaling at all, just rendered at their normal size.


Answer:

Here's a demonstration of how to properly render a circle using triangle fans:

public void render() {
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);

    glLoadIdentity();
    // Coordinate system starts out as screen space coordinates
    glOrtho(0, 400, 300, 0, 1, -1);
    glColor3d(1, 0.5, 0.5);
    renderCircle(120, 120, 100);
    glColor3d(0.5, 1, 0.5);
    renderCircle(300, 200, 50);
    glColor3d(0.5, 0.5, 1);
    renderCircle(200, 250, 30);
}

private void renderCircle(double centerX, double centerY, double radius) {
    glPushMatrix();
    glTranslated(centerX, centerY, 0);
    glScaled(radius, radius, 1);
    // Another translation here would be wrong
    renderUnitCircle();
    glPopMatrix();
}

private void renderUnitCircle() {
    glBegin(GL_TRIANGLE_FAN);
    int numVertices = 100;
    double angle = 2 * Math.PI / numVertices;
    for (int i = 0; i < numVertices; ++i) {
        glVertex2d(Math.cos(i*angle), Math.sin(i*angle));
    }
    glEnd();
}

Output image:

The GL_POINT_SIZE value is actually the size of the point in pixels onscreen, not current coordinate units. For that reason your circles were unaffected by GL_SCALE. That's one reason not to use GL_POINTS to render circles. The other (arguably more important) reason being that GL_POINT_SIZE is severely deprecated and unsupported in newer OpenGL profiles.