Yep, I can texture in immediate mode, no problem.
I'll show you the entire program, note that there's some stuff to do with terrain in here which is not really relevent...
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.Array;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.FloatBuffer;
import org.lwjgl.*;
import org.lwjgl.opengl.*;
import org.lwjgl.input.*;
/** Main class
*/
public class VATest
{
private final static float PI_OVER_180 = 0.0174532925f; // ...convert between degrees and radians
private final static int DETAIL_SCALE = 16;
private final static String TERRAIN_TEX = "d:/tmp/tex.png";
private final static String DETAIL_TEX = "d:/tmp/detail.png";
private final static int TERRAIN_ID = 0;
private final static int DETAIL_ID = 1;
/** Global variable declaration */
private static boolean finished;
private static float xpos;
private static float ypos = 1;
private static float zpos;
private static float xrot;
private static float yrot = 180;
private static float zrot;
private static float t=0;
private static Object height_map;
static int tex;
//private static float g_Shine = 10.0f;
//private static FloatBuffer g_ShineBuffer = ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asFloatBuffer();
private static FloatBuffer buf;
private static FloatBuffer buf2;
// GL context creation...
static
{
try
{
Window.create("Basic Window", 50, 50, 800, 600, 16, 0, 8, 0); // Create The Opengl Context
} catch (Exception e)
{
System.exit(1);
}
}
/**
* Main method
*/
public static void main(String args[])
{
try
{
init(); // Init Opengl
while (!finished)
{
Keyboard.poll();
processKeyboard(); // Get Keyboard Events
Mouse.poll();
processMouse();
processWindow(); // Get Window Events
render(); // Render To Screen
Window.update();
Window.paint(); // Swap Opengl Buffers
}
}
catch (Throwable t)
{
t.printStackTrace();
}
finally
{
cleanup();
}
}
/**
* Init opengl
*/
private static void init() throws Exception
{
// load height map...
try
{
FileInputStream in = new FileInputStream("d:/tmp/cds.raw");
ObjectInputStream s = new ObjectInputStream(in);
height_map = s.readObject();
}
catch (Exception e)
{
e.printStackTrace();
}
Keyboard.create();
Mouse.create();
// GL.glEnable(GL.GL_BLEND); // alpha blending
GL.glShadeModel(GL.GL_SMOOTH); // Enable Smooth Shading
GL.glClearColor(0.5f, 0.5f, 0.5f, 0.0f); // Black Background
GL.glClearDepth(1.0); // Depth Buffer Setup
GL.glEnable(GL.GL_DEPTH_TEST); // Enables Depth Testing
GL.glDepthFunc(GL.GL_LEQUAL); // The Type Of Depth Testing To Do
//enable lighting
GL.glEnable( GL.GL_LIGHTING );
// global ambient light
float[] ambient_light = { 1.0f, 1.0f, 1.0f, 1.0f };
ByteBuffer temp = ByteBuffer.allocateDirect( 16 );
temp.order( ByteOrder.nativeOrder() );
GL.glLightModel( GL.GL_LIGHT_MODEL_AMBIENT, temp.asFloatBuffer().put( ambient_light ) );
// enable & build vertex arrays...
GL.glEnableClientState(GL.GL_VERTEX_ARRAY);
// GL.glEnableClientState(GL.GL_COLOR_ARRAY);
GL.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
createVertexArrays();
GL.glMatrixMode(GL.GL_PROJECTION); // Select The Projection Matrix
GL.glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
GLU.gluPerspective(45.0f, (float)Display.getWidth() / (float)Display.getHeight(), 0.1f, 100.0f);
GL.glMatrixMode(GL.GL_MODELVIEW); // Select The Modelview Matrix
// Really Nice Perspective Calculations
GL.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
//sync to monitor
GLCaps.determineAvailableExtensions();
if(GLCaps.WGL_EXT_swap_control)
{
GL.wglSwapIntervalEXT(1);
}
}
/**
* main render loop
*/
private final static void render()
{
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
GL.glLoadIdentity(); // Reset The Current Modelview Matrix
GL.glRotatef(360 - yrot, 0.0f, 1.0f, 0.0f);
GL.glTranslatef(-xpos, -ypos, -zpos);
GL.glDrawArrays(GL.GL_QUADS, 0, 4);
}
private static final void createVertexArrays()
{
float[] vertexes = {0f, 1f, 0f,
10f, 1f, 0f,
10f, 1f, 10f,
0f, 1f, 10f};
/* float[] colors = {1f, 1f, 0f,
1f, 0f, 0f,
0f, 1f, 0f,
0f, 0f, 1f};*/
buf = ByteBuffer.allocateDirect(12*4).order(ByteOrder.nativeOrder()).asFloatBuffer().put(vertexes);
buf.flip();
// buf2 = ByteBuffer.allocateDirect(12*4).order(ByteOrder.nativeOrder()).asFloatBuffer().put(colors);
// buf2.flip();
float texCoords[]= {1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f};
FloatBuffer tex_buf = ByteBuffer.allocateDirect(2*16).order(ByteOrder.nativeOrder()).asFloatBuffer().put(texCoords);
tex_buf.flip();
tex = loadTexture("d:/tmp/detail.png");
GL.glVertexPointer(3, 0, buf);
// GL.glColorPointer(3, 0, buf2);
GL.glTexCoordPointer(2, 0, tex_buf);
}
/**
* Process keyboard events
*/
private final static void processKeyboard()
{
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE))
finished = true;
if (Keyboard.isKeyDown(Keyboard.KEY_EQUALS))
{
t -= .5f;
}
if (Keyboard.isKeyDown(Keyboard.KEY_MINUS))
{
t += .5f;
}
if (Keyboard.isKeyDown(Keyboard.KEY_UP))
{
xpos -= (float)Math.sin(yrot * PI_OVER_180) * 0.05f;
zpos -= (float)Math.cos(yrot * PI_OVER_180) * 0.05f;
}
if (Keyboard.isKeyDown(Keyboard.KEY_DOWN))
{
xpos += (float)Math.sin(yrot * PI_OVER_180) * 0.05f;
zpos += (float)Math.cos(yrot * PI_OVER_180) * 0.05f;
}
Object row = Array.get(height_map, (int)xpos);
ypos = (10 * Array.getFloat(row, (int)zpos)) + .1f;
}
/**
* Process mouse events
*/
private final static void processMouse()
{
yrot += Mouse.dx/10;
}
/**
* Process window events
*/
private final static void processWindow()
{
if (Window.isCloseRequested())
{
finished = true;
}
}
/**
* Cleanup
*/
private final static void cleanup()
{
Keyboard.destroy(); // Destroy The Keyboard
Window.destroy(); // Destroy The Opengl Context
}
/**
* Load a texture in OpenGL memory
*/
private final static int loadTexture(String path)
{
Image image = (new javax.swing.ImageIcon(path)).getImage();
// Exctract The Image
BufferedImage tex = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_3BYTE_BGR);
Graphics2D g = (Graphics2D) tex.getGraphics();
g.drawImage(image, null, null);
g.dispose();
// Flip Image
AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
tx.translate(0, -image.getHeight(null));
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
tex = op.filter(tex, null);
// Put Image In Memory
ByteBuffer scratch = ByteBuffer.allocateDirect(4 * tex.getWidth() * tex.getHeight());
byte data[] = (byte[]) tex.getRaster().getDataElements(0, 0, tex.getWidth(), tex.getHeight(), null);
scratch.clear();
scratch.put(data);
scratch.rewind();
// Create A IntBuffer For Image Address In Memory
IntBuffer buf = ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asIntBuffer();
GL.glGenTextures(buf); // Create Texture In OpenGL
GL.glBindTexture(GL.GL_TEXTURE_2D, buf.get(0));
// Typical Texture Generation Using Data From The Image
// Linear Filtering
GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
// Linear Filtering
GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
// Generate The Texture
GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, tex.getWidth(), tex.getHeight(),
0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, scratch);
return buf.get(0); // Return Image Address In Memory
}
}