I am trying to map a texture to a simple quad for the first time, but all it won't render. I am using freeglut for the implementation, and the stb_image.h header to load the texture. The code:
#include <GL/glut.h>
#include <stb_image.h>
#include <iostream>
int ww = 500, wh = 500;
void display()
{
glClearColor(1.0, 1.0, 0.7, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
glEnable(GL_TEXTURE_2D);
glTexCoord2f(0.0, 0.0); glVertex3f(10,10,0);
glTexCoord2f(0.0, 1.0); glVertex3f(10,wh-10,0);
glTexCoord2f(1.0, 1.0); glVertex3f(ww-10,wh,0);
glTexCoord2f(1.0, 0.0); glVertex3f(ww-10,10,0);
glDisable(GL_TEXTURE_2D);
glEnd();
glFlush();
}
void myinit()
{
glViewport(0, 0, ww, wh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble)ww, 0.0, (GLdouble)wh);
glMatrixMode(GL_MODELVIEW);
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
int width, height, nrChannels;
unsigned char* data = stbi_load("container.jpg", &width, &height, &nrChannels, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutInitWindowSize(ww, wh);
glutCreateWindow("texture-try");
glutDisplayFunc(display);
myinit();
glutMainLoop();
return 0;
}
It successfully loads the texture, but the quad appears just white. What am I missing?
Edit:
I moved the glBegin(GL_QUADS);
and glEnd();
inside the glEnable(GL_TEXTURE_2D);
and glDisable(GL_TEXTURE_2D);
commands as was suggested, but it still won't render the texture.
I also checked the glGetError
command, but it returns GL_NO_ERROR
.
Several things:
glBegin()
/glEnd()
pair" issue; as of posting this hasn't been fixed in the question code.GL_LINEAR_MIPMAP_LINEAR
is being used without providing any mipmaps. Drop to GL_LINEAR
or provide some mipmaps.3
to stbi_load()
's desired_channels
parameter (instead of the current 0
) to guarantee you get 3-channel image data instead of just assuming nrChannels
is 3
for all input images.GL_RGB
with the default GL_UNPACK_ALIGNMENT
of 4
can result in wonky display if your image width isn't a nice multiple of 4 so drop that down to 1
via glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
before calling glTexImage2D()
.GLUT_DOUBLE
& glutSwapBuffers()
instead of using GLUT_SINGLE
and glFlush()
.All together:
#include <GL/glut.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#include <iostream>
int ww = 500, wh = 500;
void display()
{
glClearColor(1.0, 1.0, 0.7, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(10,10,0);
glTexCoord2f(0.0, 1.0); glVertex3f(10,wh-10,0);
glTexCoord2f(1.0, 1.0); glVertex3f(ww-10,wh,0);
glTexCoord2f(1.0, 0.0); glVertex3f(ww-10,10,0);
glEnd();
glDisable(GL_TEXTURE_2D);
glutSwapBuffers();
}
void myinit()
{
glViewport(0, 0, ww, wh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble)ww, 0.0, (GLdouble)wh);
glMatrixMode(GL_MODELVIEW);
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
int width, height, nrChannels;
// https://commons.wikimedia.org/wiki/File:Container.JPG
unsigned char* data = stbi_load("container.jpg", &width, &height, &nrChannels, 3);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(ww, wh);
glutCreateWindow("texture-try");
glutDisplayFunc(display);
myinit();
glutMainLoop();
return 0;
}