2 questions

question1:
how to get it so the viewwindow is bound to the 3d coords? eg so that the view window is coupled onto the end of a cuboid in 3d space?

quesion2:
what is a file format that can have different colors for each vertex. You cant do this with obj which i made a loader for.

  1. You can move your view around by multiplying your projection matrix by other transformation matrices (i.e. translate, rotate etc.) so you can move it about as if it were attached to a moving “cube” in space.

  2. OBJ format supports materials (which look a lot like OpenGL materials), although not all descriptions of OBJ mention this. Take a look at:

http://www.csit.fsu.edu/~burkardt/data/obj/obj_format.txt

I have updated my obj loader so it supports mtls, textures and normals, however now i realise that many of the supplied texuteres do not have dimensions that are a power of 2. To remedy this i find the next biggest power of 2 and stretch the texture using j2d, but i realy would like to be able to do it some other way without using awt/imagio, how can i do this.

Also im not to sure how to implement transparency, in the mtl files, transparency is specified as a value between 0 and 1, how can i draw the surface with this transparency, which blennd function do i need to use.

Also: Im not usre what is the most expensive operations in opengl, but i hear that changing materials and binding textures is quite expensive. shoudl i build some sort of tree so i can draw the plygons changing these as few times as possible?

Hi g666,

I don’t know for sure, but I think the devIL library that comes with LWJGL can do the texture resizing for you so that you can avoid AWT.

You might find adjusting your texture coordinates rather than stretching the original image is easier.

Kev

but ogl wont let me have me have non power of 2 textures, unless there is some feature that id ont know about ??? (uite likely :P)

Na, you still have non-power of two textures, you just leave the image the same size, only fill the bit of the texture you have then adjust the texture coordinates to match the size of the image…

so, if you image was 24x24, the texture ends up being 32x32… and you texture coordinates end up being 0,0 to (24f/32f,24f/32f)

Kev

And you don’t obviously know about… the ARB_texture_non_power_of_two and ARB_texture_rectangle extensions! 8)

Cas :slight_smile:

Why didnt you tell me about the gluScaleImage method?
now why wont this work?(it fails with an index out of bounds exception in that method)



package com.ts.terestria.client.lwjglrenderer;

import org.lwjgl.*;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.glu.*;
import org.lwjgl.devil.*;

import java.nio.*;
import java.util.HashMap;

public class TextureCache{
	
	/*
	 *cannot be instanstiated
	*/
	private TextureCache(){}
	static{
		init();
	}
	
	//Strings as keys for Texture Objects
	private static HashMap textures = new HashMap();
		
	public static void init(){
		try{
			IL.create();
		}catch(LWJGLException e){}
	}
	
	
	/**
	 *returns a Texture, loading it if neccasary and adding it to the cache
	 */
	public static Texture getTexture(String path){
		//need to load it?
		if(!textures.containsKey(path))
			textures.put(path, loadTexture(path));
		return (Texture) textures.get(path);
	}
	
	
	/*
	 *returns a texture object loaded from the specified path
	*/
    public static Texture loadTexture(String path){

        ByteBuffer scratch = getImageData(path);
        
        int width = IL.ilGetInteger(IL.IL_IMAGE_WIDTH);
        int height = IL.ilGetInteger(IL.IL_IMAGE_HEIGHT);
        
       int newWidth=width, newHeight=height;

        //scale image?
        if(!isPOT(width) || !isPOT(height)){
        	
        	int newWidth = getNextPOT(width);
        	int newHeight = getNextPOT(height);
        	ByteBuffer scaled = ByteBuffer.allocateDirect(newWidth*newHeight*4);
        	        	
        	//returns 0 on success, else a GLU error code
        	int retVal = GLU.gluScaleImage(
        						GL11.GL_RGBA,
                                width,
                                height,
                                GL11.GL_UNSIGNED_BYTE,
                                scratch,
                                newWidth,
                                newHeight,
                                GL11.GL_UNSIGNED_BYTE,
                                scaled);

                scratch = scaled;

        	if(retVal != 0){
        		System.out.println("something went wrong scaling texture");
        		System.exit(1);
        	}
        }
        
        // Create A IntBuffer For Image Address In Memory
        IntBuffer buf = ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asIntBuffer();
        GL11.glGenTextures(buf); // Create Texture In OpenGL

        GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(0));
        // Typical Texture Generation Using Data From The Image

        // Linear Filtering
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
        // Linear Filtering
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
        // Generate The Texture
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, newWidth, newHeight,
        	0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, scratch);
                
 		// buf.get(0) == Image Address In Memory
        return new Texture(buf.get(0), width, height);
	}
	
	
	/**
	 *returns a byte buffer of image data loaded from the specifed path
	 */
	public static ByteBuffer getImageData(String path){
		IntBuffer image = ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asIntBuffer();
        IL.ilGenImages(image);
        IL.ilBindImage(image.get(0));
        IL.ilLoadImage(path);
        IL.ilConvertImage(IL.IL_RGBA, IL.IL_BYTE);
        ByteBuffer scratch = ByteBuffer.allocateDirect(IL.ilGetInteger(IL.IL_IMAGE_WIDTH) * IL.ilGetInteger(IL.IL_IMAGE_HEIGHT) * 3);
        IL.ilCopyPixels(0, 0, 0, IL.ilGetInteger(IL.IL_IMAGE_WIDTH), IL.ilGetInteger(IL.IL_IMAGE_HEIGHT), 1, IL.IL_RGB, IL.IL_BYTE, scratch);
        return scratch;
	}
	
	
	/**
	 *returns the next POT, if n is POT then it returns n
	 */
	public static int getNextPOT(int n){
		int i = 1;
		while(i < n){
			i *= 2;		
		}
		return i;
	}
	
	
	/**
	 *returns if n is POT
	 */
	public static boolean isPOT(int n){
		return getNextPOT(n) == n;
	}
}


Hello? Anybody out there? :-\