package classwork; import javax.media.opengl.*; import jocode.*; /** * GLART_5_texture_samples.java * * Demo six texture examples. * */ public class GLART_5_texture_samples extends JOApp { private float rotation = 0f; // texture handles (a number that refers to an allocated texture) int myTextureHandle = 0; int bgTextureHandle = 0; int screenTextureHandle = 0; /** * Main function just creates and runs the application. */ public static void main(String args[]) { GLART_5_texture_samples app = new GLART_5_texture_samples(); displayWidth = 800; displayHeight = 600; app.run(); } /** * Initialize OpenGL * */ public void setup() { // Select the Projection Matrix (controls perspective) gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); // Reset gl.glOrtho( -4f, 4f, //X: left side, right side -3f, 3f, //Y: bottom, top -9f, 9f //Z: near, far ); // Select The Modelview Matrix (controls model orientation) gl.glMatrixMode(GL.GL_MODELVIEW); // enable texturing gl.glEnable(GL.GL_TEXTURE_2D); // set the background color gl.glClearColor(.2f, .4f, .5f, 1); // Prepare a texture from the image myTextureHandle = makeTexture("images/velazquez_texture_256.jpg"); // Prepare a texture from the image bgTextureHandle = makeTexture("images/screen_bg.png"); // Allocate a blank texture same size as window screenTextureHandle = makeTexture(getWidth(), getHeight()); } /** * Render the scene. */ public void draw() { rotation += .5f; // Clear screen and depth buffer gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // draw the background image renderBackground(bgTextureHandle); // Select and reset the Modelview Matrix (controls model orientation) gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); // Where is the 'eye' glu.gluLookAt( 0f, 0f, 3f, // eye position 0f, 0f, 0f, // target to look at 0f, 1f, 0f); // which way is up // "select" our texture gl.glBindTexture(GL.GL_TEXTURE_2D,myTextureHandle); // upper left gl.glPushMatrix(); { gl.glTranslatef(-2.5f, 1.1f, 0); renderTexturePlain(); } gl.glPopMatrix(); // upper middle gl.glPushMatrix(); { gl.glTranslatef(0, 1.1f, 0); renderTextureTiled(); } gl.glPopMatrix(); // upper right gl.glPushMatrix(); { gl.glTranslatef(2.5f, 1.1f, 0); renderTextureZoomed(); } gl.glPopMatrix(); // lower left gl.glPushMatrix(); { gl.glTranslatef(-2.5f, -1.6f, 0); this.renderTextureMirrored(); } gl.glPopMatrix(); // lower middle gl.glPushMatrix(); { gl.glTranslatef(0, -1.6f, 0); renderTextureTransformed(); } gl.glPopMatrix(); // lower right gl.glPushMatrix(); { gl.glTranslatef(2.5f, -1.6f, 0); renderTextureScreen(); } gl.glPopMatrix(); // copy the screen to a texture (used in renderTextureScreen()) captureScreen(screenTextureHandle); } /** * draw a large texture over the entire screen area * assumes that the texture passed in is 1024x1024 */ public void renderBackground(int txtrHandle) { // make this the "current" texture gl.glBindTexture(GL.GL_TEXTURE_2D,txtrHandle); // switch to projection matrix, set ortho mode gl.glMatrixMode(GL.GL_PROJECTION); gl.glPushMatrix(); // preserve previous perspective view gl.glLoadIdentity(); // reset matrix gl.glOrtho( 0, 800f, 0, 600f, -3f, 3f ); // ortho mode, same size as screen // switch back to model view gl.glMatrixMode(GL.GL_MODELVIEW); gl.glPushMatrix(); // preserve the current Modelview Matrix gl.glLoadIdentity(); // clear the Modelview Matrix // draw a quad as big as the texture (NOT as big as screen!) gl.glBegin(GL.GL_QUADS); { // lower left gl.glTexCoord2f(0f, 0f); gl.glVertex3f( 0f, 0f, -2f); // lower right gl.glTexCoord2f(1f, 0f); gl.glVertex3f( 800, 0, -2); // upper right gl.glTexCoord2f(1f, 1f); gl.glVertex3f( 800, 600, -2); // upper left gl.glTexCoord2f(0f, 1f); gl.glVertex3f( 0, 600, -2); } gl.glEnd(); // return to previous modelview matrix gl.glPopMatrix(); // select projection matrix and pop back to previous projection gl.glMatrixMode(GL.GL_PROJECTION); gl.glPopMatrix(); } /** * Draw texture tiled once onto quad: glTexCoord values range from 0 to 1 */ public void renderTexturePlain() { gl.glBegin(GL.GL_QUADS); { gl.glTexCoord2f(0, 0); gl.glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left gl.glTexCoord2f(1, 0); gl.glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right gl.glTexCoord2f(1, 1); gl.glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right gl.glTexCoord2f(0, 1); gl.glVertex3f(-1.0f, 1.0f, 0.0f); // Top left } gl.glEnd(); } /** * Draw texture tiled 4x: glTexCoord values range from 0 to 4 */ public void renderTextureTiled() { float tileFactor = 4; // rotation/100f; gl.glBegin(GL.GL_QUADS); { gl.glTexCoord2f(0, 0); gl.glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left gl.glTexCoord2f(tileFactor, 0); gl.glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right gl.glTexCoord2f(tileFactor, tileFactor); gl.glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right gl.glTexCoord2f(0, tileFactor); gl.glVertex3f(-1.0f, 1.0f, 0.0f); // Top left } gl.glEnd(); } /** * Draw texture "zoomed in": glTexCoord values range from .3 to .7 */ public void renderTextureZoomed() { gl.glBegin(GL.GL_QUADS); { gl.glTexCoord2f(.3f, .3f); gl.glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left gl.glTexCoord2f(.7f, .3f); gl.glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right gl.glTexCoord2f(.7f, .7f); gl.glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right gl.glTexCoord2f(.3f, .7f); gl.glVertex3f(-1.0f, 1.0f, 0.0f); // Top left } gl.glEnd(); } /** * Draw texture mirrored: glTexCoord values range from 1 to 0 */ public void renderTextureMirrored() { gl.glBegin(GL.GL_QUADS); { gl.glTexCoord2f(1, 0); gl.glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left gl.glTexCoord2f(0, 0); gl.glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right gl.glTexCoord2f(0, 1); gl.glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right gl.glTexCoord2f(1, 1); gl.glVertex3f(-1.0f, 1.0f, 0.0f); // Top left } gl.glEnd(); } /** * Draw texture rotated. */ public void renderTextureTransformed() { // switch to Texture Matrix and rotate the texture space gl.glMatrixMode(GL.GL_TEXTURE); gl.glPushMatrix(); // preserve previous texture matrix gl.glLoadIdentity(); gl.glTranslatef(.5f,.5f,0f); // shift coord system to center of image gl.glRotatef(rotation, 0, 0, 1); // rotate around center gl.glTranslatef(-.5f,-.5f,0f); // shift back // switch back to modelview and draw the quad gl.glMatrixMode(GL.GL_MODELVIEW); gl.glBegin(GL.GL_QUADS); { gl.glTexCoord2f(0, 0); gl.glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left gl.glTexCoord2f(1, 0); gl.glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right gl.glTexCoord2f(1, 1); gl.glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right gl.glTexCoord2f(0, 1); gl.glVertex3f(-1.0f, 1.0f, 0.0f); // Top left } gl.glEnd(); // switch to Texture Matrix and return to previous state gl.glMatrixMode(GL.GL_TEXTURE); gl.glPopMatrix(); // return to modelview matrix gl.glMatrixMode(GL.GL_MODELVIEW); } /** * Draw screen image textured on quad. * The screen image is smaller (800x600) than the texture dimensions (1024x1024). * If we use 0-1 for our U and V range we'll see the extra blank space as well as the screen. * To map only to screen area we'll calculate the UV position of the right and top edge of the screen image. * * See captureScreen(). */ public void renderTextureScreen() { // "select" texture that has screen image gl.glBindTexture(GL.GL_TEXTURE_2D, screenTextureHandle); // just for fun, rotate the quad gl.glRotatef(rotation, 0, .6f, 1); gl.glRotatef(rotation*.2f, 0, 0, 1); // draw a quad with texture coordinates gl.glBegin(GL.GL_QUADS); { gl.glTexCoord2f(0, 0); gl.glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left gl.glTexCoord2f(1, 0); gl.glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right gl.glTexCoord2f(1, 1); gl.glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right gl.glTexCoord2f(0, 1); gl.glVertex3f(-1.0f, 1.0f, 0.0f); // Top left } gl.glEnd(); } /** * calls glCopyTexSubImage2D() to copy pixels from the framebuffer into a texture. * The texture must be large enough to hold the screen image (ie. a 1024x1024 * texture can hold a screen 1024x768 or smaller). */ public void captureScreen(int screenTexture) { // "select" the texture that will hold screen image gl.glBindTexture(GL.GL_TEXTURE_2D, screenTexture); // Copy framebuffer into texture gl.glCopyTexSubImage2D( GL.GL_TEXTURE_2D, // always GL_TEXTURE_2D 0, // texture detail level: always 0 0,0, // x,y offset into texture 0,0, // lower left of screen area to copy getWidth(),getHeight() // width,height of screen area to copy ); } }