summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Russel <[email protected]>2003-06-26 14:26:23 +0000
committerKenneth Russel <[email protected]>2003-06-26 14:26:23 +0000
commit557c3213e11691f0b6bf3d0de5ac8d0003ccd385 (patch)
tree8cd163c0a2bdb2df9e8901710751a171ebb50d41
parent560a89f99aa8514915de874f2e26d15d45644ffc (diff)
Checked in experimental Cg support and a couple of small demos. By
default it is not built and javadoc is not generated for it. The demos are not compiled by the jogl-demos project makefile since there are issues to be thought through with operations like cgCreateProgramFromFile and their interaction with launching over the web via Java Web Start. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/../svn-server-sync/jogl-demos/trunk@8 3298f667-5e0e-4b4a-8ed4-a3559d26a5f4
-rw-r--r--src/demos/cg/runtime_ogl/cgGL_vertex_example.cg29
-rw-r--r--src/demos/cg/runtime_ogl/cgGL_vertex_example.java278
-rw-r--r--src/demos/cg/runtime_ogl_vertex_fragment/demo_frag.cg61
-rw-r--r--src/demos/cg/runtime_ogl_vertex_fragment/demo_vert.cg46
-rw-r--r--src/demos/cg/runtime_ogl_vertex_fragment/runtime_ogl_vertex_fragment.java412
5 files changed, 826 insertions, 0 deletions
diff --git a/src/demos/cg/runtime_ogl/cgGL_vertex_example.cg b/src/demos/cg/runtime_ogl/cgGL_vertex_example.cg
new file mode 100644
index 0000000..dae355e
--- /dev/null
+++ b/src/demos/cg/runtime_ogl/cgGL_vertex_example.cg
@@ -0,0 +1,29 @@
+
+struct appdata
+{
+ float4 position : POSITION;
+ float3 normal : NORMAL;
+ float3 color : DIFFUSE;
+ float3 TestColor : SPECULAR;
+};
+
+struct vfconn
+{
+ float4 HPOS : POSITION;
+ float4 COL0 : COLOR0;
+};
+
+vfconn main(appdata IN,
+ uniform float4 Kd,
+ uniform float4x4 ModelViewProj)
+{
+ vfconn OUT;
+
+ OUT.HPOS = mul(ModelViewProj, IN.position);
+
+ OUT.COL0.xyz = Kd.xyz * IN.TestColor.xyz;
+ OUT.COL0.w = 1.0;
+
+ return OUT;
+} // main
+
diff --git a/src/demos/cg/runtime_ogl/cgGL_vertex_example.java b/src/demos/cg/runtime_ogl/cgGL_vertex_example.java
new file mode 100644
index 0000000..16c3e1a
--- /dev/null
+++ b/src/demos/cg/runtime_ogl/cgGL_vertex_example.java
@@ -0,0 +1,278 @@
+/*
+ * Portions Copyright (C) 2003 Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+/*
+ *
+ * COPYRIGHT NVIDIA CORPORATION 2003. ALL RIGHTS RESERVED.
+ * BY ACCESSING OR USING THIS SOFTWARE, YOU AGREE TO:
+ *
+ * 1) ACKNOWLEDGE NVIDIA'S EXCLUSIVE OWNERSHIP OF ALL RIGHTS
+ * IN AND TO THE SOFTWARE;
+ *
+ * 2) NOT MAKE OR DISTRIBUTE COPIES OF THE SOFTWARE WITHOUT
+ * INCLUDING THIS NOTICE AND AGREEMENT;
+ *
+ * 3) ACKNOWLEDGE THAT TO THE MAXIMUM EXTENT PERMITTED BY
+ * APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS* AND
+ * THAT NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY
+ * SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
+ * WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS
+ * OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
+ * INFORMATION, OR ANY OTHER PECUNIARY LOSS), INCLUDING ATTORNEYS'
+ * FEES, RELATING TO THE USE OF OR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+import net.java.games.cg.*;
+import net.java.games.jogl.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * cgGL_vertex_example: simple demo of Nvidia CgGL API. Based upon C version
+ * distributed with the NVidia Cg Toolkit. Ported to the Java language by
+ * Christopher Kline 5/29/2003.
+ */
+public class cgGL_vertex_example implements GLEventListener
+{
+
+ /******************************************************************************/
+ /*** Static Data ***/
+ /******************************************************************************/
+
+ private final int TextureRes = 512;
+
+ private static CGcontext Context = null;
+ private static CGprogram Program = null;
+ private static CGparameter KdParam = null;
+ private static CGparameter ModelViewProjParam = null;
+ private static CGparameter TestColorParam = null;
+ private static /*CGprofile*/ int profile;
+
+ static
+ {
+ String os = System.getProperty("os.name").toLowerCase();
+ profile = os.startsWith("mac os") ? CgGL.CG_PROFILE_ARBVP1 : CgGL.CG_PROFILE_VP20;
+ }
+
+ private float LightDiffuse[] = {1.0f, 0.0f, 0.0f, 1.0f};
+ private float LightPosition[] = {1.0f, 1.0f, 1.0f, 0.0f};
+
+ private float CubeNormals[/*6*/][/*3*/] =
+ {
+ {-1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f},
+ {1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f},
+ {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, -1.0f}
+ };
+
+ private int CubeFaces[/*6*/][/*4*/] =
+ {
+ {0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4},
+ {4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3}
+ };
+
+ private float CubeVertices[][] = new float[8][3];
+
+/******************************************************************************/
+
+ private int MATRIX_INDEX(int i, int j) { return (j + i * 4); }
+
+ private static void CheckCgError()
+ {
+ /*CGerror*/ int err = CgGL.cgGetError();
+
+ if (err != CgGL.CG_NO_ERROR)
+ {
+ System.out.println("CG error: " + CgGL.cgGetErrorString(err));
+ System.exit(1);
+ }
+ }
+
+
+ private void DrawCube(GL gl)
+ {
+ int i;
+
+ CgGL.cgGLBindProgram(Program);
+ CheckCgError();
+
+ /*
+ * Set various uniform parameters including the ModelViewProjection
+ * matrix for transforming the incoming position into HPOS.
+ */
+ if(KdParam != null)
+ CgGL.cgGLSetParameter4f(KdParam, 1.0f, 1.0f, 0.0f, 1.0f);
+
+ /* Set the concatenate modelview and projection matrices */
+ if(ModelViewProjParam != null)
+ CgGL.cgGLSetStateMatrixParameter(ModelViewProjParam,
+ CgGL.CG_GL_MODELVIEW_PROJECTION_MATRIX,
+ CgGL.CG_GL_MATRIX_IDENTITY);
+
+ CgGL.cgGLEnableProfile(profile);
+
+
+ /*
+ * Create cube with per-vertex varying attributes
+ */
+ for(i = 0; i < 6; i++)
+ {
+ gl.glBegin(GL.GL_QUADS);
+
+ gl.glNormal3f(CubeNormals[i][0], CubeNormals[i][1], CubeNormals[i][0]);
+ CgGL.cgGLSetParameter3f(TestColorParam, 1.0f, 0.0f, 0.0f);
+ float[] verts = CubeVertices[CubeFaces[i][0]];
+ gl.glVertex3f(verts[0], verts[1], verts[2]);
+
+ CgGL.cgGLSetParameter3f(TestColorParam, 0.0f, 1.0f, 0.0f);
+ verts = CubeVertices[CubeFaces[i][1]];
+ gl.glVertex3f(verts[0], verts[1], verts[2]);
+
+ CgGL.cgGLSetParameter3f(TestColorParam, 0.0f, 0.0f, 1.0f);
+ verts = CubeVertices[CubeFaces[i][2]];
+ gl.glVertex3f(verts[0], verts[1], verts[2]);
+
+ CgGL.cgGLSetParameter3f(TestColorParam, 1.0f, 1.0f, 1.0f);
+ verts = CubeVertices[CubeFaces[i][3]];
+ gl.glVertex3f(verts[0], verts[1], verts[2]);
+
+ gl.glEnd();
+ }
+
+ CgGL.cgGLDisableProfile(profile);
+ }
+
+ public void display(GLDrawable drawable)
+ {
+ GL gl = drawable.getGL();
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ DrawCube(gl);
+ //glutSwapBuffers();
+ }
+
+ void InitializeCube(float v[/*8*/][/*3*/])
+ {
+ /* Setup cube vertex data. */
+ v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1;
+ v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1;
+ v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1;
+ v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1;
+ v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1;
+ v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1;
+ }
+
+ public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged)
+ {
+ // nothing
+ }
+
+ public void init(GLDrawable drawable)
+ {
+ // Note: we initialize Cg in this init() method instead of main()
+ // because Cg (apparently) requires an active OpenGL context in order to
+ // initialize correctly (otherwise the CheckCgError() call after
+ // cgGLLoadProgram() will fail).
+
+ /* Test cgContext creation */
+ Context = CgGL.cgCreateContext();
+ CheckCgError();
+
+ /* Test adding source text to context */
+ Program = CgGL.cgCreateProgramFromFile(
+ Context, CgGL.CG_SOURCE, "cgGL_vertex_example.cg",
+ profile, null, null);
+ CheckCgError();
+
+ System.err.println(
+ "LAST LISTING----" + CgGL.cgGetLastListing(Context) + "----\n");
+
+ System.err.println(
+ "---- PROGRAM BEGIN ----\n"+
+ CgGL.cgGetProgramString(Program, CgGL.CG_COMPILED_PROGRAM)+
+ "---- PROGRAM END ----\n");
+
+ if(Program != null)
+ {
+ CgGL.cgGLLoadProgram(Program);
+ CheckCgError();
+
+ KdParam = CgGL.cgGetNamedParameter(Program, "Kd");
+ CheckCgError();
+
+ ModelViewProjParam = CgGL.cgGetNamedParameter(Program, "ModelViewProj");
+ CheckCgError();
+
+ TestColorParam = CgGL.cgGetNamedParameter(Program, "IN.TestColor");
+ CheckCgError();
+ }
+ GL gl = drawable.getGL();
+ GLU glu = drawable.getGLU();
+
+ InitializeCube(CubeVertices);
+
+ /* Enable a single OpenGL light. */
+ gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, LightDiffuse);
+ gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, LightPosition);
+ gl.glEnable(GL.GL_LIGHT0);
+ if (false) { // #if 0
+ gl.glEnable(GL.GL_LIGHTING);
+ } else { // #else
+ gl.glDisable(GL.GL_LIGHTING);
+ } // #endif
+
+ /* Use depth buffering for hidden surface elimination. */
+ gl.glEnable(GL.GL_DEPTH_TEST);
+
+ /* Setup the view of the cube. */
+ gl.glMatrixMode(GL.GL_PROJECTION);
+ glu.gluPerspective( /* field of view in degree */ 40.0f,
+ /* aspect ratio */ 1.0f,
+ /* Z near */ 1.0f, /* Z far */ 10.0f);
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ glu.gluLookAt(0.0f, 0.0f, 5.0f, /* eye is at (0,0,5) */
+ 0.0f, 0.0f, 0.0f, /* center is at (0,0,0) */
+ 0.0f, 1.0f, 0.); /* up is in positive Y direction */
+
+ /* Adjust cube position to be asthetic angle. */
+ gl.glTranslatef(0.0f, 0.0f, -1.0f);
+ if (true) { // #if 1
+ gl.glRotatef(60, 1.0f, 0.0f, 0.0f);
+ gl.glRotatef(-20, 0.0f, 0.0f, 1.0f);
+ } //#endif
+
+ }
+
+ public void reshape(GLDrawable drawable, int x, int y, int width, int height)
+ {
+ // do nothing
+ }
+
+ public static void main(String[] argv)
+ {
+ Frame frame = new Frame("NVidia Cg Toolkit \"cgGL_vertex_example\" demo");
+ GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities());
+ canvas.addGLEventListener(new cgGL_vertex_example());
+
+ frame.add(canvas);
+ frame.setSize(500, 500);
+ final Animator animator = new Animator(canvas);
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ animator.stop();
+ System.exit(0);
+ }
+ });
+ frame.show();
+ animator.start();
+ }
+
+}
diff --git a/src/demos/cg/runtime_ogl_vertex_fragment/demo_frag.cg b/src/demos/cg/runtime_ogl_vertex_fragment/demo_frag.cg
new file mode 100644
index 0000000..70206fa
--- /dev/null
+++ b/src/demos/cg/runtime_ogl_vertex_fragment/demo_frag.cg
@@ -0,0 +1,61 @@
+/*********************************************************************NVMH3****
+
+Copyright NVIDIA Corporation 2002
+TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
+*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
+BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
+WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
+BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
+ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
+Comments:
+
+******************************************************************************/
+
+// Utility functions that return the appropriate components from the vector
+// of lighting coefficients returned by the standard library lighting
+// funciton, lit().
+
+half diffuse(half4 l) { return l.y; }
+half specular(half4 l) { return l.z; }
+
+// Main shader.
+
+half4 main(float3 Peye : TEXCOORD0,
+ half3 Neye : TEXCOORD1,
+ half2 uv : TEXCOORD2,
+ half3 Kd : COLOR0,
+ half3 Ks : COLOR1,
+ uniform sampler2D diffuseMap,
+ uniform float3 Plight,
+ uniform half3 lightColor,
+ uniform half3 shininess) : COLOR
+{
+ // Normalize surface normal, vector to light source, and vector
+ // to the viewer
+ half3 N = normalize(Neye);
+ half3 L = normalize(Plight - Peye);
+ half3 V = normalize(-Peye);
+
+ // Compute half-angle vector for specular lighting
+ half3 H = normalize(L + V);
+
+ // Compute lighting values. lit() returns the diffuse coefficient
+ // in y (or zero, if NdotL < 0), and the specular coefficient in z
+ // (or zero, also if NdotL < 0).
+ half NdotL = dot(N, L), NdotH = dot(N, H);
+ half4 lighting = lit(NdotL, NdotH, shininess);
+
+ // Compute overall color for the fragment. Scale sum of diffuse
+ // and specular contributions together and by the light color.
+ half3 C = lightColor *
+ (diffuse(lighting) * Kd * (half3)tex2D(diffuseMap, uv).xyz +
+ specular(lighting) * Ks);
+
+ // Always set the alpha value to 1.
+ return half4(C, 1);
+}
diff --git a/src/demos/cg/runtime_ogl_vertex_fragment/demo_vert.cg b/src/demos/cg/runtime_ogl_vertex_fragment/demo_vert.cg
new file mode 100644
index 0000000..e767ad3
--- /dev/null
+++ b/src/demos/cg/runtime_ogl_vertex_fragment/demo_vert.cg
@@ -0,0 +1,46 @@
+/*********************************************************************NVMH3****
+
+Copyright NVIDIA Corporation 2002
+TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
+*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
+BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
+WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
+BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
+ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
+Comments:
+
+******************************************************************************/
+
+void main(float4 Pobject : POSITION,
+ float3 Nobject : NORMAL,
+ float2 TexUV : TEXCOORD0,
+ float3 diffuse : TEXCOORD1,
+ float3 specular : TEXCOORD2,
+ uniform float4x4 ModelViewProj,
+ uniform float4x4 ModelView,
+ uniform float4x4 ModelViewIT,
+
+ out float4 HPosition : POSITION,
+ out float3 Peye : TEXCOORD0,
+ out float3 Neye : TEXCOORD1,
+ out float2 uv : TEXCOORD2,
+ out float3 Kd : COLOR0,
+ out float3 Ks : COLOR1)
+{
+ // compute homogeneous position of vertex for rasterizer
+ HPosition = mul(ModelViewProj, Pobject);
+ // transform position and normal from model-space to view-space
+ Peye = mul(ModelView, Pobject).xyz;
+ Neye = mul(ModelViewIT, float4(Nobject, 0)).xyz;
+ // pass uv, Kd, and Ks through unchanged; if they are varying
+ // per-vertex, however, they'll be interpolated before being
+ // passed to the fragment program.
+ uv = TexUV;
+ Kd = diffuse;
+ Ks = specular;
+}
diff --git a/src/demos/cg/runtime_ogl_vertex_fragment/runtime_ogl_vertex_fragment.java b/src/demos/cg/runtime_ogl_vertex_fragment/runtime_ogl_vertex_fragment.java
new file mode 100644
index 0000000..38ab297
--- /dev/null
+++ b/src/demos/cg/runtime_ogl_vertex_fragment/runtime_ogl_vertex_fragment.java
@@ -0,0 +1,412 @@
+/*
+ * Portions Copyright (C) 2003 Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+/*
+ *
+ * COPYRIGHT NVIDIA CORPORATION 2003. ALL RIGHTS RESERVED.
+ * BY ACCESSING OR USING THIS SOFTWARE, YOU AGREE TO:
+ *
+ * 1) ACKNOWLEDGE NVIDIA'S EXCLUSIVE OWNERSHIP OF ALL RIGHTS
+ * IN AND TO THE SOFTWARE;
+ *
+ * 2) NOT MAKE OR DISTRIBUTE COPIES OF THE SOFTWARE WITHOUT
+ * INCLUDING THIS NOTICE AND AGREEMENT;
+ *
+ * 3) ACKNOWLEDGE THAT TO THE MAXIMUM EXTENT PERMITTED BY
+ * APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS* AND
+ * THAT NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY
+ * SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
+ * WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS
+ * OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
+ * INFORMATION, OR ANY OTHER PECUNIARY LOSS), INCLUDING ATTORNEYS'
+ * FEES, RELATING TO THE USE OF OR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+import net.java.games.cg.*;
+import net.java.games.jogl.*;
+import net.java.games.jogl.util.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+import java.nio.*;
+import java.util.*;
+
+/**
+ * Basic example of the use of the Cg runtime in a simple OpenGL program.
+ * Ported to Java from NVidia's original C source by Christopher Kline, 06
+ * June 2003. Original NVidia copyright is preserved in the source code.
+ */
+public class runtime_ogl_vertex_fragment implements GLEventListener
+{
+
+ // Global variables: hold the Cg context that we're storing our programs
+ // in as well as handles to the vertex and fragment program used in this
+ // demo.
+
+ CGcontext context;
+ CGprogram vertexProgram, fragmentProgram;
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ // Main program; do basic GLUT and Cg setup, but leave most of the work
+ // to the display() function.
+
+ public static void main(String[] argv)
+ {
+ Frame frame = new Frame("Cg demo (runtime_ogl_vertex_fragment)");
+ GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities());
+ canvas.addGLEventListener(new runtime_ogl_vertex_fragment());
+
+ // Use debug pipeline
+ canvas.setGL(new DebugGL(canvas.getGL()));
+
+ frame.add(canvas);
+ frame.setSize(512, 512);
+ final Animator animator = new Animator(canvas);
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ animator.stop();
+ System.out.println("Exiting");
+ System.exit(0);
+ }
+ });
+ frame.show();
+ animator.start();
+
+ // and all the rest happens in the display function...
+ }
+
+ public void init(GLDrawable drawable)
+ {
+ GL gl = drawable.getGL();
+
+ // Basic Cg setup; register a callback function for any errors
+ // and create an initial context
+ //cgSetErrorCallback(handleCgError); // not yet exposed in Cg binding
+ context = CgGL.cgCreateContext();
+
+ // Do one-time setup only once; setup Cg programs and textures
+ // and set up OpenGL state.
+ ChooseProfiles();
+ LoadCgPrograms();
+ LoadTextures(gl);
+
+ gl.glEnable(GL.GL_DEPTH_TEST);
+ }
+
+ private void CheckCgError()
+ {
+ /*CGerror*/ int err = CgGL.cgGetError();
+
+ if (err != CgGL.CG_NO_ERROR)
+ {
+ throw new RuntimeException("CG error: " + CgGL.cgGetErrorString(err));
+ }
+ }
+
+ private static int curTime = 0;
+
+ // display callback function
+ public void display(GLDrawable drawable)
+ {
+
+ GL gl = drawable.getGL();
+ GLU glu = drawable.getGLU();
+
+ // The usual OpenGL stuff to clear the screen and set up viewing.
+ gl.glClearColor(.25f, .25f, .25f, 1.0f);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+
+ gl.glMatrixMode(GL.GL_PROJECTION);
+ gl.glLoadIdentity();
+ glu.gluPerspective(30.0f, 1.0f, .1f, 100);
+
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ gl.glLoadIdentity();
+ glu.gluLookAt(4, 4, -4, 0, 0, 0, 0, 1, 0);
+
+ // Make the object rotate a bit each time the display function
+ // is called
+ gl.glRotatef(curTime, 0, 1, 0);
+
+ // Now make sure that the vertex and fragment programs, loaded
+ // in LoadCgPrograms() are bound.
+ CgGL.cgGLBindProgram(vertexProgram);
+ CgGL.cgGLBindProgram(fragmentProgram);
+
+ // Bind uniform parameters to vertex shader
+ CgGL.cgGLSetStateMatrixParameter(CgGL.cgGetNamedParameter(vertexProgram, "ModelViewProj"),
+ CgGL.CG_GL_MODELVIEW_PROJECTION_MATRIX,
+ CgGL.CG_GL_MATRIX_IDENTITY);
+ CgGL.cgGLSetStateMatrixParameter(CgGL.cgGetNamedParameter(vertexProgram, "ModelView"),
+ CgGL.CG_GL_MODELVIEW_MATRIX,
+ CgGL.CG_GL_MATRIX_IDENTITY);
+ CgGL.cgGLSetStateMatrixParameter(CgGL.cgGetNamedParameter(vertexProgram, "ModelViewIT"),
+ CgGL.CG_GL_MODELVIEW_MATRIX,
+ CgGL.CG_GL_MATRIX_INVERSE_TRANSPOSE);
+
+ // We can also go ahead and bind varying parameters to vertex shader
+ // that we just want to have the same value for all vertices. The
+ // vertex shader could be modified so that these were uniform for
+ // better efficiency, but this gives us flexibility for the future.
+ float Kd[] = { .7f, .2f, .2f }, Ks[] = { .9f, .9f, .9f };
+ CgGL.cgGLSetParameter3fv(CgGL.cgGetNamedParameter(vertexProgram, "diffuse"), Kd);
+ CgGL.cgGLSetParameter3fv(CgGL.cgGetNamedParameter(vertexProgram, "specular"), Ks);
+
+ // Now bind uniform parameters to fragment shader
+ float lightPos[] = { 3, 2, -3 };
+ CgGL.cgGLSetParameter3fv(CgGL.cgGetNamedParameter(fragmentProgram, "Plight"), lightPos);
+ float lightColor[] = { 1, 1, 1 };
+ CgGL.cgGLSetParameter3fv(CgGL.cgGetNamedParameter(fragmentProgram, "lightColor"),
+ lightColor);
+ CgGL.cgGLSetParameter1f(CgGL.cgGetNamedParameter(fragmentProgram, "shininess"), 40);
+
+ // And finally, enable the approprate texture for fragment shader; the
+ // texture was originally set up in LoadTextures().
+ CgGL.cgGLEnableTextureParameter(CgGL.cgGetNamedParameter(fragmentProgram,
+ "diffuseMap"));
+ // And go ahead and draw the scene geometry
+ DrawGeometry(gl);
+
+ // Disable the texture now that we're done with it.
+ CgGL.cgGLDisableTextureParameter(CgGL.cgGetNamedParameter(fragmentProgram,
+ "diffuseMap"));
+
+ ++curTime;
+ }
+
+
+ // Choose the vertex and fragment profiles to use. Try to use
+ // CG_PROFILE_ARBVFP1 and CG_PROFILE_ARBFP1, depending on hardware support.
+ // If those aren't available, fall back to CG_PROFILE_VP30 and
+ // CG_PROFILE_FP30, respectively.
+
+ int /*CGprofile*/ vertexProfile, fragmentProfile;
+
+ void ChooseProfiles()
+ {
+ // Make sure that the appropriate profiles are available on the
+ // user's system.
+ if (CgGL.cgGLIsProfileSupported(CgGL.CG_PROFILE_ARBVP1))
+ vertexProfile = CgGL.CG_PROFILE_ARBVP1;
+ else {
+ // try VP30
+ if (CgGL.cgGLIsProfileSupported(CgGL.CG_PROFILE_VP30))
+ vertexProfile = CgGL.CG_PROFILE_VP30;
+ else {
+ System.out.println("Neither arbvp1 or vp30 vertex profiles supported on this system.\n");
+ System.exit(1);
+ }
+ }
+
+ if (CgGL.cgGLIsProfileSupported(CgGL.CG_PROFILE_ARBFP1))
+ fragmentProfile = CgGL.CG_PROFILE_ARBFP1;
+ else {
+ // try FP30
+ if (CgGL.cgGLIsProfileSupported(CgGL.CG_PROFILE_FP30))
+ fragmentProfile = CgGL.CG_PROFILE_FP30;
+ else {
+ System.out.println("Neither arbfp1 or fp30 fragment profiles supported on this system.\n");
+ System.exit(1);
+ }
+ }
+ }
+
+
+ void LoadCgPrograms()
+ {
+ assert(CgGL.cgIsContext(context));
+
+ // Load and compile the vertex program from demo_vert.cg; hold on to the
+ // handle to it that is returned.
+ vertexProgram = CgGL.cgCreateProgramFromFile(context, CgGL.CG_SOURCE, "demo_vert.cg",
+ vertexProfile, null, null);
+ if (!CgGL.cgIsProgramCompiled(vertexProgram))
+ CgGL.cgCompileProgram(vertexProgram);
+
+ // Enable the appropriate vertex profile and load the vertex program.
+ CgGL.cgGLEnableProfile(vertexProfile);
+ CgGL.cgGLLoadProgram(vertexProgram);
+
+ // And similarly set things up for the fragment program.
+ fragmentProgram = CgGL.cgCreateProgramFromFile(context, CgGL.CG_SOURCE, "demo_frag.cg",
+ fragmentProfile, null, null);
+ if (!CgGL.cgIsProgramCompiled(fragmentProgram)) {
+ CgGL.cgCompileProgram(fragmentProgram);
+ }
+
+ CgGL.cgGLEnableProfile(fragmentProfile);
+ CgGL.cgGLLoadProgram(fragmentProgram);
+ }
+
+ void LoadTextures(GL gl)
+ {
+ // There is only one texture needed here--we'll set up a basic
+ // checkerboard--which is used to modulate the diffuse channel in the
+ // fragment shader.
+ int[] handle = new int[1];
+ gl.glGenTextures(1, handle);
+
+ // Basic OpenGL texture state setup
+ gl.glBindTexture(GL.GL_TEXTURE_2D, handle[0]);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_GENERATE_MIPMAP_SGIS, GL.GL_TRUE);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
+
+ // Fill in the texture map.
+ final int RES = 512;
+ float[] data = new float[RES*RES*4];
+ int dp = 0;
+ for (int i = 0; i < RES; ++i) {
+ for (int j = 0; j < RES; ++j) {
+ if ((i/32+j/32) % 2 != 0) {
+ data[dp++] = .7f;
+ data[dp++] = .7f;
+ data[dp++] = .7f;
+ }
+ else {
+ data[dp++] = .1f;
+ data[dp++] = .1f;
+ data[dp++] = .1f;
+ }
+ data[dp++] = 1.0f;
+ }
+ }
+
+ gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, RES, RES, 0, GL.GL_RGBA, GL.GL_FLOAT, data);
+
+ // Tell Cg which texture handle should be associated with the sampler2D
+ // parameter to the fragment shader.
+ CgGL.cgGLSetTextureParameter(CgGL.cgGetNamedParameter(fragmentProgram, "diffuseMap"),
+ handle[0]);
+ }
+
+ private int VERTEX(int u, int v, int nu) { return (u + v * nu); }
+
+ // Geometry creation and drawing function; we'll just draw a sphere.
+
+ private static FloatBuffer P, N, uv;
+ private static IntBuffer indices;
+ void DrawGeometry(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.
+ int nu = 30, nv = 30;
+ int nTris = 2*(nu-1)*(nv-1), nVerts = nu*nv;
+ if (P == null) {
+ int u, v;
+
+ P = BufferUtils.newFloatBuffer(3*nVerts);
+ N = BufferUtils.newFloatBuffer(3*nVerts);
+ uv = BufferUtils.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) {
+ float fv = (float)v / (float)(nv-1);
+ for (u = 0; u < nu; ++u) {
+ 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 = BufferUtils.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);
+ }
+
+ void ParametricEval(float u, float v, int offsetP, FloatBuffer p, int offsetN, FloatBuffer N)
+ {
+ float theta = (float)Math.PI * u, phi = (float)(2.0 * Math.PI * v);
+ P.put(offsetP + 0, (float)(Math.sin(theta) * Math.sin(phi)));
+ P.put(offsetP + 1, (float)(Math.sin(theta) * Math.cos(phi)));
+ P.put(offsetP + 2, (float)(Math.cos(theta)));
+
+ N.put(offsetN + 0, P.get(offsetP + 0));
+ N.put(offsetN + 1, P.get(offsetP + 1));
+ N.put(offsetN + 2, P.get(offsetP + 2));
+ }
+
+ public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged)
+ {
+ // nothing
+ }
+
+ public void reshape(GLDrawable drawable, int x, int y, int width, int height)
+ {
+ // do nothing
+ }
+
+}