starting point:
first you have to understand the “graphics pipeline” or how the data flows / gets processed
the best way is to do tutorials and at the same time reading a (good & understandable) book, as well as reading the opengl wiki
after you have undestood how to draw a quad / triangle / etc, adding a texture isnt very hard:
-
generate one, set the necessary basic parameters for it, and allocate memory + fill the memory with your image data
-
to have access to that texture, bind it to any available “texture unit” and tell your fragment shader from what texture unit to read the image data
-
delete the texture if you dont need it anymore
-
example code to generatet a RGBA texture (8bits per channel)
// creating a texture
unsigned int texture = 0;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
// set necessary texture parameters
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);
// allocate memory and set texture data
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
“data” is the pointer to your “byte array”
“GL_UNSIGNED_BYTE” says that your image data has 1 byte pre channel (R, G, B and A)
“GL_RGBA” says that your image has 4 channels (R, G, B and A)
so basically your image data has pixels like that:
struct Pixel {
unsigned char R, G, B, A;
};
- bind texture to a texture unit:
unsigned int textureunit = 1;
// assign texture unit to the sampler2D in the fragment shader
int variablelocation = glGetUniformLocation(program, "image1");
glProgramUniform1i(program, variablelocation, textureunit);
// bind texture to that unit
glActiveTexture(GL_TEXTURE0 + textureunit);
glBindTexture(GL_TEXTURE_2D, texture);
“program” is your program object which contains all your shaders (at least vertex shader + fragment shader)
- delete texture
glDeleteTextures(1, &texture);
to have access in your fragment shader to that texture:
// source code of fragment shader
uniform sampler2D image1;
void main() {
// read pixel color at certain location:
vec4 pixelcolor = texture(image1, sometexturecoordinates);
// ...
}
“sometexturecoordinates” describes the location from which you want to read the image pixel
it is a 2-dimensional float vector (vec2), [0, 1] x [0, 1], the origin it the upper left corner
if your texture coordinate exceeds these boundaries, then some “texture parameters” will describe how to fetch the “texel” (~= pixel)
“GL_CLAMP_TO_EDGE” says:
– if the texture coordinate < 0, it will read from 0
– if the texture coordinate > 1, it will read from 1