I have been learning OpenGL (with C++) for a week now, and have run into a strange issue with textures.
I was adding textures to some buttons in a menu, and at first it seemed to work fine. Then I realized, the image is shifted to the right, and looped around the other end for some reason. Also, when I attempt to load another texture, it seems to return an inverted or strangely-colored texture. I have rooted through my code and found nothing that raises a flag (for me, anyway), so I’d like to know if anyone else finds issues.
Here is the first texture I loaded…
Uploaded with ImageShack.us
Here is the second texture I loaded…
Uploaded with ImageShack.us
This is the screen I got (The last button is not supposed to be textured anyway, but the first and second are supposed to have the first and second textures, respectively)
Uploaded with ImageShack.us
Notice how the left end of each button drops down by one pixel, and is actually looped from the other end of the texture.
Does OpenGL’s glTexImage2D() require that the data be extracted from a specific file format (like RAW)?
These texture’s data were extracted from .bmp files.
If so, how would I change my code to load a texture from a .bmp?
This code is called once per frame on the menu in question…
int mainMenuStep(GLint w, GLint h)
{
static GLuint texture;
static GLuint texture1;
static bool init = true;
glfwSetTime(0);
if(init) //Loading textures (see loadTexture() same post)
{
texture = loadTexture("texture.bmp", 400, 86);
texture1 = loadTexture("text.bmp", 400, 86);
}
if(!glIsTexture( texture )) cerr << "Texture doesn't exist!
";
if(!glIsTexture( texture1 )) cerr << "Texture1 doesn't exist!
";
extern bool twoD;
extern bool mouseActed; //used to prevent individual
// clicks from performing multiple actions
if(!glfwGetMouseButton(GLFW_MOUSE_BUTTON_LEFT) && mouseActed) mouseActed = false;
if(!twoD) set2D();
else glLoadIdentity();
//START: LOGIC
extern GLint width;
extern GLint height;
int mx, my;
int highlighted;
static Rect2D startButton(-width / 4, width / 4, 2.5 *
height / 7, 1.5 * height / 7, false);
static Rect2D settButton(-width / 4, width / 4, 0.5 *
height / 7, -0.5 * height / 7, false);
static Rect2D quitButton(-width / 4, width / 4, -1.5 *
height / 7, -2.5 * height / 7, false);
glfwGetMousePos(&mx, &my);
if(startButton.intersect(mx, my, true))
{
highlighted = 1;
if(glfwGetMouseButton(GLFW_MOUSE_BUTTON_LEFT) && !mouseActed)
{
init = true;
glDeleteTextures(1, &texture);
glDeleteTextures(1, &texture1);
return INGAME;
}
}
else if(settButton.intersect(mx, my, true))
{
highlighted = 2;
if(glfwGetMouseButton(GLFW_MOUSE_BUTTON_LEFT) && !mouseActed)
{
init = true;
glDeleteTextures(1, &texture);
glDeleteTextures(1, &texture1);
return SETTMENU;
}
}
else if(quitButton.intersect(mx, my, true))
{
highlighted = 3;
if(glfwGetMouseButton(GLFW_MOUSE_BUTTON_LEFT) && !mouseActed)
{
glDeleteTextures(1, &texture);
glDeleteTextures(1, &texture1);
return QUITTING;
}
}
else highlighted = 0;
//END: LOGIC
//START: RENDERING
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Clear the background of our window to black
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear the colour buffer
glPushMatrix();
//START BUTTON
if(highlighted == 1) glColor3f(0.2f, 1.0f, 0.2f);
else glColor3f(0.0f, 0.8f, 0.0f);
startButton.draw(texture);
//SETTINGS BUTTON
if(highlighted == 2) glColor3f(1.0f, 1.0f, 0.2f);
else glColor3f(0.8f, 0.8f, 0.0f);
settButton.draw(texture1);
//CLOSE BUTTON
if(highlighted == 3) glColor3f(1.0f, 0.2f, 0.2f);
else glColor3f(0.8f, 0.0f, 0.0f);
quitButton.draw();
static GLubyte letterF[24] = {
0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
0xff, 0x00, 0xff, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
0xff, 0xc0, 0xff, 0xc0};
glColor3f (1.0f, 0.0f, 1.0f);
glRasterPos2i ((-width / 2) + 20, (height / 2) - 20);
glBitmap (10, 12, //width and height of bitmap
0.0, 0.0, //origin point of bitmap
11.0, 0.0, //x and y shift
letterF); //bitmap
glBitmap (10, 12, 0.0, 0.0, 11.0, 0.0, letterF);
glBitmap (10, 12, 0.0, 0.0, 11.0, 0.0, letterF);
glfwSwapBuffers();
glPopMatrix();
//END: RENDERING
glfwSleep(0.01 - glfwGetTime());
init = false;
return MAINMENU;
}
This is the code for loadTexture(char*, int, int)
GLuint loadTexture(char* file, GLint w, GLint h)
{
GLuint texture;
unsigned char* data = new unsigned char[w * h * 3];
fstream fileIn;
fileIn.open(file, ios::in);
int fileNameLen = strlen(file);
if(fileIn.good())
{
fileIn >> data;
fileIn.close();
}
else
{
cerr << "Failed to load texture from file: ";
for(int i = 0; i < fileNameLen; i++)
{
cerr << file[i];
}
cerr << endl;
}
glGenTextures(1, &texture);
glBindTexture( GL_TEXTURE_2D, texture );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
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, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
delete[] data;
return texture;
}
This is the code for Rect2D::draw(GLuint);
void Rect2D::draw(GLuint texture)
{
if(scrnCoords) toGLCoords();
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_TRIANGLES);
glTexCoord2d(0.0f, 1.0f);
glVertex3f(left, top, 0.0f);
glTexCoord2d(1.0f, 1.0f);
glVertex3f(right, top, 0.0f);
glTexCoord2d(1.0f, 0.0f);
glVertex3f(right, bottom, 0.0f);
glTexCoord2d(1.0f, 0.0f);
glVertex3f(right, bottom, 0.0f);
glTexCoord2d(0.0f, 0.0f);
glVertex3f(left, bottom, 0.0f);
glTexCoord2d(0.0f, 1.0f);
glVertex3f(left, top, 0.0f);
glEnd();
}