zoukankan      html  css  js  c++  java
  • GLSL新手上路 《交互式计算机图形学》附录中GLSL代码有误 修改如下

    《交互式计算机图形学》可谓是一本很不错的graphics领域的入门书籍,这是站在客观的角度来说的,尽管书中有我老板的名字。然而,对于小猪这样的菜鸟,这本书是非常合适的。以前总以为自己的图形学是多么多么的牛B,因为毕竟用Level set做过surface reconstruction以及ray tracing,用GPU做ocean surface simulation等等,自我感觉是图形学小牛,然而,CUHK的老大让我做一个基于ray casting的体绘制和面绘制结合起来,却一时想不起来如何下手。所以,最近一周恶补图形学基本知识,就用上《交互式计算机图形学》这本书了,这本书将的非常好,top-down,非常喜欢这种讲述方式,因此,用了三天,已经看得差不多了,毕竟以前对图形学领域的前沿知识还是了解的,所以,哈哈。

    下面重点说GLSL一章的问题,这本书讲的是很好,但是附录中的GLSL的代码是有问题的,不能顺利运行,我用的是《交互式计算机图形学》(第五版),主要是,

    1. 没有进行glew初始化;

    2. 读取shader文件有误;

    分别对此进行了修改,废话不多说,贴正确的code。

    //////////////////////////////////////////////////////////////////////////
    /*
     * my first glsl program, hello - glsl
     * now, go!
     *
     */


    #define GLUT_DISABLE_ATEXIT_HACK


    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <gl/glew.h>
    #include <gl/glut.h>

    // grid resolution
    #define N 64


    // vision region
    const GLdouble nearVal = 1.0;
    const GLdouble farVal  = 20.0;

    // program object ID
    GLuint program = 0;

    GLint timeParam;


    // error buffer and error message length
    GLchar *ebuffer;
    GLsizei elength;


    // high field data
    GLfloat data[N][N];

    // shader read entry function
    static char* readShaderSource(const char * shaderFile)
    {
     char *buf = NULL;

     int size(0);


     FILE *file = fopen(shaderFile, "r");

     if (!file) return NULL;

     fseek(file, 0, SEEK_END);

     size = ftell(file);

     rewind(file);


     if (size > 0)
     {
      buf = (char*)malloc(sizeof(char)*(size+1));

      size = fread(buf, sizeof(char), size, file);

      buf[size] = '\0';
     }

     fclose(file);

     return buf;
    }


    // init OpenGL
    static void initGL()
    {
     glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
     glColor3f(0.0, 0.0, 0.0);

     glMatrixMode( GL_PROJECTION );
     glLoadIdentity();
     glOrtho(-0.75, 0.75, -0.75, 0.75, -5.5, 5.5);
    }


    // init GLSL
    static void initShader(const GLchar * vShaderFile, const GLchar * fShaderFile)
    {
     GLint status;
     GLchar *vSource, *fSource;
     GLuint vShader, fShader;


     // read shader file
     vSource = readShaderSource(vShaderFile);


     if ( vSource == NULL )
     {
      printf("Failed to read vertex shader\n");

      exit( EXIT_FAILURE );
     }


     fSource = readShaderSource(fShaderFile);
     
     if ( fSource == NULL )
     {
      printf("Failed to read fragment shader\n");

      exit( EXIT_FAILURE );
     }


     //create program and shader object
     vShader = glCreateShader( GL_VERTEX_SHADER );
     fShader = glCreateShader( GL_FRAGMENT_SHADER );
     

     program = glCreateProgram();


     // bind shader to program object
     glAttachShader( program, vShader );
     glAttachShader( program, fShader );

     
     // read shader
     glShaderSource( vShader, 1, (const GLchar**)&vSource, NULL );
     glShaderSource( fShader, 1, (const GLchar**)&fSource, NULL );


     // compile vertex shader
     glCompileShader( vShader );


      // error detection
      glGetShaderiv( vShader, GL_COMPILE_STATUS, &status );
     
      if ( status == GL_FALSE )
      {
       printf("Failed to compile vertex shader\n");
     
       glGetShaderiv(vShader, GL_INFO_LOG_LENGTH, &elength);
     
       ebuffer = (char*)malloc(elength*sizeof(char));
     
       glGetShaderInfoLog(vShader, elength, NULL, ebuffer);
     
       printf("%s\n", ebuffer);
     
       exit( EXIT_FAILURE );
      }


     // compile fragment shader
     glCompileShader( fShader );

     // error detection
     glGetShaderiv( fShader, GL_COMPILE_STATUS, &status );

     if ( status == GL_FALSE )
     {
      printf("Failed to compile fragment shader\n");

      glGetShaderiv(fShader, GL_INFO_LOG_LENGTH, &elength);

      ebuffer = (char*)malloc(elength*sizeof(char));

      glGetShaderInfoLog(fShader, elength, NULL, ebuffer);

      printf("%s\n");

      exit( EXIT_FAILURE );
     }


     // link and error detection
     glLinkProgram( program );

     glGetProgramiv( program, GL_LINK_STATUS, &status );

     if ( status == GL_FALSE )
     {
      printf("Failed to link program object\n");

      glGetProgramiv( program, GL_INFO_LOG_LENGTH, &elength );

      ebuffer = (char*)malloc(elength*sizeof(char));

      glGetProgramInfoLog(program, elength, &elength, ebuffer);

      printf("%s\n");

      exit( EXIT_FAILURE );
     }


     // use program object
     glUseProgram( program );


     // set uniform parameter
     timeParam = glGetUniformLocation( program, "time" );

    }

    // mesh
    void mesh()
    {
     int i(0), j(0);

     glMatrixMode( GL_MODELVIEW );

     glLoadIdentity();

     gluLookAt(2.0, 2.0, 2.0, 0.5, 0.0, 0.5, 0.0, 1.0, 0.0);

     for (i = 0; i < N; i++)
     {
      for (j = 0; j < N; j++)
      {
       glBegin( GL_LINE_LOOP );
        glVertex3f((float)i/N, data[i][j], (float)j/N);
        glVertex3f((float)i/N, data[i][j], (float)(j+1)/N);
        glVertex3f((float)(i+1)/N, data[i][j], (float)(j+1)/N);
        glVertex3f((float)(i+1)/N, data[i][j], (float)j/N);
       glEnd();
      }
     }

    }


    static void display()
    {
     // transfer run-time to shader
     glUniform1f( timeParam, glutGet(GLUT_ELAPSED_TIME) );

     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

     mesh();

     glutSwapBuffers();

    }

    // reshape callback function
    static void reshape(int w, int h)
    {
     glMatrixMode( GL_PROJECTION );

     glLoadIdentity();

     glOrtho(-0.75, 0.75, -0.75, 0.75, -5.5, 5.5);


     glViewport(0, 0, w, h);

     glutPostRedisplay();

    }

    // keyboard callback function
    static void keyboard(unsigned char key, int x, int y)
    {
     switch(key)
     {
     case 27:
      
     case 'Q':

     case 'q':

      exit( EXIT_FAILURE );

      break;

      
     default:

      break;

     }

    }

    // idle callback function
    static void idle()
    {
     glUniform1f( timeParam, (GLfloat)glutGet(GLUT_ELAPSED_TIME) );

     glutPostRedisplay();

    }

    // check whether GLEW and GLSL are supported
    bool check()
    {
     const char * version = (const char*)glGetString( GL_VERSION );

     printf("OpenGL version : %s\n", version);


     // check OpenGL
     if ( glewIsSupported("GL_VERSION_2_0") )
     {
      printf("Ready for OpenGL 2.0\n");
     }
     else
     {
      printf("OpenGL 2.0 not supported\n");

      return false;
     }

     // check extensions
     if ( GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader )
     {
      printf("Ready for GLSL\n");
     }
     else
     {
      printf("Not totally ready\n");

      return false;
     }


     return true;

    }

    // main
    int main(int argc, char ** argv)
    {
     int i(0), j(0);

     for (i = 0; i < N; i++)
     {
      for (j = 0; j < N; j++)
      {
       data[i][j] = 0;
      }
     }

     glutInit(&argc, argv);

     glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );

     glutInitWindowSize(512, 512);

     glutCreateWindow("Simple GLSL example");

     glutDisplayFunc(display);

     glutReshapeFunc(reshape);

     glutKeyboardFunc(keyboard);

     glutIdleFunc(idle);

     // init GLEW, this is very important
     glewInit();


     // check whether GLEW and GLSL are supported
     if ( !check() )
     {
      return 0;
     }


     initGL();

     initShader("vmesh.vert", "fPassThrough.frag");

     glutMainLoop();


     return 0;

    }

    两个shader文件,分别存为vmesn.vert和fPassThrough.frag,代码如下:

    vmesh.vert文件

    //
    // vertex shader
    //


    uniform float time;


    void main()
    {
     float s;
     
     vec4 t = gl_Vertex;
     
     t.y = 0.1*sin(0.001*time + 5.0*gl_Vertex.x) * sin(0.001*time + 5.0*gl_Vertex.z);
     
     gl_Position = gl_ModelViewProjectionMatrix * t;
     
     gl_FrontColor = gl_Color;
     
    }

    fPassThrough.frag文件

    //
    // mesh shader
    //

    void main()
    {
     gl_FragColor = gl_Color;
    }

    这样就over了。

    欢迎大家提问题,多多交流。

    tc.zhu@sub.siata.c.cn

  • 相关阅读:
    7
    6
    5
    3
    4
    2
    1
    寒假工作经历
    软件工程第三周的总结
    软件工程第三周的学习报告 html<input> final finally finalize 的比较 BigInteger
  • 原文地址:https://www.cnblogs.com/tandychao/p/1798526.html
Copyright © 2011-2022 走看看