void DrawGeometry(final GL gl) { // Cache the sphere positions, normals, texture coordinates, and // vertex indices in a local array; we only need to fill them in the // first time through this function. final int nu = 30, nv = 30; final int nTris = 2 * (nu - 1) * (nv - 1), nVerts = nu * nv; if (P == null) { int u, v; P = BufferUtil.newFloatBuffer(3 * nVerts); N = BufferUtil.newFloatBuffer(3 * nVerts); uv = BufferUtil.newFloatBuffer(2 * nVerts); // Fill in the position, normal, and texture coordinate arrays. // Just loop over all of the vertices, compute their parametreic // (u,v) coordinates (which we use for texture coordinates as // well), and call the ParametricEval() function, which turns (u,v) // coordinates into positions and normals on the surface of the // object. int pp = 0, np = 0, uvp = 0; for (v = 0; v < nv; ++v) { final float fv = (float) v / (float) (nv - 1); for (u = 0; u < nu; ++u) { final float fu = (float) u / (float) (nu - 1); uv.put(uvp, fu); uv.put(uvp + 1, fv); ParametricEval(fu, fv, pp, P, np, N); pp += 3; np += 3; uvp += 2; } } // Now fill in the vertex index arrays indices = BufferUtil.newIntBuffer(3 * nTris); int ip = 0; for (v = 0; v < nv - 1; ++v) for (u = 0; u < nu - 1; ++u) { indices.put(ip++, VERTEX(u, v, nu)); indices.put(ip++, VERTEX(u + 1, v, nu)); indices.put(ip++, VERTEX(u + 1, v + 1, nu)); indices.put(ip++, VERTEX(u, v, nu)); indices.put(ip++, VERTEX(u + 1, v + 1, nu)); indices.put(ip++, VERTEX(u, v + 1, nu)); } // Tell Cg which of these data pointers are associated with which // parameters to the vertex shader, so that when we call // cgGLEnableClientState() and then glDrawElements(), the shader // gets the right input information. CGparameter param = CgGL.cgGetNamedParameter(vertexProgram, "Pobject"); CgGL.cgGLSetParameterPointer(param, 3, GL.GL_FLOAT, 0, P); param = CgGL.cgGetNamedParameter(vertexProgram, "Nobject"); CgGL.cgGLSetParameterPointer(param, 3, GL.GL_FLOAT, 0, N); param = CgGL.cgGetNamedParameter(vertexProgram, "TexUV"); CgGL.cgGLSetParameterPointer(param, 2, GL.GL_FLOAT, 0, uv); } // And now, each time through, enable the bindings to the parameters // that we set up the first time through CGparameter param = CgGL.cgGetNamedParameter(vertexProgram, "Pobject"); CgGL.cgGLEnableClientState(param); param = CgGL.cgGetNamedParameter(vertexProgram, "Nobject"); CgGL.cgGLEnableClientState(param); param = CgGL.cgGetNamedParameter(vertexProgram, "TexUV"); CgGL.cgGLEnableClientState(param); // Enable the texture parameter as well. param = CgGL.cgGetNamedParameter(fragmentProgram, "diffuseMap"); CgGL.cgGLEnableTextureParameter(param); // And now, draw the geometry. gl.glDrawElements(GL.GL_TRIANGLES, 3 * nTris, GL.GL_UNSIGNED_INT, indices); // Be a good citizen and disable the various bindings we set up above. param = CgGL.cgGetNamedParameter(vertexProgram, "Pobject"); CgGL.cgGLDisableClientState(param); param = CgGL.cgGetNamedParameter(vertexProgram, "Nobject"); CgGL.cgGLDisableClientState(param); param = CgGL.cgGetNamedParameter(vertexProgram, "TexUV"); CgGL.cgGLDisableClientState(param); param = CgGL.cgGetNamedParameter(fragmentProgram, "diffuseMap"); CgGL.cgGLDisableTextureParameter(param); }