2013-08-03 117 views
2

使用所有要呈现的对象时,我使用glDrawElements。然而,我对Compute Shaders的冒险给了我一个使用glDrawArrays的设置。与许多违反该主题的人一样,我使用这个PDF作为基础。问题是渲染时什么也没有显示。使用着色器存储对象不起作用的绘图

#include "LogoTail.h" 

LogoTail::LogoTail(int tag1) { 
    tag = tag1; 
    needLoad = false; 
    shader = LoadShaders("vertex-shader[LogoTail].txt","fragment-shader[LogoTail].txt"); 
    shaderCompute = LoadShaders("compute-shader[LogoTail].txt"); 

    for(int i = 0; i < NUM_PARTICLES; i++) 
    { 
     points[ i ].x = 0.0f; 
     points[ i ].y = 0.0f; 
     points[ i ].z = 0.0f; 
     points[ i ].w = 1.0f; 
    } 

    glGenBuffers(1, &posSSbo); 
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, posSSbo); 
    glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(points), points, GL_STATIC_DRAW); 
    glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); 

    for(int i = 0; i < NUM_PARTICLES; i++) 
    { 
     times[ i ].x = 0.0f; 
    } 

    glGenBuffers(1, &birthSSbo); 
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, birthSSbo); 
    glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(times), times, GL_STATIC_DRAW); 
    glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); 

    for(int i = 0; i < NUM_PARTICLES; i++) 
    { 
     vels[ i ].vx = 0.0f; 
     vels[ i ].vy = 0.0f; 
     vels[ i ].vz = 0.0f; 
     vels[ i ].vw = 0.0f; 
    } 

    glGenBuffers(1, &velSSbo); 
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, velSSbo); 
    glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(vels), vels, GL_STATIC_DRAW); 
    glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); 
} 

void LogoTail::Update(const double dt, float sunTime,glm::vec3 sunN) { 
    position=glm::translate(glm::mat4(), glm::vec3(4.5f,0,0)); 
} 

void LogoTail::Draw(shading::Camera& camera){ 
    shaderCompute->use(); 
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, posSSbo); 
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, velSSbo); 
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, birthSSbo); 

    glDispatchCompute(NUM_PARTICLES/WORK_GROUP_SIZE, 1, 1); 
    glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT); 

    shaderCompute->stopUsing(); 
    shader->use(); 

    shader->setUniform("camera", camera.matrix()); 
    shader->setUniform("model",position); 

    glBindBuffer(GL_ARRAY_BUFFER, posSSbo); 
    glVertexPointer(4, GL_FLOAT, 0, (void *)0); 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glDrawArrays(GL_POINTS, 0, NUM_PARTICLES); 
    glDisableClientState(GL_VERTEX_ARRAY); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    shader->stopUsing(); 
} 

头部包含所需的结构和其他变量,因此它们不会超出特定对象的范围。

这是计算着色器本身。

#version 430 core 
#extension GL_ARB_compute_shader : enable 
#extension GL_ARB_shader_storage_buffer_object : enable 

layout(std140, binding=4) buffer Pos 
{ 
    vec4 Positions[ ]; // array of vec4 structures 
}; 
layout(std140, binding=5) buffer Vel 
{ 
    vec4 Velocities[ ]; // array of vec4 structures 
}; 
layout(std140, binding=6) buffer Tim 
{ 
    float BirthTimes[ ]; // array of structures 
}; 

layout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in; 

const vec3 G = vec3(0., -0.2, 0.); 
const float DT = 0.016666; 

void main() { 
    uint gid = gl_GlobalInvocationID.x; // the .y and .z are both 1 
    vec3 p = Positions[ gid ].xyz; 
    vec3 v = Velocities[ gid ].xyz; 
    vec3 pp = p + v*DT + .5*DT*DT*G; 
    vec3 vp = v + G*DT; 
    Positions[ gid ].xyz = pp; 
    Velocities[ gid ].xyz = vp; 
} 

出于测试目的,我降低了重力。 我相信没有东西超出范围,也没有必要的束缚,但它暗示我为什么这些粒子没有绘制。另外,我还添加了一个几何着色器,它围绕每个点构建了一个四边形,但它没有解决任何问题。

+0

我认为你对glUnmapBuffer()的调用是不必要的,因为你首先不使用glMapBuffer()。 – Gigo

回答

2

最后5线在我看来,问题的:

glBindBuffer(GL_ARRAY_BUFFER, posSSbo); 
glVertexPointer(4, GL_FLOAT, 0, (void *)0); 
glEnableClientState(GL_VERTEX_ARRAY); 
glDrawArrays(GL_POINTS, 0, NUM_PARTICLES); 
glDisableClientState(GL_VERTEX_ARRAY); 
glBindBuffer(GL_ARRAY_BUFFER, 0); 

我的猜测是你要使用可编程pipeline.I旧的做事方式我不知道它是如何在OpenGL规格说明,但它似乎在新版本(GL4.2)中,您不得不将顶点缓冲区绑定到VAO(可能是供应商特定的规则?)一旦我需要实现OIT并尝试使用带有元素绘制缓冲区的Cyril Crassin's demo你正在使用GL4.2和NVidia卡。没有任何显示。然后我将它们绑定到VAO,问题就没有了。所以我建议你试试。

+1

添加VAO做到了!由于计算着色器带有opengl 4.3,因此我认为所写的内容对作者有用。然而,按照你所说的创建一个VAO,我必须包括一个以前从指数中丢失的状态。谢谢! – Behemyth