Advertisement

Shader doesn't compile the second time it's created (by new)

Started by August 15, 2017 12:08 AM
5 comments, last by sjhalayka 7 years, 5 months ago

The code is up at: https://github.com/sjhalayka/iOS_Blind_Poker

In GameViewController.mm I create and destroy a shader object. The second time the shader is created (in setupGL), it fails to compile the vertex shader and fragment shader.

Any ideas as to why that happens?

The relevant functions from GameViewController.mm are listed below. The functions setupGL and tearDownGL are called from AppDelegate.m. Note that the shader code was given by Carsten Haubold. The setupGL code can be called a second time by pressing the Home button and then switching back to the game.


	
- (void)setupGL
{
    if(gl_setup == true)
        return;
    
    gl_setup = true;
    
    NSLog(@"setupGL");
    
    [EAGLContext setCurrentContext:self.context];
    
    glClearColor(0.284313, 0.415686, 0, 1);
    
    glEnable(GL_CULL_FACE);
	    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    shader = new Shader("shader.vert", "shader.frag");
    
    if(!shader->compileAndLink())
        NSLog(@"Failed to load shader");
    
    //tell OpenGL to use this shader for all coming rendering
    glUseProgram(shader->getProgram());
    
    unsigned int m_renderbufferWidth, m_renderbufferHeight;
    CGRect Rect=[[UIScreen mainScreen] bounds];
    m_renderbufferWidth = Rect.size.width;
    m_renderbufferHeight = Rect.size.height;
    
    float projection_modelview_mat[16];
    
    init_perspective_camera(45.0f,
                            float(m_renderbufferWidth)/float(m_renderbufferHeight),
                            0.01f, 10.0f,
                            0, 0, 1, // Camera position.
                            0, 0, 0, // Look at position.
                            0, 1, 0, // Up direction vector.
                            projection_modelview_mat);
    
    GLint projection = glGetUniformLocation(shader->getProgram(), "mvp_matrix");
    glUniformMatrix4fv(projection, 1, GL_FALSE, &projection_modelview_mat[0]);
	    glGenBuffers(1, &triangle_buffer);
	    glActiveTexture(GL_TEXTURE0);
    glGenTextures(1, &card_tex);
    glBindTexture(GL_TEXTURE_2D, card_tex);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    
    NSString *fileRoot = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"card_texture.tga"];
    
    tga_32bit_image card_img;
    
    card_img.load([fileRoot UTF8String]);
    
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, card_img.width, card_img.height,
                 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, &card_img.pixels[0]);
	    
    
    glActiveTexture(GL_TEXTURE1);
    glGenTextures(1, &rank_tex);
    glBindTexture(GL_TEXTURE_2D, rank_tex);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    
    fileRoot = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"rank_texture.tga"];
    
    tga_32bit_image rank_img;
 
    rank_img.load([fileRoot UTF8String]);
    
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rank_img.width, rank_img.height,
                 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, &rank_img.pixels[0]);
}
	- (void)tearDownGL
{
    if(gl_setup == false)
        return;
    
    gl_setup = false;
    
    NSLog(@"tearDownGL");
    
    [EAGLContext setCurrentContext:self.context];
    
    glDeleteBuffers(1, &triangle_buffer);
    
    glDeleteTextures(1, &card_tex);
    
    glDeleteTextures(1, &rank_tex);
    
    delete shader;
}
 
	

 

Any chance the working directory is being changed?  Can you post your log / crash output here?  Could you add a log statement before compiling the shaders (in the loadAndCompileShaderFile function) to print out the working directory?

Advertisement

The shaders compile fine, it's just that the shader == 0 on the second go around. So, the file is loading fine, and compiling. The log length is zero:


	GLint logLength;
	glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
	

The problem is that glCreateShader(GL_VERTEX_SHADER) and glCreateShader(GL_FRAGMENT_SHADER) returns 0. The document for this page says that happens when there's an error during the creation process, period.

glGetError() returns 0, which is guaranteed to be GL_NO_ERROR.

It all works fine if I move my shader creation code from - (void)setupGL to - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect. This is unfortunate, because it loads and compiles the shader every frame. :(

This makes me wonder if I'm trying to create the shaders while the OpenGL context is invalid.

Yes, it turns out that I was calling glCreateShader() while the context was invalid. So, I call setupGL the first frame of animation, during the draw call, where the context is guaranteed to be valid.

This topic is closed to new replies.

Advertisement