diff options
Diffstat (limited to 'src/demos/cg/runtime_ogl_vertex_fragment')
3 files changed, 519 insertions, 0 deletions
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 + } + +} |