![](/img/trans.png)
[英]How pass a variable ( not uniform) float value from c++ to a vertex shader 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()
提取c_str()
,该语句将在语句末尾销毁... !
相反,请保持简单。 使用以下命令读取文件的所有内容:
const QByteArray fragmentShaderSource = fSh.readAll();
不使用循环, QTextStream
或其他奇怪的东西; 然后通过以下方式将其内容上传到着色器中
glShaderSource(fragmentShaderObject, 1, fragmentShaderSource.constData(), NULL);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.