BufferedImage + glTexImage2D

As prescribed by Riven I’ve been going down the “direct OpenGL” path and avoiding using the built-in helper features of JOGL at least until I understand the internals of OpenGL. To this end I’ve been progressing well, but I keep finding myself stuck in certain Java-specific cases where an OpenGL book that references C-specific code does not help me to move forward. Specifically, I am currently trying to understand texturing in OpenGL, and though I have been able to use the Texture and TextureData objects in JOGL I would like to directly make use of glTexImage2D to load BufferedImage data into my textures and have dug into the TextureData and Texture classes to further understand, but it seems like there’s an awful lot of code there to handle all difference BufferedImage scenarios.

Does someone have a relatively simple example I can look at that converts the BufferedImage into the NIO Buffer necessary to pass to glTextImage2D?

Google: LWJGL texture upload

First hit - just skip everything about TGA and all that’s remaining is how to upload bytes as a texture

Ah, that seems to have cleared up a lot of confusion. Thank you very much.

I am attempting to use GLSL shaders to map the texture but believe I’m missing something:

init:

		// Allocate my buffer to hold my two triangles to make up a quad
		FloatBuffer buffer = FloatBuffer.allocate(18); {
			buffer.put(-1.0f);		// Top-Left
			buffer.put(1.0f);
			buffer.put(0.0f);
			
			buffer.put(1.0f);
			buffer.put(1.0f);
			buffer.put(0.0f);
			
			buffer.put(-1.0f);
			buffer.put(-1.0f);
			buffer.put(0.0f);
			
			buffer.put(-1.0f);
			buffer.put(-1.0f);
			buffer.put(0.0f);
			
			buffer.put(1.0f);
			buffer.put(-1.0f);
			buffer.put(0.0f);
			
			buffer.put(1.0f);
			buffer.put(1.0f);
			buffer.put(0.0f);
			
			buffer.rewind();
		}
		
		vertexes = new int[1];
		gl.glGenBuffersARB(1, vertexes, 0);																		// Generate a buffer id
		gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vertexes[0]);												// Bind the buffer
		gl.glBufferDataARB(GL.GL_ARRAY_BUFFER_ARB, buffer.capacity() * 4, buffer, GL.GL_STATIC_DRAW_ARB);		// Send the vertex buffer data to the video card
		
		// Create and bind texture
		textures = new int[1];
		gl.glGenTextures(1, textures, 0);
		gl.glBindTexture(GL.GL_TEXTURE_2D, textures[0]);
		try {
			BufferedImage image = ImageIO.read(getClass().getClassLoader().getResource("resource/crate.png"));
			DataBufferByte dbb = (DataBufferByte)image.getRaster().getDataBuffer();
			byte[] data = dbb.getData();
			ByteBuffer pixels = BufferUtil.newByteBuffer(data.length);
			pixels.put(data);
			pixels.flip();
			gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, 256, 256, 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, pixels);
		} catch(Throwable t) {
			t.printStackTrace();
		}
		
		// Load the GLSL texturing functionality
		programId = gl.glCreateProgramObjectARB();
		
		// Vertex Shader
		vertexShaderId = gl.glCreateShaderObjectARB(GL.GL_VERTEX_SHADER_ARB);
		String source = getShaderSource("texture_coordinates.vert");
		gl.glShaderSourceARB(vertexShaderId, 1, new String[] {source}, new int[] {source.length()}, 0);
		gl.glCompileShaderARB(vertexShaderId);
		int[] result = new int[1];
		gl.glGetShaderiv(vertexShaderId, GL.GL_COMPILE_STATUS, result, 0);
		if (result[0] != GL.GL_TRUE) {
			throw new RuntimeException("Compile of GLSL Shader failed!");
		}
		gl.glAttachObjectARB(programId, vertexShaderId);
		
		// Fragment Shader
		fragmentShaderId = gl.glCreateShaderObjectARB(GL.GL_FRAGMENT_SHADER_ARB);
		source = getShaderSource("texture_coordinates.frag");
		gl.glShaderSourceARB(fragmentShaderId, 1, new String[] {source}, new int[] {source.length()}, 0);
		gl.glCompileShaderARB(fragmentShaderId);
		result = new int[1];
		gl.glGetShaderiv(fragmentShaderId, GL.GL_COMPILE_STATUS, result, 0);
		if (result[0] != GL.GL_TRUE) {
			throw new RuntimeException("Compile of GLSL Shader failed!");
		}
		gl.glAttachObjectARB(programId, fragmentShaderId);
		
		// Link program
		gl.glLinkProgramARB(programId);
		gl.glGetProgramiv(programId, GL.GL_LINK_STATUS, result, 0);
		if (result[0] != GL.GL_TRUE) {
			throw new RuntimeException("Linking of GLSL Shader failed!");
		}
		gl.glUseProgramObjectARB(programId);
		int texture0 = gl.glGetUniformLocationARB(programId, "texture0");
		gl.glUniform1iARB(texture0, 0);

draw:

		gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);																	// Make it white
		
		gl.glEnableClientState(GL.GL_VERTEX_ARRAY);																// Enable vertex arrays
		gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vertexes[0]);												// Bind the vertex buffer by id
		gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);																// Tell where to start on the vertex buffer
		gl.glDrawArrays(GL.GL_TRIANGLES, 0, 6);																	// Draw the vertex buffer data to the screen
		gl.glDisableClientState(GL.GL_VERTEX_ARRAY);															// Disable vertex arrays

Everything loads and the GLSL doesn’t throw any errors. The shaders are as follows:

texture_coordinates.vert:

#version 130

uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;

in vec3 a_Vertex;
in vec3 a_Color;
in vec2 a_TexCoord0;
out vec4 color;
out vec2 texCoord0;

void main(void) {
	texCoord0 = a_TexCoord0;
	color = vec4(a_Color, 1.0);
	vec4 pos = modelview_matrix * vec4(a_Vertex, 1.0);
	gl_Position = projection_matrix * pos;
}

texture_coordinates.frag:

#version 130

uniform sampler2D texture0;

in vec4 color;
in vec2 texCoord0;

out vec4 outColor;

void main(void) {
	outColor = color * texture(texture0, texCoord0.st);
}

Google it.

Then you’ll at least have a shader that stores a value in gl_FragColor.

Seriously… if you’d copy & paste code you’d be better off.

The problem is that I can’t find a complete example that actually works. Everything I’m finding is either snippets or code for a larger project. I did search before I posted and have tried several variations but cannot seem to narrow down why it’s not working.

Does anyone have some sample code I can look at to understand this better?

Google: glsl tutorial

First hit. (lighthouse3d.com/…/glsl) for the full story.
Second hit: (lighthouse3d.com/…?shaders) to copy & paste

I’ve actually already gone through that exact tutorial and copied the shader source exactly but to no avail. I believe it has to do with my JOGL code, not the GLSL source that I’m stuck at this point.

Don’t you see that you don’t write anything into gl_FragColor, while you should?

And every code snippet overthere has it, except if they only change a few lines of the previous shader, and show their code like:


...

outColor = vec4(1,1,1,1);

...

I mean, the describing text there is very clear that it left stuff out that was already in the previous X provided samples.

Yes I know, and I was able to correct my code to include reference to gl_FragColor, but that still has not solved my problem. Because I’ve copied directly from other shader examples is why I believe that it’s something in my JOGL-specific code that is the problem at this point.

Try not using the ARB versions of the functions. In a lot of cases you can just remove ARB, but a few use slightly different names.