OpenGL Shader Problem

This demo is exercise #2 in the book “Computer Graphics Programming” by Gordon & Clevenger, Third Edition. It uses openGL source code and is supposed to create a single point, 30 pixels in size, and shade it a blue color. Unfortunately it does not do this, for reasons unknown to me. I can do the same thing in Processing using a shader with a lot less code, but would like to get this demo to run correctly. There is a very long error message of unknown significance which the Processing editor will not allow me to copy/paste so I’m also attaching a screen shot of the first few lines. The code does run and I see a window with a black background but no blue point. Any enlightenment would be appreciated.

import javax.swing.*;
import processing.opengl.PGraphicsOpenGL;
import com.jogamp.opengl.GL4;
import com.jogamp.opengl.*;
import com.jogamp.opengl.awt.GLCanvas;

GLAutoDrawable drawable;
GLCanvas myCanvas;

final int GL_COLOR_BUFFER_BIT = 0x00004000;
final int GL_POINTS = 0x0000;
final int GL_VERTEX_SHADER = 35633;
final int GL_FRAGMENT_SHADER = 35632;

String[] vshaderSource = new String[3];
String[] fshaderSource = new String[4];

class Wnd implements GLEventListener {

  int renderingProgram;
  int vao[] = new int[1];

  Wnd() {
    JFrame frame = new JFrame("OpenGL Demo");
    frame.setBounds(200, 200, 600, 400);
    myCanvas = new GLCanvas();
    myCanvas.addGLEventListener(this);
    frame.add(myCanvas);
    frame.setVisible(true);
  }

  void display(GLAutoDrawable drawable) {
    GL4 gl = (GL4)GLContext.getCurrentGL();
    gl.glUseProgram(renderingProgram);
    gl.glDrawArrays(GL_POINTS, 0, 1);
    // gl.glClearColor(1.0, 0.0, 0.0, 1.0);
    // gl.glClear(GL_COLOR_BUFFER_BIT);
    gl.glPointSize(30.0f);
  }

  void init(GLAutoDrawable drawable) {
    GL4 gl = (GL4)GLContext.getCurrentGL();
    renderingProgram = createShaderProgram();
    gl.glGenVertexArrays(vao.length, vao, 0);
    gl.glBindVertexArray(vao[0]);
  }
  void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
  }
  void dispose(GLAutoDrawable drawable) {
  }

  int createShaderProgram() {
    GL4 gl = (GL4)GLContext.getCurrentGL();

    String vshaderSource[] = {
      "#version 410   \n",
      "void main(void)  \n",
      "{gl_Position = vec4(0.0,0.0,0.0,1.0);} \n",
    };

    String fshaderSource[] = {
      "#version 410   \n",
      "out vec4 color;  \n",
      "void main(void)  \n",
      "{color = vec4(0.0,0.0,1.0,1.0);} \n",
    };

    int vShader = gl.glCreateShader(GL_VERTEX_SHADER);
    gl.glShaderSource(vShader, 3, vshaderSource, null, 0);
    gl.glCompileShader(vShader);
    int fShader = gl.glCreateShader(GL_FRAGMENT_SHADER);
    gl.glShaderSource(fShader, 4, fshaderSource, null, 0);
    gl.glCompileShader(fShader);

    int vfProgram = gl.glCreateProgram();
    gl.glAttachShader(vfProgram, vShader);
    gl.glAttachShader(vfProgram, fShader);
    gl.glLinkProgram(vfProgram);

    gl.glDeleteShader(vShader);
    gl.glDeleteShader(fShader);

    return vfProgram;
  }
}

void setup() {
  surface.setVisible(false);
  javax.swing.SwingUtilities.invokeLater(new Runnable() {
    public void run() {
      Wnd wnd = new Wnd();
      wnd.display(drawable); // Builds components on EventDispatchThread
    }
  }
  );
}

Part of Error Message:

Hi @svan,

in principle you don’t need the whole GL background and code, as processing gives you a PShader which handle this for you …

PShader shader;

String vshaderSource[] = {
  "#version 410", 
  "uniform mat4 transform;",
  "in vec4 vertex;",
  "void main(void) {", 
  "   gl_Position = transform * vertex;",
  "}"
};

String fshaderSource[] = {
  "#version 410", 
  "uniform float mytime;",
  "void main(void) {", 
  "   float t = sin(mytime)*0.5+0.5;",
  "   gl_FragColor = vec4(1.0-t,t,0.0,1.0);",
  "}", 
};

void setup() {
  size(640, 480, P2D);  
  rectMode(CENTER);
  shader = new PShader(g.parent, vshaderSource, fshaderSource);
}

void draw() {
  background(0);
  translate(width/2,height/2);
  shader.set("mytime",millis()/250.0);
  shader(shader);
  fill(255);
  rect(0,0,100,100);
}

ezgif.com-gif-maker (1)

Cheers
— mnse

Thanks. I’m aware that I can do the same thing a whole lot easier in Processing. See my other thread which @Scudly helped me with:
https://discourse.processing.org/t/inline-shader-code-will-not-run/40627
It’s no big deal if I never get the text book version to run, but it just bugs me when code won’t work as expected and I thought maybe someone else could get it to work. So far you’re the only one to respond. I was amazed that it even ran in Processing, even though it didn’t work as expected; it failed to run at all in other editors due to dependencies I could never fix. I’m just glad that I’m not sitting in the lecture hall.

Mac doesn’t like gl_FragColor, but “out vec4 outColor” substitution fixes it as pointed out to me in another thread. Interesting to see your version of inline code which is different from what is in the book (no line breaks) and not quite the same technique used by @Scudly. I appreciate all the help; it’s not an easy topic, but Processing has simplified it a lot.

Impressive that the screenshot is a running app; didn’t know that was possible.

Hi @svan,

gave your code a try and if I changed a bit, it worked like a charm on my box (Win64).

Cheers
— mnse

import javax.swing.*;
import processing.opengl.PGraphicsOpenGL;
import com.jogamp.opengl.GL4;
import com.jogamp.opengl.*;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.util.FPSAnimator; 

GLAutoDrawable drawable;
GLCanvas myCanvas;

final int GL_COLOR_BUFFER_BIT = 0x00004000;
final int GL_POINTS = 0x0000;
final int GL_VERTEX_SHADER = 35633;
final int GL_FRAGMENT_SHADER = 35632;

String[] vshaderSource = new String[3];
String[] fshaderSource = new String[4];

class Wnd implements GLEventListener {

  public int renderingProgram = -1;
  int vao[] = new int[1];

  Wnd() {
    JFrame frame = new JFrame("OpenGL Demo");
    frame.setBounds(200, 200, 600, 400);
    myCanvas = new GLCanvas();
    myCanvas.addGLEventListener(this);    
    frame.add(myCanvas);
    frame.setVisible(true);
  }

  void display(GLAutoDrawable drawable) {
    GL4 gl = (GL4)GLContext.getCurrentGL();
    gl.glUseProgram(renderingProgram);

    // just to see if it loops
    int uniformLocation = gl.glGetUniformLocation(renderingProgram, "mytime");
    if (uniformLocation == -1)
      println("nouniform");
    else 
    gl.glUniform1f(uniformLocation, millis()/250.);

    gl.glDrawArrays(GL_POINTS, 0, 1);      
    //gl.glClearColor(1.0, 0.0, 0.0, 1.0);
    //gl.glClear(GL_COLOR_BUFFER_BIT);
    gl.glPointSize(30.0f);
  }

  void init(GLAutoDrawable drawable) {
    GL4 gl = (GL4)GLContext.getCurrentGL();   
    renderingProgram = createShaderProgram();    
    gl.glGenVertexArrays(vao.length, vao, 0);
    gl.glBindVertexArray(vao[0]);

    // Automatically init redraw 60fps synced 
    new FPSAnimator(myCanvas, 60, true).start();     
    println("initialized!");
  }
  void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
  }
  void dispose(GLAutoDrawable drawable) {
  }

  int createShaderProgram() {
    GL4 gl = (GL4)GLContext.getCurrentGL();

    String vshaderSource[] = {
      "#version 410   \n", 
      "void main(void)  \n", 
      "{gl_Position = vec4(0.0,0.0,0.0,1.0);} \n", 
    };

    String fshaderSource[] = {
      "#version 410   \n", 
      "out vec4 color;  \n", 
      "uniform float mytime;  \n", 
      "void main(void)  \n", 
      "{\n", 
      "float t = sin(mytime)*0.5+0.5;  \n", 
      "color = vec4(1.0-t,0.0,t,1.0);  \n", 
      "} \n", 
    };

    int vShader = gl.glCreateShader(GL_VERTEX_SHADER);
    gl.glShaderSource(vShader, vshaderSource.length, vshaderSource, null, 0);
    gl.glCompileShader(vShader);
    int fShader = gl.glCreateShader(GL_FRAGMENT_SHADER);
    gl.glShaderSource(fShader, fshaderSource.length, fshaderSource, null, 0);
    gl.glCompileShader(fShader);

    int vfProgram = gl.glCreateProgram();
    gl.glAttachShader(vfProgram, vShader);
    gl.glAttachShader(vfProgram, fShader);
    gl.glLinkProgram(vfProgram);

    gl.glDeleteShader(vShader);
    gl.glDeleteShader(fShader);

    return vfProgram;
  }
}

void setup() {
  surface.setVisible(false);
  javax.swing.SwingUtilities.invokeLater(new Runnable() {
    public void run() {
      new Wnd();
      // no need to call disply as automatically called
      // if you call it here before init it will throw "No OpenGL context current on this thread"
      //wnd.display(drawable); // Builds components on EventDispatchThread
    }
  }
  );
}

PS: For P4 (resp. java 9+) regarding your InaccessibleObjectException above, you need to set the following java run.options in your preferences file to get it to run.

run.options=--add-exports java.base/java.lang=ALL-UNNAMED --add-exports java.desktop/sun.awt=ALL-UNNAMED --add-exports java.desktop/sun.java2d=ALL-UNNAMED

relates to: 1317 – JOGL AWT sample crashes on Java 9

ezgif.com-gif-maker (2)

Thanks for looking at it. After changing preferences.txt I was able to get it to run on Windows 11. When I try the same thing on a Mac it fails because I have to close Processing and restart it to have the preference changes to take effect. When I run the code a second time and check the preferences.txt file it was overwritten on the restart and no longer contains the appended run.options= field. It appears that the run.options additional code will solve the error problem if I could only get the changes to ‘stick’ on a Mac.

Hi Svan,

Editing of preferences.txt only on closed PDE, otherwise it gets overridden …
So, close all PDE’s. Edit preferences.txt. open PDE’s. Afterwards it should be persistent…

Cheers
— mnse

Editing of preferences.txt only on closed PDE, otherwise it gets overridden …

That was the problem, editor has to be closed for preferences changes to persist. Error message is now gone but still no colored rectangle on the Mac; does work on Windows 11. Lots of ‘nouniform’ in the log window so I know it’s looping. I’ll keep working with it; I don’t see any other error messages. Thanks for all your efforts.

Just Mac! … A neverending adventure… :wink: :rofl: