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)
- /**
- * Simple passthrough shader file
- * Includes vertex, fragment and geometry shaders
- * @author Andrew Lowndes
- * @date 21/10/08
- */
-
- float4x4 modelviewproj : ModelViewProjection;
-
- //structures
- struct FragmentOutput {
- float4 color : COLOR;
- };
-
- struct VertexOutput {
- float4 position : POSITION;
- float4 color : COLOR;
- };
-
- //functions
- FragmentOutput FragmentMain(float4 color: COLOR) {
- FragmentOutput OUT;
- OUT.color = color;
- return OUT;
- }
-
- VertexOutput VertexMain(float4 position: POSITION,
- float4 color: COLOR,
- uniform float4x4 modelviewproj) {
- VertexOutput OUT;
-
- OUT.position = mul(modelviewproj,position);
- OUT.color = color;
-
- return OUT;
- }
-
- TRIANGLE void GeometryMain(AttribArray<float4> position : POSITION,
- AttribArray<float4> colour : COLOR) {
- for (int i=0; i<position.length;i++) {
- emitVertex(position[i], colour[i]);
- }
- }
-
- //techniques
- technique Passthrough {
- pass {
- VertexProgram = compile gp4vp VertexMain(modelviewproj);
- FragmentProgram = compile gp4fp FragmentMain();
- GeometryProgram = compile gp4gp GeometryMain();
-
- CullFaceEnable = false;
- CullFace = Back;
-
- StencilTestEnable = false;
-
- DepthTestEnable = true;
- DepthFunc = LEqual;
- DepthMask = true;
-
- BlendEnable = false;
- ColorMask = { 1, 1, 1, 1 };
- }
- }
-
Java (Main Program Code)
- import java.io.*;
- import java.nio.*;
-
- import java.awt.*;
- import java.awt.event.*;
- import javax.swing.*;
-
- import javax.media.opengl.*;
- import javax.media.opengl.glu.*;
-
- import com.sun.opengl.util.*;
- import com.sun.opengl.cg.*;
-
- /*
- * Opengl window for testing opengl scripts using standard opengl objects
- * Uses Jogl JSR-231 standard/ CG
- * @author Andrew Lowndes
- */
- public class CGTester extends GLCanvas implements GLEventListener {
- //private variables
- private CGcontext cgContext;
-
- private CGeffect cgEffect;
- private CGtechnique cgTechnique;
-
- private CGparameter cgVertexParam_modelviewproj;
-
- private GL gl;
- private GLU glu = new GLU();
-
- private float rotate = 0.0f;
- private javax.swing.Timer animTimer;
-
- /**
- * Constructor
- */
- public CGTester() {
- super(new GLCapabilities());
- addGLEventListener(this);
- }
-
- /**
- * Main method
- */
- public static void main(String[] args) {
- //setup the look and feel
- try {
- UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
- } catch(Exception e) {
- }
-
- //make the stand alone window
- JFrame ourWindow = new JFrame();
-
- //setup the window
- ourWindow.setSize(640,480);
- ourWindow.setTitle("CG Tester");
- ourWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- ourWindow.setFocusable(true);
- ourWindow.setLocation(100,100);
- ourWindow.setBackground(Color.BLACK);
-
- //setup the opengl panel
- final CGTester glCanvas = new CGTester();
- glCanvas.setFocusable(true);
-
- //construct the window
- ourWindow.getContentPane().setBackground(Color.BLACK);
- ourWindow.getContentPane().setLayout(new BorderLayout());
- ourWindow.getContentPane().add(glCanvas, BorderLayout.CENTER);
-
- //constuct the timers
- final FPSAnimator anim = new FPSAnimator(glCanvas,60);
- ourWindow.addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- new Thread(new Runnable() {
- public void run() {
- anim.stop();
- glCanvas.deInit();
- System.exit(0);
- }
- }).start();
- }
- });
-
- //display our window now
- ourWindow.setVisible(true);
-
- anim.start();
- }
-
- /**
- * Unbind and repare to kill program
- */
- public void deInit() {
- CgGL.cgDestroyEffect(cgEffect);
- CgGL.cgDestroyContext(cgContext);
- }
-
- /**
- * Called for OpenGl startup
- * @param our opengl control
- */
- public void init(GLAutoDrawable glControl) {
- //Setup OpenGL
- gl = glControl.getGL();
-
- gl.glShadeModel(gl.GL_SMOOTH); //enable smooth shading
-
- gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //clear to black
- gl.glClearDepth(1.0f); //clear the depth buffer too
-
- gl.glEnable(gl.GL_DEPTH_TEST);
- gl.glDepthFunc(gl.GL_LEQUAL);
- gl.glHint(gl.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_NICEST); //make our perspective look nice
-
- //Setup CG
- cgContext = CgGL.cgCreateContext();
- ErrorCG("Creating cg context");
-
- CgGL.cgGLRegisterStates(cgContext);
- ErrorCG("Registering the standard cgFX states");
-
- //load the cgx file
- String cgfxContents = new String();
- try {
- InputStream in = CGTester.class.getResource("passthrough_shader.cgfx").openStream();
- BufferedReader bf = new BufferedReader(new InputStreamReader(in));
- String line;
- while((line = bf.readLine()) != null){
- cgfxContents += line + "\n";
- }
- } catch (Exception e) {
- System.out.println("Could not load cgfx file!");
- System.exit(0);
- }
-
- cgEffect = CgGL.cgCreateEffect(cgContext, cgfxContents, null);
- ErrorCG("Loading effects file");
-
- cgTechnique = CgGL.cgGetFirstTechnique(cgEffect);
- ErrorCG("Getting first technique in effect");
-
- CgGL.cgValidateTechnique(cgTechnique);
- ErrorCG("Loading the technique");
-
- cgVertexParam_modelviewproj = CgGL.cgGetNamedEffectParameter(cgEffect, "modelviewproj");
- ErrorCG("Getting technique parameters");
-
- //once setup has initialised, setup timers
- animTimer = new Timer(30, new ActionListener() {
- public void actionPerformed(ActionEvent event) {
- rotate += 0.6f;
- }
- });
- animTimer.start();
- }
-
- /**
- * Check to see whether CG has spung an error
- * @param error output string
- */
- private void ErrorCG(String errorMessage) {
- IntBuffer cgError = IntBuffer.allocate(2);
- String errorString = CgGL.cgGetLastErrorString(cgError);
-
- if (cgError.get() != CgGL.CG_NO_ERROR) {
- System.err.println("Stage: " + errorMessage);
- System.err.println(errorString);
-
- if (cgError.get() == CgGL.CG_COMPILER_ERROR)
- System.out.println(CgGL.cgGetLastListing(cgContext));
-
- System.exit(0);
- }
- }
-
- /**
- * Called every repaint
- * @param our opengl control
- */
- public void display(GLAutoDrawable glControl) {
- gl = glControl.getGL();
-
- //setup graphics
- gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
- gl.glLoadIdentity();
-
- gl.glTranslatef(0.0f,0.0f,-3.0f);
- gl.glRotatef(rotate, 0.0f, 1.0f, 0.0f);
-
- //assign cg shader
- CgGL.cgGLSetStateMatrixParameter(cgVertexParam_modelviewproj, CgGL.CG_GL_MODELVIEW_PROJECTION_MATRIX, CgGL.CG_GL_MATRIX_IDENTITY);
-
- CGpass pass = CgGL.cgGetFirstPass(cgTechnique);
- while (pass!=null) {
- CgGL.cgSetPassState(pass);
-
- gl.glBegin(GL.GL_TRIANGLES);
- gl.glColor3f(0.0f,1.0f,1.0f);
- gl.glVertex3f(0.75f,-0.75f,0.0f);
-
- gl.glColor3f(1.0f,1.0f,0.0f);
- gl.glVertex3f(0.0f, 0.75f, 0.0f);
-
- gl.glColor3f(1.0f,0.0f,1.0f);
- gl.glVertex3f(-0.75f,-0.75f,0.0f);
- gl.glEnd();
-
- CgGL.cgResetPassState(pass);
- pass = CgGL.cgGetNextPass(pass);
- }
- }
-
-
- /**
- * Called on start and resize
- * @param our opengl control
- * @param x position of opengl context
- * @param y position of opengl context
- * @param width of opengl context
- * @param height of opengl context
- */
- public void reshape(GLAutoDrawable glControl, int x, int y, int width, int height) {
- gl = glControl.getGL();
-
- if (height<=0) height=1; //make sure we dont divide by 0
-
- gl.glViewport(0,0, width, height); //set the viewport matrix parameters
-
- //change our projection matrix to relate to the new aspect ratio
- gl.glMatrixMode(gl.GL_PROJECTION);
- gl.glLoadIdentity();
-
- glu.gluPerspective(45.0f, (float)width/(float)height, 0.1f, 100.0f);
-
- gl.glMatrixMode(gl.GL_MODELVIEW);
- gl.glLoadIdentity();
-
- display(glControl);
- }
-
- /**
- * Unused
- */
- public void displayChanged(GLAutoDrawable glControl, boolean a, boolean b) {
- }
- }
Java (Applet Code)
- import java.applet.*;
- import java.awt.*;
-
- import javax.media.opengl.*;
- import com.sun.opengl.util.*;
-
- /**
- * Main Program Applet Class
- * Sets up an applet for us with opengl event class
- * @author Andrew Lowndes
- * @date 10/08/08
- */
- public class CGTesterApplet extends Applet {
- private FPSAnimator programAnimControl;
- CGTester graphicsWindow;
-
- /**
- * On applet load, create our opengl context and add it to
- * our applet
- */
- public void init() {
- //setup the opengl container
- graphicsWindow = new CGTester();
- graphicsWindow.setFocusable(true);
-
- //put everything together
- setLayout(new BorderLayout());
- setBackground(Color.BLACK);
- add(graphicsWindow);
-
- //setup the animator
- programAnimControl = new FPSAnimator(graphicsWindow,60);
- }
-
- /**
- * Start the animator when the applet is started
- */
- public void start() {
- programAnimControl.start();
- }
-
- /**
- * Stop the animator when the applet is stopped
- */
- public void stop() {
- graphicsWindow.deInit();
- programAnimControl.stop();
- }
- }