Sign in to follow this  
theZapper

iOS Shaders compile (even though they shouldn't)

Recommended Posts

theZapper    150
I'm pretty confused here. I'm trying to write an OpenGL ES 2.0 app for iOS. However, when my shaders compile I get no errors messages, even if they contain obvious errors like undefined variables. I then get link errors saying [font="Menlo"][size="2"][b]ERROR: One or more attached shaders not successfully compiled.[/b][/size][/font]

[font="Menlo"] [/font]Does anyone know why this would be?

I'm using iOS sdk 4.3 on the simulator, I'm still waiting for my iPod for testing.

Cheers

Share this post


Link to post
Share on other sites
theZapper    150
Yep, here are the two methods. buildShader always seems to pass and return a valid shader handle, even when I the shaders have errors.

[code]void cShader::buildProgram(const char* vShader, const char* fShader){

cout << vShader << "\n" << fShader;



ifstream myfile(vShader);

std::stringstream ss;

if (myfile.is_open())

{

ss << myfile.rdbuf();

//cout << ss.str().c_str() << endl;



myfile.close();

}



GLuint vertexShader = buildShader(ss.str().c_str(), GL_VERTEX_SHADER);



myfile.open(fShader);

if (myfile.is_open())

{

ss.clear();

ss.str("");

ss << myfile.rdbuf();

//cout << ss.str().c_str() << endl;



myfile.close();

}



GLuint fragmentShader = buildShader(ss.str().c_str(), GL_FRAGMENT_SHADER);



programHandle = glCreateProgram();

glAttachShader(programHandle, vertexShader);

glAttachShader(programHandle, fragmentShader);

glLinkProgram(programHandle);



GLint linkSuccess;

glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess);



if (linkSuccess == GL_FALSE)

{

GLchar messages[256];

glGetProgramInfoLog(programHandle, sizeof(messages), 0, &messages[0]);

std::cout << messages;

exit(1);

}



// save often used parameters for later

projectionUniform = glGetUniformLocation(programHandle, "uni_proj");

}




GLuint cShader::buildShader(const char* source, GLenum shaderType)

{

GLuint shaderHandle = glCreateShader(shaderType);

glShaderSource(shaderHandle, 1, &source, 0);

glCompileShader(shaderHandle);



GLint compileSuccess;

glGetProgramiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess);



if (!compileSuccess)

{

GLchar messages[256];

glGetProgramInfoLog(shaderHandle, sizeof(messages), 0, &messages[0]);

std::cout << messages;

exit(1);

}



return shaderHandle;


}[/code]

These are the shaders I'm currently trying to compile. I've systematically commented bits in and out to find the problems.

Vertex Shader:

[code]
// Attributes change on a per vertex basisattribute vec4 att_pos;

//attribute vec4 srcCol;

attribute vec2 att_tex01;

attribute vec4 att_nml;




// Varyings are output to the fragment shader and are interpolated between vertices

//varying vec4 destCol;

varying vec2 var_tex01;

varying vec4 var_nml;

varying vec4 var_pos;




// Uniforms remain constant over the course of the draw call

uniform mat4 uni_proj;

uniform mat4 uni_modelView;

//uniform vec3 uni_pointLight1;




void main()

{

//destCol = srcCol;

//var_tex01 = att_tex01;

var_nml = att_nml;

var_pos = uni_modelView * att_pos;



gl_Position = uni_proj * uni_modelView * att_pos;


}
[/code]

Pixel Shader:

[code][color=#FF3DF7]//varying lowp vec4 destCol;[/color]uniform sampler2D uni_texture0;

//uniform vec3 uni_pointLight1;




varying mediump vec2 var_tex01;

varying mediump vec4 var_nml;

varying mediump vec4 var_pos;




void main()

{

//vec4 light = vec4(0.0, 1.0, 0.0, 0.0);

//vec4 L = normalize(light - var_pos);

//float diff = max(dot(var_nml, L), 0.0);



//gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);// * diff;



gl_FragColor = var_nml; //texture2D(uni_texture0, var_tex01);


[color=#971F8E]}[/color][/code]



As they stand, these two currently compile and link, but if I comment in the first line in the pixel shader (vec4 light...) they will still compile but fail to link.

I had similar problems with the variables in the vertex shader being spelt wrong, which should give a syntax error and un-recognised symbol error, but they quite happily compiled then failed to link.

Share this post


Link to post
Share on other sites
karwosts    840
[code]
glGetProgramiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess);
[/code]

GL_COMPILE_STATUS is not a valid argument to glGetProgramiv. You probably mean glGetShaderiv here.

[url="http://www.opengl.org/sdk/docs/man/xhtml/glGetShader.xml"]glGetShaderiv[/url]
[url="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgram.xml"]glGetProgramiv[/url]

This is why you need to call glGetError, it would be throwing errors that you're using the glGetProgramiv incorrectly.

Share this post


Link to post
Share on other sites
theZapper    150
You superstar!

In the meantime I've actually just put this bit of code in...

[code]GLint infoLength;
glGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH, &infoLength);

if (infoLength > 0)
{

char infoLog[512];

glGetShaderInfoLog(shaderHandle, infoLength, NULL, infoLog);
std::cout << infoLog;

}[/code]


... which started pumping out errors (Notice the correct usage of glGetShaderiv this time though!)

I'm betting I inserted the wrong function name by not paying attention to the intellisense popup in Xcode. So it's all Xcode's fault really.

I also found that you need to stick a precision qualifier on the problem vec4 light definition, I thought it was only the varyings and global type ones, but there we go.


Thanks again mate!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this