0

I'm writing an application that renders every frame of in interleaved stereoscopic 3d. To make this happen, I am writing two fragment shaders: one to render the left eye's frame's odd rows, and one to render the even rows of pixels of the right frame.

I was using OSX's builtin OpenGL Shader Builder application, and I was able to successfully render every odd row as green: OpenGL Shader Builder odd row fragment shader

As you can see, the frag code I'm using looks like this:

    void main(){
        if ( mod(gl_FragCoord.y - 0.5, 2.0) == 1.0){
            gl_FragCoord = vec4(0.0, 1.0, 0.0, 1.0);
        }
    }

However, I wrote a small OpenGL application to test this shader (Btw, this is NVIDIA OpenGL 2.1, OSX 10.6.8):

    #include <iostream>
    #include <stdio.h>


    #ifdef __APPLE__
    #include <OpenGL/gl.h>
    #include <OpenGL/glu.h>
    #include <GLUT/glut.h>


    void DrawGLScene(){
      glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

      glFlush();
      glutSwapBuffers();
    }


    void Shading(){
      //Fragment shader we want to use
      GLuint oddRowShaderId = glCreateShader(GL_FRAGMENT_SHADER);
      std::cout << "Creating the fragment shader with id " << oddRowShaderId << std::endl;

      const GLchar *source[] = 
      { "void main(){   \n",
        "  if (mod(gl_FragCoord.y-0.5, 2.0) == 0.0){\n",
        "    gl_FragColor = vec4( 0.0, 1.0, 0.0, 1.0 );\n",
        //"    gl_BackColor = vec4( 0.0, 1.0, 0.0, 1.0 );\n"
        "  }\n",
        "}\n"
      };

      std::cout << "Shader source:\n" << source[0] << source[1] << source[2] << source[3] <       < source[4] << std::endl;


      std::cout << "Gathering shader source code" << std::endl;
      glShaderSource(oddRowShaderId, 1, source, 0);

      std::cout << "Compiling the shader" << std::endl;
      glCompileShader(oddRowShaderId);

      std::cout << "Creating new glCreateProgram() program" << std::endl;
      GLuint shaderProgramId = glCreateProgram();    //Shader program id

      std::cout << "Attaching shader to the new program" << std::endl;
      glAttachShader(shaderProgramId, oddRowShaderId); //Add the fragment shader to the         program

      std::cout << "Linking the program " << std::endl;
      glLinkProgram(shaderProgramId);                //Link the program


      std::cout << "Using the shader program for rendering" << std::endl;
      glUseProgram(shaderProgramId);                  //Start using the shader
    }

    void keyboard(int key, int x, int y){
      switch(key){
      case 's':
        Shading();
        break;
      case 'q':
        exit(0);
        break;
      }

    }

    void idleFunc(){
      glutPostRedisplay();        //Redraw the scene.
    }

    int main(int argc, char** argv){
      glutInit(&argc, argv);
      glutInitWindowPosition(100, 100);
      glutInitWindowSize(1000,1000);
      glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
      glutCreateWindow("anaglyph test");
      glutDisplayFunc(DrawGLScene);
      glutSpecialFunc(keyboard);
      glutIdleFunc(idleFunc);

      glutMainLoop();
    }

This is the output I get from running the code: Error Output I have a feeling I may not be compiling and glUsePrograming the fragment shader correctly.

genpfault
  • 51,148
  • 11
  • 85
  • 139
a10y
  • 309
  • 6
  • 11
  • 1
    You're not doing any error checking of your shader compile and link, which is not good. You should be using glGetShaderiv/glGetProgramiv to query GL_COMPILE_STATUS and GL_LINK_STATUS after each compile and after linking, and if they don't come back as TRUE use glGetShaderInfoLog/glGetProgramInfoLog to see what it's complaining about. Also I'll not recommend doing equality tests on floats as you might get some rounding problems. See if you can reproduce `==1.0` with a greater/less than comparison that is tolerant of minor rounding errors. – Tim Nov 14 '12 at 01:12
  • thanks so much! I Implemented those functions now, and I found out it was a compilation problem. I seem to have fixed that, but now [I am getting this bus error when I try and run the program](http://i.imgur.com/gBJDz.png) – a10y Nov 14 '12 at 01:35
  • quick sidenote: the bus error is definitely being caused by the linker. Right now, I changed the code so that instead of creating a GLchar** array of each line of source, I just made it a single GLchar* and pass a pointer to it to glShaderSource(). Here's a gist of the new source file: https://gist.github.com/4069710 – a10y Nov 14 '12 at 01:42

1 Answers1

0

Your can save some performance and gain some compatibility and it will result in less headache by using 2 pixel texture mask (even pixels are black, odd - white) and tile it on top of full-screen quads (you will have 2 of them: right eye and left eye). Use inverted mask or put some coord offset on second quad. In general it will look like this:

(perspective and huge gaps added for visualization) enter image description here

Put scene texture(or whatever you have) on quad and use mask color to discard fragments or transparency. To avoid using 2 g-buffers (GPU memory) you can render a full scene for one eye in texture and for another in view and on top of it render full-screen quad with first scene texture and transparency mask. Or render them separate if you need two outputs.


Main point is that you should use masking instead of logic operations based on texture coordinates.

JAre
  • 4,666
  • 3
  • 27
  • 45