Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - raft

Pages: 1 ... 125 126 [127] 128 129 ... 133
1891
Support / Streaming algorithm
« on: May 15, 2006, 01:16:10 am »
ehm, so i have an un-generatable memory leak somewhere, thanks for the gift :roll:
Code: [Select]
r a f t

1892
Support / Streaming algorithm
« on: May 14, 2006, 10:31:15 pm »
of course, it's much and much more likely that my code is buggy rather than the vm itself ;)

what i was trying to say that i'm not sure if java spec dictates to perform a complete garbage collection if no memory is available, does it ? or does vm simply throw an OutOfMemoryError even if there are some objects waiting to be collected ?
Code: [Select]
r a f t

1893
Support / Streaming algorithm
« on: May 14, 2006, 02:32:37 pm »
Quote from: "EgonOlsen"
The VM will do it for you before giving an out of memory error. If it still occurs, there must be a reference somewhere to the objects that should be collected.


i'm not that sure about this. during a test i was quickly switching between nodes in karga and hence creating a new world and forgetting the old one. i've got OutOfMemoryError for a couple times. this never happens if i put some time between node switches

i guess java vm doesnt try to make a complete garbage collection on a request for memory. (or maybe buggy) otherwise i cant explain why this happens
Code: [Select]
r a f t

1894
Projects / Technopolies
« on: May 12, 2006, 05:44:56 pm »
looks great ;)
and nice to see you working on techno again
Code: [Select]
r a f t

1895
Projects / aptal karga (foolish crow)
« on: May 06, 2006, 12:40:40 am »
well, except a couple of minor bug fixes there is nothing new on coding side. i've just reorganized the site and added some cosmetic makeup.

and, ehm, i've drunk and slept a lot meanwhile :roll: ;)

another shot from village with mipmapping enabled and maximum resolution (ogss)


the new login screen


Code: [Select]
r a f t

1896
Support / texture aliasing
« on: March 30, 2006, 06:25:52 pm »
sure. i'll be glad indeed ;)
Code: [Select]
r a f t

1897
Support / texture aliasing
« on: March 29, 2006, 08:14:04 pm »
here is a simple area based MipMapper implementation based on Egon's one. it uses java5 syntax but not java5 specific classes so can be converted to earlier versions of java

to use, create an instance of MipMapper and add Object3D's to be mip mapped with addObject(Object3D). call MipMapper.mipMap(World, FrameBuffer) either before or after render/draw.

please note:
* it requires the upcoming version (1.11) of jPCT
* it isnt suitable for textures which are modified or replaced over time

Code: [Select]
r a f t

Code: [Select]

import com.threed.jpct.*;

import java.util.*;
import java.awt.*;
import java.awt.image.*;

/**
 * a simple area based mip mapper implementation.
 * i.e: mip map level per polygon is decided according to ratio:
 * area of polygon on screen / area of polygon on texture
 *
 * @author r a f t
 */
public class MipMapper {
    /** the number of mipmap levels */
    public static final int LEVELS = 8; // enough for mip mapping a 1024x1024 texture to 8x8
   
    /** the minimum mipmap size (lower isn't possible, higher is) */
    public static final int MIN_SIZE = 8;
   
    /** original texture will be used dwon to this ratio (polygon area / texture area) */
    public static final float FIRST_LEVEL = 1/2.5f;
   
    /** debug switch for showing colored mip maps */
    public static boolean colorMipmaps = false;
   
    private final TextureManager tm = TextureManager.getInstance();
   
    private final int[] visListData = new int[2];
   
    private final BitSet changedObjects = new BitSet(256);
    private final BitSet processedTextures = new BitSet(256);
   
    private final Map<Integer, ObjectData> mipMapData = new HashMap<Integer, ObjectData>();
    private final Map<String, Integer> textureIds = new HashMap<String, Integer>();
    private final Set<String> createdTextures = new HashSet<String>();
   
    public MipMapper() {}
   
    /** adds the object to mipmap list */
    public void addObject(Object3D object3d) {
        mipMapData.put(object3d.getID(), new ObjectData(object3d));
    }
   
    /** removes the object from mipmap list */
    public void removeObject(int id) {
        mipMapData.remove(id);
    }
   
    /** creates mipmap textures if they arent already created */
    private void createMipMaps(Object3D object3d) {
        PolygonManager pm = object3d.getPolygonManager();
       
        for (int polygonId = 0; polygonId < pm.getMaxPolygonID(); polygonId++) {
            int textureId = pm.getPolygonTexture(polygonId);
           
            if (!processedTextures.get(textureId)) {
               
                Texture texture = tm.getTextureByID(textureId);
                int owidth = texture.getWidth();
                int oheight = texture.getHeight();
               
                TexelGrabber tg = new TexelGrabber();
                texture.setEffect(tg);
                texture.applyEffect();
                texture.removeEffect();
               
                int[] texels = tg.texels;
                BufferedImage origTextureImage = new BufferedImage(owidth, oheight, BufferedImage.TYPE_INT_RGB);
                int[] pixels = ((DataBufferInt) ((BufferedImage) origTextureImage).getRaster().getDataBuffer()).getData();
               
                Texture lastTexture = texture;
                int lastTextureId = textureId;
               
                for (int offset = 1; offset < LEVELS; offset++) {
                    int width = (int) ((float) owidth/Math.pow(2, offset));
                    int height = (int) ((float) oheight/Math.pow(2, offset));
                   
                    width = Math.max(MIN_SIZE, width);
                    height = Math.max(MIN_SIZE, height);
                   
                    if ((lastTexture.getWidth() != width) || (lastTexture.getHeight() != height)) {
                       
                        if (colorMipmaps) {
                            int[] tmpy = new int[texels.length];
                            int col = 200<<(8*((offset-1)%3));
                            for (int i = 0; i < tmpy.length; i++) {
                                tmpy[i] = col;
                            }
                            texels = tmpy;
                        }
                        System.arraycopy(texels, 0, pixels, 0, owidth*oheight);
                       
                        Image mipmapTextureImage = origTextureImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
                        Texture mipmapTexture = new Texture(mipmapTextureImage);
                       
                        String textureName = getTextureName(textureId, offset);
                       
                        if (tm.containsTexture(textureName))
                            tm.replaceTexture(textureName, mipmapTexture);
                        else tm.addTexture(textureName, mipmapTexture);
                       
                        lastTexture = mipmapTexture;
                        lastTextureId = tm.getTextureID(textureName);
                       
                        textureIds.put(textureName, lastTextureId);
                        createdTextures.add(textureName);
                       
                        Logger.log("mip map texture created " + textureName + " " + width + "x" + height, Logger.MESSAGE);
                       
                    } else {
                        // no need to create a new texture so use last one
                        String textureName = getTextureName(textureId, offset);
                        textureIds.put(textureName, lastTextureId);
                       
                        Logger.log("re-used last mipmap texture " + textureName + " " + width + "x" + height, Logger.MESSAGE);
                    }
                   
                } // for offset
                processedTextures.set(textureId);
            } // if (!processedTextures.get(textureId)
        } // for polygonId
    }
   
    private String getTextureName(int baseTextureId, int offset) {
        return "mipmap/" + baseTextureId + "/" + offset;
    }
   
    /**
     * Does the actual mipmapping based on the current visibility list.
     * Has to be executed after/before rendering/drawing the scene, so it's always
     * "one step behind" but if you don't move very fast, this shouldn't matter.
     */
    public void mipMap(World world, FrameBuffer buffer) {
        if (mipMapData.isEmpty())
            return; // no mipMapped objects so return
       
        VisList vl = world.getVisibilityList();
       
        int size = vl.getSize();
        int lastObjectId = -1;
       
        ObjectData objectData = null;
        changedObjects.clear();
       
        for (int i = 0; i < size; i++) {
            vl.getData(i, visListData);
           
            if (lastObjectId != visListData[0]) {
                lastObjectId = visListData[0];
                objectData = mipMapData.get(visListData[0]);
            }
           
            if (objectData != null) {
                SimpleVector v0, v1, v2;
                int polygonId = visListData[1];
               
                if ((v0 = Interact2D.project3D2D(world.getCamera(),
                        buffer, objectData.pm.getTransformedVertex(polygonId, 0))) == null)
                    continue;
                if ((v1 = Interact2D.project3D2D(world.getCamera(),
                        buffer, objectData.pm.getTransformedVertex(polygonId, 1))) == null)
                    continue;
                if ((v2 = Interact2D.project3D2D(world.getCamera(),
                        buffer, objectData.pm.getTransformedVertex(polygonId, 2))) == null)
                    continue;
               
                float polygonArea = calculateArea(v0, v1, v2);
                float ratio = polygonArea / objectData.textureAreas[polygonId];
               
                int offset = -1; boolean done = false;
                while (!done && (++offset < LEVELS - 1)) {
                    done = ratio > FIRST_LEVEL;
                    ratio *= 4f;
                }
               
                int targetTex = objectData.orgTex[polygonId][offset];
               
                if (targetTex != objectData.curTex[polygonId]) {

                    changedObjects.set(lastObjectId);
                    objectData.curTex[polygonId] = targetTex;
                    objectData.pm.setPolygonTexture(polygonId, targetTex);
                }
            }
        }
       
        for (int i = changedObjects.nextSetBit(0); i >= 0; i = changedObjects.nextSetBit(i+1)) {
            world.getObject(i).recreateTextureCoords();
        }
    }
   
    /** resets all textures to their original states
     * i.e. disables mip mapping */
    public void reset() {
        for (ObjectData objectData : mipMapData.values())
            objectData.reset();
    }
   
    /**
     * useful for cleanup purposes
     * (i.e you dont want call TextureManager.flush() for whatever reason)
     */
    public void dispose() {
        for (String textureName : createdTextures) {
            if (tm.containsTexture(textureName))
                tm.replaceTexture(textureName, tm.getDummyTexture());
            else Logger.log("couldnt find texture " + textureName, Logger.WARNING);

        }
    }
   
    private float calculateArea(SimpleVector... v) {
        float area = 0f;
        for (int i = 0; i < v.length; i++) {
            int j = (i + 1) % v.length;
            area += v[i].x * v[j].y;
            area -= v[i].y * v[j].x;
        }
        area /= 2.0;
        return (area < 0) ? -area : area;
    }
   
    /** data structure to store polygon data per object */
    private class ObjectData {
        private final Object3D object3d;
        private final PolygonManager pm;
       
        private final int[][] orgTex;
        private final int[] curTex;
        private final float[] textureAreas;
       
        private ObjectData(Object3D object3d) {
            this.object3d = object3d;
            pm = object3d.getPolygonManager();
           
            orgTex = new int[pm.getMaxPolygonID()][LEVELS];
            curTex = new int[pm.getMaxPolygonID()];
           
            textureAreas = new float[pm.getMaxPolygonID()];
           
            createMipMaps(object3d);
           
            for (int i = 0; i < orgTex.length; i++) {
                int textureId = pm.getPolygonTexture(i);
               
                orgTex[i][0] = textureId;
                for (int offset = 1; offset< LEVELS; offset++) {
                    orgTex[i][offset] = textureIds.get(getTextureName(textureId, offset));
                }

                curTex[i] = orgTex[i][0];
               
                float uvArea = calculateArea(pm.getTextureUV(i, 0), pm.getTextureUV(i, 1), pm.getTextureUV(i, 2));
                Texture texture = tm.getTextureByID(textureId);
                textureAreas[i] = uvArea * texture.getWidth() * texture.getHeight();
            }
        }
       
        private void reset() {
            boolean changed = false;
            for (int polygonId = 0; polygonId < orgTex.length; polygonId++) {
                int originalTextureId = orgTex[polygonId][0];
               
                if (originalTextureId != curTex[polygonId]) {
                    changed = true;
                    pm.setPolygonTexture(polygonId, originalTextureId);
                    curTex[polygonId] = originalTextureId;
                }
            }
            if (changed)
                object3d.recreateTextureCoords();
        }
    }
   
    /**
     * small helper class to access a texture's texels.
     */
    private class TexelGrabber implements ITextureEffect {
       
        private int[] texels = null;
       
        public void init(Texture tex) {}
       
        public void apply(int[] dest, int[] source) {
            texels = source;
        }
    }
}

1898
Projects / aptal karga (foolish crow)
« on: March 28, 2006, 12:42:59 am »
i've just noticed Egon has replaced the screenshots at projects page. i'm quite happy with them :) ehm especially after those quasimodo things..  :roll:

btw, an area based mip mapping (mip map level per polygon is decided according to the area of polygon on screen / area of polygon on initial texture) is active and default at the moment, m to switch mip mapping on/off, M to switch between area and distance based mip mapping

it's still work in progress: its effect and performance will be slightly improved but (at least to me) its effect is like a dream at the moment

Code: [Select]
r a f t

1899
Support / texture aliasing
« on: March 25, 2006, 12:33:19 am »
i first thought the non performance slow down is caused by this: the cost of checking lots of polygons' distance to camera is balanced by copying less pixels of texture to FrameBuffer. i dont know jPCT's internals but it should somehow copy some portion of texture to FrameBuffer

i think the same about default behaviour, i will do it after tuning MipMapper. i guess i must read something about how hardware does that ;)

Code: [Select]
r a f t

1900
Projects / "Visual" JPCT
« on: March 25, 2006, 12:16:56 am »
Crate, why do you plan to use swt instead of awt ? you're true for mixing awt and swing has some problems, but if necessary you can stick to awt. it will run well with AWTGLRenderer as the name implies. life is easier with pure java components.

as you know, the major problem with awt swing combination is awt components are drawn on top swing ones regardless of their z-order. but this doesnt mean you can not use swing features: JLayeredPane (and hence JDesktopPane) effectively layouts and z-orders awt components, which means you can still use JDesktopPane and JInternalFrames for MDI. only titles bars and borders of internal frames will be hidden below awt components. you're working on a helper application, not a commercial one that will go to customer so it doesnt matter so much IMHO. if you care you can still implement your own internal frames on top of awt: basicly they're nothing but dragable and click sensitive components

this is what a thought at a glance

Code: [Select]
r a f t

1901
Support / texture aliasing
« on: March 24, 2006, 11:27:51 pm »
hey, i've asked for an idea, you've come with an implementation :) :D :lol:

i've adapted your MipMapper to karga. it's off by default, can be turned on/off by the key M. filtering also can be turned on/off by the key F. OGSS_FAST is default at the moment.

surprisingly (at least for me) while running it has little or no impact on overall performance and it reduces aliasing a lot. well not as much as oversampling but it performs quite better than oversampling. for the first use it takes a while to create initial images but that's all. i guess with some fine tuning (non linear distance etc) it will perform quite well

thanks a lot Egon :wink:

Code: [Select]
r a f t

1902
Support / Sound?
« on: March 24, 2006, 05:54:30 pm »
it's an option but at the moment i prefer staying with pure java.

1903
Projects / aptal karga (foolish crow)
« on: March 24, 2006, 02:31:54 am »
to deal with texture aliasing i've added support for over sampling: use shift and +/- to switch among modes. i dont know who has a such monstrous fast machine but it's there to use :wink:

Code: [Select]
r a f t

1904
Projects / Technopolies
« on: March 24, 2006, 02:28:12 am »
sory to hear that, both for you, your family and Technopolies :roll:
i wish you all good luck, take care

sometimes coding takes me out of my depressed mood..
anyway, hope to see you here again soon

Code: [Select]
r a f t

1905
Support / Sound?
« on: March 23, 2006, 09:00:03 pm »
how do you adjust sound effects to distance and direction with java sound ? by 'manually' calculating pan and gain values ?

is there any lightweight pure java alternative to java sound ? i dont want jmf since it's a quite fat api and people say it's slow

ps: i know almost nothing about sound programming

Code: [Select]
r a f t

Pages: 1 ... 125 126 [127] 128 129 ... 133