LWJGL Forum
Programming => Lightweight Java Gaming Library => Topic started by: kramer on October 15, 2003, 23:39:24
-
Hi guys,
I've been trying to texture a vertex buffer object square but had problems so thought I'll take a step back and texture a vertex array (since the syntax/concept of VA and VBO are closely related) but have had no luck. I even tried just added some colours but that doesn't seem to have any effect either.
If anyone has a snippet of code showing how to do this, I would greatly appreciate it.
Cheers,
K
-
I would be happy to help, as i just got textures and materials working with vertex arrays myself.
First i would suggest getting materials working, as they are a little easier to debug then textures imo.
Do you have vertex arrays working enough to render an object?
Does it just render in full white with no material/texture?
What draw method are you using? glDrawElements or glDrawArrays, or other?
Can you paste the important lines of your code where you call the gl*Pointer() methods and the glDraw*() method(s)? Do you have lighting on?
Also make sure your buffers are flip() 'ed before passing them on to LWJGL after filling them up so the position and limit are set correctly.
-
Thanks thinker.
Yes, I can render the basic object, and yes it comes out default white. I am using glDrawArrays() and am not using lighting.
- I call this during my init:
GL.glEnableClientState(GL.GL_VERTEX_ARRAY);
GL.glEnableClientState(GL.GL_COLOR_ARRAY);
createVertexArrays();
- here is my draw call:
GL.glDrawArrays(GL.GL_QUADS, 0, 4);
- here is where I build the buffers:
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();
GL.glVertexPointer(3, 0, buf);
GL.glColorPointer(3, 0, buf2);
}
If you could give me the important snippets of how you got it working, that would be great.
-
First try to enable lighting:
//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 ) );
In my application, if i comment out the line where i enable lighting, my objects that do not have a texture will just render all white.
-
Ok, I messed around with some stuff and managed to get colors working in the example i gave above, I then tried putting a texture on but no luck.
So I added the lighting code you gave to my init(), but no luck. I tried it with just color pointer to see what would happen and the result is a black square. I know the square is rendering because my background is grey.
Now I haven't messed around with OpenGl lighting before, so I may be missing some trivial thing...
-
Can you get textures working if you don't use a vertex arrays? Just to validate that you have the texture loaded correctly and that lighting and such is correct. Once you have that with out arrays then at least you know to focus aspects that are different.
-
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
}
}
-
Lol, I found out what I was doing wrong...
When I was cutting this example from the main app I'm working from to try and figure out vertex arrays, I inadvertantly cut out this line:
GL.glEnable(GL.GL_TEXTURE_2D);
No wonder I couldn't get any texturing... heh
-
ahh, great. glad it works for you now :)