2016-04-24 9 views
1

Ich habe erfolgreich ein Standard-Basis-Transform-Feedback-Partikelsystem mit Punktsprites geschrieben. Kein Flackern, die Partikel werden von einem Puffer in den nächsten geladen, der dann gerendert wird, dann wird der Ausgabepuffer bei der nächsten Iteration zum Eingabepuffer. Alle GPU-Seite, Standard-Transformations-Feedback. Wunderbar! EIN GROSSES PROBLEM: Es funktioniert nur, wenn ich gl_PointCoord nicht verwende. Eine flache Farbe für meinen Punkt Sprites funktioniert gut. Aber ich brauche gl_PointCoord, um etwas sinnvolles zu tun. Alle meine Shader, egal ob sie gl_PointCoord verwenden oder nicht, kompilieren und verlinken einfach gut. Wenn der Shader zur Laufzeit jedoch gl_PointCoord verwendet (ob sich gl_PointCoord tatsächlich im Ausführungspfad befindet), stürzt das Programm ab. Ich explizit glEnable (GL_POINT_SPRITE). Dies hat keine Auswirkung. Wenn man gl_PointCoord auslässt und glPointSize (100.0f) einstellt und vec4 (1.0,1.0,1.0,1.) Verwendet, dann liefert das Partikelsystem genau so große weiße blockige Quadrate (wie erwartet). Aber mit gl_PointCoord in irgendeiner Weise (als Standard-Textur-Lookup-Koord oder prozedurale Farbe oder irgendetwas anderes) stürzt meine Shader zur Laufzeit ab, nach erfolgreichem Kompilieren und Verknüpfen. Ich verstehe einfach nicht warum. Es hat glShaderSource, glCompileShader, glAttachShader, glLinkProgram übergeben. Ich kompiliere meine Shader als # 430 und 440, und ich habe sogar 300 es probiert. Alle kompilieren, verknüpfen und ich überprüft den Status der Kompilierung und Verknüpfung. Alles gut. Ich benutze ein High-End-Microsoft Surface Book Pro, Visual Studio 2015. NVIDIA GeForce GPU. Ich habe auch sichergestellt, dass alle meine Fahrer auf dem neuesten Stand sind. Unglücklicherweise habe ich bei Point-Sprites keine Billboard-Vertices vom Vertex-Shader, um sie als Texturkoordinaten in den Fragment-Shader zu interpolieren. gl_FragCoord funktioniert auch nicht (wie ich es für Punktsprites erwarten würde). Weiß jemand, wie man das löst oder eine andere Technik für Texturkoordinaten für Punktsprites benutzt?gl_PointCoord kompiliert und verbindet, stürzt aber zur Laufzeit ab

glBeginTransformFeedback (GL_POINTS); // Wenn mein Fragment Shader gl_PointCoord verwendet, stürzt es hier schwer ab.

Bei der Antwort bitte verstehen, ich bin sehr erfahren in Schreiben von Shadern, Vertex Shaders, Pixel Shader, Tessellation Kontrolle, Tessellation Evaluation und Geometrie Shader, in GLSL und HLSL. Aber ich behaupte nicht, alles zu wissen. Ich hätte etwas Einfaches vergessen können; Ich habe nur keine Ahnung, was das sein könnte. Ich denke, es könnte ein Zustand sein, den ich nicht aktiviert habe. Soweit Transformations-Feedback geht, richte ich auch die variierenden Attribute korrekt über glTransformFeedbackVaryings ein. C++:

void Render(void* pData) 
{ 
    auto pOwner = static_cast<CPointSpriteSystem*>(pData); 
    glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); 
    glEnable(GL_POINT_SPRITE); 
    glEnable(GL_POINT_SMOOTH); 
    //glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); 
    m_Shader.Activate(); 
    auto num_particles = pOwner->m_NumPointSprites; 
    FeedbackIndex = 0; 
    while (true) 
    { 
     m_Shader.SetSubroutine(GL_VERTEX_SHADER, "RenderPass", 
      vssubroutines[FeedbackIndex], 
      vsprevSubLoc[FeedbackIndex], 
      vsupdateSub[FeedbackIndex]); 
     m_Shader.SetSubroutine(GL_FRAGMENT_SHADER, "RenderPixelPass", 
      pssubroutines[0], 
      psprevSubLoc[0], 
      psrenderSub[0]); 
     if (!FeedbackIndex) 
     { 
      glEnable(GL_RASTERIZER_DISCARD); 
      glBindVertexArray(m_vao[bufferIndex]); 
      glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_Feedback[bufferIndex]); 
      glBeginTransformFeedback(GL_POINTS);//if feedback fragment shader uses gl_PointCoord, will always hard-crash here 
      glDrawArrays(GL_POINTS, 0, num_particles); 
      glEndTransformFeedback(); 
      glFlush(); 
     } 
     else 
     { 
      m_Shader.SetSubroutine(GL_FRAGMENT_SHADER, "RenderPixelPass", 
       pssubroutines[(int)pOwner->m_ParticleType], 
       psprevSubLoc[(int)pOwner->m_ParticleType], 
       psrenderSub[(int)pOwner->m_ParticleType]); 
      glPointSize(100.0f); 
      glDisable(GL_RASTERIZER_DISCARD); 
      glDrawTransformFeedback(GL_POINTS, m_Feedback[bufferIndex]); 
      bufferIndex = 1 - bufferIndex; 
      break; 
     } 
     FeedbackIndex = 1 - FeedbackIndex; 
    } 
} 

VS Feedback:

#version 310 es 
subroutine void RenderPassType(); 
subroutine uniform RenderPassType RenderPass; 
layout(location=0) in vec3 VertexPosition; 
layout(location=1) in vec3 VertexVelocity; 
layout(location=2) in float VertexStartTime; 
layout(location=3) in vec3 VertexInitialVelocity; 
out vec3 Position; 
out vec3 Velocity; 
out float StartTime; 
out float Transp; 
uniform float g_fCurSeconds; 
uniform float g_fElapsedSeconds; 
uniform float Time; 
uniform float H; 
uniform vec3 Accel; 

#ifdef USE_VIEW_BLOCK 
layout(std140) uniform view_block{ 
    mat4 g_mView, 
     g_mInvView, 
     g_mPrevView, 
     g_mPrevInvView, 
     g_mProj, 
     g_mInvProj; 
}; 
uniform mat4 g_mWorld; 
#endif 

subroutine(RenderPassType) void UpdateSphere(){ 
    Position=VertexPosition+VertexVelocity*g_fElapsedSeconds; 
    Velocity=VertexVelocity; 
    StartTime=VertexStartTime; 
} 
subroutine(RenderPassType) void Render(){ 
    gl_Position=g_mProj*g_mInvView*vec4(VertexPosition,1.0); 
} 

void main(){ 
    RenderPass();" 
} 

PS Feedback:

#version 310 es //version 430 and 440 same results 
subroutine void RenderPixelType(); 
subroutine uniform RenderPixelType RenderPixelPass; 
uniform sampler2D tex0; 
layout(location=0) out vec4 g_FragColor; 

subroutine(RenderPixelType) void Basic(){ 
    g_FragColor=vec4(1.0,1.0,1.0,1.0); 
} 

subroutine(RenderPixelType) void ProceduralSphere(){ 
#if 1 
    vec2 coord=gl_PointCoord;//at runtime: BOOM! 
    coord=coord*2.0-1.0; 
    float len=length(coord); 
    if(len>1.0) discard; 
    g_FragColor=vec4(1.0-len,1.0-len,1.0-len,1.0); 
#else 
    g_FragColor=vec4(1.0,1.0,1.0,1.0);//always works 
#endif 
} 

subroutine(RenderPixelType) void StandardImage(){ 
    g_FragColor=texture2D(tex0,gl_PointCoord); //boom!! 
    g_FragColor=vec4(1.0,1.0,1.0,1.0); 
} 

void main(){ 
    RenderPixelPass(); 
} 
+0

Könnten Sie bitte Ihren Quellcode angeben, damit wir versuchen können, das Problem zu reproduzieren? – datenwolf

+0

Just updated original Post – Frankoguy

+0

Es kann ein Fehler im Treiber oder irgendwo in Ihrem Programm sein. Ohne den vollständigen Quellcode (was ist pOwner?) Ist es schwer zu sagen. – Rei

Antwort

3

löste ich das Problem! Das Problem war eigentlich, dass ich keinen Wert an Transp geschrieben habe (float transp deklariert; // in vs). Ich dachte beiläufig, dass ich das nicht tun müsste. Aber ich begann, etwas Fett zu trimmen, und sobald ich ein generisches float (das eigentlich von späteren Shader-Stufen nicht verwendet wurde: Transp = 0.0f) schrieb und dann als #version 430 kompilierte, fing alles an, wie ursprünglich erwartet zu funktionieren : kleine weiße Kugeln

Verwandte Themen