当前位置: 首页 > 知识库问答 >
问题:

gl_PointCoord编译和链接,但在运行时崩溃

步德宇
2023-03-14

我成功地编写了一个带有点精灵的标准基本变换反馈粒子系统。没有闪烁,粒子从一个缓冲区更新到下一个缓冲区,然后进行渲染,然后输出缓冲区在下一次迭代时成为输入缓冲区。所有GPU端,标准转换反馈。精彩的一个大问题是:只有在我不使用gl_PointCoord的情况下,它才有效。在我的点精灵中使用平面颜色效果很好。但我需要gl_PointCoord做任何有意义的事。我所有的着色器,不管是否使用gl_PointCoord,编译和链接都很好。但是,在运行时,如果着色器使用gl_PointCoord(无论gl_PointCoord是否实际在执行路径中),程序将崩溃。我是glEnable(GL_POINT_SPRITE)。这没有任何效果。省略gl_PointCoord,设置glPointSize(100.0f),并使用vec4(1.0,1.0,1.0,1.)粒子系统的渲染效果与大的白色块状正方形一样好(如预期)。但是,在成功编译和链接之后,以任何方式使用gl_PointCoord(作为标准纹理查找coord或程序颜色或任何其他方式)都会在运行时使我的着色器崩溃。我就是不明白为什么。它通过了glShaderSource、glCompileShader、glAttachShader和glLinkProgram。我将我的着色器编译为#版本430和440,我甚至尝试了300个。我检查了编译和链接的状态。很好。我使用的是高端微软surface book pro,visual studio 2015。NVIDIA GeForce GPU。我还确保我所有的司机都是最新的。不幸的是,对于点精灵,我没有来自顶点着色器的公告牌顶点可用于作为纹理坐标插值到片段着色器中。gl_FragCoord也不起作用(正如我对点精灵的期望)。有人知道如何解决这个问题,或者使用另一种技术为点精灵创建纹理坐标吗?

glBeginTransformFeedback(总分)//如果我的片段着色器使用gl_PointCoord,它会在这里崩溃。

回复时,请理解我在使用GLSL和HLSL编写着色器、顶点着色器、像素着色器、镶嵌控制、镶嵌评估和几何着色器方面非常有经验。但我并不声称什么都知道。我可能忘记了一些简单的东西;我只是不知道那可能是什么。我想这可能是我没有启用的状态。就转换反馈而言,我还通过glTransformFeedbackVaryings正确设置了不同的attrib。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反馈:

#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反馈:

#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();
}

共有1个答案

龚星洲
2023-03-14

我解决了问题!问题实际上是我没有给Transp写一个值(声明为浮点Transp;//in vs)。我漫不经心地认为我不必这样做。但是我开始修剪一些脂肪,当我写出一个通用的浮点(实际上并没有被以后的着色器阶段使用:Transp=0.0f),然后编译为#version 430时,这一切都开始按照最初的预期工作:白色的小球

 类似资料:
  • 问题内容: 我正在尝试使用JavaMail API发送电子邮件。我从自解压二进制文件在我的主目录中安装了jdk 1.5。我正在使用Ubintu 9.10 我使用下一条命令编译程序: 〜/ jdk1.5.0_22 / bin / javac -classpath〜/ jdk1.5.0_22 / jre / lib / javamail-1.4.3 / mail.jar:〜/ jdk1.5.0_22

  • 主要内容:编译(Compile),链接(Link),总结我们平时所说的程序,是指双击后就可以直接运行的程序,这样的程序被称为 可执行程序(Executable Program)。在 Windows 下,可执行程序的后缀有 和 (其中 比较常见);在类 UNIX 系统(Linux、Mac OS 等)下,可执行程序没有特定的后缀,系统根据文件的头部信息来判断是否是可执行程序。 可执行程序的内部是一系列计算机指令和数据的集合,它们都是二进制形式的,CPU 可

  • 编译和链接参数是每一个C/C++程序员需要经常面对的问题。构建每一个C/C++应用均需要经过编译和链接两个步骤,CGO也是如此。 本节我们将简要讨论CGO中经常用到的编译和链接参数的用法。 2.10.1 编译参数:CFLAGS/CPPFLAGS/CXXFLAGS 编译参数主要是头文件的检索路径,预定义的宏等参数。理论上来说C和C++是完全独立的两个编程语言,它们可以有着自己独立的编译参数。 但是因

  • 问题内容: 注意:这是从Comparable和Comparator合约衍生出来的,涉及null 该代码可以在Eclipse(20090920-1017)中编译并正常运行 但是它不能在上编译javac 1.6.0_17。这是错误消息: 有人可以解释为什么差异吗?这是一个错误吗?如果是这样,谁有错误? 问题答案: 这是一个已确认的错误:错误ID 6468354。这是相关的摘录: 此问题是由以下事实引起

  • 条款46: 宁可编译和链接时出错,也不要运行时出错 除了极少数情况下会使C++抛出异常(例如,内存耗尽 ---- 见条款7)外,运行时错误的概念和C++没什么关系,就象在C中一样。没有下溢,上溢,除零检查;没有数组越界检查,等等。一旦程序通过了编译和链接,你就得靠自己了 ---- 一切后果自负。这很象跳伞运动,一些人从中找到了刺激,另一些人则吓得摔成了残废。这一思想背后的动机当然在于效率:没有运行

  • 问题内容: 尝试1,香草链接到图书馆 我正在尝试使用修补版本的OpenSSL(因此DTLS更易于使用)。OpenSSL在 ./include/openssl子文件夹有大量的头文件(我认为应该如此): GCC链接到include文件夹,并给我一个错误-它找不到SSL。我或多或少地在使用与别人相同的东西。这在OSX(10.6)上有效,但在Ubuntu上无效: 尝试2,符号链接到/ usr / incl