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.

  • \$\begingroup\$ Wait, you want to apply a texture from an image file, or you want to create the texture procedurally with code? \$\endgroup\$ Jan 1 '12 at 23:58
  • \$\begingroup\$ apply a texture from an image file \$\endgroup\$
    – test_help
    Jan 2 '12 at 1:25
  • \$\begingroup\$ Do you know how to texture a normal quad? I'm not sure if your problem is how to do spherical texture mapping, or just any kind of texture mapping. \$\endgroup\$ Jan 2 '12 at 1:32

There are three main components to basic texturing.

  1. The texture object, which represents a chunk of video memory storing the image.
  2. Texture coordinates, also known as UVs, which specify how to apply the 2D image to the 3D triangles of a model.
  3. 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 glBindTexture with 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 glEnable(GL_TEXTURE_2D) and 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.

  • \$\begingroup\$ @test_help getting the right UVs to the right vertices is your responsibility and procedurally choosing the right UVs to map a texture to a sphere is a special case known as spherical texture mapping which you'll probably need too for this case \$\endgroup\$ Jan 2 '12 at 2:51
  • \$\begingroup\$ I don't have much experience with OpenGL (plan to get acquainted with it in a few months though) but from your description here (nice detailed post by the way) the whole texture object creation part seems so overly complicated compared with everything else I've used before (e.g. DX, XNA).. \$\endgroup\$ Jan 2 '12 at 3:00
  • 2
    \$\begingroup\$ "When you do the draw call on the application side, don't forget to do glEnable(GL_TEXTURE_2D) and glEnableClientState(GL_TEXTURE_COORD_ARRAY)." None of these are necessary if you're using shaders and generic vertex attributes. \$\endgroup\$ Jan 2 '12 at 5:01
  • 1
    \$\begingroup\$ @NathanReed: No, it is not. Indeed, glEnable(GL_TEXTURE_2D) is illegal if you're using the core profile. Just look at the docs for glEnable in 3.3; you won't find GL_TEXTURE_2D anywhere. When using shaders, it is simply irrelevant; the texture for that texture unit is defined by the sampler type in the shader and the texture unit assigned to that sampler. So if you have a sampler1D set to texture unit 4, you'd better put a 1D texture in texture unit 4. \$\endgroup\$ Jan 2 '12 at 5:13
  • 1
    \$\begingroup\$ @JariKomppa: Actually, that's not terribly useful for core OpenGL 3.1+. Many of those resources that are linked from there are dead and some are utterly worthless (find an image editor that exports KTX format). That page hasn't been updated in years; it was never anything more than a publicity stunt by the ARB to keep people from asking for an "SDK" for OpenGL. \$\endgroup\$ Jan 2 '12 at 20:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.