# Use a fragment and vertex shader through GL4

I’m attempting to set up a fragment and vertex shader where the vertex shader outputs a quad that covers the entire screen and the fragment shader draws a signed distance function on it.

I know that you can attach fragment shade through `loadShader("myshader.glsl");` but I want to have more flexibility and be able to use compute shaders.

Currently, I’m running into this error message “OpenGL error 1282 at top endDraw(): invalid operation”

The shaders have worked on a previous project so hopefully, they are correct. My guess is that I’ve missed something when I’m setting up the state for the shaders in the Java code.

Here is the code:

``````#version 400 core

/* A very basic vertex shader to allow us to take a picel point, transform them with
* a matrix and then output the clipspace coordinates
*/

layout(location = 0) in vec2 a_position;

uniform vec2 u_resolution;
uniform mat3 u_matrix;

void main() {
// Multiply the position by the matrix.
vec2 position = (u_matrix * vec3(a_position, 1)).xy;

// convert the position from pixels to 0.0 to 1.0
vec2 zeroToOne = position / u_resolution;

// convert from 0->1 to 0->2
vec2 zeroToTwo = zeroToOne * 2.0;

// convert from 0->2 to -1->+1 (clipspace)
vec2 clip_space = zeroToTwo - 1.0;

gl_Position = vec4(clip_space * vec2(1, -1), 0, 1);
}
``````

``````#version 400 core

// fragment shaders don't have a default precision so we need
// to pick one. highp is a good default. It means "high precision"
precision highp float;
uniform vec2 u_resolution;

// .x = f(p)
// .y = ∂f(p)/∂x
// .z = ∂f(p)/∂y
// .yz = ∇f(p) with ‖∇f(p)‖ = 1
vec3 sdgCircle( in vec2 p, in float r )
{
float l = length(p);
return vec3( l-r, p/l );
}

// we need to declare an output for the fragment shader
layout(location = 0) out vec4 outColor;

void main()
{
vec2 p = (2.0*gl_FragCoord.xy-u_resolution.xy)/u_resolution.y;

vec3 dg = sdgCircle(p,0.5);
float d = dg.x;
vec2 g = dg.yz;

// central differenes based gradient, for comparison
// g = vec2(dFdx(d),dFdy(d))/(2.0/iResolution.y);

// coloring
vec3 col = (d>0.0) ? vec3(0.9,0.6,0.3) : vec3(0.4,0.7,0.85);
col *= 1.0 + vec3(0.5*g,0.0);
//col = vec3(0.5+0.5*g,1.0);
col *= 1.0 - 0.5*exp(-16.0*abs(d));
col *= 0.9 + 0.1*cos(150.0*d);
col = mix( col, vec3(1.0), 1.0-smoothstep(0.0,0.01,abs(d)) );

outColor = vec4(col,1.0);
}
``````

Main Program

``````import com.jogamp.opengl.*;
import com.jogamp.common.nio.Buffers;
import java.nio.FloatBuffer;

LightingSystem ls;
GL4 gl;

void setup() {
size(1000, 1000, P2D);

PGL pgl = ((PGraphicsOpenGL)g).pgl;
gl = ((PJOGL)pgl).gl.getGL4();
//ls = new LightingSystem(gl, 5000, (float) width, (float) height);
}

void draw() {
background(0);
//ls.update();
//ls.render();
}

void dispose() {
//ls.release();
}

``````

``````import com.jogamp.opengl.GL4;

private GL4 gl;

// Vertex Buffer Object
private int[] vbo = new int[1];
private int numberOfIndicesToRender;

ShaderProgram(GL4 gl, String vertexFileName, String fragmentFileName, float width, float height) {
this.gl = gl;

// Fill screen with a rectangle we can draw on

gl.glGenBuffers(1, vbo, 0);
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, vbo[0]);

float[] vertices = createRectangle(gl, 0.0, 0.0, width, height);
this.numberOfIndicesToRender = vertices.length;
FloatBuffer rectangleFB = Buffers.newDirectFloatBuffer(vertices);
int numberOfBytes = rectangleFB.limit()*4;
gl.glBufferData(GL4.GL_ARRAY_BUFFER, numberOfBytes, rectangleFB, GL4.GL_STATIC_DRAW);
gl.glEnableVertexAttribArray(0);
// Since the vertex has 1 vec2 variable, then the stride is 8
// position attribute (no offset)
gl.glVertexAttribPointer(0, 2, GL4.GL_FLOAT, false, 2 * 4, 0);

// Pass the transformation matrix
float[] matrix =
{ 1.0, 0.0, 0.0
, 0.0, 1.0, 0.0
, 0.0, 0.0, 1.0
};
gl.glUniformMatrix3fv(matrixLocation, 1, false, Buffers.newDirectFloatBuffer(matrix));

// Pass the resolution
gl.glUniform2f(resolutionLocation, width, height);
}

/**
* Adds two triangles (creating a rectangle) to the currently bound buffer.
*/
float[] createRectangle(GL4 gl, float x, float y, float width, float height){
float x1 = x;
float x2 = x + width;
float y1 = y;
float y2 = y + height;

float[] res = {x1, y1,
x2, y1,
x1, y2,
x1, y2,
x2, y1,
x2, y2};

return res;
}

void draw() {
gl.glDrawArrays(GL4.GL_TRIANGLES, 0, numberOfIndicesToRender);
}

void release() {
}
}
``````

``````
/**
* Helper class that contains static methods
*/

// int[] vlengths = new int[]{vlines[0].length()};

int[] vlengths = new int[vlines.length];

for (int i = 0; i < vlines.length; i++){
vlengths[i] = vlines[i].length();
}

int[] compiled = new int[1];

if (compiled[0] == 0) {
int[] logLength = new int[1];

byte[] log = new byte[logLength[0]];

throw new IllegalStateException("Error compiling the shader '" + shaderPath + "': " + new String(log));
}

}

public boolean updateUniform1i(GL4 gl, int compute_program, String uniformName, int uniformValue) {

int loc = gl.glGetUniformLocation(compute_program, uniformName);
if (loc != -1)
{
gl.glUniform1i(loc, uniformValue);
return true;
}
return false;
}

public boolean updateUniform1f(GL4 gl, int compute_program, String uniformName, float uniformValue) {
Integer loc = gl.glGetUniformLocation(compute_program, uniformName);
if (loc != -1)
{
gl.glUniform1f(loc, uniformValue);
return true;
}
return false;
}

public boolean updateUniform2f(GL4 gl, int compute_program, String uniformName, float uniformValue1, float uniformValue2) {

int loc = gl.glGetUniformLocation(compute_program, uniformName);
gl.glUniform2f(loc, uniformValue1, uniformValue2);

if (loc != -1)
{
gl.glUniform2f(loc, uniformValue1, uniformValue2);
return true;
}
return false;
}

public boolean updateUniform3f(GL4 gl, int compute_program, String uniformName, float uniformValue1, float uniformValue2, float uniformValue3) {

int loc = gl.glGetUniformLocation(compute_program, uniformName);
if (loc != -1)
{
gl.glUniform3f(loc, uniformValue1, uniformValue2, uniformValue3);
return true;
}
return false;
}
}

``````

Have you looked at the compute shader example posted à while back its in the gallery section. Probs a good starting point.