Java OpenGL triangle not showing

Viewed 45

I don't know much about OpenGL so I am following along with a book I found online. The book is here: https://www.google.com/books/edition/Computer_Graphics_Programming_in_OpenGL/GG1CEAAAQBAJ?hl=en&gbpv=1

I am running across a problem after the third exercise where I am trying to display a triangle. When run, there aren't any errors and the program shows an empty black window and no blue triangle. Just before this section of the book, we switched from using inline shader code to reading from a glsl file. If I had to take a guess, it would be something about the external code file that is giving me issues.

I have double checked the book to make sure I haven't mistyped anything. There are a few sections that seam to be author mistakes (specifically the naming of the vertex shader being vertexShader, instead of vShader), so I tried to write the code as it made sense to do so.

Is there anything about this code that stands out as an issue? I will post the code from the main class, as well as the separate shader files. I used a direct path because my IDE was not finding the files through relative pathing.

import javax.swing.*;
import static com.jogamp.opengl.GL4.*;
import com.jogamp.opengl.*;
import com.jogamp.opengl.awt.GLCanvas;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import java.util.Vector;

import com.jogamp.opengl.util.*;

public class Code extends JFrame implements GLEventListener
{

    
    
    private GLCanvas myCanvas;
    private int renderingProgram;
    private int vao[] = new int[1];
    
    public Code()   {
        setTitle("title");
        setSize(600,400);
        setLocation(200,200);
        myCanvas = new GLCanvas();
        myCanvas.addGLEventListener(this);
        this.add(myCanvas);
        this.setVisible(true);

    }
    
    public void display(GLAutoDrawable drawable)    {
        GL4 gl = (GL4) GLContext.getCurrentGL();
        gl.glUseProgram(renderingProgram);
        gl.glPointSize(10.f);
        //gl.glDrawArrays(GL_POINTS, 0, 1);
        gl.glDrawArrays(GL_TRIANGLES, 0, 3);
    }
    
    public static void main(String[] args) {
        new Code();
    }
    
    public void init(GLAutoDrawable drawable) {
        GL4 gl = (GL4) GLContext.getCurrentGL();
        renderingProgram = createShaderProgram();
        gl.glGenVertexArrays(vao.length, vao, 0);
        gl.glBindVertexArray(vao[0]);
    }
    
    private int createShaderProgram()   {
        GL4 gl = (GL4) GLContext.getCurrentGL();
        String vshaderSource[];
        String fshaderSource[];
        
        vshaderSource = readShaderSource("C:\\Users\\finks\\eclipse-workspace\\muddy\\src\\com\\muddy\\pkg\\vertShader.glsl");
        fshaderSource = readShaderSource("C:\\Users\\finks\\eclipse-workspace\\muddy\\src\\com\\muddy\\pkg\\fragShader.glsl");
        
        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;
    }
    
    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {}
    public void dispose(GLAutoDrawable drawable) {}
    
    private String[] readShaderSource(String filename) {
        
        Vector<String> lines = new Vector<String>();
        Scanner sc;
        String[] program;
        try {
            sc = new Scanner(new File(filename));
            while(sc.hasNext()) {
                lines.addElement(sc.nextLine());
            }
            program = new String[lines.size()];
            for(int i = 0; i < lines.size(); i++) {
                program[i] = (String)lines.elementAt(i) + "\n";
                    
            }
        }
        catch(IOException e) {
            System.err.println("IOException reading file: " + e);
            return null;
        }
        return program;
    }
}

fragShader.glsl

#version 430
out vec4 color;
void main(void)
{ 
    if(gl_FragCoord.x < 295) color = vec4(1.0,0.0,0.0,1.0);
        else color=vec4(0.0, 0.0, 1.0, 1.0);
}

vertShader.glsl

#version 430
void main(void)
{   if(gl_VertexID == 0) gl_Position = vec4(0.25, -0.25, 0.0, 1.0);
    else if (gl_VertexID == 1) gl_Position = vec4(-0.25, -0.25, 0.0, 1.0)
    else gl_Position = vec4(0.25, 0.25, 0.0, 1.0);
}
1 Answers

The problem is the way you load the text files with a java.util.Scanner.

The Scanner, by default, generates tokens delimited by any kind of whitespace character. Your code reads the file, generates tokens from it which you then join/concatenate again by a line break character (\n).

That means, OpenGL will see a shader source code like this:

#version
430
out
vec4
color;
void
main(void)
{
...

which is actually illegal, since the complete GLSL version is not within one line of the shader.

You should check the compile status of each shader object in order to spot such errors via glGetShaderi(yourShaderObject, GL_COMPILE_STATUS) and additionally, print the shader log output with glGetShaderInfoLog(yourShaderObject).

And there is absolutely no need to break up the file into tokens like this, or even fix up Windows/Linux/macOS line breaks. The driver will handle them just fine. So, just give the whole file to OpenGL.

Related