Nvidia Sli support with LWJGL + OpenGL + Java?

Started by crash0veride007, September 01, 2005, 03:53:27

Previous topic - Next topic

crash0veride007

will do thanks
Hey when will orangytangs GLSL tut be returning to the WIKI? I know I came across it in the old wiki once.

Matzon

I can dig it out from an sql dump, unless he has a copy...

Orangy Tang

No local copy here I'm afraid. If you can stick what you can salvage up then I'll rework and expand it.

crash0veride007

Ok I am trying to use rendermonkey and Shader Designer to play however these two use GLSL or the high-level shading language.
However it's seems that the org.lwjgl.test.opengl.shaders package examples use the ASM like ARB shader language. So how do I go about using a shader generated by rendermonkey instead? Where am I going wrong?

spasi

org.lwjgl.test.opengl.shaders contains examples of both low-level ARB shaders and high-level GLSL shaders. Have a look at Shaders.java, ShadersVSH and ShadersFSH.java to get a taste of the GLSL API. First step is the method getShaderText in Shaders.java, which is used to read the contents of a shader text file in a ByteBuffer. It's simple after that.

crash0veride007

Thanks, DUH! it was in front of my face the whole time. Ok next question what is the function of the UniformLocation? I noticed that any shader program generated by rendermonkey or shader designer does not have this?

int UniformLocation;

UniformLocation = getUniformLocation(PROGRAM_ID, "UNIFORMS");

public int getUniformLocation(int ID, String name) {
      fileBuffer.clear();
      int length = name.length();
      char[] charArray = new char[length];
      name.getChars(0, length, charArray, 0);
      for ( int i = 0; i < length; i++ )
      fileBuffer.put((byte)charArray);
      fileBuffer.put((byte)0); // Must be null-terminated.
      fileBuffer.flip();
      int location = ARBShaderObjects.glGetUniformLocationARB(ID, fileBuffer);
      if ( location == -1 )
      throw new IllegalArgumentException("The uniform \"" + name + "\" does not exist in the Shader Program.");
      return location;
   }

it seems to have some significagance with sending a value to the Shader?

If I outputed a simple shader from rendermonkey for instance what calls would i use to apply that shader to a cube,plane, or sphere? (see next thread post)

crash0veride007

So basicly apply this fragment/vertex shader from Shader Designer:

FRAG:
varying float LightIntensity;
varying vec3 MCPosition;

//Create uniform variables so dots can be spaced and scaled by user
uniform vec3 Spacing;
uniform float DotSize;

//Create colors as uniform variables so they can be easily changed
uniform vec3 ModelColor, PolkaDotColor;

void main(void)
{
  float insidesphere, sphereradius, scaledpointlength;
  vec3 scaledpoint, finalcolor;

  // Scale the coordinate system
  // The following line of code is not yet implemented in current drivers:
  // mcpos = mod(Spacing, MCposition);
  // We will use a workaround found below for now
  scaledpoint       = MCPosition - (Spacing * floor(MCPosition/Spacing));

  // Bring the scaledpoint vector into the center of the scaled coordinate system
  scaledpoint       = scaledpoint - Spacing/2.0;

  // Find the length of the scaledpoint vector and compare it to the dotsize
  scaledpointlength = length(scaledpoint);
  insidesphere      = step(scaledpointlength,DotSize);
 
  // Determine final output color before lighting
  finalcolor        = vec3(mix(ModelColor, PolkaDotColor, insidesphere));

  // Output final color and factor in lighting
  gl_FragColor      = clamp((vec4( finalcolor, 1.0 ) * LightIntensity), vec4(0.0), vec4(1.0));
}

VERTEX
uniform float SpecularContribution;
uniform vec3 LightPosition;

varying vec3 MCPosition;
varying float LightIntensity;

void main(void)
{
   float diffusecontribution  = 1.0 - SpecularContribution;
   
   // compute the vertex position in eye coordinates
   vec3  ecPosition           = vec3(gl_ModelViewMatrix * gl_Vertex);
   
   // compute the transformed normal
   vec3  tnorm                = normalize(gl_NormalMatrix * gl_Normal);
   
   // compute a vector from the model to the light position
   vec3  lightVec             = normalize(LightPosition - ecPosition);
   
   // compute the reflection vector
   vec3  reflectVec           = reflect(-lightVec, tnorm);
   
   // compute a unit vector in direction of viewing position
   vec3  viewVec              = normalize(-ecPosition);
   
   // calculate amount of diffuse light based on normal and light angle
   float diffuse              = max(dot(lightVec, tnorm), 0.0);
   float spec                 = 0.0;
   
   // if there is diffuse lighting, calculate specular
   if(diffuse > 0.0)
      {
         spec = max(dot(reflectVec, viewVec), 0.0);
         spec = pow(spec, 16.0);
      }
   
   // add up the light sources, since this is a varying (global) it will pass to frag shader    
   LightIntensity  = diffusecontribution * diffuse * 1.5 +
                         SpecularContribution * spec;
   
   // the varying variable MCPosition will be used by the fragment shader to determine where
   //    in model space the current pixel is                      
   MCPosition      = vec3 (gl_Vertex);
   
   // send vertex information
   gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;
}

to this code:

package JavaGL;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.ARBFragmentShader;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.ARBVertexShader;
import org.lwjgl.opengl.GLContext;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.glu.GLU;
import org.lwjgl.opengl.Util;

public class GLSLShaderPolys {
   public static boolean done = false;
   public static String windowTitle = "Crash0veride007 JavaGL";
   public static DisplayMode displayMode;
   public static float angle =0.0f;
   public static IntBuffer programBuffer = BufferUtils.createIntBuffer(1);
   public static ByteBuffer fileBuffer = BufferUtils.createByteBuffer(1024 * 10);
   public String vertexshaderfile;
   public String fragmentshaderfile;
   public String vertexshaderfileread = "JavaGL/shaders/polkadot3d.vert";
   public String fragmentshaderfileread = "JavaGL/shaders/polkadot3d.frag";
   public ByteBuffer vertexshadersource;
   public ByteBuffer fragmentshadersource;
   public int VERTEX_ID;
   public int FRAGMENT_ID;
   public int PROGRAM_ID;
   //public int UniformLocation;
   
   public static void main(String[] args) {
       GLSLShaderPolys runit = new GLSLShaderPolys();
       runit.run();
   }
   
   public void run() {
       long startTime = System.currentTimeMillis() + 5000;
       long fps = 0;
       try {
           init();
           while (!done) {
               MainLoop();
               Display.update();
               if (startTime > System.currentTimeMillis()) {
                   fps++;
               } else {
                   long timeUsed = 5000 + (startTime - System.currentTimeMillis());
                   startTime = System.currentTimeMillis() + 5000;
                   String outdata = fps + " frames in " + (float) (timeUsed / 1000f) + " seconds = "+ (fps / (timeUsed / 1000f))+" FPS";
                   System.out.println( outdata );
                   Display.setTitle(windowTitle + " " + outdata);
                   fps = 0;
               }
           }
           cleanup();
           System.exit(0);
       } catch (Exception e) {
           e.printStackTrace();
           System.exit(0);
       }
   }
   
   public void MainLoop() {
       rendershit();
       if(Display.isCloseRequested()) {
           done = true;
       }
   }
   
   public void createWindow() throws Exception {
       DisplayMode d[] = Display.getAvailableDisplayModes();
       for (int i = 0; i < d.length; i++) {
           if (d.getWidth() == 640
                   && d.getHeight() == 480
                   && d.getBitsPerPixel() == 32) {
               displayMode = d;
               break;
           }
       }
       Display.setDisplayMode(displayMode);
       Display.setTitle(windowTitle);
       Display.create();
   }
   
   public void init() throws Exception {
       createWindow();
       initShader();
       initGL();
       
   }
   
   public void initShader() {
       if ( !GLContext.getCapabilities().GL_ARB_vertex_shader && !GLContext.getCapabilities().GL_ARB_fragment_shader) {
           System.out.println("The ARB_vertex_shader extension is not supported.");
           System.out.println("The ARB_fragment_shader extension is not supported.");
           cleanup();
           System.exit(-1);
       } else if ( GLContext.getCapabilities().GL_ARB_vertex_shader && GLContext.getCapabilities().GL_ARB_fragment_shader ) {
           System.out.println("The ARB_vertex_shader extension is supported continuing!");
           System.out.println("The ARB_fragment_shader extension is supported continuing!");
       }
       
       vertexshaderfile = vertexshaderfileread;
       vertexshadersource = getShaderText(vertexshaderfileread);
       VERTEX_ID = ARBShaderObjects.glCreateShaderObjectARB(ARBVertexShader.GL_VERTEX_SHADER_ARB);
        System.out.println("Vertex Shader ID:"+VERTEX_ID);
       ARBShaderObjects.glShaderSourceARB(VERTEX_ID, vertexshadersource);
       ARBShaderObjects.glCompileShaderARB(VERTEX_ID);
       printShaderObjectInfoLog(vertexshaderfile, VERTEX_ID);
       ARBShaderObjects.glGetObjectParameterARB(VERTEX_ID, ARBShaderObjects.GL_OBJECT_COMPILE_STATUS_ARB, programBuffer);
       if ( programBuffer.get(0) == GL11.GL_FALSE ) {
           System.out.println("A compilation error occured in the Vertex shader:"+vertexshaderfileread);
           cleanup();
           System.exit(-1);
       }
       
       fragmentshaderfile = fragmentshaderfileread;
       fragmentshadersource = getShaderText(fragmentshaderfileread);
       FRAGMENT_ID = ARBShaderObjects.glCreateShaderObjectARB(ARBFragmentShader.GL_FRAGMENT_SHADER_ARB);
       System.out.println("Fragment Shader ID:"+FRAGMENT_ID);
       ARBShaderObjects.glShaderSourceARB(FRAGMENT_ID, fragmentshadersource);
       ARBShaderObjects.glCompileShaderARB(FRAGMENT_ID);
       printShaderObjectInfoLog(fragmentshaderfile, FRAGMENT_ID);
       ARBShaderObjects.glGetObjectParameterARB(FRAGMENT_ID, ARBShaderObjects.GL_OBJECT_COMPILE_STATUS_ARB, programBuffer);
       if ( programBuffer.get(0) == GL11.GL_FALSE ) {
           System.out.println("A compilation error occured in the Fragment shader:"+fragmentshaderfileread);
           cleanup();
           System.exit(-1);
       }
       
       PROGRAM_ID = ARBShaderObjects.glCreateProgramObjectARB();
       System.out.println("Shader Program ID:"+PROGRAM_ID);
       ARBShaderObjects.glAttachObjectARB(PROGRAM_ID, VERTEX_ID);
       ARBShaderObjects.glAttachObjectARB(PROGRAM_ID, FRAGMENT_ID);
       ARBShaderObjects.glLinkProgramARB(PROGRAM_ID);
       printShaderProgramInfoLog(PROGRAM_ID);
       ARBShaderObjects.glGetObjectParameterARB(PROGRAM_ID, ARBShaderObjects.GL_OBJECT_LINK_STATUS_ARB, programBuffer);
       if ( programBuffer.get(0) == GL11.GL_FALSE ) {
           System.out.println("A Linking error occured in the shader program:"+PROGRAM_ID);
           cleanup();
           System.exit(-1);
       }
       //UniformLocation = getUniformLocation(PROGRAM_ID, "UNIFORMS");
   }
   
   public ByteBuffer getShaderText(String path) {
       ByteBuffer shader = null;
       try {
           ClassLoader loader = GLSLShaderPolys.class.getClassLoader();
           InputStream inputStream = loader.getResourceAsStream(path);
           if ( inputStream == null ){
               System.out.println("A shader source file could not be found:"+path);
               cleanup();
               System.exit(-1);
           }
           System.out.println("Loading shader source file:"+path);
           BufferedInputStream stream = new BufferedInputStream(inputStream);
           byte character;
           while ( (character = (byte)stream.read()) != -1 )
               fileBuffer.put(character);
           stream.close();
           fileBuffer.flip();
           shader = BufferUtils.createByteBuffer(fileBuffer.limit());
           shader.put(fileBuffer);
           shader.clear();
           fileBuffer.clear();
       } catch (IOException e) {
           System.out.println("A shader source file could not be found:"+path);
           cleanup();
           System.exit(-1);
       }
       return shader;
   }
   
   public void printShaderObjectInfoLog(String file, int ID) {
       ARBShaderObjects.glGetObjectParameterARB(ID, ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB, programBuffer);
       int logLength = programBuffer.get(0);
       if ( logLength <= 1 )
           return;
       ByteBuffer log = BufferUtils.createByteBuffer(logLength);
       ARBShaderObjects.glGetInfoLogARB(ID, null, log);
       char[] charArray = new char[logLength];
       for ( int i = 0; i < logLength; i++ )
           charArray = (char)log.get();
       System.out.println("\nInfo Log of Shader Object: " + file);
       System.out.println("--------------------------");
       System.out.println(new String(charArray, 0, logLength));
   }
   
   public void printShaderProgramInfoLog(int ID) {
       ARBShaderObjects.glGetObjectParameterARB(ID, ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB, programBuffer);
       int logLength = programBuffer.get(0);
       if ( logLength <= 1 )
           return;
       ByteBuffer log = BufferUtils.createByteBuffer(logLength);
       ARBShaderObjects.glGetInfoLogARB(ID, null, log);
       char[] charArray = new char[logLength];
       for ( int i = 0; i < logLength; i++ )
           charArray = (char)log.get();
       System.out.println("\nShader Program Info Log: ");
       System.out.println("--------------------------");
       System.out.println(new String(charArray, 0, logLength));
   }
   
   /*public int getUniformLocation(int ID, String name) {
      fileBuffer.clear();
      int length = name.length();
      char[] charArray = new char[length];
      name.getChars(0, length, charArray, 0);
      for ( int i = 0; i < length; i++ )
      fileBuffer.put((byte)charArray);
      fileBuffer.put((byte)0); // Must be null-terminated.
      fileBuffer.flip();
      int location = ARBShaderObjects.glGetUniformLocationARB(ID, fileBuffer);
      if ( location == -1 )
      throw new IllegalArgumentException("The uniform \"" + name + "\" does not exist in the Shader Program.");
      return location;
   }*/
   
   public void initGL() {
       //GL11.glEnable(GL11.GL_TEXTURE_2D);
       //GL11.glEnable(GL11.GL_CULL_FACE);
       //GL11.glCullFace(GL11.GL_BACK);
       //GL11.glFrontFace(GL11.GL_CCW);
       GL11.glShadeModel(GL11.GL_SMOOTH);
       GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
       GL11.glClearDepth(1.0);
       GL11.glEnable(GL11.GL_DEPTH_TEST);
       GL11.glDepthFunc(GL11.GL_LEQUAL);
       //GL11.glAlphaFunc(GL11.GL_NOTEQUAL, 0.0f);
       //GL11.glEnable(GL11.GL_BLEND);
       //GL11.glEnable(GL11.GL_ALPHA_TEST);
       //GL11.glPolygonMode(GL11.GL_FRONT, GL11.GL_FILL);
       //GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
       GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
       GL11.glMatrixMode(GL11.GL_PROJECTION);
       GL11.glLoadIdentity();
       GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
       GLU.gluPerspective(80.0f,(float) displayMode.getWidth() / (float) displayMode.getHeight(),0.1f,1000.0f);
       GL11.glMatrixMode(GL11.GL_MODELVIEW);
       GL11.glLoadIdentity();
       GLU.gluLookAt(0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
   }
   
   public void rendershit() {
       ARBShaderObjects.glUseProgramObjectARB(PROGRAM_ID);
       GL11.glPushMatrix();
       GL11.glColor3f(1.0f,1.0f,1.0f);
       GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
       //ARBShaderObjects.glUniform4fARB(UniformLocation,4.0f, 16.0f,0.5f,0.5f);
       GL11.glBegin(GL11.GL_QUADS);
       GL11.glVertex3f(-1.0f, 1.0f, 1.0f);
       GL11.glVertex3f(1.0f, 1.0f, 1.0f);
       GL11.glVertex3f(1.0f, -1.0f, 1.0f);
       GL11.glVertex3f(-1.0f, -1.0f, 1.0f);
       GL11.glEnd();
       GL11.glPopMatrix();
       ARBShaderObjects.glUseProgramObjectARB(0);
       //GL11.glFlush();
   }
   
   public void cleanup() {
       ARBShaderObjects.glDetachObjectARB(PROGRAM_ID, VERTEX_ID);
       ARBShaderObjects.glDetachObjectARB(PROGRAM_ID, FRAGMENT_ID);
       ARBShaderObjects.glDeleteObjectARB(VERTEX_ID);
       ARBShaderObjects.glDeleteObjectARB(FRAGMENT_ID);
       ARBShaderObjects.glDeleteObjectARB(PROGRAM_ID);
       Display.destroy();
   }
}

spasi

Quote from: "crash0veride007"what is the function of the UniformLocation? I noticed that any shader program generated by rendermonkey or shader designer does not have this?

it seems to have some significagance with sending a value to the Shader?

Yes, uniforms are constant values inside a GLSL shader program, that can be set programmatically. Uniform locations (integers) are used instead of their names (strings) in order to avoid the obvious overhead. So, instead of doing glUniform4f("LIGHT_POS", x, y, z, w) you're doing this glUniform4f(lightPos, x, y, z, w), where lightPos is the location of the uniform LIGHT_POS, returned by glGetUniformLocation. The getUniformLocation method is just a helper function that wraps the uniform String in a ByteBuffer and calls glGetUniformLocation.

Quote from: "crash0veride007"If I outputed a simple shader from rendermonkey for instance what calls would i use to apply that shader to a cube,plane, or sphere?

After successfully compiling the shaders and linking the program, you just enable the shader program with glUseProgramObject. You'll find everything in the examples. :wink:

crash0veride007

in noticed you never do a glEnable disable of the GLSL shader?

spasi

Quote from: "crash0veride007"I noticed that any shader program generated by rendermonkey or shader designer does not have this?

BTW, uniform values in RenderMonkey and Shader Designer are set through their UI.

Quote from: "crash0veride007"So basicly apply this fragment/vertex shader from Shader Designer:

You'll also need to set the values of these uniforms of course:

//Create uniform variables so dots can be spaced and scaled by user 
uniform vec3 Spacing; 
uniform float DotSize; 

//Create colors as uniform variables so they can be easily changed 
uniform vec3 ModelColor, PolkaDotColor;

Matzon

Quote from: "Orangy Tang"No local copy here I'm afraid. If you can stick what you can salvage up then I'll rework and expand it.
and so it was done...
http://lwjgl.org/wiki/doku.php/lwjgl/tutorials/opengl/basicshaders

what a crock to do!

spasi

Quote from: "crash0veride007"in noticed you never do a glEnable disable of the GLSL shader?

Yeah, it's not needed, glUseProgramObject does it automatically. Just bind a valid program ID and GLSL will be enabled. With glUseProgramObject(0) you go back to fixed functionality.