User:Igabriel85/Computer graphics/2014-2015/Laborator 4

(J)OGL BASICS (PART 3)
NOTE: Grab the application template from the following link: Computer graphics -- 2013-2014 -- info.uvt.ro/JOGL-Template

Textures
A texture is a rectangular array of data containing information about color, luminance, color and alpha. Each element in this array is called a texel.

Textures can be 1D, 2D or 3D (used to simulate certain characteristics in the material they depict)

Texture mapping allows one to glue together an image of an object on a polygon. For example images of walls, vegetation, landscapes, etc. NOTE: besides being applied to polygons textures could be also applied to other primitives such as points, lines, polygons, bitmaps and images. It implies mapping texture coordinates to geometric coordinates.

NOTE: you can download textures from the following link:.

Links:


 * Texturing
 * 3D Textures

Creating and displaying 2D textures
The steps involved in generating a 2D texture are as follows:


 * Generate a name for our texture using glGenTextures function (method)
 * Bind (select) our texture in a target. The target is in our case GL_TEXTURE_2D but can also take other values such as GL_TEXTURE_3D or GL_TEXTURE_1D. The binding is accomplished by using the glBindTexture function (method)
 * Specify the pixel storage mode by using the glPixelStorei function (method). This affects how the pixels stored in memory are read
 * Define the filters used when the texture is scaled (resized) during the drawing by using the glTexParameteri function (method)
 * Construct the texture with the representation of the picture file by using either glTexImage2D or gluBuild2DMipmaps functions (methods) depending on whether we want mipmaps (multiple levels of detail in our texture) or not
 * Enable GL_TEXTURE_2D by using the glEnable function (method)
 * Render the texture by assigning vertex coordinates to texture coordinates. The texture coordinates are usually given inside the [0, 1] interval. One can specify a texture coordinate by using the glTexCoord2* family functions (methods)

NOTE: an alternate method for generating textures by using the Texture and TextureIO classes is presented at the following link: Grafica -- 2014-2015 -- info.uvt.ro/Laborator 5.

Important: texture size must be a power of 2 (32x32, 64x64, 512x128, etc) for the texture loader to work properly. Failing to provide a power of 2 texture size will result in an error.

The following code fragments exemplifies the previous steps (IMPORTANT - Please be sure to download and copy the classes found inside the following arhive: textureManager.zip):

NOTE: While the previous code reads textures from image files, the textures can also be generated by specifying the pixel matrix. This (uses glTexImage2D) and this (uses glDrawPixels) exemplifies how you can achieve this.

Textures can also be repeated or clamped:
 * repeated - copies of the texture map tile the surface
 * clamped - a single copy of the image appears on a large surface

The previous techniques are useful when one decides to give texture coordinates outside the [0, 1] interval.

Links:


 * Texturing
 * Mipmapping
 * Texturing tutorial
 * Texturing tutorial based on the NeHe examples

Replacing parts of a texture with another
(J)OGL allows one to replace parts of a texture with another. This technique is also used for improving performance as replacing a texture is much faster than rebuilding it each time.

The following code fragment shows how one can replace a texture with another. Be sure to generate 2 textures inside init, and change NO_TEXTURES = 1 with NO_TEXTURES = 2 inside your code before testing it.

NOTE arguments 3,4,5 and 6 from the glTexSubImage2D represent the position in pixels (arguments 3 and 4) from where a portion of given width (argument 5) and height (argument 6) will be replaced by the pixel data given as last argument. The width and height need to be smaller than the initial image size (tex[0].getWidth, tex[0].getHeight - in our example). The coordinate center (0,0) is situated in the lower left corner of the image.

Links:


 * Texture replacement
 * Multiple views
 * Texture replacement based on Nehe examples

Anisotropic Fitering
Mipmapping often produces blurred images for distant textures viewed at oblique angles. This is due to the fact that texture mapping mode assumes the texture space is a square (isotropic) while in reality it is rather long and narrow (anisotropic). To overcome this problem one could apply anisotropic filtering as detailed in the following code fragment:

Texture transparency and blending
Blending means combining two or more textures by mixing their components.

Transparency means making some pixels transparent. The transparency factor can range from opaque to fully transparent.

Steps for blending

 * Enable blending by using the glEnable(GL.GL_BLEND) function (method)
 * Set the blend function by using the glBlendFunc(mode, mode) function (method)
 * Draw the object(s)
 * disabling blending by using the gl.glDisable(GL.GL_BLEND) function (method)

Note: (for 3D graphics) there are cases when you need to disable the depth test while blending, by using the glEnable(GL_DEPTH_TEST) and glDisable(GL_DEPTH_TEST) functions (methods)

Steps for transparency (alpha testing)

 * Enable alpha testing by using the glEnable(GL_ALPHA_TEST) function (method)
 * Set alpha testing by using the glAlphaFunc(GL_GREATER, 0.7f) function (method) which tells OGL to discard the pixels with an alpha value greater then 0.7 (for example)

IMPORTANT: In order to enable blending we need two textures. As a result the code fragment in the init method for creating a texture needs to be duplicated:

NOTE: The previous method is inefficient as it requires one to copy several lines of code multiple times. A better approach would be to create a class for handling texture creation and manipulation (binding, enabling, disabling).

Links:


 * OpenGL Programming Guide -- Blending, Antialiasing, Fog, and Polygon Offset
 * NeHe blending and transparency
 * OpenGL FAQ -- Transparency, Translucency, and Blending
 * glBlendFunc

API

 * JOGL JavaDoc;

Exercises

 * Creati o clasa TextureHandler pentru generarea unei texturi si incarcati cu ajutorul acesteia doua texturi pe doua corupuri oareacare. Clasa trebuie sa contina urmatoarele metode:
 * o metoda numita bind pentru a selecta si lega textura. Wrapper pentru gl.glBindTexture(GL.GL_TEXTURE_2D, texture[0]);.
 * o metoda numita enable pentru a activa textura. Wrapper pentru gl.glEnable(GL.GL_TEXTURE_2D);.
 * o metoda numita disable pentru a dezactiva textura. Wrapper pentru gl.glDisable(GL.GL_TEXTURE_2D);.
 * o metoda numita getTexture pentru objecte de tip TextureReader.Texture.
 * un constructor numit TextureHandler(GL gl, GLU glu, String filename, boolean mipmapped) pentru generarea texturilor. O mare parte din codul din metoda init va trece in acest contructor. Acesta trebuie sa primeasca ca si argumente o referinta catre objecte GL si GLU, calea catre imagine si un argument boolean care specifica daca se va folosi mipmapping.
 * o metoda private numita makeRGBTexture(...) ca si cea prezentata in laborator.


 * Creati o tabla de sah si inlocuiti patratele albe cu niste texturi.
 * Creati doua patrate una peste cealalta si aplicati texturi diferite pe aceasta. Folositi 5 optiuni de blending intre aceastea.

NOTE: Trebuie sa folositi TextureHandler-ul pentru restul exercitiilor!