Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 并行图形计算_Java_Opengl_Optimization_Graphics_Parallel Processing - Fatal编程技术网

Java 并行图形计算

Java 并行图形计算,java,opengl,optimization,graphics,parallel-processing,Java,Opengl,Optimization,Graphics,Parallel Processing,我目前正在用Java开发一个游戏。在这个项目中,我一直在研究如何按程序生成小行星和行星的纹理。下面的函数运行得很好,事实上它完全符合我的预期,我对结果非常满意。对象在初始化时生成图形一次,然后存储BuffereImage以供以后渲染 因为我使用的是3D噪声(),所以在我的图形中实现某种动画非常容易。通过增加i变量并在每一帧上重新生成我的图形,我可以通过3D噪波“动画化”,产生一种非常整洁的效果。然而,这是非常累人的,因为它必须在每一帧上迭代每个图形的每个像素 这里是我的问题,以及随后的问题。使用

我目前正在用Java开发一个游戏。在这个项目中,我一直在研究如何按程序生成小行星和行星的纹理。下面的函数运行得很好,事实上它完全符合我的预期,我对结果非常满意。对象在初始化时生成图形一次,然后存储BuffereImage以供以后渲染

因为我使用的是3D噪声(),所以在我的图形中实现某种动画非常容易。通过增加i变量并在每一帧上重新生成我的图形,我可以通过3D噪波“动画化”,产生一种非常整洁的效果。然而,这是非常累人的,因为它必须在每一帧上迭代每个图形的每个像素

这里是我的问题,以及随后的问题。使用像LWJGL这样的库的GPU是否有加速这一过程的方法?我一直在尝试阅读LWJGL和其他OpenGL库,但没有效果。由于每个循环都独立于循环中以前的计算,我想这是并行计算的完美目标,我只是不确定如何做到这一点

另一种降低计算时间的方法是降低渲染图像的“分辨率”,或者将更新量降低到每秒一次,但我对这些解决方案都不太感兴趣

TL:DR用Java简化图形并行计算

当前算法运行的两张图片:
henriknilsson.ml/2017-01-21%2022'49.PNG
henriknilsson.ml/2017-01-21%2023'20.PNG

行星。生成图形

private static BufferedImage generateGraphic(int seed, double radius, double i){
    BufferedImage image = new BufferedImage((int)radius * 2, (int)radius * 2, BufferedImage.TYPE_4BYTE_ABGR);

    Random r = new Random(seed);

    //Select two random colors

    int cr = r.nextInt(256);
    int cg = r.nextInt(256);
    int cb = r.nextInt(256);

    Color color = new Color(cr, cg, cb);

    cr *= r.nextDouble() + 0.5;
    cg *= r.nextDouble() + 0.5;
    cb *= r.nextDouble() + 0.5;

    if(cr > 255)cr = 255;
    if(cg > 255)cg = 255;
    if(cb > 255)cb = 255;

    Color color2 = new Color(cr, cg, cb);

    OpenSimplexNoise osn = new OpenSimplexNoise(seed);
    double modifierx = r.nextDouble() * 5 + radius / 5;
    double modifiery = modifierx;

    double limit1 = 0.15;
    double limit2 = 0.05;

    //Offset the x and y modifiers for a Gas-giant "look"

    if(r.nextBoolean()){
        modifierx *= r.nextInt(8) + 4;
        modifiery /= 2;
    }

    //Itterate through every pixel

    for(int x = 0; x < image.getWidth(); x++){
        for(int y = 0; y < image.getWidth(); y++){
            double distance = Math.sqrt((x - radius) * (x - radius) + (y - radius) * (y - radius));

            if(distance > radius){
                image.setRGB(x, y, 0);
            }
            else{
                Color c;
                float noise = (float)osn.eval(x / modifierx, y / modifiery, i);

                if(noise > limit1){
                    c = color;
                }
                else if (noise > limit2){
                    float alpha = (float)(1 - (noise - limit2) / (limit1 - limit2)); 
                    c = Functions.blend(color, color2, alpha);
                }
                else{
                    c = color2;
                }

                float red = (float)c.getRed() / 255;
                float green = (float)c.getGreen() / 255;
                float blue = (float)c.getBlue() / 255;


                //Random offset
                double q = (((double)r.nextInt(81) + 960) / 1000);

                //Shadow
                double s = (Math.sqrt(radius * radius - distance * distance + 250) / radius);

                red *= q;
                green *= q;
                blue *= q;

                red *= s;
                green *= s;
                blue *= s;

                //Limit values
                if(red > 1)red = 1;
                if(green > 1)green = 1;
                if(blue > 1)blue = 1;

                image.setRGB(x, y, new Color(red, green, blue).getRGB());
            }
        }
    }
    return image;
}
private static buffereImage generateGraphic(整数种子、双半径、双i){
BuffereImage=new BuffereImage((int)radius*2,(int)radius*2,buffereImage.TYPE_4BYTE_ABGR);
随机r=新随机(种子);
//选择两种随机颜色
int cr=r.nextInt(256);
int cg=r.nextInt(256);
int cb=r.nextInt(256);
颜色=新颜色(cr、cg、cb);
cr*=r.nextDouble()+0.5;
cg*=r.nextDouble()+0.5;
cb*=r.nextDouble()+0.5;
如果(cr>255)cr=255;
如果(cg>255)cg=255;
如果(cb>255)cb=255;
颜色2=新颜色(cr、cg、cb);
OpenSimplexNoise osn=新的OpenSimplexNoise(种子);
双修饰符x=r.nextDouble()*5+半径/5;
双修饰符=修饰符x;
双限值1=0.15;
双极限2=0.05;
//偏移x和y修改器以获得气态巨人“外观”
if(r.nextBoolean()){
modifierx*=r.nextInt(8)+4;
修饰性/=2;
}
//通过每一个像素进行扫描
对于(int x=0;x半径){
setRGB(x,y,0);
}
否则{
颜色c;
浮动噪声=(浮动)osn.eval(x/modifierx,y/modifiery,i);
如果(噪声>限制1){
c=颜色;
}
否则如果(噪音>限制2){
浮点α=(浮点)(1-(噪声-限值2)/(限值1-限值2));
c=函数。混合(颜色、颜色2、alpha);
}
否则{
c=颜色2;
}
float red=(float)c.getRed()/255;
浮点绿色=(浮点)c.getGreen()/255;
float blue=(float)c.getBlue()/255;
//随机偏移
双q=((双)r.nextInt(81)+960)/1000);
//影子
双s=(数学sqrt(半径*半径-距离*距离+250)/半径);
红色*=q;
绿色*=q;
蓝色*=q;
红色*=s;
绿色*=s;
蓝色*=s;
//极限值
如果(红色>1)红色=1;
如果(绿色>1)绿色=1;
如果(蓝色>1)蓝色=1;
setRGB(x,y,新颜色(红色,绿色,蓝色).getRGB();
}
}
}
返回图像;
}
函数。混合

public static Color blend(Color c1, Color c2, float ratio) {
    if ( ratio > 1f ) ratio = 1f;
    else if ( ratio < 0f ) ratio = 0f;
    float iRatio = 1.0f - ratio;

    int i1 = c1.getRGB();
    int i2 = c2.getRGB();

    int a1 = (i1 >> 24 & 0xff);
    int r1 = ((i1 & 0xff0000) >> 16);
    int g1 = ((i1 & 0xff00) >> 8);
    int b1 = (i1 & 0xff);

    int a2 = (i2 >> 24 & 0xff);
    int r2 = ((i2 & 0xff0000) >> 16);
    int g2 = ((i2 & 0xff00) >> 8);
    int b2 = (i2 & 0xff);

    int a = (int)((a1 * iRatio) + (a2 * ratio));
    int r = (int)((r1 * iRatio) + (r2 * ratio));
    int g = (int)((g1 * iRatio) + (g2 * ratio));
    int b = (int)((b1 * iRatio) + (b2 * ratio));

    return new Color( a << 24 | r << 16 | g << 8 | b );
}
公共静态混色(颜色c1、颜色c2、浮动比率){
如果(比率>1f)比率=1f;
如果(比率<0f)比率=0f,则为else;
浮动利率=1.0f-比率;
int i1=c1.getRGB();
int i2=c2.getRGB();
int a1=(i1>>24&0xff);
int r1=((i1&0xff0000)>>16);
int g1=((i1&0xff00)>>8);
int b1=(i1和0xff);
inta2=(i2>>24&0xff);
int r2=((i2&0xff0000)>>16);
int g2=((i2&0xff00)>>8);
int b2=(i2和0xff);
inta=(int)((a1*iRatio)+(a2*ratio));
int r=(int)((r1*iRatio)+(r2*ratio));
int g=(int)((g1*iRatio)+(g2*ratio));
intb=(int)((b1*iRatio)+(b2*ratio));

返回新颜色(a你需要多快?CPU上的并行化非常容易,而且你几乎可以免费获得相当于CPU核数的加速。另一方面,GPU加速也不太容易。如果将数据传输到GPU和从GPU传输数据来弥补计算中的加速,这是值得怀疑的电子游戏到GPU是另一个问题,though@NicoSchertler在屏幕上只有五个半径为100px的行星,这会使我的fps远低于我的目标60 fps,如果这是某种量化的话。我仍然不确定如何在CPU上将其拆分为线程。另外,你能否进一步详细说明将游戏转移到GPU,请:)在最简单的情况下,只需将行分布在线程上(尽可能多的内核)。可能会给你一些想法。我的第二个评论是关于使用OpenGL渲染整个游戏,这样你就不必在CPU和GPU之间传输图像数据。但这需要进行大量重写。速度要快多少