Texture coordinates odd problem.A white Line in the bottom.

Hello everybody.

I am a new comer to opengl.

Now, i run into an odd question and hope get the answer from this forum.THX.

I am draw a not-power-of-2 width and length texture in an upside-down orthographic projection setting.

All is ok, except when the y ordinate’s decimal is 0.5.

This is part of my codes:The texture is 60 x 60

Set projection matrix:
glOrtho(0, (GLfloat)w, (GLfloat)h, 0, 0, 1);

Gen the texture:
char* tmppixel = new char [WPowerof2 * WPowerof2 * 4];
memset(tmppixel, 0xFF, WPowerof2 * WPowerof2 * 4);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WPowerof2, HPowerof2, 0, GL_RGB, GL_UNSIGNED_BYTE, tmppixel);
delete [] tmppixel;
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TextureImage[0]->sizeX, TextureImage[0]->sizeY,
GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

Set texture coorinates and screen coordinates:

GLfloat coordinates[] = {
0, 0,
60.0/64.0, 0,
0, 60.0/64.0,
60.0/64.0, 60.0/64.0
};

movf = 0.5;
float x = 50.0f; 
float y = 50.0f + movf; 
float m_nImageWf = (float)(60);
float m_nImageHf  = (float)(60);

GLfloat vertices[] = {
    x,                      y,
    m_nImageWf + x, y,
    x,                      m_nImageHf + y,
    m_nImageWf + x, m_nImageHf + y };

These are several screenshots of the results:

this is the result, just run the code above, a white line come out in the bottom
[ATTACH=CONFIG]207[/ATTACH]

when i change the value of movf, and other code is unchanged
movf = 0.49;
[ATTACH=CONFIG]208[/ATTACH]

when i change the projection,and other code is unchanged, the white line wont come out
glOrtho(0, (GLfloat)w, (GLfloat)0, h, 0, 1);
[ATTACH=CONFIG]209[/ATTACH]

this is the result, change texture coordinates, draw full size texture (64 x 64), the top line of the texture come out in the bottom
GLfloat coordinates[] = {
0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
1.0, 1.0
};
[ATTACH=CONFIG]210[/ATTACH]

Using power-of-2 width and length texture won’t come about this problem, just when the coordinates demical is 0.5 and upside down projection this problem come out.

How could it happen? Any advise will be welcome.

Try using GL_CLAMP_TO_EDGE for the texture’s WRAP_S and WRAP_T modes.

Also, I’d texture a quad with 0…1 texture coordinates and use GL_NEAREST to check exactly what you’ve got in your texture and make sure it’s what you think it is. Or just read it back and write it to an image file to view in your favorite image viewer.

Thanks for reply.Photon.

I set the texture paras to GL_CLAMP_TO_EDGE and GL_NEAREST. And it seems like the same.

My problem is when i draw the texture in the window at coordinates (x, 50.5) - (x + tex_w, 50.5 + tex_h), a white line will appear in the bottom.

But when at coordinates (x, 50.505) - (x + tex_w, 50.505 + tex_h), it displays correctly. And change the args of the function glOrtho (0, (GLfloat)w,

(GLfloat)0, h, 0, 1) the coordinates (x, 50.5) - (x + tex_w, 50.5 + tex_h) won’t come with a white line in the bottom either.

A few things look odd about your texture population above, but that may not be it. For instance you’re allocating 4 bytes per texel, but then telling OpenGL that’s RGB UBYTE data.

Try pasting the affected code into a short stand-alone test program, and if still problems, post that. Here’s a starter to paste into.


#include <stdio.h>
#include <stdlib.h>
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glx.h>
#include <GL/glut.h>

void checkGLError( const char hdr[] )
{
  int err = glGetError();
  if( err )
  {
    fprintf(stderr, "ERROR %s: %s
", hdr, gluErrorString(err));
    exit(1);
  }
}

void reshape(GLsizei w, GLsizei h)
{
  glViewport(0, 0, w, h);
  glutPostRedisplay();
}

void keyboard( unsigned char key, int x, int y )
{
  // Key Bindings
  switch( key )
  {
    case 27 : exit(0);                    break;
  }
}

void display()
{
  glClearColor( 0,0,1,1 );
  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  glutSwapBuffers();
  checkGLError( "display() end" );
}

main( int argc, char *argv[] )
{
  glutInit( &argc, argv );
  glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB ); 
  glutCreateWindow( "window title" );
  checkGLError( "Create window" );

  glutReshapeFunc ( reshape  );
  glutDisplayFunc ( display  );
  glutKeyboardFunc( keyboard );

  glutPostRedisplay();
  glutMainLoop();
}

Thanks Photon.

This is my test code. Run in windows using visual studio 2008. This problem also happens in ios and android devices.


#include “stdafx.h”
#include “windows.h” // include windows header file
#include <stdio.h>
#include <stdlib.h>
#define GL_GLEXT_PROTOTYPES
#include <gl/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
//#include <GL/glx.h> // comment this line for compiling
#include <GL/glut.h>
#include <gl/glaux.h>

#pragma comment( lib, “opengl32.lib” ) // Link OpenGL32.lib
#pragma comment( lib, “glu32.lib” ) // Link GLu32.lib
#pragma comment( lib, “glaux.lib” ) // Link GLaux.lib

void checkGLError( const char hdr[] )
{
int err = glGetError();
if( err )
{
fprintf(stderr, "ERROR %s: %s
", hdr, gluErrorString(err));
exit(1);
}
}

void reshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glutPostRedisplay();
}

void keyboard( unsigned char key, int x, int y )
{
// Key Bindings
switch( key )
{
case 27 : exit(0); break;
}
}

int LoadGLTextures(); // Load Bitmaps And Convert To Textures
void SceneShow(GLfloat x, GLfloat y); // Draw Texture
void SceneShowFull(GLfloat x, GLfloat y); // Draw full Texture buffer in video card
void SceneSetView();
void display()
{
glClearColor( 1, 0, 0, 1 );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

SceneShow(1, 1.496);
SceneShow(71, 1.497);
SceneShow(141, 1.498);
SceneShow(211, 1.499); // a white line appears
SceneShow(1, 71.500); // a white line appears
SceneShow(71, 71.501); // a white line appears
SceneShow(141, 71.502);
SceneShow(211, 71.503);

SceneShowFull(1, 141.496);
SceneShowFull(71, 141.497);
SceneShowFull(141, 141.498);
SceneShowFull(211, 141.499); // the image’s top line appears in bottom
SceneShowFull(1, 211.500); // the image’s top line appears in bottom
SceneShowFull(71, 211.501); // the image’s top line appears in bottom
SceneShowFull(141, 211.502);
SceneShowFull(211, 211.503);

glutSwapBuffers();
checkGLError( “display() end” );
}

void main( int argc, char *argv[] )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB );
glutCreateWindow( “window title” );
checkGLError( “Create window” );

SceneSetView();
LoadGLTextures();

glutReshapeFunc ( reshape );
glutDisplayFunc ( display );
glutKeyboardFunc( keyboard );

glutPostRedisplay();
glutMainLoop();
}

AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image
{
FILE *File=NULL;

if (!Filename)                              // Make Sure A Filename Was Given
{
	return NULL;                            // If Not Return NULL
}

File=fopen(Filename,"r");   

if (File)                               // Does The File Exist?
{
	fclose(File);                           // Close The Handle

	//return auxDIBImageLoad((LPCWSTR)(Filename));               // Load The Bitmap And Return A Pointer
	return auxDIBImageLoadA(Filename);
}

return NULL;                                // If Load Failed Return NULL

}

#define MAX_TEXTURE 1
char *ForTextureBMP[MAX_TEXTURE]=
{
“lawnpic.bmp”,
};

GLuint texture[1];
int NextPowerOf2( size_t in )
{
–in; // in -= 1;
in |= in >> 16;
in |= in >> 8;
in |= in >> 4;
in |= in >> 2;
in |= in >> 1;
return (++in); // in + 1;
}

int LoadGLTextures() // Load Bitmaps And Convert To Textures
{
int Status=FALSE; // Status Indicator
int TotalBmp = MAX_TEXTURE;
int WPowerof2;
int HPowerof2;

AUX_RGBImageRec *TextureImage[1];                   // Create Storage Space For The Texture

memset(TextureImage,0,sizeof(void *)*1);                // Set The Pointer To NULL

// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
for (int i = 0; i &lt; TotalBmp; i++)
{
	if (TextureImage[0]=LoadBMP(ForTextureBMP[i]))
	{
		Status=TRUE;                            // Set The Status To TRUE
		glGenTextures(1, &texture[i]);                  // Create The Texture
		 
		// Typical Texture Generation Using Data From The Bitmap
		glBindTexture(GL_TEXTURE_2D, texture[i]);

		WPowerof2 = NextPowerOf2(TextureImage[0]-&gt;sizeX);
		HPowerof2 = NextPowerOf2(TextureImage[0]-&gt;sizeY);
		char* tmppixel = new char [WPowerof2 * WPowerof2 * 3];
		memset(tmppixel, 0xFF, WPowerof2 * WPowerof2 * 3); // fill texture buffer with white color
		// Generate The Texture
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WPowerof2, HPowerof2, 0, GL_RGB, GL_UNSIGNED_BYTE, tmppixel);
		delete [] tmppixel;
		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TextureImage[0]-&gt;sizeX, TextureImage[0]-&gt;sizeY,  GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]-&gt;data);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Nearest Filtering
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Nearest Filtering
		//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);  !!!!!!!! discomment still won't solve the problem
		//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);  !!!!!!!! discomment still won't solve the problem
	}

	if (TextureImage[0])                            // If Texture Exists
	{
		if (TextureImage[0]-&gt;data)                   // If Texture Image Exists
		{
			free(TextureImage[0]-&gt;data);             // Free The Texture Image Memory
		}
	 
		free(TextureImage[0]);                      // Free The Image Structure
	}
}
return Status;                              // Return The Status

}

void SceneSetView()
{
glutInitWindowPosition(400,400);
glutInitWindowSize(320, 320);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glOrtho(0, 300, 300, 0, 0, 1); // !!! IMPORTANT : Maybe this line cause the problem
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
}

void SceneShow(GLfloat argx, GLfloat argy)
{
float x = argx;
float y = argy;
float m_nImageWf = (float)(60);
float m_nImageHf = (float)(60);

GLfloat coordinates[] = {
    0,         0,
    60.0/64.0, 0,
    0,         60.0/64.0,
    60.0/64.0, 60.0/64.0
};

GLfloat vertices[] = {
    x,              y,
    m_nImageWf + x, y,
    x,              m_nImageHf + y,
    m_nImageWf + x, m_nImageHf + y };

glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

}

void SceneShowFull(GLfloat argx, GLfloat argy)
{
float x = argx;
float y = argy;
float m_nImageWf = (float)(60);
float m_nImageHf = (float)(60);

GLfloat coordinates[] = {
    0, 0,
    1, 0,
    0, 1,
    1, 1
};

GLfloat vertices[] = {
    x,              y,
    m_nImageWf + x, y,
    x,              m_nImageHf + y,
    m_nImageWf + x, m_nImageHf + y };

glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

}


This is my test image.[ATTACH=CONFIG]214[/ATTACH]. I’m using a bitmap which not allowed to be uploaded in the code above, so convert to a bmp file by yourself.

Thanks again.

And this is the result run in my computer.
[ATTACH=CONFIG]215[/ATTACH]