Jogl

Passthrough CG Vertex, Fragment and Geometry shader

Works with:
FF3
Chrome
IE6
IE7
Opera
Safari

Description

This demonstrates using CG shaders with Opengl in an applet. As G80 shader profiles are used, a modern graphics card (geforce 8 series or greater) is required. Also, as CG shaders are used, the CG dynamic link libraries are needed, which can be found here.

Demo

CgFx (Shader Code)

  1. /**
  2. * Simple passthrough shader file
  3. * Includes vertex, fragment and geometry shaders
  4. * @author Andrew Lowndes
  5. * @date 21/10/08
  6. */
  7.  
  8. float4x4 modelviewproj : ModelViewProjection;
  9.  
  10. //structures
  11. struct FragmentOutput {
  12.     float4 color : COLOR;
  13. };
  14.  
  15. struct VertexOutput {
  16.     float4 position : POSITION;
  17.     float4 color : COLOR;
  18. };
  19.  
  20. //functions
  21. FragmentOutput FragmentMain(float4 color: COLOR) {
  22.     FragmentOutput OUT;
  23.     OUT.color = color;
  24.     return OUT;
  25. }
  26.  
  27. VertexOutput VertexMain(float4 position: POSITION,
  28.                         float4 color: COLOR,
  29.                         uniform float4x4 modelviewproj) {
  30.     VertexOutput OUT;
  31.    
  32.     OUT.position = mul(modelviewproj,position);
  33.     OUT.color = color;
  34.    
  35.     return OUT;
  36. }
  37.  
  38. TRIANGLE void GeometryMain(AttribArray<float4> position : POSITION,
  39.                             AttribArray<float4> colour : COLOR) {
  40.     for (int i=0; i<position.length;i++) {
  41.         emitVertex(position[i], colour[i]);
  42.     }
  43. }
  44.  
  45. //techniques
  46. technique Passthrough {
  47.     pass {
  48.         VertexProgram = compile gp4vp VertexMain(modelviewproj);
  49.         FragmentProgram = compile gp4fp FragmentMain();
  50.         GeometryProgram = compile gp4gp GeometryMain();
  51.        
  52.         CullFaceEnable = false;
  53.         CullFace = Back;
  54.        
  55.         StencilTestEnable = false;
  56.        
  57.         DepthTestEnable = true;
  58.         DepthFunc = LEqual;
  59.         DepthMask = true;
  60.        
  61.         BlendEnable = false;
  62.         ColorMask = { 1, 1, 1, 1 };
  63.     }
  64. }
  65.  

Java (Main Program Code)

  1. import java.io.*;
  2. import java.nio.*;
  3.  
  4. import java.awt.*;
  5. import java.awt.event.*;
  6. import javax.swing.*;
  7.  
  8. import javax.media.opengl.*;
  9. import javax.media.opengl.glu.*;
  10.  
  11. import com.sun.opengl.util.*;
  12. import com.sun.opengl.cg.*;
  13.  
  14. /*
  15. * Opengl window for testing opengl scripts using standard opengl objects
  16. * Uses Jogl JSR-231 standard/ CG
  17. * @author Andrew Lowndes
  18. */
  19. public class CGTester extends GLCanvas implements GLEventListener {
  20.     //private variables
  21.     private CGcontext cgContext;
  22.    
  23.     private CGeffect cgEffect;
  24.     private CGtechnique cgTechnique;
  25.    
  26.     private CGparameter cgVertexParam_modelviewproj;
  27.    
  28.     private GL gl;
  29.     private GLU glu = new GLU();
  30.  
  31.     private float rotate = 0.0f;
  32.     private javax.swing.Timer animTimer;
  33.    
  34.     /**
  35.     * Constructor
  36.     */
  37.     public CGTester() {
  38.         super(new GLCapabilities());
  39.         addGLEventListener(this);
  40.     }
  41.    
  42.     /**
  43.     * Main method
  44.     */
  45.     public static void main(String[] args) {
  46.         //setup the look and feel
  47.         try {
  48.             UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
  49.         } catch(Exception e) {
  50.         }
  51.    
  52.         //make the stand alone window
  53.         JFrame ourWindow = new JFrame();
  54.        
  55.         //setup the window
  56.         ourWindow.setSize(640,480);
  57.         ourWindow.setTitle("CG Tester");
  58.         ourWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  59.         ourWindow.setFocusable(true);
  60.         ourWindow.setLocation(100,100);
  61.         ourWindow.setBackground(Color.BLACK);
  62.        
  63.         //setup the opengl panel
  64.         final CGTester glCanvas = new CGTester();
  65.         glCanvas.setFocusable(true);
  66.        
  67.         //construct the window
  68.         ourWindow.getContentPane().setBackground(Color.BLACK);
  69.         ourWindow.getContentPane().setLayout(new BorderLayout());
  70.         ourWindow.getContentPane().add(glCanvas, BorderLayout.CENTER);
  71.        
  72.         //constuct the timers
  73.         final FPSAnimator anim = new FPSAnimator(glCanvas,60);
  74.         ourWindow.addWindowListener(new WindowAdapter() {
  75.             public void windowClosing(WindowEvent e) {
  76.               new Thread(new Runnable() {
  77.                   public void run() {
  78.                     anim.stop();
  79.                     glCanvas.deInit();
  80.                     System.exit(0);
  81.                   }
  82.                 }).start();
  83.             }
  84.         });
  85.        
  86.         //display our window now
  87.         ourWindow.setVisible(true);
  88.        
  89.         anim.start();
  90.     }
  91.    
  92.     /**
  93.     * Unbind and repare to kill program
  94.     */
  95.     public void deInit() {
  96.         CgGL.cgDestroyEffect(cgEffect);
  97.         CgGL.cgDestroyContext(cgContext);
  98.     }
  99.    
  100.     /**
  101.     * Called for OpenGl startup
  102.     * @param our opengl control
  103.     */
  104.     public void init(GLAutoDrawable glControl) {
  105.         //Setup OpenGL
  106.         gl = glControl.getGL();
  107.        
  108.         gl.glShadeModel(gl.GL_SMOOTH); //enable smooth shading
  109.        
  110.         gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //clear to black
  111.         gl.glClearDepth(1.0f); //clear the depth buffer too
  112.        
  113.         gl.glEnable(gl.GL_DEPTH_TEST);
  114.         gl.glDepthFunc(gl.GL_LEQUAL);
  115.         gl.glHint(gl.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_NICEST); //make our perspective look nice
  116.        
  117.         //Setup CG
  118.         cgContext = CgGL.cgCreateContext();
  119.         ErrorCG("Creating cg context");
  120.  
  121.         CgGL.cgGLRegisterStates(cgContext);
  122.         ErrorCG("Registering the standard cgFX states");
  123.    
  124.         //load the cgx file
  125.         String cgfxContents = new String();
  126.         try {
  127.             InputStream in = CGTester.class.getResource("passthrough_shader.cgfx").openStream();
  128.             BufferedReader bf = new BufferedReader(new InputStreamReader(in));
  129.             String line;
  130.             while((line = bf.readLine()) != null){
  131.                 cgfxContents += line + "\n";
  132.             }
  133.         } catch (Exception e) {
  134.             System.out.println("Could not load cgfx file!");
  135.             System.exit(0);
  136.         }
  137.    
  138.         cgEffect = CgGL.cgCreateEffect(cgContext, cgfxContents, null);
  139.         ErrorCG("Loading effects file");
  140.    
  141.         cgTechnique = CgGL.cgGetFirstTechnique(cgEffect);
  142.         ErrorCG("Getting first technique in effect");
  143.        
  144.         CgGL.cgValidateTechnique(cgTechnique);
  145.         ErrorCG("Loading the technique");
  146.    
  147.         cgVertexParam_modelviewproj = CgGL.cgGetNamedEffectParameter(cgEffect, "modelviewproj");
  148.         ErrorCG("Getting technique parameters");
  149.    
  150.         //once setup has initialised, setup timers
  151.         animTimer = new Timer(30, new ActionListener() {
  152.             public void actionPerformed(ActionEvent event) {
  153.                 rotate += 0.6f;
  154.             }
  155.         });
  156.         animTimer.start();
  157.     }
  158.    
  159.     /**
  160.     * Check to see whether CG has spung an error
  161.     * @param error output string
  162.     */
  163.     private void ErrorCG(String errorMessage) {
  164.         IntBuffer cgError = IntBuffer.allocate(2);
  165.         String errorString = CgGL.cgGetLastErrorString(cgError);
  166.        
  167.         if (cgError.get() != CgGL.CG_NO_ERROR) {
  168.             System.err.println("Stage: " + errorMessage);
  169.             System.err.println(errorString);
  170.            
  171.             if (cgError.get() == CgGL.CG_COMPILER_ERROR)
  172.                 System.out.println(CgGL.cgGetLastListing(cgContext));
  173.            
  174.             System.exit(0);
  175.         }
  176.     }
  177.    
  178.     /**
  179.     * Called every repaint
  180.     * @param our opengl control
  181.     */
  182.     public void display(GLAutoDrawable glControl) {
  183.         gl = glControl.getGL();
  184.        
  185.         //setup graphics
  186.         gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
  187.         gl.glLoadIdentity();
  188.  
  189.         gl.glTranslatef(0.0f,0.0f,-3.0f);
  190.         gl.glRotatef(rotate, 0.0f, 1.0f, 0.0f);
  191.  
  192.         //assign cg shader
  193.         CgGL.cgGLSetStateMatrixParameter(cgVertexParam_modelviewproj, CgGL.CG_GL_MODELVIEW_PROJECTION_MATRIX, CgGL.CG_GL_MATRIX_IDENTITY);
  194.        
  195.         CGpass pass = CgGL.cgGetFirstPass(cgTechnique);
  196.         while (pass!=null) {
  197.             CgGL.cgSetPassState(pass);
  198.            
  199.             gl.glBegin(GL.GL_TRIANGLES);
  200.                 gl.glColor3f(0.0f,1.0f,1.0f);
  201.                 gl.glVertex3f(0.75f,-0.75f,0.0f);
  202.  
  203.                 gl.glColor3f(1.0f,1.0f,0.0f);
  204.                 gl.glVertex3f(0.0f, 0.75f, 0.0f);
  205.            
  206.                 gl.glColor3f(1.0f,0.0f,1.0f);
  207.                 gl.glVertex3f(-0.75f,-0.75f,0.0f);
  208.             gl.glEnd();
  209.            
  210.             CgGL.cgResetPassState(pass);
  211.             pass = CgGL.cgGetNextPass(pass);
  212.         }
  213.     }
  214.    
  215.    
  216.     /**
  217.     * Called on start and resize
  218.     * @param our opengl control
  219.     * @param x position of opengl context
  220.     * @param y position of opengl context
  221.     * @param width of opengl context
  222.     * @param height of opengl context
  223.     */
  224.     public void reshape(GLAutoDrawable glControl, int x, int y, int width, int height) {
  225.         gl = glControl.getGL();
  226.        
  227.         if (height<=0) height=1; //make sure we dont divide by 0
  228.        
  229.         gl.glViewport(0,0, width, height); //set the viewport matrix parameters
  230.        
  231.         //change our projection matrix to relate to the new aspect ratio
  232.         gl.glMatrixMode(gl.GL_PROJECTION);
  233.         gl.glLoadIdentity();
  234.        
  235.         glu.gluPerspective(45.0f, (float)width/(float)height, 0.1f, 100.0f);
  236.        
  237.         gl.glMatrixMode(gl.GL_MODELVIEW);
  238.         gl.glLoadIdentity();
  239.        
  240.         display(glControl);
  241.     }
  242.    
  243.     /**
  244.     * Unused
  245.     */
  246.     public void displayChanged(GLAutoDrawable glControl, boolean a, boolean b) {
  247.     }
  248. }

Java (Applet Code)

  1. import java.applet.*;
  2. import java.awt.*;
  3.  
  4. import javax.media.opengl.*;
  5. import com.sun.opengl.util.*;
  6.  
  7. /**
  8. * Main Program Applet Class
  9. * Sets up an applet for us with opengl event class
  10. * @author Andrew Lowndes
  11. * @date 10/08/08
  12. */
  13. public class CGTesterApplet extends Applet {
  14.     private FPSAnimator programAnimControl;
  15.     CGTester graphicsWindow;
  16.    
  17.     /**
  18.     * On applet load, create our opengl context and add it to
  19.     * our applet
  20.     */
  21.     public void init() {
  22.         //setup the opengl container
  23.         graphicsWindow = new CGTester();
  24.         graphicsWindow.setFocusable(true);
  25.        
  26.         //put everything together
  27.         setLayout(new BorderLayout());
  28.         setBackground(Color.BLACK);
  29.         add(graphicsWindow);
  30.        
  31.         //setup the animator
  32.         programAnimControl = new FPSAnimator(graphicsWindow,60);
  33.     }
  34.    
  35.     /**
  36.     * Start the animator when the applet is started
  37.     */
  38.     public void start() {
  39.         programAnimControl.start();
  40.     }
  41.    
  42.     /**
  43.     * Stop the animator when the applet is stopped
  44.     */
  45.     public void stop() {
  46.         graphicsWindow.deInit();
  47.         programAnimControl.stop();
  48.     }
  49. }