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: crash0veride007what 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: crash0veride007If 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: crash0veride007I 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: crash0veride007So 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 TangNo 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: crash0veride007in 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.