PDA

View Full Version : Texture not showing on basic plane



FloorPlay
06-04-2016, 10:58 AM
Hello all.

I'm teaching myself openGL, or Glut to be more precise, over these last few weeks. I have been at it all day trying to learn about texturing but for the life of me cannot get a texture to show on a simple 4 vertices plane. I'm using a 24bit 200X200 BMP image. I have a custom texture loader that I'm using. The texture is being loaded OK. The plane however remains a darkish black color. I have tried changing image size, dimensions, aspect etc but nothing. Using Eclipse, Windows 8.1 Glut and minGW. Could somebody please have a look at my code and tell me what I'm doing wrong.

LOADER


GLuint loadTexture(const char * filename) {

FILE * file;
GLuint texture;
int width, height;
unsigned char * data;

file = fopen(filename, "rb");

if (file == NULL){
cout << "No file found!!!" << endl;
return 0;
}

width = 100;
height = 300;

data = (unsigned char *)malloc(width * height * 3);
fread(data, width * height * 3, 1, file );
fclose(file);

for(int i = 0; i < width * height; ++i) {

int index = i*3;
unsigned char B,R;

B = data[index];
R = data[index+2];

data[index] = R;
data[index+2] = B;
}

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, 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_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
gluBuild2DMipmaps(GL_TEXTURE_2D, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
free(data);

return texture;
}



PLANE OBJECT


void pictureFrame(void) {

GLuint tex1 = loadTexture(".\\Textures\\one.bmp");
glEnable(GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, tex1);

glNormal3f(0, 0, 1);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex2f(0.0, 1.0);
glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
glTexCoord2f(1.0, 0.0); glVertex2f(1.0, 0.0);
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
}

Hermannicus
06-04-2016, 01:38 PM
gluBuild2DMipmaps(GL_TEXTURE_2D, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);

Is it returning 0?

GClements
06-04-2016, 02:13 PM
The plane however remains a darkish black color.


glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE);


Try removing that call. If the lighting calculations result in black (e.g. because the surface normal is facing away from the light), you'll get a black surface regardless of the texture (x*0=0, for any x).

Removing it will allow you to check that texturing is working correctly. If it is, then you can work out the issues with the lighting.

BBeck1
06-05-2016, 10:22 AM
Try moving your bind statement to after your parameter statements. I just had basically the same problem and that was part of my fix.

Also, are you sure those are float parameters rather than integer? (glTexParameterf?)

I just got this working for the first time a few minutes ago, so what do I know. But here's my code that is now working after texturing black instead of the image.



int Width;
int Height;
int Components;
bool TextureLoaded = false;

FREE_IMAGE_FORMAT ImageFormat = FreeImage_GetFileType(File.c_str(), 0);
FIBITMAP* ImageBitMap = FreeImage_Load(ImageFormat, File.c_str());

FIBITMAP* TempPointer = ImageBitMap;
ImageBitMap = FreeImage_ConvertTo32Bits(ImageBitMap);
FreeImage_Unload(TempPointer);

Width = FreeImage_GetWidth(ImageBitMap);
Height = FreeImage_GetHeight(ImageBitMap);

GLubyte* Texture = new GLubyte[4 * Width*Height];
char* Pixels = (char*)FreeImage_GetBits(ImageBitMap);

for (int x = 0; x < (Width*Height); x++)
{
Texture[x * 4 + 0] = Pixels[x * 4 + 2];
Texture[x * 4 + 1] = Pixels[x * 4 + 1];
Texture[x * 4 + 2] = Pixels[x * 4 + 0];
Texture[x * 4 + 3] = Pixels[x * 4 + 3];
}

TextureID = 0;
glGenTextures(1, &TextureID);

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_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)Texture);
glBindTexture(GL_TEXTURE_2D, TextureID);
if (GenerateMipMaps) glGenerateMipmap(GL_TEXTURE_2D);


This is OGL 4.5 with FreeImage, GLFW, and GLEW in C++. (Seems like there's so many possible combinations with OGL you have to be specific).

Someone else also said that if your texture is not power of 2 and square that you have to use GL_CLAMP_TO_EDGE because the others like GL_REPEAT will not work. Not sure if that comes into play. I just changed it to GL_CLAMP_TO_EDGE to be safe. (Edit: I just tried it on mine with a 637 by 767 image and GL_REPEAT works fine on mine. So, I have no idea what they were talking about. Maybe a prior version of OGL?)

GClements
06-05-2016, 10:55 AM
Someone else also said that if your texture is not power of 2 and square that you have to use GL_CLAMP_TO_EDGE because the others like GL_REPEAT will not work.

This is incorrect. On any implementation supporting OpenGL 2.0 (or the ARB_texture_non_power_of_two extension), power-of-two texture sizes have no significance. Power-of-two textures may be more efficient than non-power-of-two, but there are no differences in behaviour.