Draw a bitmap

I use Windows + Delphi 7 and have a 2D situation :

gDC:=GetDC(Handle); {Windows handle}
RC:=CreateRenderingContext(gDC,[opDoubleBuffered],24,0,0,0,0,0);
ActivateRenderingContext(gDC,RC);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glViewport(0,0,ClientWidth,ClientHeight);
glOrtho(0,ClientWidth,ClientHeight,0,0,1);

I want to draw a rectangular bitmap into my OpenGL backbuffer. I estimate that I need one GL_QUADS and bind a texture to it.

  1. Is this a good Idea? If yes:
  2. How do I obtain a texture from a bitmap in memory (= not from a file, I have a TBitmap)
  3. How do I bind that texture to a GL_QUADS?

Theoretically this sounds easy :smiley: I read a lot about bitmaps and textures but haven’t got a clue yet :sick:

Thanks for any help,

Bernd

1: Well, you’re using legacy-opengl, but there is nothing particular bad about this I think.
2: Generate a empty texture with glGenTextures, bind it with glBindTexture, fill your data in with glTexImage2D
3: you don’t bind it to GL_QUADS, you just bind it, all following calls will have the texture bound, until you bind a new texture.
Also make sure to set the UVs (0,1 for the top-left corner, 1,1 for the top-right corner, 0,0 for the bottom-left corner and 0,1 for the bottom-right corner)

I’m not familiar with Delphi, but from a brief look at the documentation, you can get the underlying bitmap handle (HBITMAP) via the Handle member, on which you can call the GetDIBits() GDI function.

IIRC, Windows uses GL_BGR format (i.e. blue first). Also, if the width isn’t a multiple of 4, you need to call glPixelStorei(GL_UNPACK_ALIGNMENT, 1) (the default is 4-byte alignment).

You don’t. You just bind it (with glBindTexture), enable texturing (glEnable(GL_TEXTURE2D)), then draw a quad, specifying texture coordinates as well as vertex coordinates (texture coordinates (0,0) are the lower-left corner for a bottom-up bitmap or the top-left corner for a top-down bitmap).

This is what works now:


VAR Bitmap:TBitmap;
    TextureID:LongInt;
    Buffer:Windows.BITMAP;
BEGIN
  ....
  (* Fill Bitmap *)
  ....
  glEnable(GL_TEXTURE_2D);
  glDisable(GL_BLEND);
  glColor4f(1,1,1,1);
  glGenTextures(1,@TextureID);
  glBindTexture(GL_TEXTURE_2D,TextureID);
  GetObject(Bitmap.Handle,SizeOf(Buffer),@Buffer);
  glTexImage2D(GL_TEXTURE_2D,0,3,Bitmap.Width,Bitmap.Height,0,GL_BGR,GL_UNSIGNED_BYTE,Buffer.bmBits);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST{GL_LINEAR});
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST{GL_LINEAR});
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP{GL_REPEAT});
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP{GL_REPEAT});
  glBegin(GL_QUADS);
    glTexCoord2f(0,0); glVertex3f(rX1,rY1,0);
    glTexCoord2f(1,0); glVertex3f(rX2,rY2,0);
    glTexCoord2f(1,1); glVertex3f(rX3,rY3,0);
    glTexCoord2f(0,1); glVertex3f(rX4,rY4,0);
  glEnd;
  glDisable(GL_TEXTURE_2D);
  glDeleteTextures(1,@TextureID);
  ....
END;

Thank you all for your help!