---
title: "OpenGL SuperBible in Java: The GLShaderManager class"
description: "Learn to create and manage shaders in Java using LWJGL. This tutorial shows you how to compile vertex and fragment shaders, link them into a program, and retrieve attribute and uniform locations for efficient use in your OpenGL applications.  The code examples cover shader compilation, linking, and utilizing a map for easy access to shader locations.  Improve your OpenGL development skills today!\n"
slug: "OpenGL-Superbible-in-Java-The-GLShaderManager"
created: 2011-10-24T00:00:00Z
updated: 2011-10-24T00:00:00Z
tags:
  - "java"
  - "opengl"
  - "opengl-superbible"
  - "lwjgl"
ai_assisted: false
---

When I started using the OpenGL SuperBible book to learn OpenGL, I noticed that the first examples from the book used some classes made by the author to encapsulate some complexity that would be explained later. As I was translating the examples do Java code, I had to figure out what those classes did before reading and testing the examples from the book.

One of those classes is the GLShaderManager, which I actually transformed in 2 classes. The first is the `GLShader.java`. The objective of `GLShader.java` is to receive 2 shader programs: a vertex program and a fragment program, and compile the programs, link them and extract the uniform and attribute ids into a Map on the client side for easier use later.

The code in the example is available at: [http://code.google.com/p/opengl-superbible-java/][1]

I rewrote the examples using [LWJGL][2].

The main tricks of the class are on the constructor. It receives 2 strings as parameters, the `vertexShaderSource` and the `fragmentShaderSource`.

So, the first step is compiling the shader sources. The code for compiling the Vertex Shader is as follows:

```java
int vertexShader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
GL20.glShaderSource(vertexShader, vertexShaderSource);
GL20.glCompileShader(vertexShader);

String vertexShaderErrorLog = GL20.glGetShaderInfoLog(vertexShader, 65536);
if (vertexShaderErrorLog.length() != 0) {
    System.err.println(
        "Vertex shader compile log: \n" + vertexShaderErrorLog);
}
```

First, a shader pointer is created with `glCreateShader`. The parameter indicates which type of shader to create. The second line attaches the shader source the the shader id. And, on the 3rd line, the shader is compiled.

The rest of the code checks if the compilation of the shader was OK and displays a message if something went wrong. (May be a good place to throw an exception).

Next thing to do is compiling the Fragment Shader.

```java
int fragmentShader = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
GL20.glShaderSource(fragmentShader, fragmentShaderSource);
GL20.glCompileShader(fragmentShader);

String fragmentShaderErrorLog = GL20.glGetShaderInfoLog(fragmentShader, 65536);
if (fragmentShaderErrorLog.length() != 0) {
    System.err.println("Fragment shader compile log: \n" + fragmentShaderErrorLog);
}
```

The code is almost the same as compiling the vertex shader, but passing `GL_FRAGMENT_SHADER` as a parameter to `glCreateShader`.

Now that we've compiled both the vertex shader and fragment shader, we have to link them together in a program.

```java
program = GL20.glCreateProgram();
GL20.glAttachShader(program, vertexShader);
GL20.glAttachShader(program, fragmentShader);

GL20.glLinkProgram(program);
String log = GL20.glGetProgramInfoLog(program, 65536);
if (log.length() != 0) {
    System.err.println("Program link log:\n" + log);
}

```

The first line creates a pointer to the program. Then, both the vertex shader and fragment shaders are attached to the program. The last step is to link them. Again, after linking the program we check if something went wrong.

By now, your shaders are compiled, linked and ready to use. But we may do something else. Each uniform or attribute created on your vertex and shader programs receives a pointer to be use the client code. But you have to find out which is which. Heres the code to identify the attribute ids:

```java
int numAttributes = GL20.glGetProgram(program, GL20.GL_ACTIVE_ATTRIBUTES);
int maxAttributeLength = GL20.glGetProgram(program, GL20.GL_ACTIVE_ATTRIBUTE_MAX_LENGTH);
for (int i = 0; i < numAttributes; i++) {
    String name = GL20.glGetActiveAttrib(program, i, maxAttributeLength);
    int location = GL20.glGetAttribLocation(program, name);
    System.out.println(name + ":" + location);
    attributeLocations.put(name, location);
}
```

First, we find out how many attributes we have. Then the size of the larges attribute name. Then, we loop for each attribute, get its name and its pointer and put it inside a map. The code for the uniform IDs is almost the same:

```java
int numUniforms = GL20.glGetProgram(program, GL20.GL_ACTIVE_UNIFORMS);
int maxUniformLength = GL20.glGetProgram(program, GL20.GL_ACTIVE_UNIFORM_MAX_LENGTH);
for (int i = 0; i < numUniforms; i++) {
    String name = GL20.glGetActiveUniform(program, i, maxUniformLength);
    int location = GL20.glGetUniformLocation(program, name);
    uniformLocations.put(name, location);
    System.out.println(name + ":" + location);
}
```

The code to activate the shader is pretty simple:

```java
public void useShader() {
    //Enable shader
    GL20.glUseProgram(program);
}
```

And this is how we encapsulate setting a uniform value. There, we can see the Map we made at the constructor in action. We could opt to not creating the map and getting the location on the fly on this method.

```java
public void setUniformMatrix4(String uniformName, boolean traverse, FloatBuffer matrixdata) {
    int location = uniformLocations.get(uniformName);
    GL20.glUniformMatrix4(location, traverse, matrixdata);
}
```

Thats it. Thats the first part of my port of the GLShaderManager class to Java using lwjgl. I've also ported this code to Android (2.2+) with minimal changes.

[1]: http://code.google.com/p/opengl-superbible-java/
[2]: https://www.lwjgl.org/