yeah sure…
try
{
// Load some texture
Texture texture = TextureIO.newTexture(glsl1.class.getResource(“moon.png”), false, “png”);
// Store the OpenGL texture object ID for later use
textureID = texture.getTextureObject();
}
that moon.png can be read by anyone and is locateted in my root of my project folder with its subfolders: src, lib, librc and bin…
I also put the pic in the different sub folders too, just to check…then i got the error: URL was null.
Quite funny and irritating;-)
I’ll get an white rectangle on black ground. Absolutly correct when there is no texture to load, but the file exists;-)
Here your code:
package glsl1;
import com.sun.opengl.util.Animator;
import com.sun.opengl.util.texture.Texture;
import com.sun.opengl.util.texture.TextureIO;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
import static javax.media.opengl.GL.*;
/**
* SimpleShaderTemplate.java
* @author Mathias 'cylab' Henze
*/
public class glsl1 implements GLEventListener
{
private GLU glu = new GLU();
// Hold the shader program for later use
private int program;
// Holds the texture object for later use
private int textureID;
public static void main(String[] args)
{
Frame frame = new Frame("Simple JOGL GLSL Application");
GLCanvas canvas = new GLCanvas();
canvas.addGLEventListener(new glsl1());
frame.add(canvas);
frame.setSize(640, 480);
final Animator animator = new Animator(canvas);
frame.addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent e)
{
// Run this on another thread than the AWT event queue
// so that Animator.stop() completes before exiting
new Thread(new Runnable()
{
public void run()
{
animator.stop();
System.exit(0);
}
}).start();
}
});
frame.setLocationRelativeTo(null);
frame.setVisible(true);
animator.start();
}
public void init(GLAutoDrawable drawable)
{
// drawable.setGL(new DebugGL(drawable.getGL()));
GL gl = drawable.getGL();
// You won't get far without error checking ;)
String errors = null;
try
{
// Load some texture
Texture texture = TextureIO.newTexture(glsl1.class.getResource("moon.png"), false, "png");
// Store the OpenGL texture object ID for later use
textureID = texture.getTextureObject();
}
catch (Exception ex)
{
Logger.getLogger(glsl1.class.getName()).log(Level.SEVERE, null, ex);
}
// This is the shader source. For simplicity just use a single concatenated string
String[] shader =
{
// This variable specifies the texture unit to use, called "sampler" in GLSL
"uniform sampler2D texUnit;\n" +
// main() is called for every pixel on screen (called "fragment" in GLSL) while rasterizing
"void main(void)\n" +
"{\n" +
// The gl_TexCoord array is a build in GLSL variable that holds the glTexCoordXX() values
" vec2 texCoord = gl_TexCoord[0].xy;\n" +
// texture2D() gets a texel from the texture unit at the given location
" vec4 texel = texture2D(texUnit, texCoord);\n" +
// Now assign the texel to be the current pixels output color.
// Mask out green, to see that the shader is indeed used (vec4 is r,g,b,a)
" gl_FragColor = texel * vec4(1.0, 0.0, 1.0, 1.0);\n" +
"}\n"
};
// Since java Strings aren't 0-terminated, store the length for submission to glShaderSource
// (maybe this unnecessary and JOGL implicitly 0-terminates the Strings, but you never know)
int[] lengths = { shader[0].length() };
// Create and store a shader program
program = gl.glCreateProgramObjectARB();
// Create the fragment shader object
int frag = gl.glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
// Tell the shader program to use the fragment shader
gl.glAttachObjectARB(program, frag);
// Copy the shader source to GL implementation.
// You need the amount of Strings, the String[] and an array of the Strings lenghts
gl.glShaderSourceARB(frag, shader.length, shader, lengths, 0);
// Compile the shader
gl.glCompileShaderARB(frag);
// Check for compile errors
if ((errors = getGLErrorLog(gl, frag)) != null)
throw new RuntimeException("Compile error\n" + errors);
// Link the program
gl.glLinkProgramARB(program);
// Check for link errors
if ((errors = getGLErrorLog(gl, program)) != null)
throw new RuntimeException("Link error\n" + errors);
// Use the program, to be able to assign values to the uniforms
gl.glUseProgramObjectARB(program);
// Get the location of the texUnit uniform, so we can assign a value to it
int texUnit = gl.glGetUniformLocationARB(program, "texUnit");
// Assign the GL_TEXTURE0 unit to the uniform variable
// CAUTION: you need to set the plain texture _unit_ _number_,
// not the GL constant nor the textur object here!!!
gl.glUniform1iARB(texUnit, 0);
// Enable VSync
gl.setSwapInterval(1);
// Setup the clear color
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}
public void display(GLAutoDrawable drawable)
{
GL gl = drawable.getGL();
// Clear the drawing area
gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset the current matrix to the "identity"
gl.glLoadIdentity();
// Move the "drawing cursor" around
gl.glTranslatef(0.0f, 0.0f, -3.0f);
// Choose the current texture unit
gl.glActiveTexture(GL_TEXTURE0);
// Bind a texture to the current texture unit
gl.glBindTexture(GL_TEXTURE_2D, textureID);
// Enable the shader program
gl.glUseProgramObjectARB(program);
// Draw a quad to be textured
gl.glBegin(GL_QUADS);
{
gl.glTexCoord2f(0, 0);
gl.glVertex3f(-1, -1, 0);
gl.glTexCoord2f(1, 0);
gl.glVertex3f(1, -1, 0);
gl.glTexCoord2f(1, 1);
gl.glVertex3f(1, 1, 0);
gl.glTexCoord2f(0, 1);
gl.glVertex3f(-1, 1, 0);
}
gl.glEnd();
// Disable all shaders
gl.glUseProgramObjectARB(0);
// Flush all drawing operations to the graphics card
gl.glFlush();
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
{
GL gl = drawable.getGL();
if (height <= 0)
{ // avoid a divide by zero error!
height = 1;
}
final float h = (float) width / (float) height;
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(45.0f, h, 1.0, 20.0);
gl.glMatrixMode(GL_MODELVIEW);
gl.glLoadIdentity();
}
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)
{
}
// Checks for arbitrary GL errors. Could also be accomplished by enabling the DebugGL pipeline
private String getGLError(GL gl)
{
boolean hasError = false;
String message = "";
for (int glErr = gl.glGetError(); glErr != GL.GL_NO_ERROR; glErr = gl.glGetError())
{
message += (hasError ? "\n" : "") + glu.gluErrorString(glErr);
hasError = true;
}
return hasError ? message : null;
}
// Checks the info log for compile/link errors
private String getGLErrorLog(GL gl, int obj)
{
boolean hasError = false;
int[] infologLength = {0};
int[] charsWritten = {0};
byte[] infoLog;
String message = "";
String error = getGLError(gl);
if (error != null)
{
message += error;
hasError = true;
}
gl.glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, infologLength, 0);
error = getGLError(gl);
if (error != null)
{
message += (hasError ? "\n" : "") + error;
hasError = true;
}
if (infologLength[0] > 1)
{
infoLog = new byte[infologLength[0]];
gl.glGetInfoLogARB(obj, infologLength[0], charsWritten, 0, infoLog, 0);
message += (hasError ? "\n" : "") + "InfoLog:\n" + new String(infoLog);
hasError = true;
}
error = getGLError(gl);
if (error != null)
{
message += (hasError ? "\n" : "") + error;
hasError = true;
}
return hasError ? message : null;
}
}