Get pixels from a CUDA graphics resource - opengl

How can I obtain a pixel buffer object and get the RGB pixels into an array, given a CUDA graphics resource? Could somebody provide an example or confirm if my own attempt is correct? The existing code looks like this:
cutilSafeCall(cudaGraphicsMapResources(1, &render_cuda_pbo_resource, stream));
uchar4 *d_output;
size_t num_bytes;
cutilSafeCall(cudaGraphicsResourceGetMappedPointer((void **)&d_output, &num_bytes, render_cuda_pbo_resource));
I have added the following code:
glBindTexture (GL_TEXTURE_2D, renderTex);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
glBegin(GL_QUADS);
glTexCoord2f (0.0, 0.0);
glVertex3f (-1.0, -1.0, 0.0);
glTexCoord2f (1.0, 0.0);
glVertex3f (1.0, -1.0, 0.0);
glTexCoord2f (1.0, 1.0);
glVertex3f (1.0, 1.0, 0.0);
glTexCoord2f (0.0, 1.0);
glVertex3f (-1.0, 1.0, 0.0);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
glReadPixels(10, 10, width, height, GL_BGRA, GL_UNSIGNED_BYTE, data);

You don't.
OpenGL objects are OpenGL objects; CUDA objects are CUDA objects. If you want CUDA to put stuff into OpenGL objects, you must give CUDA OpenGL objects and have it put the stuff into them. This is generally done with cudaGraphicsGLRegisterBuffer.

Related

OpenGL Texture doesn't show

I'm trying to show a texture in Qt with opengl but it just doesn't show the texture when i run.
I did some research and found out I needed to make the height and width of the texture as a power of 2. my texture is now (1024x1024).
I also added a lot of glTexParameterf's that could resolve my problem, but still no luck.
void WorldView::paintGL ()
{
this->dayOfYear = (this->dayOfYear+1);
this->hourOfDay = (this->hourOfDay+1) % 24;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// store current matrix
glMatrixMode( GL_MODELVIEW );
glPushMatrix( );
gluLookAt(camPosx ,camPosy ,camPosz,
camViewx,camViewy,camViewz,
camUpx, camUpy, camUpz );
//Draw Axes
glDisable( GL_LIGHTING );
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(10.0, 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 10.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 10.0);
glEnd();
//load texture
QImage img;
if(!img.load(":/files/FloorsCheckerboardSmall.bmp"))
printf("could not open image");
//try showing texture
glEnable( GL_LIGHTING );
glEnable( GL_COLOR_MATERIAL );
glEnable(GL_TEXTURE_2D);
unsigned int m_textureID;
glGenTextures(1, &m_textureID);
glBindTexture(GL_TEXTURE_2D,m_textureID);
glTexImage2D(GL_TEXTURE_2D,0,(GLint)img.depth(),(GLsizei)img.width(),(GLsizei)img.height(),0,GL_RGB,GL_UNSIGNED_BYTE,img.bits());
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glColor3d(1.0,0.0,0.0);
glBegin(GL_POLYGON);
glTexCoord2d(0.0,5.0);
glVertex2d(0.0,3.0);
glTexCoord2d(0.0,0.0);
glVertex2d(0.0,0.0);
glTexCoord2d(5.0,0.0);
glVertex2d(3.0,0.0);
glTexCoord2d(5.0,5.0);
glVertex2d(3.0,3.0);
glEnd();
}
EDIT1: Could it be my texture is too big?
EDIT2: glBindTexture(GL_TEXTURE_2D,m_textureID); placed before glBindTexture instead of before glColor3d
SOLVED: My img.depth() returned an invalid internalFormat value. I replaced this GLint with the valid interalFormat value GL_RGBA. I also changed the format from GL_RGB to GL_RGBA (see genpfaults answer)
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,(GLsizei)img.width(),(GLsizei)img.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,img.bits());
You have to call
glBindTexture(GL_TEXTURE_2D,m_textureID);
before calling glTexImage2D(...). Or OpenGL won't know where the data you send it belongs.
vvvvvvvvvvvvvvvvvv
glTexImage2D(GL_TEXTURE_2D,0,(GLint)img.depth(),(GLsizei)img.width(),(GLsizei)img.height(),0,GL_RGB,GL_UNSIGNED_BYTE,img.bits());
img.depth() returns 32
Then you need to pass in a valid internalFormat value, not img.depth(). Try GL_RGBA.
You should also set format to GL_RGBA since img.bits() is actually four-component.

fastest way to set every pixel

I have programmed a little raytracer in c++,
and want to show the raytraced image in a window.
I tried using a pixel buffer object in opengl,
then map the buffer into memory and manipulate the pixels one by one,
but at fullscreen resolution 1920x1080, I only get 4 fps
without raytracing and without changing the pixels colors
just the mapping and unmapping!
so i'm basically looking for the fastest way to display a raytraced image in a window.
i'm currently doing this way:
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, width * height * 4, 0, GL_STREAM_DRAW_ARB);
if (pixels = (uint*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB))
{
//modify pixels
glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
}
else
return;
//copy from pbo to texture
glBindTexture(GL_TEXTURE_2D, pbo_texture);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//draw image
glColor4f(1.0, 1.0, 1.0, 1.0);
glBindTexture(GL_TEXTURE_2D, pbo_texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, -1.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, 0.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, 0.0);
glEnd();
glutSwapBuffers();
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
glBindTexture(GL_TEXTURE_2D, 0);
Check the memory traversal if you use loops. You should traverse your buffer in the right order, otherwise you may have cache miss at each iteration. If you use nested loops sometimes you only have to switch the x/y iteration order.
Also, don't read data from graphic memory. It tends to be slow. Only write to PBO.
It looks like a syncro issue. I'm not sure you need to map pbo at every frame. Check this link on OpenGL Pixel Buffer Object (PBO). There's also a workaround for stalls which could improve things

Partly Transparent HUD-style overlay in OpenGL

I'm trying to make a program showing a red rotating cube in the background, overlayed with a textured quad.
The texture is a simple 24-bit bitmap of the words "Hello World" in black over a white background. I want the white background to be transparent so that the cube can be seen behind the overlay. The image loader checks the value of each pixel and adds the relevant alpha value to convert the image into a 32-bit bitmap.
At the moment, my program displays the overlay with black text but a red background, same colour as the cube. Below is the code used for the initial texture set up:
if (bitmap->Load("test.bmp")) {
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3, bitmap->GetWidth(), bitmap->GetHeight(),
0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap->GetPixelData());
}
And this is the whole of my display function, in case anything is interfering with anything else.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40, 1, 0.1, 27.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glTranslatef(0.0, 0.0, -1.1);
glRotatef(angle, 1.0, 1.0, 0.0);
glutSolidCube(0.1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 640, 480, 0.0, -1.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_CULL_FACE);
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glTexCoord2d(0.0, 0.0); glVertex2f(0.0, 0.0);
glTexCoord2d(1.0, 0.0); glVertex2f(320.0, 0.0);
glTexCoord2d(1.0, 1.0); glVertex2f(320.0, 240.0);
glTexCoord2d(0.0, 1.0); glVertex2f(0.0, 240.0);
glEnd();
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glFlush();
glutSwapBuffers();
The default texture environment is GL_MODULATE which mixes in the current color (red from your cube) with the incoming texel value.
Switch to GL_DECAL or do a glColor3ub(255,255,255) before you render your text.

wglShareLists fails with error 6 : ERROR_INVALID_HANDLE The handle is invalid

I try to share a HPBUFFERARB between two classes : TGLForm and TGLForm2.
(I tried FBO but having an old Borland Builder 6 version I can't manage using FBO)
My goal is to display the same buffer in two openGL windows.
So I declared outside of the first Form this object :
struct GLRenderToTexture
{
struct
{
HDC hdc;
HGLRC hGlRc;
HPBUFFERARB hBuffer;
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;
PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB;
PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB;
PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB;
PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB;
PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB;
PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB;
PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB;
} wgl;
unsigned int texture; // the texture we're going to render to
};
GLRenderToTexture RTT;
I intialize it so as to have the same pixel format as the first GLForm :
void __fastcall TGLForm::FormCreate(TObject *Sender)
{
ghDC = GetDC(Handle);
if (!bSetupPixelFormat(ghDC)) Close();
ghRC = wglCreateContext(ghDC);
wglMakeCurrent(ghDC, ghRC);
InitializeGL();
int pixelFormats;
int intAttrs[32] ={WGL_RED_BITS_ARB,8,WGL_GREEN_BITS_ARB,8,WGL_BLUE_BITS_ARB,8,WGL_ALPHA_BITS_ARB,8,WGL_DRAW_TO_PBUFFER_ARB, GL_TRUE,WGL_BIND_TO_TEXTURE_RGBA_ARB, GL_TRUE,WGL_SUPPORT_OPENGL_ARB,GL_TRUE,WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,WGL_DOUBLE_BUFFER_ARB,GL_FALSE,0}; // 0 terminate the list
unsigned int numFormats = 0;
// get an acceptable pixel format to create the PBuffer with
if (RTT.wgl.wglChoosePixelFormatARB(ghDC, intAttrs, NULL, 1, &pixelFormats, &numFormats)==FALSE)
AnsiString error = AnsiString().sprintf("wglChoosePixelFormatARB returned %i", GetLastError()); // GetLastError will tell us why it failed
//Set some p-buffer attributes so that we can use this p-buffer as a 2d texture target
const int attributes[]= {WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB, // p-buffer will have RBA texture format
WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, 0}; // Of texture target will be GL_TEXTURE_2D
// the size of the PBuffer must be the same size as the texture
RTT.wgl.hBuffer= RTT.wgl.wglCreatePbufferARB(ghDC, pixelFormats, ClientWidth, ClientHeight, attributes);
RTT.wgl.hdc= RTT.wgl.wglGetPbufferDCARB(RTT.wgl.hBuffer);
RTT.wgl.hGlRc= wglCreateContext(RTT.wgl.hdc);
wglMakeCurrent(NULL,NULL);
}
Here is my first DrawScene : the "PaintGL()" drawing is perfectly drawn on this form :
void TGLForm::DrawSceneForm1()
{
wglMakeCurrent(ghDC, ghRC);
ClientWidth = 1920;
ClientHeight = 1080;
// create a texture to use as the backbuffer
glGenTextures(1, &RTT.texture);
glBindTexture(GL_TEXTURE_2D, RTT.texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// make sure this is the same color format as the screen
glTexImage2D(GL_TEXTURE_2D, 0, 4, ClientWidth, ClientHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
// switch to the texture context
wglMakeCurrent(RTT.wgl.hdc, RTT.wgl.hGlRc);
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE);
glClear(GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_TEXTURE_2D);
// switch back to the screen context
wglMakeCurrent(ghDC, ghRC);
wglShareLists(ghRC, RTT.wgl.hGlRc);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE);
glClear(GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, ClientWidth, ClientHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
wglMakeCurrent(RTT.wgl.hdc, RTT.wgl.hGlRc);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, RTT.texture);
PaintGL();
glDisable(GL_TEXTURE_2D);
wglMakeCurrent(ghDC, ghRC);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, RTT.texture);
RTT.wgl.wglBindTexImageARB(RTT.wgl.hBuffer, WGL_FRONT_LEFT_ARB);
glBegin(GL_QUADS);
glColor4ub(255,255,255,255);
glTexCoord2f (0.0, 0.0); glVertex2f (-1.0, -1.0);
glTexCoord2f (1.0, 0.0); glVertex2f (1.0, -1.0);
glTexCoord2f (1.0, 1.0); glVertex2f (1.0, 1.0);
glTexCoord2f (0.0, 1.0); glVertex2f (-1.0, 1.0);
glEnd();
RTT.wgl.wglReleaseTexImageARB(RTT.wgl.hBuffer, WGL_FRONT_LEFT_ARB);
glDisable(GL_TEXTURE_2D);
glFlush();
SwapBuffers(ghDC);
wglMakeCurrent(NULL,NULL);
}
And here is my second GLForm's DrawScene : the problem is that I only see the colored quad but this QUAD is not textured, or the texture is empty :
void TGLForm2::DrawSceneForm2()
{
wglMakeCurrent(ghDC2, ghRC2);
ClientWidth = 1920;
ClientHeight = 1080;
wglShareLists(RTT.wgl.hGlRc, ghRC2);
if (wglShareLists(RTT.wgl.hGlRc,ghRC2) == FALSE)
SCmsgError(AnsiString().sprintf("wglShareLists returned %i", GetLastError()));
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE); //ARC
glClear(GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, ClientWidth, ClientHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, RTT.texture);
RTT.wgl.wglBindTexImageARB(RTT.wgl.hBuffer, WGL_FRONT_LEFT_ARB);
glBegin(GL_QUADS);
glColor4ub(200,200,200,200);
glTexCoord2f (0.0, 0.0); glVertex2f (-1.0, -1.0);
glTexCoord2f (1.0, 0.0); glVertex2f (1.0, -1.0);
glTexCoord2f (1.0, 1.0); glVertex2f (1.0, 1.0);
glTexCoord2f (0.0, 1.0); glVertex2f (-1.0, 1.0);
glEnd();
RTT.wgl.wglReleaseTexImageARB(RTT.wgl.hBuffer, WGL_FRONT_LEFT_ARB);
glDisable(GL_TEXTURE_2D);
glFlush();
SwapBuffers(ghDC);
}
=> How may I check if this texture is empty or not ?
export it to a bitmap and check it ?
=> the wglShareLists in the DrawSceneForm2 returns an error with GetLastError :
Error 6 : ERROR_INVALID_HANDLE The handle is invalid.
=> Does somebody see what is wrong in this wglShareList or in my code ?
When calling wglShareLists, the context must not be current. Preferrably share before you do anything else. Sharing contexts will share anything created thereafter just fine. The best thing is to create all contexts that need to be shared at startup. If you use WGL_ARB_create_context, then you can even do this atomically within the creation call.
If you can't for some reason (though, why?) then wglMakeCurrent(0,0); first (you do the opposite in your code, you make the context current just before sharing).
I had a similar problem where :
wglShareLists returns 0
GetLastError() returns 3221684311 (0xc0070057)
It turns out you cant do much with the hglrc2 (2nd parameter passed into wglShareLists) before you call wglShareLists. In my case I created, and glUseProgram a shader, and then tried wglShareLists resulting in the errors shown above. Moving wglShareLists to immediately after wglCreateContext(hDC) of 2nd RC worked. I was able to share textures across the 2 contexts.

rectangular texture in OpenGL with both width and height POT

I'm trying to use rectangular texture with OpenGL. When the height is equal to the width of the texture, everything looks fine, however, when the height is different than the width the texture looks distorted.
My display function is (h and w are globals storing the height and the width of the image):
Please note that the size of the drawn image doesn't matter. It is distorted regardless of the actual polygon size.
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, texName);
glTranslatef(-2.0f,-2.0f,0.0f);
glScalef(1.0f/128.0f,1.0f/128.0f,1.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(0.0, w, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(h, w, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(h, 0.0, 0.0);
// Will be distorted also with the following:
/*glScalef(1.0f/128.0f,1.0f/128.0f,1.0f);
glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(0.0, h, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(w, h, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(w, 0.0, 0.0);*/
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
}
I'm loading the texture with:
void *data = LoadBMP("c:\\dev\\64x128_face.bmp");
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w,
h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
data);
When I'm loading a 64x64 square texture image, it looks fine. However when I'm loading a rectangular texture image, the image looks distorted.
How does OpenGL support rectangular POT texture? What's wrong with my code?
Your rect image is 64x128 but you render it with these commands:
glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(0.0, w, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(h, w, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(h, 0.0, 0.0);
where h is height (=128) and w (=64) is width.
But you placed height on x (which is width) and width on y (which is height).
Maybe try this instead:
glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(0.0, h, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(w, h, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(w, 0.0, 0.0);
You should probably check the support of the GL_ARB_texture_non_power_of_two extension before you use non-power-of-two values for h and w in glTexImage2D(), because specifying arbitrary heights and widths is only valid with this extension.