Some basic OpenGL 2D drawing questions

Hello, I’m a very very n00b in OpenGL, I can’t get all opengl drawing function in nehe and the red book to work! :frowning:
Even the basic one to draw triangle and square :frowning:

The sample is working perfectly, but when I use it in my code, it show nothing or even worse my previous rendering is gone!
Is this related with my opengl initialization? Cos the different from the sample is only in initialization.
I use kevglass spaceinvaders tutorial to init GL and render texture, this is for 2D games anyway, and so far I can render opaque and full transparent (bitmask) image in screen, it’s great! :slight_smile:
Now I’m trying to draw rectangle, circle, fill rectangle, circle, and drawing scaling image with alpha blending.
Anyone can help me with some code? I’m not going to deep with opengl, it’s frustrating me, I only need to have a working replacement to my Java2D rendering functions.

This is my GL init :


            // init GL
            // enable textures since we're going to use these for our sprites
            GL11.glEnable(GL11.GL_TEXTURE_2D);

            // disable the OpenGL depth test since we're rendering 2D graphics
            GL11.glDisable(GL11.GL_DEPTH_TEST);

            GL11.glMatrixMode(GL11.GL_PROJECTION);
            GL11.glLoadIdentity();

            GL11.glOrtho(0, size.width, size.height, 0, -1, 1);

            // enable transparency
            GL11.glEnable(GL11.GL_BLEND);
            GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

All textures and how to load it is plain same with kevglass tutorial.

I need code with this one :


    Color col;

    public void fillRect(int x, int y, int width, int height) {
       // draw and fill rectangle with specified coordinate and color col 
    }

    public void drawRect(int x, int y, int width, int height) {
       // draw rectangle 
    }

    public boolean drawImage(Texture tex, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2) {
       // drawing texture tex to dx1, dy1 with size dx2-dx1, dy2-dy1
       // and draw partial of image from sx1, sy1 with size sx2-sx1, sy2-sy1
    }



    // this is what i do to draw image
    // i even don't know what is going on there :) directly taken from the tutorial
    public boolean drawImage(Texture tex, int x, int y) {
       // store the current model matrix
       GL11.glPushMatrix();

       texture.bind();

       // translate to the right location and prepare to draw
       GL11.glTranslatef(x, y, 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, texture.getHeight());
          GL11.glVertex2f(0, texture.getImageHeight());

          GL11.glTexCoord2f(texture.getWidth(), texture.getHeight());
          GL11.glVertex2f(texture.getImageWidth(), texture.getImageHeight());

          GL11.glTexCoord2f(texture.getWidth(), 0);
          GL11.glVertex2f(texture.getImageWidth(), 0);
       }
       GL11.glEnd();

       // restore the model view matrix to prevent contamination
       GL11.glPopMatrix();

       return true;
    }

Hopefully someone kind here can help…
Have been fiddle with this GL stuff overnight and got not advance than rendering image… :frowning:
Guess this basic operation should be easy to do.

Thanks in advance…

PS: if anyone curious what I’m trying to do, i’m trying to replace my Java2D rendering with OpenGL
so I’m not taking this opengl stuff too much, cos so far I see it’s about making 3D stuff
if anyone know any LWJGL resources related with 2D, please let me know

The sample is working perfectly, but when I use it in my code,
it show nothing or even worse my previous rendering is gone!

You forgot to reset the matrix mode. Try that.

By the way, it is not easy to implements some particular parts of Java2D painting with OpenGL. Fonts are really difficult and antialiasing can be tricky.

Did you disable texturing before rendering the primitives?
Here’s a some stuff (mainly copy-paste from some of my older stuff, might not work 100% but might give you ideas):


private static final float TWOPI = (float)Math.PI*2;

      public static void glColor(Color color) {
            glColor4ub(color.getRedByte(), color.getGreenByte(), color.getBlueByte(), color.getAlphaByte());
      }

      public static void glRect(int x, int y, int width, int height, float lineWidth) {
            glDisable(GL_TEXTURE_2D);
            glLineWidth(lineWidth);
            glBegin(GL_LINE_LOOP);
                  glVertex2f(x, y);
                  glVertex2f(x+width, y);
                  glVertex2f(x+width, y+height);
                  glVertex2f(x, y+height);
            glEnd();
      }

      public static void glFillRect(int x, int y, int width, int height) {
            glDisable(GL_TEXTURE_2D);
            glRecti(x, y, x + width, y + height);
      }

      public static void glCircle(int centerx, int centery, float radius, int slices) {
            float step = TWOPI/slices;
            glDisable(GL_TEXTURE_2D);
            glBegin(GL_LINE_LOOP);
                  for(float angle = 0.0f; angle < TWOPI; angle += step)
                        glVertex2f(centerx+(float)Math.cos(angle)*radius, centery+(float)Math.sin(angle)*radius);
            glEnd();
      }

      public static void glFillCircle(int centerx, int centery, float radius, int slices) {
            float step = TWOPI/slices;
            glDisable(GL_TEXTURE_2D);
            glBegin(GL_TRIANGLE_FAN);
                  for(float angle = 0.0f; angle < TWOPI; angle += step)
                        glVertex2f(centerx+(float)Math.cos(angle)*radius, centery+(float)Math.sin(angle)*radius);
            glEnd();
      }
      
      public static void glDrawImage(Texture tex, int x, int y, int w, int h, int subx, int suby, int subw, int subh) {
            float tx0 = ((float) subx / tex.getWidth());
            float tx1 = ((float) (subx + subw) / tex.getWidth());
            float ty0 = ((float) suby / tex.getHeight());
            float ty1 = ((float) (suby + subh) / tex.getHeight());
            glEnable(GL_TEXTURE_2D);
            glBindTexture(GL_TEXTURE_2D, tex.getID());
            glBegin(GL_QUADS);
                  glTexCoord2f(tx0, ty0);
                  glVertex2f(x, y);
                  glTexCoord2f(tx1, ty0);
                  glVertex2f(x+w, y);
                  glTexCoord2f(tx1, ty1);
                  glVertex2f(x+w, y+h);
                  glTexCoord2f(tx0, ty1);
                  glVertex2f(x, y+h);
            glEnd();
    }

I suggest to create an Image-class (which just holds precalculated texture coordinates and reference to Texture), so you can draw images like this:


public static void glDrawImage(Image image, int x, int y, int width, int height) {
            glEnable(GL_TEXTURE_2D);
            glBindTexture(GL_TEXTURE_2D, image.getTexture().getID());
            glBegin(GL_QUADS);
                  glTexCoord2f(image.getTX0(), image.getTY0());
                  glVertex2f(x, y);
                  glTexCoord2f(image.getTX1(), image.getTY0());
                  glVertex2f(x+width, y);
                  glTexCoord2f(image.getTX1(), image.getTY1());
                  glVertex2f(x+width, y+height);
                  glTexCoord2f(image.getTX0(), image.getTY1());
                  glVertex2f(x, y+height);
            glEnd();
      }

public static void glDrawImage(Image image, int x, int y) {
            glDrawImage(image, x, y, image.getWidth(), image.getHeight());
      }

When rendering images you should set R,G,B to 1.0f (unless you want to colorize the image) and alpha to whatever you want.

For example
glColor4f(1.0f,1.0f,1.0f,0.5f) // 50% transparent
glDrawImage(…

Wow!! Thank you very much Inquisitor!!!
You are my hero! ;D
Now I got a working drawing/filling rectangle, thanks!
Alpha blending also working perfectly! I’m happyyy :smiley:
But the public static void glDrawImage(Texture tex, int x, int y, int w, int h, int subx, int suby, int subw, int subh) need a little modification.
It is only working for image that has power of 2 dimension, could you help me a little more about it, I have trying to change the tex.getWidth to tex.getImageWidth and vice versa, but it’s not working :frowning:
This is my modification that working for only image that has power of 2 dimension :


    public boolean drawImage(Texture texture,
                             int dx1, int dy1, int dx2, int dy2,
                             int sx1, int sy1, int sx2, int sy2) {
        GL11.glEnable(GL11.GL_TEXTURE_2D);

        texture.bind();

        float tx0 = ((float) sx1 / texture.getImageWidth());
        float tx1 = ((float) sx2 / texture.getImageWidth());
        float ty0 = ((float) sy1 / texture.getImageHeight());
        float ty1 = ((float) sy2 / texture.getImageHeight());
        // 0.25, 0.5, 0.25, 0.5
        // 32.0, 64.0, 32.0, 64.0

//        System.out.println(tx0+", "+tx1+", "+ty0+", "+ty1);

        GL11.glBegin(GL11.GL_QUADS);
            GL11.glTexCoord2f(tx0, ty0);
            GL11.glVertex2f(dx1, dy1);

            GL11.glTexCoord2f(tx1, ty0);
            GL11.glVertex2f(dx2, dy1);

            GL11.glTexCoord2f(tx1, ty1);
            GL11.glVertex2f(dx2, dy2);

            GL11.glTexCoord2f(tx0, ty1);
            GL11.glVertex2f(dx1, dy2);
        GL11.glEnd();

        return true;
    }

Thank you very much Inquisitor for the wonderful code! :slight_smile:

PS: Shadowcaster2, I’m really a opengl n00b, I don’t even know what do you mean by “reset the matrix mode”

No probs, glad i could help.

The method looks fine now. You can use only power-of-2 textures with opengl. There are some extensions to to overcome this but I think they aren’t very supported and you should get better performance with pow2 textures anyways.

I also have a problem with basic i’m trying to draw two boxes with the code below but they don’t come out how i want them too, any help would be appreciated


public void square(int x, int y, int length) {
            GL11.glColor3f(1f,0f,0f);
                        
            GL11.glBegin(GL11.GL_LINE_LOOP);
            {
                  GL11.glVertex2f(x, y);
                  GL11.glVertex2f(x + length, y);
                  GL11.glVertex2f(x + length, y + length);
                  GL11.glVertex2f(x, y + length);
            }
            GL11.glEnd();

public void renderloop() {
                  
                        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
            GL11.glPushMatrix();
            GL11.glTranslatef(160, 120, 0.0f);
            
                        // draw first box
            square(10, 10, 100);
                        
                        //draw second box
                        square(10, 200, 100);
                        
            GL11.glPopMatrix();
}

i’m trying to draw to seperate boxes but they just apper connected
thx