glTexImage2D
Allocates a 2D texture image and optionally uploads pixels into it.
Signature
void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *data);
How it works
The texture equivalent of glBufferData. It has many parameters because it describes TWO formats: how the GPU should STORE the texels (internalformat) and how YOUR data in memory is laid out (format + type). The driver converts from one to the other.
Passing nullptr as data just allocates — that is how you create empty render targets for framebuffers.
Parameters
GL_TEXTURE_2D, or one cube face: GL_TEXTURE_CUBE_MAP_POSITIVE_X + i.
Mipmap level. 0 is the full-size image.
How the GPU stores the texture.
Common values
- GL_RGB8 / GL_RGBA8
- 8 bits per channel — standard data textures.
- GL_SRGB8 / GL_SRGB8_ALPHA8
- Color images painted in sRGB (albedo). The GPU linearizes on sampling.
- GL_RGBA16F / GL_RGBA32F
- Floating point — HDR render targets.
- GL_DEPTH_COMPONENT24 / 32F
- Depth texture (shadow maps).
- GL_RED / GL_R8
- Single channel (masks, font atlases).
Width in texels.
Height in texels.
Must be 0 (historical parameter).
Channel order of YOUR data.
Common values
- GL_RGB / GL_RGBA
- 3 or 4 channels, as stb_image returns.
- GL_RED
- Single channel.
- GL_DEPTH_COMPONENT
- Depth data (use with nullptr).
Type of each channel of YOUR data: GL_UNSIGNED_BYTE for images from disk, GL_FLOAT for HDR.
Pixel data, starting at the BOTTOM-left row. nullptr to only allocate.
Tips & pitfalls
Images load top-down but OpenGL expects bottom-up: call stbi_set_flip_vertically_on_load(true), or the texture appears upside down.
RGB images with a width not multiple of 4 look skewed: set
glPixelStorei(GL_UNPACK_ALIGNMENT, 1) first.format must match the channel count stb_image reported — GL_RGB for 3, GL_RGBA for 4.
Errors
When the call is invalid it does nothing and sets an error, which glGetError returns:
- GL_INVALID_VALUE
- Size is negative or larger than GL_MAX_TEXTURE_SIZE, or border ≠ 0.
- GL_INVALID_OPERATION
- format/type combination is not compatible with internalformat.
Example
1int w, h, n;
2stbi_set_flip_vertically_on_load(true);
3unsigned char* pixels = stbi_load("wall.jpg", &w, &h, &n, 0);
4GLenum fmt = (n == 4) ? GL_RGBA : GL_RGB;
5
6glBindTexture(GL_TEXTURE_2D, tex);
7glTexImage2D(GL_TEXTURE_2D, 0, fmt, w, h, 0, fmt, GL_UNSIGNED_BYTE, pixels);
8glGenerateMipmap(GL_TEXTURE_2D);
9stbi_image_free(pixels);