I managed to create a sphere (calculating all the vertices etc etc). Now I want to apply a texture on it. I have no idea how. I googled some "OpenGL 3 texture tutorials" but I can't seem to find anything simple. I am using shaders btw. Is there anywhere a very basic step by step tutorial on how to implement a texture? A texture is just an image that wraps around a shape right? Sounds simple, but from what I have seen on the web it's kinda complicated.
There are three main components to basic texturing.
- The texture object, which represents a chunk of video memory storing the image.
- Texture coordinates, also known as UVs, which specify how to apply the 2D image to the 3D triangles of a model.
- The pixel shader has to perform a texture lookup using the texture object and the UV coordinate for that pixel, which returns a color that can be output or used for further shading.
First you need to create a texture object, which is done with
glGenTextures. Then bind it using
GL_TEXTURE_2D, and load an image into it using
glTexImage2D. (Binding the texture object is how you tell
glTexImage2D where the image should go.) Loading the image file and extracting/decompressing the image data into a raw bitmap format is your responsibility; OpenGL won't handle this for you. There are a variety of texture formats available, but stick with
GL_RGBA8 for now.
Then, you need to provide UVs. These are normally part of the vertex buffer, so you should include a float2 component in your vertex struct for this. The UVs would usually be created by an artist using modeling software, but they can be generated programmatically as well. In any case, getting the right UVs to the right vertices is your responsibility. Assuming you're using vertex arrays / buffers, you'll use
glTexCoordPointer to tell OpenGL where the UVs are in your buffer.
Finally, in the shader you'll need to declare a
sampler2D variable, which will refer to the texture object, and you'll also need to add
vec2 parameters to your vertex and pixel shaders with the
TEXCOORD0 semantic, for the UVs. The vertex shader will receive the UVs from the vertex buffer and should pass them through unchanged to the pixel shader. In the pixel shader, you'll call the
texture2D function, passing the sampler and the UVs. It returns a
vec4 representing the color of the texture at the sampled point.
When you do the draw call on the application side, don't forget to do
glEnableClientState(GL_TEXTURE_COORD_ARRAY). You'll also need to bind the texture object you created, and use
glUniform1i to set the sampler parameter to 0 (meaning texture unit 0; you'd use other numbers if you were using multiple textures at the same time, such as a color map and normal map).
I assume you can google the GL calls I mentioned to find out all the details. There are a bunch of moving pieces here but really it's not that complicated. Most of the work is just getting your data to the right place at the right time.