如何使用 JOGL 处理和 return 数组
How to process and return an array with JOGL
我正在尝试使用 JOGL 连接 Java 和 GLSL 以并行处理数组。我对在屏幕上绘制任何东西不感兴趣。我希望能够获取一对浮点数组,将它们传递给着色器程序,用 GPU 处理它们,然后 return 将值返回到 Java 代码。
例如,我有浮点数组
float[] array1 = {...};
float[] array2 = {...};
然后我有一个包含行
的着色器程序
float resultArray = sin(array2)*array1; // Just a random function of the two arrays
然后 return 将 'resultArray' 作为浮点数组返回到我的 Java 程序以用于其他目的。
我当前的代码是
int v = gl.glCreateShader(GL.GL_VERTEX_SHADER);
int f = gl.glCreateShader(GL.GL_FRAGMENT_SHADER);
String vertShader =
"
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
}
";
gl.glShaderSource(v, 1, vertShader, (int[])null);
gl.glCompileShader(v);
String fragShader =
"
out float resultArray;
varying float array1;
varying float array2;
void main( void )
{
// Assuming this code should go in the fragment shader
float resultArray = sin(array2)*array1;
}
";
gl.glShaderSource(f, 1, fragShader, (int[])null);
gl.glCompileShader(f);
int shaderprogram = gl.glCreateProgram();
gl.glAttachShader(shaderprogram, v);
gl.glAttachShader(shaderprogram, f);
gl.glLinkProgram(shaderprogram);
gl.glValidateProgram(shaderprogram);
gl.glUseProgram(shaderprogram);
float[] resultArray = gl.callSomeMethodThatDoesntExist(shaderprogram, array1, array2);
但我不确定如何将浮点数组传递给着色器,也不知道如何在处理后得到结果。
任何人都可以指出正确的方向吗?
嘿@Daniel,您可以使用制服将数组传递给着色器。我喜欢将制服视为着色器的参数或输入。
来自https://www.khronos.org/opengl/wiki/Uniform_(GLSL):
These [uniforms] act as parameters that the user of a shader program can pass to that program.
struct Thingy
{
vec4 an_array[3];
int foo;
};
layout(location = 2) uniform Thingy some_thingies[6];
有些人更喜欢将数组作为纹理传入,其中 r、g、b 值表示您在着色器中需要的一些值。
uniform sampler2D myTexture;
为了取回你的输出;通常你的着色器会输出到默认的帧缓冲区。
The Default Framebuffer is the Framebuffer that OpenGL is created with. It is created along with the OpenGL Context. Like Framebuffer Objects, the default framebuffer is a series of images. Unlike FBOs, one of these images usually represents what you actually see on some part of your screen.
The default framebuffer is created at the time the OpenGL context is constructed.
据我所知,片段着色器只能输出到帧缓冲区,因此如果您需要取回某种数组,则需要输出到帧缓冲区,然后从中提取数据帧缓冲区。
User-defined outputs from a fragment shader represent a series of
"colors". These color values are directed into specific buffers based
on the glDrawBuffers state. These are called "fragment colors", though
you can treat them like any arbitrary data.
根据您设置帧缓冲区的方式,您还可以输出到多个缓冲区,请参阅:https://www.khronos.org/opengl/wiki/Fragment_Shader#Output_buffers
The mapping between fragment colors and actual buffers within a Framebuffer is defined by glDrawBuffers, which is part of the framebuffer's state.
For example, if we set our draw buffers up like this:
const GLenum buffers[] = {GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT2,
GL_NONE, GL_COLOR_ATTACHMENT0}; glDrawBuffers(4, buffers);
不幸的是,尽管片段着色器仅在每个像素的基础上对它们可用的数据进行操作,而您无法控制是哪个像素。为了解决这个问题,人们经常使用一种称为延迟着色的技术,其中所需的像素信息作为片段着色器的纹理输入传递(通常用于进行 post 处理)。
希望这个答案不会冗长复杂,不幸的是,使用着色器取回数组比您预期的要复杂一些。
或者,OpenCL 可能更适合您正在尝试做的事情,尽管我没有这方面的经验。
我正在尝试使用 JOGL 连接 Java 和 GLSL 以并行处理数组。我对在屏幕上绘制任何东西不感兴趣。我希望能够获取一对浮点数组,将它们传递给着色器程序,用 GPU 处理它们,然后 return 将值返回到 Java 代码。
例如,我有浮点数组
float[] array1 = {...};
float[] array2 = {...};
然后我有一个包含行
的着色器程序float resultArray = sin(array2)*array1; // Just a random function of the two arrays
然后 return 将 'resultArray' 作为浮点数组返回到我的 Java 程序以用于其他目的。
我当前的代码是
int v = gl.glCreateShader(GL.GL_VERTEX_SHADER);
int f = gl.glCreateShader(GL.GL_FRAGMENT_SHADER);
String vertShader =
"
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
}
";
gl.glShaderSource(v, 1, vertShader, (int[])null);
gl.glCompileShader(v);
String fragShader =
"
out float resultArray;
varying float array1;
varying float array2;
void main( void )
{
// Assuming this code should go in the fragment shader
float resultArray = sin(array2)*array1;
}
";
gl.glShaderSource(f, 1, fragShader, (int[])null);
gl.glCompileShader(f);
int shaderprogram = gl.glCreateProgram();
gl.glAttachShader(shaderprogram, v);
gl.glAttachShader(shaderprogram, f);
gl.glLinkProgram(shaderprogram);
gl.glValidateProgram(shaderprogram);
gl.glUseProgram(shaderprogram);
float[] resultArray = gl.callSomeMethodThatDoesntExist(shaderprogram, array1, array2);
但我不确定如何将浮点数组传递给着色器,也不知道如何在处理后得到结果。
任何人都可以指出正确的方向吗?
嘿@Daniel,您可以使用制服将数组传递给着色器。我喜欢将制服视为着色器的参数或输入。
来自https://www.khronos.org/opengl/wiki/Uniform_(GLSL):
These [uniforms] act as parameters that the user of a shader program can pass to that program.
struct Thingy
{
vec4 an_array[3];
int foo;
};
layout(location = 2) uniform Thingy some_thingies[6];
有些人更喜欢将数组作为纹理传入,其中 r、g、b 值表示您在着色器中需要的一些值。
uniform sampler2D myTexture;
为了取回你的输出;通常你的着色器会输出到默认的帧缓冲区。
The Default Framebuffer is the Framebuffer that OpenGL is created with. It is created along with the OpenGL Context. Like Framebuffer Objects, the default framebuffer is a series of images. Unlike FBOs, one of these images usually represents what you actually see on some part of your screen. The default framebuffer is created at the time the OpenGL context is constructed.
据我所知,片段着色器只能输出到帧缓冲区,因此如果您需要取回某种数组,则需要输出到帧缓冲区,然后从中提取数据帧缓冲区。
User-defined outputs from a fragment shader represent a series of "colors". These color values are directed into specific buffers based on the glDrawBuffers state. These are called "fragment colors", though you can treat them like any arbitrary data.
根据您设置帧缓冲区的方式,您还可以输出到多个缓冲区,请参阅:https://www.khronos.org/opengl/wiki/Fragment_Shader#Output_buffers
The mapping between fragment colors and actual buffers within a Framebuffer is defined by glDrawBuffers, which is part of the framebuffer's state. For example, if we set our draw buffers up like this:
const GLenum buffers[] = {GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT2, GL_NONE, GL_COLOR_ATTACHMENT0}; glDrawBuffers(4, buffers);
不幸的是,尽管片段着色器仅在每个像素的基础上对它们可用的数据进行操作,而您无法控制是哪个像素。为了解决这个问题,人们经常使用一种称为延迟着色的技术,其中所需的像素信息作为片段着色器的纹理输入传递(通常用于进行 post 处理)。
希望这个答案不会冗长复杂,不幸的是,使用着色器取回数组比您预期的要复杂一些。
或者,OpenCL 可能更适合您正在尝试做的事情,尽管我没有这方面的经验。