Pro OpenGL ES for iOS

(singke) #1

330 CHAPTER 10: OpenGL ES 2, Shaders, and...^


Not only are we going to add clouds to our model, but we’ll also see how to handle
multitexturing using shaders, as in, how does one tell a shader to use more than one
texture? Remember the lesson about texture units in Chapter 6? They come in really
handy right now, because that is where the textures are stored, ready for the fragment
shader to pick them up. Normally, for a single texture, the system defaults in a way that
no additional setup is needed, save for the normal call to glBindTexture(). However, if
you want to use more than one, there is some setup required. The steps are as follows:


  1. Load the new texture in your main program.

  2. Add a second uniform sampler2D to your fragment shader to support a
    second texture and pick it up via glGetUniformLocation().

  3. Tell the system which texture unit to use with which sampler.

  4. Activate and bind the desired textures to the specified TUs while in the
    main loop, drawInRect().
    Now to a few specifics: you already know how to load textures. That is, of course, a no-
    brainer. So, in step 2, you will want to add something like the following to the fragment
    shader, the same one used for the previous couple of exercises:
    uniform sampler2D cloud_texture;
    And to loadShaders():
    uniforms[UNIFORM_SAMPLER1] = glGetUniformLocation(program, "cloud_texture");
    uniforms[UNIFORM_SAMPLER0] = glGetUniformLocation(
    program, "s_texture");
    Step 3 is added in the view controller’s setupGL(). The glUniform1i() call takes the
    ‘‘location’’ of the uniform in the fragment shader for the first argument and takes the
    actual TU number in the second. So, in this case, sampler0 is bound to texture unit 0,
    while sampler1 goes to texture unit 1. Since a single texture always defaults to TU0, as
    well as the first sampler, the setup code is not needed.
    glUseProgram(m_DaysideProgram);
    glUniform1i(uniforms[UNIFORM_SAMPLER0],0);
    glUniform1i(uniforms[UNIFORM_SAMPLER1],1);


glUseProgram(m_NightsideProgram);
glUniform1i(uniforms[UNIFORM_SAMPLER0],0);
glUniform1i(uniforms[UNIFORM_SAMPLER1],1);
When running the main loop, in step 4, you can do the following:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,m_EarthNightTexture.name);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,m_EarthCloudTexture.name);

[self useProgram:m_NightsideProgram];
Free download pdf