PDA

View Full Version : Texture coordinates odd problem.A white Line in the bottom.



tunion
06-22-2012, 08:18 AM
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
782

when i change the value of movf, and other code is unchanged
movf = 0.49;
783

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);
784

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
};
785

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.

Dark Photon
06-22-2012, 08:31 AM
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.

tunion
06-22-2012, 07:18 PM
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.

Dark Photon
06-23-2012, 10:37 AM
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.

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\n", 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();
}

tunion
06-25-2012, 08:22 AM
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\n", 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 < 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]->sizeX);
HPowerof2 = NextPowerOf2(TextureImage[0]->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]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->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]->data) // If Texture Image Exists
{
free(TextureImage[0]->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.790. 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.

tunion
06-25-2012, 08:34 AM
And this is the result run in my computer.
791