Qt QFile 和 OpenGL ES 2.0 顶点着色器意外的文件结尾

Qt QFile and OpenGL ES 2.0 Vertex Shader Unexpected End of File

我有工作的 Open GL 代码,它在 Qt 源代码中将着色器源作为 const char* 变量。这很好用并且编译得很好。现在我想将着色器移动到它们自己的文件中,并存储为 qresources。当我使用 QFile 读取着色器时,片段着色器编译但不编译顶点着色器。我似乎无法弄清楚为什么。如果有任何帮助,我将不胜感激 - 请参阅下面的代码。

错误:

Vertex Shader failed to compile! 
Error in vertex shader compilation!
Info log: Compile failed.
ERROR: Unexpected end of source found
ERROR: 1 compilation errors. No code generated.


Fragment Shader successfully compiled! 
Linking was unsuccessful... 

工作代码:

    // Compile Shaders
    const char* VertexShaderSource = "\
            attribute highp   vec4  inVertex;\
            attribute mediump vec2  inTexCoord;\
            varying mediump vec2  TexCoord;\
            void main()\
            {\
                gl_Position = inVertex;\
                TexCoord = inTexCoord;\
            }";

    const char* FragmentShaderSource = "\
                   #ifdef GL_IMG_texture_stream2\n \
                   #extension GL_IMG_texture_stream2 : enable \n \
                   #endif \n \
                       varying mediump vec2 TexCoord; \
                       uniform samplerStreamIMG sTexture; \
                       uniform sampler2D table1; \
                       uniform sampler2D table2; \
                       uniform sampler2D table3; \
                       uniform sampler2D palette; \
                       void main(void) \
                       {    \
                       highp vec4 texVal = textureStreamIMG( sTexture, TexCoord ); \
                       highp vec4 tb1Val = texture2D( table1, TexCoord ); \
                       highp vec4 tb2Val = texture2D( table2, TexCoord ); \
                       highp vec4 tb3Val = texture2D( table3, TexCoord ); \
                       highp float index = ( texVal.g * 255.0 ) * 256.0 + texVal.b * 255.0; \
                       highp float x = ( mod(index,256.0) ) / 256.0; \
                       highp float y = ( index / 256.0 ) / 256.0; \
                       highp vec4 palValue = texture2D( palette, vec2(x, y) ); \
                       gl_FragColor = vec4(palValue.a,palValue.r,palValue.g,palValue.b); \
                       }";

损坏的代码:

// Compile Shaders
QFile vSh(":/vertex.vsh");
bool vSuccess = vSh.open(QIODevice::ReadOnly);
qDebug() << "Success opening Vertex Shader: " << vSuccess;
QTextStream vIn(&vSh);
QString vOut;
while (!vIn.atEnd())
{
    vOut.append(QString("%1%2").arg(vIn.readLine()).arg("\n"));
}
qDebug() << vOut;
const char* VertexShaderSource = vOut.toStdString().c_str();

QFile fSh(":/fragment.fsh");
bool fSuccess = fSh.open(QIODevice::ReadOnly);
qDebug() << "Success opening Fragment Shader: " << fSuccess;
QTextStream fIn(&fSh);
QString fOut;
while (!fIn.atEnd())
{
    fOut.append(QString("%1%2").arg(fIn.readLine()).arg("\n"));
}
qDebug() << fOut;
const char* FragmentShaderSource = fOut.toStdString().c_str();

// Create vertex and fragment shaders
GLuint vertexShaderObject = glCreateShader(GL_VERTEX_SHADER);
GLuint fragmentShaderObject = glCreateShader(GL_FRAGMENT_SHADER);
const GLchar *vSrc = VertexShaderSource;
const GLchar *fSrc = FragmentShaderSource;
glShaderSource(vertexShaderObject, 1, &vSrc, NULL);
glShaderSource(fragmentShaderObject, 1, &fSrc, NULL);
glCompileShader(vertexShaderObject);
glCompileShader(fragmentShaderObject);
GLint compiled;
glGetShaderiv(vertexShaderObject, GL_COMPILE_STATUS, &compiled);
if (compiled)
{
    qDebug() << "Vertext Shader successfully compiled!";
}
else {

    qDebug() << "Vertex Shader failed to compile!";
    GLchar infoLog[2048];
    glGetShaderInfoLog(vertexShaderObject, 2048, NULL, infoLog);
    fprintf(stderr, "Error in vertex shader compilation!\n");
    fprintf(stderr, "Info log: %s\n", infoLog);

}
...

输出:

Success opening Vertex Shader:  true 
"attribute highp   vec4  inVertex;
attribute mediump vec2  inTexCoord;
varying mediump vec2  TexCoord;
void main()
{
                gl_Position = inVertex;
                TexCoord = inTexCoord;
}
" 
Success opening Fragment Shader:  true 
"#ifdef GL_IMG_texture_stream2
#extension GL_IMG_texture_stream2 : enable
#endif
varying mediump vec2 TexCoord;
uniform samplerStreamIMG sTexture;
uniform sampler2D table1;
uniform sampler2D table2;
uniform sampler2D table3;
uniform sampler2D palette;
void main(void)
{
        highp vec4 texVal = textureStreamIMG( sTexture, TexCoord );
        highp vec4 tb1Val = texture2D( table1, TexCoord );
        highp vec4 tb2Val = texture2D( table2, TexCoord );
        highp vec4 tb3Val = texture2D( table3, TexCoord );
        highp float index = ( texVal.g * 255.0 ) * 256.0 + texVal.b * 255.0;
        highp float x = ( mod(index,256.0) ) / 256.0;
        highp float y = ( index / 256.0 ) / 256.0;
        highp vec4 palValue = texture2D( palette, vec2(x, y) );
        gl_FragColor = vec4(palValue.a,palValue.r,palValue.g,palValue.b);
}
" 
Vertex Shader failed to compile! 
Error in vertex shader compilation!
Info log: Compile failed.
ERROR: Unexpected end of source found
ERROR: 1 compilation errors. No code generated.


Fragment Shader successfully compiled! 
Linking was unsuccessful... 

const char* FragmentShaderSource = fOut.toStdString().c_str();

此处的这一行容易触发未定义的行为——您正在从临时文件(toStdString() 返回的 std::string)中提取 c_str(),这将是在语句末尾销毁...!


相反,保持简单。使用以下命令读取所有文件内容:

const QByteArray fragmentShaderSource = fSh.readAll(); 

不使用循环,QTextStream,或其他奇怪的东西;然后通过

将其内容上传到着色器中
glShaderSource(fragmentShaderObject, 1, fragmentShaderSource.constData(), NULL);