void OGLRectangle::LoadTexture(const char* filename)
{
unsigned int texture;
int width, height;
BYTE * data;
FILE * file;
file = fopen(filename, "rb");
width = 1920;
height = 1080;
data = new BYTE[height * width * 3];
fread(data, width * height * 3, 1, file);
fclose(file);
glGenTextures(1.0, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
tex = texture;
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, 2, width, height,0, GL_RGB, GL_UNSIGNED_BYTE, data);
delete [] data;
}
I have this code to render in an image, the method is called with:
LoadTexture("C:\\Users\Rhys\Documents\Hills.bmp");
The file exists.
Then I'm trying to render it to the openGL window using;
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex);
glBegin(GL_QUADS);
glTexCoord2d(0.0, 0.0); glVertex2d(0.0, 0.0);
glTexCoord2d(1.0, 0.0); glVertex2d(100.0, 0.0);
glTexCoord2d(1.0, 1.0); glVertex2d(100.0, 100.0);
glTexCoord2d(0.0, 1.0); glVertex2d(0.0, 100.0);
glEnd();
glDisable(GL_TEXTURE_2D);
However, all I'm getting on screen is a darkish blue box, with no texture rendered in it.
I have searched for tutorials on how to do this, even asked my lecturer and I still cannot seem to find out why its not working.
Any help will be greatly appreciated.
The .bmp files loading must be little different
This code simply loads bmp file to memory m_pcbData without compression and indexed color support.
bool CBMPImage::LoadFromFile(const CString& FileName)
{
BITMAPINFOHEADER BitmapInfo;
ZeroMemory(&BitmapInfo, sizeof(BITMAPINFOHEADER));
BITMAPFILEHEADER BitmapFile;
ZeroMemory(&BitmapFile, sizeof(BITMAPFILEHEADER));
std::ifstream FileStream(FileName, std::ios::binary | std::ios::in);
if (!FileStream.good())
return false;
// Read bitmap file info
FileStream.read(reinterpret_cast<char*>(&BitmapFile), sizeof(BITMAPFILEHEADER));
// Read bitmap info
FileStream.read(reinterpret_cast<char*>(&BitmapInfo), sizeof(BITMAPINFOHEADER));
// Proper bitmap file supports only 1 plane
if (BitmapInfo.biPlanes != 1)
return false;
m_cbAlphaBits = 0;
m_cbRedBits = 0;
m_cbGreenBits = 0;
m_cbBlueBits = 0;
// Retrives bits per pixel info
m_cbBitsPerPel = (BMPbyte)BitmapInfo.biBitCount;
// Width and height of image
m_nWidth = BitmapInfo.biWidth;
m_nHeight = BitmapInfo.biHeight;
// Compute bitmap file size
m_nSize = 4 * ((m_nWidth * m_cbBitsPerPel + 31) / 32) * m_nHeight;
// Less important info
m_nPixelWidthPerMeter = BitmapInfo.biXPelsPerMeter;
m_nPixelHeightPerMeter = BitmapInfo.biYPelsPerMeter;
// Indexes info not important in our case
m_nClrCount = BitmapInfo.biClrUsed;
m_nClrImportant = BitmapInfo.biClrImportant;
// COMPRESSION MUST BE BI_RGB
m_Compression = (BMPCompression)BitmapInfo.biCompression;
delete [] m_pcbData;
m_pcbData = NULL;
// Allocate proper data size
m_pcbData = new BMPbyte[m_nSize];
// Read actual image data, considering offset of file header
FileStream.seekg(BitmapFile.bfOffBits);
FileStream.read(reinterpret_cast<char*>(m_pcbData), m_nSize);
FileStream.close();
return true;
}
than load bmp texture data to OpenGL
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Image.GetWidth(), Image.GetHeight(), 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid*)Image.GetImageData());
GL_BGR_EXT is important because bmp stores image data in reverse byte order.
Secondly you must specify your material color as white because of usage that texture environment GL_TEXTURE_ENV_MODE, GL_MODULATE
And as mentioned #Reto Koradi, you must specify to generate mipmaps before texture image loading using one of these function calls.
glGenerateMipmap(GL_TEXTURE_2D);
or
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
Plus as you used not power of two textures (width = 1920;
height = 1080;) it may not work.
You're setting the attribute to sample with mipmaps:
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
You should only set that if your textures actually has mipmaps. To generate mipmaps, you can call:
glGenerateMipmap(GL_TEXTURE_2D);
after the glTexImage2D() call. Or you can simply set the sampler attribute to not use mipmaps:
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
As has already been pointed out: If your image file is indeed a BMP, and not just a raw image file, your image loading code will also need work.
Related
I have two choices. I can read my image pinmap.jpg from Resource.rc or read the image from STBI_Image library.
// Simple helper function to load an image into a OpenGL texture with common settings
inline bool ReadImageFromResource(GLuint* out_texture, int width, int height) {
// Locate the resource in the application's executable.
HRSRC imageResHandle = FindResource(
NULL, // This component.
MAKEINTRESOURCE(IDR_IMAGE1), // Resource name.
L"Image"); // Resource type.
HRESULT hr = (imageResHandle ? S_OK : E_FAIL);
// Load the resource to the HGLOBAL.
HGLOBAL imageResDataHandle = NULL;
if (SUCCEEDED(hr)) {
imageResDataHandle = LoadResource(NULL, imageResHandle);
hr = (imageResDataHandle ? S_OK : E_FAIL);
}
// Lock the resource to retrieve memory pointer.
LPVOID image_data = NULL;
if (SUCCEEDED(hr)) {
image_data = LockResource(imageResDataHandle);
UnlockResource(imageResDataHandle);
hr = (image_data ? S_OK : E_FAIL);
}
if (image_data == NULL)
return false;
// Create a OpenGL texture identifier
GLuint image_texture;
glGenTextures(1, &image_texture);
glBindTexture(GL_TEXTURE_2D, image_texture);
// Setup filtering parameters for display
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // This is required on WebGL for non power-of-two textures
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Same
// Upload pixels into texture
#if defined(GL_UNPACK_ROW_LENGTH) && !defined(__EMSCRIPTEN__)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
#endif
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image_data);
*out_texture = image_texture;
return true;
}
The results is:
When I read the image from STBI-library, then the image looks like this:
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
// Simple helper function to load an image into a OpenGL texture with common settings
inline bool ReadImageFromSTBI(const char* filename, GLuint* out_texture, int* out_width, int* out_height)
{
// Load from file
int image_width = 0;
int image_height = 0;
unsigned char* image_data = stbi_load(filename, &image_width, &image_height, NULL, 4);
if (image_data == NULL)
return false;
// Create a OpenGL texture identifier
GLuint image_texture;
glGenTextures(1, &image_texture);
glBindTexture(GL_TEXTURE_2D, image_texture);
// Setup filtering parameters for display
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // This is required on WebGL for non power-of-two textures
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Same
// Upload pixels into texture
#if defined(GL_UNPACK_ROW_LENGTH) && !defined(__EMSCRIPTEN__)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
#endif
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_width, image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
stbi_image_free(image_data);
*out_texture = image_texture;
*out_width = image_width;
*out_height = image_height;
return true;
}
You see the difference between the color and the image above is shifted due to the C to the left. It should be at the right side of the image. Notice that the image above is displayed with GL_RBG and this image is displayed with GL_RGBA. Else, I cannot display the image.
Question:
It seems to be different data depending on how I load the data of the image. I have looked at the data of the image. The variable image_data differes.
How do I properly display images with OpenGL if the image is loaded by Resource.rc file and not loaded by file such as STBI-library?
LoadResource does not decode, decompress, or interpret the resource data in any way. What you get in your image_data is a pointer to a memory block that contains exactly the contents of your pinmap.jpg file.
Interestingly, what you have is a bitmap rather than an actual JPEG file. If it wasn't, you'd get a bunch of noise instead of anything resembling your image. From what my crystal ball tells me, you imported that once-has-been JPEG into the resource editor with the "Add Resource > Import..." function of Visual Studio. When done this way, it converts the file to a bitmap, overwriting the original on disk. (Seriously, Microsoft, what were you smoking!?)
The results you observe thus can be explained:
The horizontal wrap-around offset is due to the BITMAP file and info headers at the beginning of the resource.
The colors are off because of the BGR <-> RGB mismatch.
If you want to keep the resource as JPEG, you can add it by manually editing the rc file, or by reverting the file after Visual Studio is done with messing it up. However, if you choose this route, you must decompress the JPEG (because OpenGL expects plain RGB data rather than JPEG). One way would be to call stbi_load_from_memory on that image_data you got from LockResource. Stbi will decompress the JPEG into RGB (in that order).
If you want to keep working with the BITMAP resource, then all you need is to skip the headers and flip the channels.
For skipping the headers you parse the BITMAPFILEHEADER that's located at image_data. The offset to the pixel data is in the bfOffBits field in the header:
actual_image_data = (char*)image_data + ((BITMAPFILEHEADER*)image_data)->bfOffBits;
For fixing the channel order you can pass GL_BGR for the format parameter (not the internalformat!!) of glTexImage2D:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, actual_image_data);
In my opengl application, texture is not rendered correctly on the model.
Here is a screenshot of the result:
Here is what the bunny should look like:
expected result
Here is the code to load the texture.
stbi_set_flip_vertically_on_load(1);
m_LocalBuffer = stbi_load(path.c_str(), &m_Width, &m_Height, &m_BPP, 0);
GLCall(glGenTextures(1, &m_RendererID));
GLCall(glBindTexture(GL_TEXTURE_2D, m_RendererID));
GLCall(glGenerateMipmap(GL_TEXTURE_2D));
GLenum format = GL_RGBA;
//..switching on m_BPP to set format, omitted here
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, format, GL_UNSIGNED_BYTE, m_LocalBuffer));
GLCall(glBindTexture(GL_TEXTURE_2D, 0));
if (m_LocalBuffer) {
stbi_image_free(m_LocalBuffer);
}
Here is the texture file I'm using
Texture File
I downloaded the asset from https://blenderartists.org/t/uv-unwrapped-stanford-bunny-happy-spring-equinox/1101297 (the 3.3Mb link)
Here is the code where I read in the texCoords
for (size_t i = 0; i < mesh->mNumVertices; i++) {
//..read in positions and normals
if (mesh->mTextureCoords[0]) {
vertex.TexCoords.x = mesh->mTextureCoords[0][i].x;
vertex.TexCoords.y = mesh->mTextureCoords[0][i].y;
}
}
I'm loading the model as an obj file using assimp. I just read the texture coord from the result and pass it to the shader. (GLCall is just a debug macro I have in the renderer)
What could potentially be the cause for this? Let me know if more info is needed. Thanks a lot!
The image seems to be flipped vertically (around the x-axis). To compensated that, you've to flip the image manually, after loading it. Or if you've flipped the image then you've to omit that. Whether the image has to be flipped or not, depends on the image format.
I am using OpenGL, GLM, ILU and GLUT libraries for loading and texturing 3D models. The models appear to load in correctly, however when it comes to the texturing the texture seems to repeat.
I have included two pictures below showing non-textured, textured.
non-textured:
textured:
If you look closely enough to the last image, the texture is applied to a tiny scale and repeated across the whole model.
For the code, I first start by loading the texture.
ILboolean success = false;
if (ilGetInteger(IL_VERSION_NUM) < IL_VERSION)
{
return false;
}
ilInit(); /*Initialize the DevIL library*/
ilGenImages(1, &ilTextureID); //Generate DevIL image objects
ilBindImage(ilTextureID); /* Binding of image object */
success = ilLoadImage((const ILstring)theFilename); /* Loading of image*/
if (!success)
{
ilDeleteImages(1, &ilTextureID);
return false;
}
success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); // Convert every colour component into unsigned byte.
if (!success)
{
return false;
}
textureWidth = ilGetInteger(IL_IMAGE_WIDTH);
textureHeight = ilGetInteger(IL_IMAGE_HEIGHT);
glGenTextures(1, &GLTextureID); // GLTexture name generation
glBindTexture(GL_TEXTURE_2D, GLTextureID); // Binding of GLtexture name
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Use linear interpolation for magnification filter
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Use linear interpolation for minifying filter
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH),
ilGetInteger(IL_IMAGE_HEIGHT), 0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE,
ilGetData()); /* Texture specification */
glBindTexture(GL_TEXTURE_2D, GLTextureID); // Binding of GLtexture name
ilDeleteImages(1, &ilTextureID);
I have tried things like adding,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
but this just seems to make the model non-textured.
Then I call the method to model loading method and apply the texture:
m_model = glmReadOBJ(mdlFilename);
glmFacetNormals(m_model);
glmVertexNormals(m_model, 180.0f, false);
m_TextureID = mdlTexture.getTexture();
m_model->textures[m_model->numtextures - 1].id = m_TextureID;
m_model->textures[m_model->numtextures - 1].width = mdlTexture.getTWidth();
m_model->textures[m_model->numtextures - 1].height =mdlTexture.getTHeight();
For the above code, whilst I was debugging I am getting negative values for
"vertices", "normals" and "facetnorms" for the 3D model, but I am getting values for "numnormals", "numtexcoords" and "numfacetnorms". I'm not entirely sure if this is normal.
And finally for the rendering of the model:
glPushMatrix();
//transformations here...
glTranslatef(mdlPosition.x, 0.0f, -mdlPosition.z);
glRotatef(mdlRotationAngle, 0, 1, 0);
glScalef(mdlScale.x, mdlScale.y, mdlScale.z);
glmDraw(m_model, GLM_SMOOTH | GLM_TEXTURE | GLM_MATERIAL);
glPopMatrix();
I can't find my mistake, why text has not been created? When using texture instead of text I get nothing or black background with colored points, please help
GLuint texture;
SDL_Surface *text = NULL;
TTF_Font *font = NULL;
SDL_Color color = {0, 0, 0};
font = TTF_OpenFont("../test.ttf", 20);
text = TTF_RenderText_Solid(font, "Hello, SDL !!!", color);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, text->w, text->h, 0, GL_RGB, GL_UNSIGNED_BYTE, text->pixels);
SDL_FreeSurface(text);
One thing you could add is to specify texture filters, e.g.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
Few things you have to check first
is the font loaded properly? check if "font == NULL", maybe your
font path is wrong
is the shader (if you use a shader) setup properly?
My guess is that you set the wrong pixel format type in glTexImage2D cause random color dots apear on your texture
Below is my code that load image via SDL_image for OpenGL use, I think it would be a good start to figure out what step you missed or forgot.
BTW, this code is not perfect. The types of pixel format is more than four (like index color) and I only handle some of them.
/*
* object_, originalWidth_ and originalHeight_ are private variables in
* this class, don't panic.
*/
void
Texture::Load(string filePath, GLint minMagFilter, GLint wrapMode)
{
SDL_Surface* image;
GLenum textureFormat;
GLint bpp; //Byte Per Pixel
/* Load image file */
image = IMG_Load(filePath.c_str());
if (image == nullptr) {
string msg("IMG error: ");
msg += IMG_GetError();
throw runtime_error(msg.c_str());
}
/* Find out pixel format type */
bpp = image->format->BytesPerPixel;
if (bpp == 4) {
if (image->format->Rmask == 0x000000ff)
textureFormat = GL_RGBA;
else
textureFormat = GL_BGRA;
} else if (bpp == 3) {
if (image->format->Rmask == 0x000000ff)
textureFormat = GL_RGB;
else
textureFormat = GL_BGR;
} else {
string msg("IMG error: Unknow pixel format, bpp = ");
msg += bpp;
throw runtime_error(msg.c_str());
}
/* Store widht and height */
originalWidth_ = image->w;
originalHeight_ = image->h;
/* Make OpenGL texture */
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &object_);
glBindTexture(GL_TEXTURE_2D, object_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minMagFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, minMagFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexImage2D(
GL_TEXTURE_2D, // texture type
0, // level
bpp, // internal format
image->w, // width
image->h, // height
0, // border
textureFormat, // format(in this texture?)
GL_UNSIGNED_BYTE, // data type
image->pixels // pointer to data
);
/* Clean these mess up */
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
SDL_FreeSurface(image);
}
For more information, you should check out SDL wiki or deep into it's source code to fully understand the architecture of SDL_Surface.
I am using OpenGL, I can load tga files properly, but for some reason when i render jpg files, i do not see them correctly.
This is what the image is supposed to look like--
And this is what it looks like.. why is it stretched? is it because of the coordinates?
Here is the code i am using for drawing.
void Renderer::DrawJpg(GLuint tex, int xi, int yq, int width, int height) const
{
glBindTexture(GL_TEXTURE_2D, tex);
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex2i(0+xi, 0+xi);
glTexCoord2i(0, 1); glVertex2i(0+xi, height+xi);
glTexCoord2i(1, 1); glVertex2i(width+xi, height+xi);
glTexCoord2i(1, 0); glVertex2i(width+xi, 0+xi);
glEnd();
}
This is how i am loading the image...
imagename=s;
ILboolean success;
ilInit();
ilGenImages(1, &id);
ilBindImage(id);
success = ilLoadImage((const ILstring)imagename.c_str());
if (success)
{
success = ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE); /* Convert every colour component into
unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA */
if (!success)
{
printf("image conversion failed.");
}
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
width = ilGetInteger(IL_IMAGE_WIDTH);
height = ilGetInteger(IL_IMAGE_HEIGHT);
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH),
ilGetInteger(IL_IMAGE_HEIGHT), 0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE,
ilGetData());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Linear Filtered
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Linear Filtered
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
I probably should mention this, but some images did get rendered properly, I thought it was because width != height. But that is not the case, images with width != height also get loaded fine.
But for other images i still get this problem.
You probably need to call
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
before uploading the texture data with glTexImage2D.
From the reference pages:
GL_UNPACK_ALIGNMENT
Specifies the alignment requirements for the start of each pixel row
in memory. The allowable values are 1 (byte-alignment), 2 (rows
aligned to even-numbered bytes), 4 (word-alignment), and 8 (rows start
on double-word boundaries).
The default value for the alignment is 4 and your image loading library probably returns pixel data with byte-aligned rows, which explains why some of your images look OK (when the width is a multiple of four).
Always try to have the images width and height of the power of two because some GPU support textures only in NPOT resolution. (for example 128x128, 512x512 but not 123x533, 128x532)
And i think that here instead of GL_REPEAT you should use GL_CLAMP_TO_EDGE :)
GL_REPEAT is used when your texture coordinates are > 1.0f, CLAMP_TO_EDGE too but guarantees the image will fill the polygon without unwanted lines on edges. (it's blocking your linear filtering on edges)
Remember to try out code where floats are used (sample from comment) :)
Here is good explanation http://open.gl/textures :)