Opengl 4.3:在Vertex&;中使用一个SSBO对象;片段着色器

Opengl 4.3:在Vertex&;中使用一个SSBO对象;片段着色器,opengl,Opengl,一段时间以来,我一直在尝试将着色器存储缓冲区对象(SSBO)与opengl 4.3内核结合使用,但我甚至无法让着色器程序链接 下面是我的顶点着色器的代码 # version 430 core in vec3 vertex; uniform mat4 perspectiveMatrix, viewMatrix, modelMatrix; in vec3 normal; out vec3 lightVectors[3]; out vec3 vertexNormal; out vec3 camer

一段时间以来,我一直在尝试将着色器存储缓冲区对象(SSBO)与opengl 4.3内核结合使用,但我甚至无法让着色器程序链接

下面是我的顶点着色器的代码

# version 430 core

in vec3 vertex;
uniform mat4
perspectiveMatrix,
viewMatrix,
modelMatrix;

in vec3 normal;
out vec3 lightVectors[3];
out vec3 vertexNormal;
out vec3 cameraVector;

layout(std430,binding=1)buffer Lights
{
  vec3 positions[3];
  vec3 attenuations[3];
  vec3 colors[3];
}buf1;

void main()
{
 vec4 worldVertex=modelMatrix*vec4(vertex,1.0);
 gl_Position=perspectiveMatrix*viewMatrix*worldVertex;

 vertexNormal=(modelMatrix*vec4(normal,0)).xyz;
 for(int i=0;i<3;i++){
  lightVectors[i]=buf1.positions[i]-worldVertex.xyz;
 }
 cameraVector=(inverse(viewMatrix)*vec4(0,0,0,1)).xyz-worldVertex.xyz;

}
这是我用于照明计算的SSBO

我需要在顶点和片段着色器中使用这一个缓冲区,因为在我的顶点着色器中,这是代码的一部分

lightVectors[i]=buf1.positions[i]-worldVertex.xyz;
使用SSBO中定义的灯光位置

在片段着色器中

float getAtten(i) and
vec3 computeLight()
方法使用缓冲区颜色[3]和衰减[3]“阵列”来计算漫反射和镜面反射分量

但是我无法使用上面的SSBO定义链接顶点和碎片着色器 而且着色器信息日志是空的,所以我也不知道错误

有没有一种方法可以在顶点和碎片着色器中使用上述定义的SSBO,而不创建两个单独的SSBO,即一个用于顶点着色器,另一个用于碎片着色器

这是我的着色器类。我的所有着色器都扩展到此类以实现

public abstract class StaticShader extends Shader3D
{
 private int      
 vertexShaderID=-1,
 fragmentShaderID=-1;

 private boolean alive=false;
 private boolean isActive=false;

 public StaticShader(Object vertexShader,Object fragmentShader)
 {
   programID=GL20.glCreateProgram();  
   vertexShaderID=loadShader(vertexShader,GL20.GL_VERTEX_SHADER);
   fragmentShaderID=loadShader(fragmentShader,GL20.GL_FRAGMENT_SHADER);

   GL20.glAttachShader(programID,vertexShaderID);
   GL20.glAttachShader(programID,fragmentShaderID);
   bindAttributes();

   activateShader();
  }

 private int loadShader(Object src,int shaderType)
 {
     StringBuilder source=super.loadSource(src);

     int shaderID=GL20.glCreateShader(shaderType);
     GL20.glShaderSource(shaderID,source);
     GL20.glCompileShader(shaderID);

     if(GL20.glGetShaderi(shaderID,GL20.GL_COMPILE_STATUS)==GL11.GL_FALSE)
     {
       infoLogSize=GL20.glGetShaderi(shaderID,GL20.GL_INFO_LOG_LENGTH);
       System.err.println(GL20.glGetShaderInfoLog(shaderID,infoLogSize));
       System.err.println("COULD NOT COMPILE SHADER");
       System.exit(-1);
     }    

     return shaderID;
 }

protected void activateShader()
 {   
  GL20.glLinkProgram(programID);
  if(GL20.glGetProgrami(programID,GL20.GL_LINK_STATUS)==GL11.GL_FALSE)
  {  
    infoLogSize=GL20.glGetProgrami(programID,GL20.GL_INFO_LOG_LENGTH);
    System.err.println(GL20.glGetProgramInfoLog(programID,infoLogSize));
    System.err.println("COULD NOT LINK SHADER");
    System.exit(-1);
  } 

  GL20.glValidateProgram(programID); 
  if(GL20.glGetProgrami(programID,GL20.GL_VALIDATE_STATUS)==GL11.GL_FALSE)
  {
    infoLogSize=GL20.glGetProgrami(programID,GL20.GL_INFO_LOG_LENGTH);  
    System.err.println(GL20.glGetProgramInfoLog(programID,infoLogSize));
    System.err.println("COULD NOT VALIDATE SHADER");
    System.exit(-1);
  } 
 }

 public void dispose()
 {   
    GL20.glUseProgram(0);

    GL20.glDetachShader(programID,vertexShaderID);
    GL20.glDetachShader(programID,fragmentShaderID);

    GL20.glDeleteShader(vertexShaderID);
    GL20.glDeleteShader(fragmentShaderID);

    GL20.glDeleteProgram(programID);
 }        
}
我使用的是LWJGL2.9.3JavaOpenGL版本

该程序编译得很好,但是glLinkprogram()不正确 返回false,着色器信息日志为空

我甚至没有创建任何类型的缓冲区对象,我只是在学习语法


任何帮助都将不胜感激,请提前向您和在评论中帮助过我的人表示感谢,但我现在非常沮丧

在您的代码中,我发现链接器错误:

错误:SSBO(命名灯光)着色器之间的绑定不匹配

对于不同着色器阶段中的相同命名缓冲区对象,必须使用相同的绑定点

在顶点着色器中:

layout(std430, binding=1) buffer Lights
{
  vec3 positions[3];
  vec3 attenuations[3];
  vec3 colors[3];
} buf1;
Lights
列出缓冲区的外部可见名称,
buf1
是着色器中块的名称

这意味着您必须为片段着色器中的缓冲区对象
灯光
使用相同的绑定点:

layout(std430,binding=1) buffer Lights // <---- binding=1 instead of binding=2
{
    vec3 positions[3];
    vec3 attenuations[3];
    vec3 colors[3];
}buf2;

是的,这是可能的。链接失败时,链接器信息日志不太可能是空的,因此您可能希望首先查看该日志(或在此处显示代码)。上面给出的着色器代码总是打印编译/链接错误并退出应用程序。我希望这对那些从谷歌来寻找如何初始化SSBO的简单解决方案的人有所帮助,它的工作原理与UBO完全相同,只是您将GL_UNIFORM_BUFFER更改为GL_着色器_STORAGE_BUFFER。着色器代码也相同,只是
std430
buffer
而不是
std140
uniform
。SSBO没有太多内容,但有很多关于UBOs的学习资料。你是对的,它确实显示了绑定不匹配错误。我没有正确地看到它,这是我的错误。但是现在当我运行程序时,信息日志是空的。我要更新我的问题,谢谢你的提示,但仍然没有任何工作,因为我没有使用任何缓冲区对象,只是着色器代码。目前还没有创建和使用缓冲区,我只是在学习语法。程序在链接阶段崩溃
layout(std430, binding=1) buffer Lights
{
  vec3 positions[3];
  vec3 attenuations[3];
  vec3 colors[3];
} buf1;
layout(std430,binding=1) buffer Lights // <---- binding=1 instead of binding=2
{
    vec3 positions[3];
    vec3 attenuations[3];
    vec3 colors[3];
}buf2;
 // use buffer to create a buffer block (shader storage block)
 buffer BufferName { // externally visible name of buffer
     int count; // typed, shared memory...
     ... // ...
     vec4 v[]; // last member may be an array that is not sized
               // until after link time (dynamically sized)
 } Name; // name of block within the shader