gpt4 book ai didi

java - GP/GPU : ping pong technique with JOGL

转载 作者:太空宇宙 更新时间:2023-11-04 12:42:35 25 4
gpt4 key购买 nike

我尝试使用 JOGL 和 GLSL 在 GPU 上实现 react 扩散模型。

我使用 2 个 FramebufferObject 的乒乓球技术(我也尝试过使用 1 个 FBO 和 2 个颜色附件,但没有成功)。着色器似乎是正确的,因为我已经尝试过统一(经过一些调整)并且它有效。经过一周的尝试后,我完全不知道如何让这段代码发挥作用。我真的不是 JOGL 专家,所以也许我错过了一些明显的东西。

结果是图像随着时间的推移而变白:没有反应扩散行为,我不明白为什么!

预先感谢您的帮助。这是我的代码:

package gpu2;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import java.nio.IntBuffer;
import java.nio.FloatBuffer;
import java.io.File;

import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.glu.GLU;
import com.jogamp.opengl.util.FPSAnimator;
import com.jogamp.opengl.GLFBODrawable;
import com.jogamp.opengl.FBObject;
import com.jogamp.opengl.FBObject.Colorbuffer;
import com.jogamp.opengl.FBObject.ColorAttachment;
import com.jogamp.opengl.FBObject.TextureAttachment;
import com.jogamp.opengl.util.glsl.ShaderCode;
import com.jogamp.opengl.util.glsl.ShaderProgram;
import com.jogamp.opengl.util.glsl.ShaderUtil;
import com.jogamp.opengl.util.GLBuffers;
import com.jogamp.opengl.util.texture.Texture;
import com.jogamp.opengl.util.texture.TextureIO;

import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLOffscreenAutoDrawable;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.util.awt.AWTGLReadBufferUtil;
import com.jogamp.opengl.GLDrawableFactory;

import static com.jogamp.opengl.GL.*; // GL constants
import static com.jogamp.opengl.GL2.*; // GL2 constants

import gpu2.ModelParam;

/**
* JOGL 2.0 Program Template (GLCanvas)
* This is a "Component" which can be added into a top-level "Container".
* It also handles the OpenGL events to render graphics.
*/
@SuppressWarnings("serial")
public class JOGL2Setup_GLCanvas extends GLCanvas implements GLEventListener {
// Define constants for the top-level container
private static String TITLE = "JOGL 2.0 Setup (GLCanvas)"; // window's title
private static final int CANVAS_WIDTH = 512; // width of the drawable
private static final int CANVAS_HEIGHT = 512; // height of the drawable
private static final int FPS = 30; // animator's target frames per second

private final float[] canvasVertices = {
-1f, -1f, 0.0f,
-1f, 1f, 0.0f,
1f, -1f, 0.0f,
1f, 1f, 0.0f,
};

private final float[] canvasTexCoords = {
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
};

/** The entry main() method to setup the top-level container and animator */
public static void main(String[] args) {
// Run the GUI codes in the event-dispatching thread for thread safety
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// Create the OpenGL rendering canvas
GLCanvas canvas = new JOGL2Setup_GLCanvas();
canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));

// Create a animator that drives canvas' display() at the specified FPS.
final FPSAnimator animator = new FPSAnimator(canvas, FPS, true);

// Create the top-level container
final JFrame frame = new JFrame(); // Swing's JFrame or AWT's Frame
frame.getContentPane().add(canvas);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
// Use a dedicate thread to run the stop() to ensure that the
// animator stops before program exits.
new Thread() {
@Override
public void run() {
if (animator.isStarted()) animator.stop();
System.exit(0);
}
}.start();
}
});
frame.setTitle(TITLE);
frame.pack();
frame.setVisible(true);
animator.start(); // start the animation loop
}
});
}

// Setup OpenGL Graphics Renderer

private GLU glu; // for the GL Utility
private GL2 gl;

//OpenGl data
private int vboVertices;
private int vboTextCoord;
private Texture textureFile;

private FBObject fbo[];

private ShaderProgram shaderCompute;
private ShaderProgram shaderVisu;
private ShaderProgram shaderComputeInit;

private int currentSourceBuffer = 0;
private int currentDestBuffer = 1;

private int currentFrame = 0;
private int maxFrameCount = 5000000;
private float clearUniform = 0;

ModelParam params = new ModelParam();

public JOGL2Setup_GLCanvas() {
this.addGLEventListener(this);
}

@Override
public void init(GLAutoDrawable drawable) {
gl = drawable.getGL().getGL2(); // get the OpenGL graphics context
glu = new GLU(); // get GL Utilities
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // set background (clear) color

gl.glEnable(GL_TEXTURE_2D);

gl.glEnable( GL_COLOR_MATERIAL );
gl.glEnable( GL_FRAMEBUFFER );
gl.glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NEAREST); // best perspective correction

viewOrtho(gl);

gl.glViewport(0,0,CANVAS_WIDTH,CANVAS_HEIGHT);

int[] buffers = new int[2];
gl.glGenBuffers(2, buffers, 0);

vboVertices = buffers[0];
vboTextCoord = buffers[1];

gl.glBindBuffer(GL_ARRAY_BUFFER, vboVertices);
gl.glBufferData(GL_ARRAY_BUFFER, canvasVertices.length*(Float.SIZE/Byte.SIZE)*3, FloatBuffer.wrap(canvasVertices), GL_STATIC_DRAW);

gl.glBindBuffer(GL_ARRAY_BUFFER, vboTextCoord);
gl.glBufferData(GL_ARRAY_BUFFER, canvasTexCoords.length*(Float.SIZE/Byte.SIZE)*2, FloatBuffer.wrap(canvasTexCoords), GL_STATIC_DRAW);

gl.glBindBuffer( GL_ARRAY_BUFFER, 0 );

// ------------ create Texture Source------------------------
textureFile = initializeTexture();
if (textureFile==null) {
System.out.println("cannot load texture from disk");
}

// ------------ load shaders ------------------------
shaderCompute = loadShader(gl, "compute.vsh", "compute.fsh");
shaderComputeInit = loadShader(gl, "compute.vsh", "computeInit.fsh");
shaderVisu = loadShader(gl, "visu.vsh", "visu.fsh");

// ------------ create FBO ------------------------

initFBO();


}

/**
* Called back by the animator to perform rendering.
*/
@Override
public void display(GLAutoDrawable drawable) {

if (currentFrame < maxFrameCount) {
prepareNextStep();

renderToFBO();
currentFrame++;

}
renderFBOToScreen();
}

private void prepareNextStep() {
currentSourceBuffer = 1 - currentSourceBuffer;
currentDestBuffer = 1 - currentDestBuffer;
}

private void renderToFBO()
{
fbo[currentDestBuffer].bind(gl);
//gl.glClear(GL_COLOR_BUFFER_BIT);

viewOrtho(gl);

shaderCompute.useProgram(gl, true);

setShaderUniformFloat(gl, shaderCompute.program(), "diffuseU", 0.211f);
setShaderUniformFloat(gl, shaderCompute.program(), "diffuseV", 0.088f);
setShaderUniformFloat(gl, shaderCompute.program(), "feed", 0.007f);
setShaderUniformFloat(gl, shaderCompute.program(), "kill", 0.08f);
setShaderUniformFloat(gl, shaderCompute.program(), "Tech", 1f);

setShaderUniformFloat(gl, shaderCompute.program(), "currentFrame", currentFrame);
setShaderUniformFloat2(gl, shaderCompute.program(), "resolution", CANVAS_WIDTH, CANVAS_HEIGHT);

drawDataBuffer(shaderCompute, true);

shaderCompute.useProgram(gl, false);
fbo[currentDestBuffer].unbind(gl);
}

void drawDataBuffer(ShaderProgram currentShader, boolean sencondImage) {
// --- draw vbo
gl.glEnableClientState(GL_VERTEX_ARRAY);
gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//textcoords
gl.glBindBuffer(GL_ARRAY_BUFFER,vboTextCoord);
gl.glTexCoordPointer(2, GL_FLOAT, 0, 0);
//vertices
gl.glBindBuffer( GL_ARRAY_BUFFER, vboVertices );
gl.glVertexPointer(3, GL_FLOAT, 0, 0);

//activate texture data from last fbo
final FBObject.Colorbuffer texSource = (FBObject.Colorbuffer) fbo[currentSourceBuffer].getColorbuffer(0);
gl.glActiveTexture(GL_TEXTURE0);
gl.glBindTexture(GL_TEXTURE_2D, texSource.getName());
setShaderUniform1i(gl, currentShader.program(), "textureData", 0);

if (sencondImage) {
//activate texture with image from file
gl.glActiveTexture(GL_TEXTURE1);
gl.glBindTexture(GL_TEXTURE_2D, textureFile.getTextureObject());
textureFile.bind(gl);
setShaderUniform1i(gl, currentShader.program(), "textureImage", 1);
}

//draw buffer on screens
gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, canvasVertices.length / 3);

//disable texture image
if (sencondImage) {
gl.glActiveTexture(GL_TEXTURE1);
textureFile.disable(gl);
}
//disable texture data
gl.glActiveTexture(GL_TEXTURE0);
gl.glDisable(texSource.getName());

gl.glDisableClientState(GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL_VERTEX_ARRAY);

}

public void renderFBOToScreen()
{
gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear color and depth buffers
gl.glLoadIdentity(); // reset the model-view matrix

viewOrtho(gl);
gl.glEnable(GL_TEXTURE_2D);

final FBObject.Colorbuffer tex0 = (FBObject.Colorbuffer) fbo[currentDestBuffer].getColorbuffer(0);
gl.glActiveTexture(GL_TEXTURE0);
gl.glBindTexture(GL_TEXTURE_2D, tex0.getName());

//activate shader
shaderVisu.useProgram(gl, true);

// --- draw vbo
gl.glEnableClientState(GL_VERTEX_ARRAY);
gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//textcoords
gl.glBindBuffer(GL_ARRAY_BUFFER, vboTextCoord);
gl.glTexCoordPointer(2, GL_FLOAT, 0, 0);
//vertices
gl.glBindBuffer( GL_ARRAY_BUFFER, vboVertices );
gl.glVertexPointer(3, GL_FLOAT, 0, 0);

//draw buffer on screens
gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, canvasVertices.length / 3);

gl.glDisableClientState(GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL_VERTEX_ARRAY);

gl.glBindBuffer( GL_ARRAY_BUFFER, 0 );
//desactivate shader
shaderVisu.useProgram(gl, false);

}

private void initFBO()
{
try {

gl.glEnable(GL_TEXTURE_2D);

fbo = new FBObject[2];

//first fbo
fbo[currentSourceBuffer] = new FBObject(); // Create FrameBuffer
fbo[currentSourceBuffer].init(gl, CANVAS_WIDTH, CANVAS_HEIGHT, 0);
fbo[currentSourceBuffer].reset(gl, CANVAS_WIDTH, CANVAS_HEIGHT, 0); // int width, height - size of FBO, can be resized with the same call
fbo[currentSourceBuffer].bind(gl);

int tex = genTexture(gl);
gl.glBindTexture(GL_TEXTURE_2D, tex);
gl.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, CANVAS_WIDTH, CANVAS_HEIGHT, 0, GL_RGBA, GL_FLOAT, null);
fbo[currentSourceBuffer].attachTexture2D(gl, 0, GL_RGBA32F, GL_RGBA, GL_FLOAT, GL_NEAREST, GL_NEAREST, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
//gl.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
int DrawBuffers[] = {GL_COLOR_ATTACHMENT0};
gl.glDrawBuffers(1, DrawBuffers, 0); // "1" is the size of DrawBuffers
fbo[currentSourceBuffer].unbind(gl);

//second fbo
fbo[currentDestBuffer] = new FBObject(); // Create FrameBuffer
fbo[currentDestBuffer].init(gl, CANVAS_WIDTH, CANVAS_HEIGHT, 0);
fbo[currentDestBuffer].reset(gl, CANVAS_WIDTH, CANVAS_HEIGHT, 0); // int width, height - size of FBO, can be resized with the same call
fbo[currentDestBuffer].bind(gl);

tex = genTexture(gl);
gl.glBindTexture(GL_TEXTURE_2D, tex);
gl.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, CANVAS_WIDTH, CANVAS_HEIGHT, 0, GL_RGBA, GL_FLOAT, null);
fbo[currentDestBuffer].attachTexture2D(gl, 0, GL_RGBA32F, GL_RGBA, GL_FLOAT, GL_NEAREST, GL_NEAREST, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
//ogl.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
gl.glDrawBuffers(1, DrawBuffers, 1); // "1" is the size of DrawBuffers
fbo[currentDestBuffer].unbind(gl);

} catch (Exception e) {
System.out.println("Problem with fbo init " + e);
e.printStackTrace();
}

}

private Texture initializeTexture() {

Texture t = null;

try {
t = TextureIO.newTexture(new File("e:/shaders/wiki.jpg"), false);

t.setTexParameteri(gl, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
t.setTexParameteri(gl, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
t.setTexParameteri(gl, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
t.setTexParameteri(gl, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

} catch (Exception e) {
System.out.println("Unable to read texture file: " + e);
e.printStackTrace();
}

return t;
}

private ShaderProgram loadShader(GL2 gl, String vertexShader, String fragmentShader)
{
ShaderCode vertShader = ShaderCode.create(gl, GL2.GL_VERTEX_SHADER, 1, getClass(), new String[]{"e:/shaders/"+vertexShader},false);
vertShader.compile(gl);

ShaderCode fragShader = ShaderCode.create(gl, GL2.GL_FRAGMENT_SHADER, 1, getClass(), new String[]{"e:/shaders/"+fragmentShader},false);
fragShader.compile(gl);

ShaderProgram newShader = new ShaderProgram();
newShader.init(gl);
newShader.add(vertShader);
newShader.add(fragShader);

newShader.link(gl, System.out);

vertShader.destroy(gl);
fragShader.destroy(gl);

return newShader;
}

public static void setShaderUniform1i(GL2 inGL,int inProgramID,String inName,int inValue) {
int tUniformLocation = inGL.glGetUniformLocation(inProgramID,inName);
if (tUniformLocation != -1) {
inGL.glUniform1i(tUniformLocation, inValue);
} else {
System.out.println("UNIFORM COULD NOT BE FOUND! NAME="+inName);
}
}

public static void setShaderUniformFloat(GL2 inGL,int inProgramID,String inName,float inValue) {
int tUniformLocation = inGL.glGetUniformLocation(inProgramID,inName);
if (tUniformLocation != -1) {
inGL.glUniform1f(tUniformLocation, inValue);
} else {
System.out.println("UNIFORM COULD NOT BE FOUND! NAME="+inName);
}
}
public static void setShaderUniformFloat2(GL2 inGL,int inProgramID,String inName,float inValue1 ,float inValue2) {
int tUniformLocation = inGL.glGetUniformLocation(inProgramID,inName);
if (tUniformLocation != -1) {
inGL.glUniform2f(tUniformLocation, inValue1, inValue2);
} else {
System.out.println("UNIFORM COULD NOT BE FOUND! NAME="+inName);
}
}

private void viewOrtho(GL2 gl) // Set Up An Ortho View
{
gl.glMatrixMode(GL_PROJECTION); // Select Projection
gl.glPushMatrix(); // Push The Matrix
gl.glLoadIdentity(); // Reset The Matrix
gl.glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
gl.glMatrixMode(GL_MODELVIEW); // Select Modelview Matrix
gl.glPushMatrix(); // Push The Matrix
gl.glLoadIdentity(); // Reset The Matrix
}

private int genTexture(GL2 gl) {
final int[] tmp = new int[1];
gl.glGenTextures(1, tmp, 0);
return tmp[0];
}

/**
* Called back before the OpenGL context is destroyed. Release resource such as buffers.
*/
@Override
public void dispose(GLAutoDrawable drawable) { }
}

以及对应的GLSL Shader:

#version 120

uniform sampler2D textureData;
uniform sampler2D textureImage;


uniform vec2 resolution;

uniform float diffuseU;
uniform float diffuseV;
uniform float feed;
uniform float kill;
uniform float Tech = 1.0;
uniform float currentFrame = 0.0;

void main() {
//coords
vec2 position = ( gl_FragCoord.xy / resolution.xy );
vec2 pixel = 1./resolution;

//get data from texture
vec4 imgSource = texture2D(textureImage, gl_TexCoord[0].st);
vec2 oldUV = texture2D(textureData, gl_TexCoord[0].st).rg;

if(currentFrame<10){
if (distance(position,vec2(0.5,0.5 - currentFrame * 0.01f)) < 0.2f)
oldUV = vec2(0.0,0.2);
else if (distance(position,vec2(0.5,0.5 - currentFrame * 0.01f)) < 0.3f)
oldUV = vec2(0.5,0.1);
else
oldUV = vec2(0.1,0.0);

gl_FragColor = vec4(oldUV.rg, 0.0, 1.0);
return;
}

//get neightboors
vec2 dataUp = texture2D(textureData, position + pixel * vec2(0., 1.)).rg;
vec2 dataDown = texture2D(textureData, position + pixel * vec2(0., -1.)).rg;
vec2 dataLeft = texture2D(textureData, position + pixel * vec2(-1., 0.)).rg;
vec2 dataRight = texture2D(textureData, position + pixel * vec2(1., 0.)).rg;
//adapt parameters
vec2 imgParam = imgSource.rg;
float dU = diffuseU ;//+ 0.01 * (imgParam - 0.5);
float dV = diffuseV ;//+ 0.01 * (imgParam - 0.5);
float F = feed ;//+ 0.01 * (imgParam - 0.5);
float K = kill ;//+ 0.01 * (imgParam - 0.5);
//compute new values
vec2 laplace = (dataUp+dataDown+dataLeft+dataRight) - 4.0 * oldUV;
float uvv = oldUV.r * oldUV.g * oldUV.g;
// calculate delta quantities
float du = dU * laplace.r - uvv + F*(1.0 - oldUV.r);
float dv = dV * laplace.g + uvv - (F+K)*oldUV.g;
vec2 newUV = oldUV + vec2(du, dv)* Tech;

gl_FragColor = vec4(newUV.rg, 0.0, 1.0);
}

最佳答案

一些注意事项:

  • 避免使用已弃用的 OpenGL(和 GLU),使用 GL4(或 GL3)

  • 除非你需要awt/swt/swing,更喜欢newt,更多here

  • 更喜欢 Animator 而不是 FPSAnimator,更多 here

  • 更喜欢直接缓冲区而不是数组,因为否则 jogl 必须在下面创建它们,并且您无法跟踪(=完成后释放)这些 native 分配

  • 借助显式位置,GL4 还可以让您避免必须处理的所有统一开销(以及潜在的错误)(尤其是在运行时)

  • 目前更喜欢直接缓冲区管理而不是 FBObject,除非您真的知道 FBObject 在做什么。一旦你让它工作起来,你就可以继续使用该类。这可能是(其中之一)原因是您的代码无法正常工作,因为某些内容没有按照您的需要进行设置。而且,替换FBObject所需的代码行本质上是相同的

  • (如果您因任何原因无法使用显式位置)更喜欢某种字面方式来定义纹理统一位置,这通常是另一个导致错误的棘手部分,例如 this

  • 还喜欢纹理采样器,为您提供更大的灵 active

  • 下次不要等一个星期,早点告诉我们! :) 沮丧可能是一件令人讨厌的事情,很容易让你沮丧。我们可以一起帮助您让它发挥作用;)

关于java - GP/GPU : ping pong technique with JOGL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36686895/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com