Pixel eines BufferedImage bearbeiten (Performance)

Marlon

Mitglied
Hallo!
Ein sich in der Open Beta befindendes Echtzeitrollenspiel läuft flüssig mit relativ konstanten 40 fps.
Nun soll das bestehende Programm um Beleuchtungseffekte (Lichter und Schatten) erweitert werden und somit habe ich einen ersten Ansatz implementiert, welcher die Pixel eines BufferedImages (das Offscreen Image, welches über den gesamten Bildschirmbereich gelegt wird und Dunkelheit, Schatten und Lichter darstellen soll) auslesen und bearbeiten soll.
Allerdings führt folgende Einbindung dazu, dass das Spiel nicht mehr gleichmässig läuft (FPS nicht mehr konstant) und insgesamt viel langsamer:

Java:
	private void updateLightImage() {
		int[] pixel = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
		
        for(int p=0;p<pixel.length;p++) {
            pixel[p]=(brightness << 24) | (0 << 16) | (0 << 8) | 0;
        }
	}

Weiss jemand, wie man dieses Problem umgehen/besser lösen könnte. Oder hat jemand andere Tipps zu diesem Thema?
Vielen Dank im Vorraus!
Marlon
 

Marco13

Top Contributor
Hm ... ???:L Erstens müßte das ja nur gemacht werden, wenn 'brightness' sich ändert, und zweitens... warum manuell und Pixelweise? Ein einfaches
Code:
Graphics2D g = image.createGraphics();
g.setColor(colorWithBrightness);
g.fillRect(0,0,w,h);
g.dispose();
sollte es doch tun!?
 
S

SlaterB

Gast
das wäre mit Begründung überzeugender, wie soll das grundsätzlich betrachtet schneller sein?,
muss das nicht letztlich auch die Pixel-Werte des Arrays verändern? da wird ja wohl kaum System.arrayCopy() oder ähnliches intern helfen,
stattdessen noch der Overhead der Methodenaufrufe, des Graphics-Objekt usw.

das neue Pixel '(brightness << 24) | (0 << 16) | (0 << 8) | 0' kann man in diesem Fall vielleicht nur einmal ausrechnen,
aber das sieht mir eh nur nach einem Beispiel aus, und solcher Kleinkram wird nicht die Welt retten,

ich kann nicht wirklich hier etwas beitragen aber wenn dann ist so ein BufferedImage an sich die Grundquelle alles Langsamkeit und mit diesen Java-Mitteln nicht schnell zu bekommen?
 
Zuletzt bearbeitet von einem Moderator:

Marco13

Top Contributor
BufferedImages (vor allem die int-basierten) verwenden intern "Magie" (viel, viel, schwarze und kryptische Magie :shock: ). Nach außen hin wird glaubich unter dem Namen "Managed Images" zusammengefasst. Innen sind das höchst implementierungsspefifische Pipelines für die Maloperationen und ein (Grafik)speichermanagement, das auf Dinge zurückgreift, die von einem int[] Array schon sehr weit weg ist. Natürlich ist das immernoch kein "fundiertes Argument" dafür, dass ein fillRect schneller sein muss, aber... nach einigem Wühlen im Sun-Quellcode bin ich mir ganz unfundiert und subjektiv ziemlich sicher, dass das so ist :) Kommt im Zweifelsfall auf einen Versuch an...

EDIT: Um es zumindest noch etwas weiter zu begründen:
Eine (leider sehr Alte) Quelle für die Bedenken: BufferedImage as Good as Butter, Part II | Java.net
Eine etwas neuere: Java Graphics: Code Snippets, Musings, and Discoveries: Images: Managed Images
Und eine von jemandem, der aus Erfahrung spechen dürfte: Java Image Processing - Managed Images and Performance

Der (etwas schwammige und grob vereinfachte, nagel' mich darauf nicht fest) Grundtenor ist, dass wenn man sich erstmal den Speicherbereich des Bildes für direkten Zugriff (als int[] Array) geholt hat, Sun intern nicht mehr so viele Möglichkeiten hat, das Bild z.B. im VRAM zu halten, und das eben die Performance in den Keller drücken kann. Aber wie gesagt, das war nur ein Hinweis - Ausprobieren und ggf. Sun-Code lesen könnte da noch mehr Einsichten oder Sicherheit bringen.
 
Zuletzt bearbeitet:

Marlon

Mitglied
Hm ... ???:L Erstens müßte das ja nur gemacht werden, wenn 'brightness' sich ändert, und zweitens... warum manuell und Pixelweise? Ein einfaches
Code:
Graphics2D g = image.createGraphics();
g.setColor(colorWithBrightness);
g.fillRect(0,0,w,h);
g.dispose();
sollte es doch tun!?

Jetzt wird es interessant. :)
Ich muss ja erstmal alle Pixel "dunkel" machen (siehe brightness), um dann anschliessend die Stellen an denen Lichter stehen aufzuhellen, also den Alpha zu verändern.

Bilder sagen mehr als tausend Worte: http://www.asantee.net/ethanon/screenshots/eth075_3.jpg

Vielleicht gibt es aber auch tatsächlich eine Möglichkeit, dies eleganter zu lösen (ohne vorher jeden einzelnen Pixel anzupacken).

Edit: Ich möchte noch hinzufügen dass ich bei dem Spiel jedes Bild als BufferedImage UND als VolatileImage im Speicher halte. Gezeichnet werden natürlich (ultraschnell, mit bis zu 240 FPS) lediglich die VolatileImages, jedoch habe ich noch nicht herausgefunden ob und wenn dann wie es möglich ist, diese VolatileImages direkt zu verändern, so dass die Performance nicht in den Keller geht.

Edit2: Das Bild ist übrigens nicht von dem Spiel noch aus meiner Hand, es handelt sich um eine 2D Engine, welche ich im Netz gefunden habe und leider noch nicht fertiggestellt worden ist.
 
Zuletzt bearbeitet:
S

SlaterB

Gast
hübsches Bild,


nur um noch eine offensichtliche Frage zu stellen:
wie entstehen denn dort die Lichtquellen und die Schatten oder ist das bisher nur fest vorgegeben?

wenn das alles schon existiert (und nicht gerade deine Frage ist), dann sind das doch 100x aufwendigere Methoden als jetzt 5 Pixel zu ändern
 

Marco13

Top Contributor
Analog zum oben beschriebenen Verfahren würden sich für solche Punktförmigen Lichtquellen, die mit der Entfernung dunkler werden, dann vermutlich raidale "GradientPaint" anbieten...
 

Marlon

Mitglied
Ich habe mich nun länger und intensiver mit dem oben genannten Problem befasst und nach Lösungen gesucht, ein BufferedImage (bzw. VolatileImage) ohne grossartigen Performanceverlust bei jedem Frameschritt zu bearbeiten und anzuzeigen.
Leider erfolglos!
Falls noch jemand weiter weiss oder sich mal intensiver mit dem Thema beschäftigt hat bin ich ihm unendlich dankbar, wenn er mir ein paar Hilfestellungen geben könnte!
 

schalentier

Gesperrter Benutzer
Also ich vermute, wenn du wirklich jedes Pixel beleuchten willst (egal mit welchem Algorithmus), geht das in Echtzeit nur mit einem Shader in der Grafikkarte (also wenn du Java nimmst, OpenGL und GSGL).

Was du versuchen kannst sind Lightmaps. Also vorberechnete Tiles, die nur Alphainformationen enthalten und ueber die eigentlichen Textur-Tiles gezeichnet werden. Die generierst du einmalig am Anfang (z.B. 128 Stueck mit steigendem Alphawert) und speicherst pro Tile einen Helligkeitswert, anhand welchem du eine entsprechende Lightmap zeichnest. Aber auch hier wird wohl Java2D/Swing recht schnell in die Knie gehen.
 

Empire Phoenix

Top Contributor
Versuch mal folgendes:
ein halbtransparentes schwarz weeiß bild, das du über dein hauptbufferdeimage renderst. Dieses kann dann auch eine geringere auflösung haben was schonmal performance sparen sollte.
 

Marco13

Top Contributor
Ich kapier's nicht. Das hier malt ein Bild im dunkeln, und die Maus ist eine Taschenschlampe...
Java:
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.Point;
import java.awt.RadialGradientPaint;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


class LightEffectPanel extends JPanel implements MouseMotionListener
{   
    private Point point = new Point(0,0);
    private BufferedImage image;
    
    public LightEffectPanel()
    {
        BufferedImage i = null;
        try {
            i = ImageIO.read(new File("image.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        image = new BufferedImage(i.getWidth(), i.getHeight(), 
                BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = image.createGraphics();
        g.drawImage(i,0,0,null);
        g.dispose();
        addMouseMotionListener(this);
    }
    
    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;
        g.drawImage(image, 0,0,null);
        
        g.setComposite(AlphaComposite.SrcOver);
        Point2D center = new Point2D.Float(point.x, point.y);
        float[] dist = {0.0f, 1.0f};
        Color[] colors = {new Color(255,255,255,0), new Color(16,16,16,230) };
        RadialGradientPaint p =
             new RadialGradientPaint(
                center, 100, dist, colors, CycleMethod.NO_CYCLE);
        g.setPaint(p);
        g.fillRect(0,0,getWidth(),getHeight());
    }

    @Override
    public void mouseDragged(MouseEvent e) {
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        point = e.getPoint();
        repaint();
    }
}

class LightEffectTest
{
    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new LightEffectTest();
            }
        });
    }
    
    
    public LightEffectTest()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new LightEffectPanel());
        f.setSize(600,600);
        f.setVisible(true);
    }
    
}
Was genau meinst du? :bahnhof:
 

Marlon

Mitglied
Danke für den Code, hat mir sehr geholfen!
Für ein einzelnes Licht funktioniert das ganze auch super und läuft recht fix, allerdings wird es problematisch, wenn mehrere Lichter (Kerzen, Lagerfeuer usw...) auf dem Bildschirm positioniert werden, da sich diese dann gegenseitig verdunkeln (es werden mehrere Bilder übereinander gezeichnet).
Gibt es eine Möglichkeit, meherere Lichtquellen mit diesem Verfahren darzustellen?
 

Marco13

Top Contributor
So ähnlich, nur schnell hingetippt, geht vielleicht auch eleganter...
Java:
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.Point;
import java.awt.RadialGradientPaint;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


class LightEffectPanel2 extends JPanel implements MouseMotionListener
{
    private Point point = new Point(0,0);
    private BufferedImage image;
    private BufferedImage shadow;

    public LightEffectPanel2()
    {
        BufferedImage i = null;
        try {
            i = ImageIO.read(new File("image.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        image = new BufferedImage(i.getWidth(), i.getHeight(),
                BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = image.createGraphics();
        g.drawImage(i,0,0,null);
        g.dispose();

        shadow = new BufferedImage(i.getWidth(), i.getHeight(),
                BufferedImage.TYPE_INT_ARGB);

        addMouseMotionListener(this);
    }

    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;
        g.drawImage(image, 0,0,null);

        drawLights();

        g.drawImage(shadow, 0,0, null);
    }

    private void drawLights()
    {
        Graphics2D g = shadow.createGraphics();
        g.setComposite(AlphaComposite.Src);
        g.setColor(new Color(0,0,16,240));
        g.fillRect(0,0,getWidth(),getHeight());

        drawLight(g, new Point(100,100));
        drawLight(g, point);

        g.dispose();
    }

    private void drawLight(Graphics2D g, Point pt)
    {
        float radius = 100;
        g.setComposite(AlphaComposite.DstOut);
        Point2D center = new Point2D.Float(pt.x, pt.y);
        float[] dist = {0.0f, 1.0f};
        Color[] colors = {new Color(255,255,255,255), new Color(0,0,0,0) };
        RadialGradientPaint p =
             new RadialGradientPaint(
                center, radius, dist, colors, CycleMethod.NO_CYCLE);
        g.setPaint(p);
        g.fillOval(pt.x-(int)radius,pt.y-(int)radius,(int)radius*2,(int)radius*2);
    }



    @Override
    public void mouseDragged(MouseEvent e) {
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        point = e.getPoint();
        repaint();
    }
}

class LightEffectTest2
{
    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new LightEffectTest2();
            }
        });
    }


    public LightEffectTest2()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new LightEffectPanel2());
        f.setSize(600,600);
        f.setVisible(true);
    }

}

EDIT: Die main hatte noch den alten Test gestartet. Jetzt stimmts. Danke an Fu3L für den Hinweis.
 
Zuletzt bearbeitet:

Marlon

Mitglied
Hei super!
Zwar geht die Prozessorleistung total in den Keller, wenn das BufferedImage bearbeitet wird, jedoch habe ich deine hier beschriebene Funktionalität einfach auf ein VolatileImage angewendet und es funktioniert!
Die Menge der Lichter im Spiel (jedes Monster trägt eine kleine Fackel mit sich rum) spielt dabei gar keine Rolle.
Vielen vielen Dank!
 

Marco13

Top Contributor
Ja, wie gesagt, war nur ein schneller Test. Wenn's zuuu langsam wird, kann man mal schauen, wo man da noch was optimieren kann.
 

Marlon

Mitglied
Eine abschliessende Frage noch: Weisst du wie man das Programm umschreiben muss, damit die Lichtquellen nun auch eine Farbe ausstrahlen, das heisst den Leuchtkreis farblich verändern?
 

Marco13

Top Contributor
Ja, irgendwann wird's halt kompliziert. Grob was in der Richtung kann man mit
Java:
    private void drawLights()
    {
        Graphics2D g = shadow.createGraphics();
        g.setComposite(AlphaComposite.Src);
        g.setColor(new Color(0,0,16,240));
        g.fillRect(0,0,getWidth(),getHeight());

        drawLight(g, new Point(100,100), Color.WHITE);
        drawLight(g, point, new Color(250,190,0));


        g.dispose();
    }

    private void drawLight(Graphics2D g, Point pt, Color lightColor)
    {
        int radius = 100;
        Point2D center = new Point2D.Float(pt.x, pt.y);
        float[] dist = {0.0f, 1.0f};
        Color[] colors = {
            new Color(
                lightColor.getRed(),
                lightColor.getGreen(),
                lightColor.getBlue(),255),
            new Color(0,0,0,0) };
        RadialGradientPaint p =
             new RadialGradientPaint(
                center, radius, dist, colors, CycleMethod.NO_CYCLE);
        g.setPaint(p);
        g.setComposite(AlphaComposite.DstOut);
        g.fillOval(pt.x-radius,pt.y-radius,radius*2,radius*2);
        g.setComposite(AlphaComposite.SrcOver);
        g.fillOval(pt.x-radius,pt.y-radius,radius*2,radius*2);
    }
erreichen, aber eigentlich sollten sich die Lichthelligkeiten ja addieren.... da müßte man sich vielleicht was ausgefeilteres überlegen.
 

Marlon

Mitglied
Ja danke erstmal! Leider führt das tatsächlich nicht zum erwünschten Ergebnis, da ja somit über den Hintergrund "drübergemalt" und somit verdeckt wird.

Vermutlich müsste man den Hintergrund gesondert anpacken und an den beleuchteten Stellen Farben "wegnehmen". Leider weiss ich nicht wie man das performant am besten angeht, da ich ja nicht wieder dahin gehen möchte jeden Pixel einzelnd zu bearbeiten.
 

Marco13

Top Contributor
Du solltest dir selbst klarmachen, was du willst, und wie das ganze aussehen soll.... Und das dann möglichst genau beschreiben. Rote Gegenstände sehen in grünem Licht schwarz aus, und Grüne weiß. Klingt komisch, ist aber so. Vielleicht muss man da noch irgendwo eine ColorConvertOp (Java Platform SE 6) einklinken, aber wie man das jetzt "physikalisch korrekt" berechnet (und das muss es zumindest ansatzweise sein, damit es es plausibel aussieht) weiß ich aus dem Stegreif auch nicht. Die Methode [c]void letMyRenderedStuffLookCool()[/c] gibt's halt in der Form noch nicht.
 

Marco13

Top Contributor
NOCH nicht.

Wieder einmal frage ich mich, warum ich das mache. Aber selbst deine zu erwartende Antwort ("Das ist so langsam ;( !", "Das braucht so viel Speicher ;( !", "Das sollte ein bißchen rötlicher sein ;( !") wird mich nicht davon abhalten, sowas in Zukunft weiterhin zu tun.

Java:
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.Point;
import java.awt.RadialGradientPaint;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;
import java.util.*;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


class LightEffectPanel4 extends JPanel implements MouseMotionListener
{
    private Point point = new Point(0,0);

    private BufferedImage inImage;
    private BufferedImage lightsImage;
    private BufferedImage lightImage;
    private BufferedImage outImage;

    public LightEffectPanel4()
    {
        inImage = loadInputImage();
        int w = inImage.getWidth();
        int h = inImage.getHeight();
        lightsImage = new BufferedImage(w,h,
                BufferedImage.TYPE_INT_ARGB);
        lightImage = new BufferedImage(w,h,
                BufferedImage.TYPE_INT_ARGB);
        outImage = new BufferedImage(w,h,
                BufferedImage.TYPE_INT_ARGB);

        addMouseMotionListener(this);
    }

    private BufferedImage loadInputImage()
    {
        BufferedImage i = null;
        try {
            i = ImageIO.read(new File("img.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        BufferedImage image = new BufferedImage(i.getWidth(), i.getHeight(),
                BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = image.createGraphics();
        g.drawImage(i,0,0,null);

        //g.setColor(Color.WHITE);
        //g.fillRect(0,0,i.getWidth(),i.getHeight());

        g.dispose();
        return image;
    }


    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;
        drawLights();
        multiply(inImage, lightsImage, outImage);
        g.drawImage(outImage, 0,0,null);
    }

    private void drawLights()
    {
        Graphics2D g = lightsImage.createGraphics();
        g.setColor(Color.BLACK);
        g.fillRect(0,0,lightsImage.getWidth(),lightsImage.getHeight());
        g.dispose();

        drawLight(point, new Color(255,230,128));
        drawLight(new Point(190,210), Color.RED);
        drawLight(new Point(160,180), Color.GREEN);
        drawLight(new Point(220,180), Color.BLUE);
    }

    private void drawLight(Point pt, Color color)
    {
        int radius = 100;
        Point2D center = new Point2D.Float(pt.x, pt.y);
        Color black = new Color(0,0,0,0);
        int steps = 10;
        float[] dist = new float[steps];
        Color[] colors = new Color[steps];
        boolean quadratic = true;
        for (int i=0; i<steps; i++)
        {
            float x = (float)i / (steps-1);
            dist[i] = x;
            float y = x;
            if (quadratic)
            {
                y *= x;
            }
            colors[i] = interpolate(color, black, y);
        }
        RadialGradientPaint p =
             new RadialGradientPaint(
                center, radius, dist, colors, CycleMethod.NO_CYCLE);

        Graphics2D g = lightImage.createGraphics();
        g.setColor(Color.BLACK);
        g.fillRect(0,0,lightImage.getWidth(),lightImage.getHeight());
        g.setPaint(p);
        g.fillOval(pt.x-radius,pt.y-radius,radius*2,radius*2);
        g.dispose();
        add(lightsImage, lightImage, lightsImage);
    }



    @Override
    public void mouseDragged(MouseEvent e) {
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        point = e.getPoint();
        repaint();
    }


    private static Color interpolate(Color c0, Color c1, float t)
    {
        int a0 = c0.getAlpha();
        int r0 = c0.getRed();
        int g0 = c0.getGreen();
        int b0 = c0.getBlue();
        int a1 = c1.getAlpha();
        int r1 = c1.getRed();
        int g1 = c1.getGreen();
        int b1 = c1.getBlue();
        int da = a1-a0;
        int dr = r1-r0;
        int dg = g1-g0;
        int db = b1-b0;
        int a = (int)(a0 + da * t);
        int r = (int)(r0 + dr * t);
        int g = (int)(g0 + dg * t);
        int b = (int)(b0 + db * t);
        return new Color(r,g,b,a);
    }

    private static int[] getData(BufferedImage i)
    {
        Raster raster = i.getRaster();
        DataBuffer dataBuffer = raster.getDataBuffer();
        if (!(dataBuffer instanceof DataBufferInt))
        {
            throw new IllegalArgumentException(
                "Image does not have a DataBufferInt");
        }
        DataBufferInt dataBufferInt = (DataBufferInt)dataBuffer;
        int data[] = dataBufferInt.getData();
        return data;
    }

    private static int getA(int argb) { return (argb >> 24) & 0xFF; }
    private static int getR(int argb) { return (argb >> 16) & 0xFF; }
    private static int getG(int argb) { return (argb >>  8) & 0xFF; }
    private static int getB(int argb) { return (argb >>  0) & 0xFF; }
    private static int getARGB(int a, int r, int g, int b)
    {
        return (a << 24) | (r << 16) | (g << 8)  | (b << 0);
    }

    private static void multiply(BufferedImage i0, BufferedImage i1, BufferedImage result)
    {
        int data0[] = getData(i0);
        int data1[] = getData(i1);
        int dataResult[] = getData(result);

        int w = i0.getWidth();
        int h = i0.getHeight();
        for (int x=0; x<w; x++)
        {
            for (int y=0;y<h; y++)
            {
                int argb0 = data0[x+y*w];
                int a0 = getA(argb0);
                int r0 = getR(argb0);
                int g0 = getG(argb0);
                int b0 = getB(argb0);
                int argb1 = data1[x+y*w];
                int a1 = getA(argb1);
                int r1 = getR(argb1);
                int g1 = getG(argb1);
                int b1 = getB(argb1);
                int ar = (a0*a1) >> 8;
                int rr = (r0*r1) >> 8;
                int gr = (g0*g1) >> 8;
                int br = (b0*b1) >> 8;
                int argb = getARGB(ar, rr, gr, br);
                dataResult[x+y*w] = argb;
            }
        }
    }

    private static void add(BufferedImage i0, BufferedImage i1, BufferedImage result)
    {
        int data0[] = getData(i0);
        int data1[] = getData(i1);
        int dataResult[] = getData(result);

        int w = i0.getWidth();
        int h = i0.getHeight();
        for (int x=0; x<w; x++)
        {
            for (int y=0;y<h; y++)
            {
                int argb0 = data0[x+y*w];
                int a0 = getA(argb0);
                int r0 = getR(argb0);
                int g0 = getG(argb0);
                int b0 = getB(argb0);
                int argb1 = data1[x+y*w];
                int a1 = getA(argb1);
                int r1 = getR(argb1);
                int g1 = getG(argb1);
                int b1 = getB(argb1);
                int ar = Math.min(255, a0+a1);
                int rr = Math.min(255, r0+r1);
                int gr = Math.min(255, g0+g1);
                int br = Math.min(255, b0+b1);
                int argb = getARGB(ar, rr, gr, br);
                dataResult[x+y*w] = argb;
            }
        }
    }


}

class LightEffectTest4
{
    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new LightEffectTest4();
            }
        });
    }


    public LightEffectTest4()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new LightEffectPanel4());
        f.setSize(600,600);
        f.setVisible(true);
    }

}
 

Marlon

Mitglied
Ich danke dir vielmals für deine erneute Hilfe!!!
Das ist ja schon eine ganze Menge und daraus lässt sich sicher etwas schöpfen!
Aber ich muss schliesslich ehrlich sein: Für meine Zwecke ist das zu langsam :( ..
Bei dem Vorgang auf jeden Pixel zuzugreifen geht die Performance in die Knie.
Ich hoffe ich werde in den nächsten Tagen etwas hinbekommen, ansonsten fahre ich das nächste Update erstmal ohne Farben.
Nochmal DANKE! :)
Marlon
 

Marco13

Top Contributor
Je nachdem, was langsam ist, könnte man noch ein bißchen was (oder ggf. sehr viel) einsparen. Das hängt von der größe der Lichter ab. Im Moment werden die Lichter in ein Bild gemalt, das so groß ist, wie das original. Eigentlich müßte das 'lightImage' aber nur radius*radius groß sein, und dann eben an die passende Stelle eingefügt. Wie groß sind die Lichter denn? (Und um wie viele Lichter geht es?)

Ansonsten behaupte ich mal, dass man es mit reinem Java3D (d.h. ohne OpenGL etc.) in dieser Form nicht viel schneller bekommt.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
BraunBerry Java Game Pixel "einfärben" Spiele- und Multimedia-Programmierung 6
T Probleme bei "Pixel-Fighting"-Spiel: Unausgewogene Mannschaften??? Spiele- und Multimedia-Programmierung 4
Q Mehr objekte darstellen als Pixel vorhanden Spiele- und Multimedia-Programmierung 6
Androbin Pixel-genaue Kollisionserkennung Spiele- und Multimedia-Programmierung 5
J Bestimmte Pixel transparent erscheinen lassen Spiele- und Multimedia-Programmierung 5
M pixel auslesen in JOGLE Spiele- und Multimedia-Programmierung 3
B Java Pixel Malen Spiele- und Multimedia-Programmierung 3
Kr0e OpenGL .. Pixel Buffer Objekt oder Frame Buffer Object? Spiele- und Multimedia-Programmierung 2
Steev LWJGL: org.lwjgl.LWJGLException: Pixel format not accelerated Spiele- und Multimedia-Programmierung 9
M pixel perfect collision detection bei rotierenden Bildern Spiele- und Multimedia-Programmierung 13
G Pixel setzen mit TYPE_INT_ARGB Spiele- und Multimedia-Programmierung 10
D cm in pixel Spiele- und Multimedia-Programmierung 37
R int[] der Pixel aus PNG oder JPG ? Spiele- und Multimedia-Programmierung 2
P Bild, Pixel- / Bereichsfarbe auslesen Spiele- und Multimedia-Programmierung 12
G Pixel Häufigkeiten entsprechent einfärben Spiele- und Multimedia-Programmierung 6
K Einzelne Pixel in einem Bild lesen Spiele- und Multimedia-Programmierung 5
S BMP-Bild Pixel für Pixel bearbeiten Spiele- und Multimedia-Programmierung 1
V Tranzparente Pixel Spiele- und Multimedia-Programmierung 5
S Pixel zeichnen Spiele- und Multimedia-Programmierung 3
G 2 dim. Pixel Array in AWT? Spiele- und Multimedia-Programmierung 7
N Seltsame Exception bei Code eines Spiele-Tutorials Spiele- und Multimedia-Programmierung 6
R Ideen für die Backend-Entwicklung eines Games gesucht Spiele- und Multimedia-Programmierung 8
A Programmieren eines Memorys mit Java (in Eclipse) Spiele- und Multimedia-Programmierung 5
T Position eines Image verändern mithilfe eines Timers Spiele- und Multimedia-Programmierung 6
E Programmierung eines 2.5D Point&Click Adventures ohne Spieleengine machbar? Spiele- und Multimedia-Programmierung 14
K Click innerhalb eines 45° gekippten Rechtecks Spiele- und Multimedia-Programmierung 9
J LibGdx_3D: Klamotten eines Charakters modifizieren Spiele- und Multimedia-Programmierung 2
K Erstellen eines Fotoalbums mit Java Spiele- und Multimedia-Programmierung 8
R Fehler beim Laden eines 2D-Bildes Spiele- und Multimedia-Programmierung 3
L OpenGL TransformationMatrix eines Flugzeugs Spiele- und Multimedia-Programmierung 2
M Programmierung eines "Fantasy Rollenspiels" Spiele- und Multimedia-Programmierung 5
E Laufanimation eines Sprites Spiele- und Multimedia-Programmierung 6
Finalspace Entwicklung eines Jump & Run Spiels Video-Tutorial Spiele- und Multimedia-Programmierung 12
T Hintergrundmusik eines Spiels mit Hilfe von JLayer Spiele- und Multimedia-Programmierung 12
M Cylinder anhand eines Vektors ausrichten (Java3d) Spiele- und Multimedia-Programmierung 0
M bewegen eines Objektes Spiele- und Multimedia-Programmierung 2
U Hilfe bei Implementierung eines PointSounds in Java3D Spiele- und Multimedia-Programmierung 1
gamebreiti Index eines Elements einer ArrayList abfragen Spiele- und Multimedia-Programmierung 1
X "Rebuffen" - Messen der Zeit eines Timers Spiele- und Multimedia-Programmierung 3
S Design eines Schachspiels Spiele- und Multimedia-Programmierung 3
S Mausklicks innerhalb eines JFrames/SWTBrowser ohne richtige Maus simulieren Spiele- und Multimedia-Programmierung 6
F Programmierung eines Bots Spiele- und Multimedia-Programmierung 23
A Wann ist ein Punkt inerhalb eines Polygons? Spiele- und Multimedia-Programmierung 2
F LWJGL Problem mit Erstellen eines Objekts und der Kamera Spiele- und Multimedia-Programmierung 5
R Drehen eines Bildes relativ zur Mauszeigerposition Spiele- und Multimedia-Programmierung 2
M Pattern zur Auswahl eines Objektes anhand vieler Kriterien Spiele- und Multimedia-Programmierung 2
H Skalierung eines Polygons ohne das es verschoben wird Spiele- und Multimedia-Programmierung 3
R Triangulation eines komplexen Polygons Spiele- und Multimedia-Programmierung 4
L Lwjgl Darstellung eines Kreises im Raum Spiele- und Multimedia-Programmierung 3
G Rotieren eines Objekts (2D) Spiele- und Multimedia-Programmierung 8
F nur Ausschnitt eines Image zeichnen Spiele- und Multimedia-Programmierung 9
S Umfang eines Polygons erzeugen Spiele- und Multimedia-Programmierung 1
D Highscoreliste eines Applets funktioniert online nicht Spiele- und Multimedia-Programmierung 4
W CannotRealizeException (jmf) beim abspielen eines liedes Spiele- und Multimedia-Programmierung 3
F Meine Aufgabe: Client-Server am Beispiel einer Implementation eines Tic-Tac-Toe Netzwerkspieles Spiele- und Multimedia-Programmierung 7
D Koordinaten eines 2D Sprites Spiele- und Multimedia-Programmierung 2
B Teile eines Bildes laden - BitBlk und drawImage Spiele- und Multimedia-Programmierung 3
S Interpolation eines Bildes Spiele- und Multimedia-Programmierung 6
S Problem beim laden eines Bildes in einer Methode Spiele- und Multimedia-Programmierung 14
N Bildposition innerhalb eines anderen Bildes ermitteln Spiele- und Multimedia-Programmierung 2
G rotation eines würfels Spiele- und Multimedia-Programmierung 9
G Bewegung eines Grafikobjektes Spiele- und Multimedia-Programmierung 7
A Programmieren eines Bruchrechners Spiele- und Multimedia-Programmierung 3
H Decke zeichnen mit Hilfe eines Polygons Spiele- und Multimedia-Programmierung 2
J Rotieren eines 2D Images endet in Java heap space Error Spiele- und Multimedia-Programmierung 15
W Affine Transformation, Rotieren eines Objekts Spiele- und Multimedia-Programmierung 2
S fließende/bewegende Striche eines Auswahlrechtecks Spiele- und Multimedia-Programmierung 9
A Bounds eines gedrehten Objekts berechnen Spiele- und Multimedia-Programmierung 30
T Erstellen eines ausdruckbaren Formulars Spiele- und Multimedia-Programmierung 5
T Umsetzung eines 2D Jump and Runs Spiele- und Multimedia-Programmierung 7
T Brightness eines Bildes [DRINGEND] Spiele- und Multimedia-Programmierung 2
S Java3D - mehrere Instanzen eines Geometrieobjektes erzeugen Spiele- und Multimedia-Programmierung 3
ARadauer Grauwerte eines jpg ermitteln Spiele- und Multimedia-Programmierung 4
A Anzeigen eines Grapfen Spiele- und Multimedia-Programmierung 13
R Die korrekte Breite/Höhe eines Bildes wird nicht erkannt. Spiele- und Multimedia-Programmierung 2
S Problem bzgl. Umsetzung eines Rollenspiel Spiele- und Multimedia-Programmierung 6
M Ausschneiden eines Bereichs / Avatar Spiele- und Multimedia-Programmierung 2
G Ermitteln eines Punktes in einer anderen TransformGroup Spiele- und Multimedia-Programmierung 2
M Frage eines Anfängers Spiele- und Multimedia-Programmierung 3
DEvent [2D] Farbe bestimmten Pixels eines Bildes ändern Spiele- und Multimedia-Programmierung 3
V Wie berechnet man das Bild eines Schwarzen Loches in Java? Spiele- und Multimedia-Programmierung 10
G Breite eines Strings Spiele- und Multimedia-Programmierung 2
S Text an einer Seite eines Cubes Spiele- und Multimedia-Programmierung 7
F Image eines bestimmten Bereichs eines JPanels erstellen Spiele- und Multimedia-Programmierung 4
N Grafik als Hintergrund eines Rechtecks verwenden? Spiele- und Multimedia-Programmierung 4
N Rundenstrategiespiel - Problem beim Drehen eines Bildes Spiele- und Multimedia-Programmierung 18
F Brauche Hilfe bei Bewegung eines Rechtecks [Applet] Spiele- und Multimedia-Programmierung 5
T Java2D Spiel, beim Hinzufügen eines Bildes ruckelt das ganze Spiele- und Multimedia-Programmierung 3
F Position eines Objektes auslesen. Spiele- und Multimedia-Programmierung 7
W Rotation eines Objektes Spiele- und Multimedia-Programmierung 2
M Zerschneiden eines Bildes mit Wellenlinien? Spiele- und Multimedia-Programmierung 2
S Simulation in der Art eines Schachbrett Spiele- und Multimedia-Programmierung 2
A 2-Achsen Rotation eines Würfels Spiele- und Multimedia-Programmierung 4
L nicht sichtbare Kanten eines Würfels Spiele- und Multimedia-Programmierung 2
B BufferedImage Position Spiele- und Multimedia-Programmierung 8
B BufferStrategy zu BufferedImage? Irgendwie? Spiele- und Multimedia-Programmierung 2
D getsubimage aus BufferedImage und Rueckwandlung in ein ImagePlus bild Spiele- und Multimedia-Programmierung 0
V BufferedImage[] aus anderer Classe auslesen Spiele- und Multimedia-Programmierung 2
F [JMyron] Bild von int[] zu BufferedImage Spiele- und Multimedia-Programmierung 2
Q BufferedImage vs. Heap Space ‒ Warum wird der Speicher nicht freigegeben? Spiele- und Multimedia-Programmierung 6

Ähnliche Java Themen

Neue Themen


Oben