Bezier
TextureReader
This is a simplified version. The complete class as used by NeHe [1] may be found at koders [2] , search with TextureReader
oneBezier
We load two textures, only the last is used ( you may modify the code to use the other)
TextureReader.Texture bs_texture=null; TextureReader.Texture spider_texture=null; ... try { bs_texture = TextureReader.readTexture("images/bs-1.png"); spider_texture = TextureReader.readTexture("images/spiderman.jpg"); } catch (IOException ex) { System.out.println(ex.getMessage()); }
The controlpoints for the Bezier is described like this:
float ctrlpoints[]; ... ctrlpoints= new float[]// [v][u][xyz] [4][4][3] { -1.5f,-1.5f,0.0f, -0.5f,-1.5f,0.0f, 0.5f,-1.5f,0.0f, 1.5f,-1.5f,0.0f , -1.5f,-0.5f,0.0f, -0.5f,-0.5f,0.0f, 0.5f,-0.5f,0.0f, 1.5f,-0.5f,0.0f , -1.5f,0.5f,0.0f, -0.5f,0.5f,0.0f, 0.5f,0.5f, 0.0f, 1.5f,0.5f,0.0f , -1.5f,1.5f,0.0f, -0.5f,1.5f,0.0f, 0.5f,1.5f,0.0f, 1.5f,1.5f,0.0f };
and the 4 center controlpoints may be offset to "stretch" the surface
private void offsetControls(float offset) { // adjust z-values of the 4 "center" points ctrlpoints[18-1]= ctrlpoints[21-1]= ctrlpoints[30-1]= ctrlpoints[33-1]=offset; }
We render the Bezier surface like this (without texture):
public void drawMe(GL gl,float offset, boolean showGrid,boolean showCtrls,boolean showTexture) { offsetControls(offset); if(showCtrls) drawControls(gl); if(showTexture && bs_texture!=null) { textureMe(gl,spider_texture); //textureMe(gl,bs_texture); } else { stdMaterials.setMaterial(gl, stdMaterials.MAT_RED_PLASTIC, GL.GL_FRONT); stdMaterials.setMaterial(gl, stdMaterials.MAT_GREEN_PLASTIC, GL.GL_BACK); gl.glMap2f(GL.GL_MAP2_VERTEX_3,0.0f,1.0f,3,4,0.0f,1.0f,12,4,ctrlpoints,0); gl.glEnable(GL.GL_MAP2_VERTEX_3); gl.glEnable(GL.GL_AUTO_NORMAL); gl.glEnable(GL.GL_NORMALIZE); gl.glMapGrid2f(20,0.0f,1.0f,20,0.0f, 1.0f); gl.glFrontFace(GL.GL_CW); if(showGrid) gl.glEvalMesh2(GL.GL_LINE, 0, 20, 0, 20); else gl.glEvalMesh2(GL.GL_FILL, 0, 20, 0, 20); gl.glFrontFace(GL.GL_CCW); } }
Render with texture:
private void textureMe(GL gl,TextureReader.Texture tex) { gl.glTexEnvi(GL.GL_TEXTURE_ENV,GL.GL_TEXTURE_ENV_MODE,GL.GL_DECAL); gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_NEAREST); gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_NEAREST); gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S,GL.GL_REPEAT); gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_T,GL.GL_REPEAT); gl.glEnable(GL.GL_TEXTURE_2D); gl.glEnable(GL.GL_MAP2_VERTEX_3); gl.glEnable(GL.GL_MAP2_TEXTURE_COORD_1); gl.glEnable(GL.GL_MAP2_TEXTURE_COORD_2); gl.glTexImage2D(GL.GL_TEXTURE_2D,0,3, tex.getWidth(), tex.getHeight(), 0,GL.GL_RGB,GL.GL_UNSIGNED_BYTE, tex.getPixels()); // map geometri gl.glMap2f(GL.GL_MAP2_VERTEX_3, 0.0f,1.0f,3,4,0.0f,1.0f,12,4, ctrlpoints,0); // map bs_texture float txpts[]=new float[]{0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f}; gl.glMap2f(GL.GL_MAP2_TEXTURE_COORD_2,0,1,2,2,0,1,4,2, txpts,0); gl.glMapGrid2f(20,0.0f,1.0f,20,0.0f, 1.0f); gl.glEvalMesh2(GL.GL_FILL, 0, 20, 0, 20); }
The controlpoints are rendered like this:
private void drawControls(GL gl) { // assuming they are offset correctly stdMaterials.setMaterial(gl, stdMaterials.MAT_BLACK_PLASTIC, GL.GL_FRONT_AND_BACK); // ctrlpoints[4][4][3] int u,v; for(u=0;u<4;u++) { gl.glBegin(GL.GL_LINE_STRIP); for(v=0;v<4;v++) { gl.glVertex3f( ctrlpoints[v*12+u*3+0], ctrlpoints[v*12+u*3+1], ctrlpoints[v*12+u*3+2]); } gl.glEnd(); } for(v=0;v<4;v++) { gl.glBegin(GL.GL_LINE_STRIP); for(u=0;u<4;u++) { gl.glVertex3f( ctrlpoints[v*12+u*3+0], ctrlpoints[v*12+u*3+1], ctrlpoints[v*12+u*3+2]); } gl.glEnd(); } }