Board logo

标题: [原创教程] Html5 Canvas + WebGL 简单示例 [打印本页]

作者: 523066680    时间: 2017-7-7 15:41     标题: Html5 Canvas + WebGL 简单示例

HTML5 Canvas 示例

WebGL工具库:
[attach]10725[/attach]
作者: 523066680    时间: 2017-7-8 17:18

HTML JS 分离,从 顶点着色器确定一个点的位置,并着色。
  1. <!DOCTYPE html>
  2. <html lang="en">
  3.   <head>
  4.     <meta charset="utf-8" />
  5.     <title>WebGL</title>
  6.   </head>
  7.   <body onload="main()">
  8.     <canvas id="example1" width="400" height="400">
  9.       Please use a browser that supports "canvas"
  10.     </canvas>
  11.     <script src="./lib/webgl-utils.js"></script>
  12.     <script src="./lib/webgl-debug.js"></script>
  13.     <script src="./lib/cuon-utils.js"></script>
  14.     <script src="./example1.js"></script>
  15.   </body>
  16. </html>
复制代码
  1. function main()
  2. {
  3.     // Vertex shader program 顶点着色器
  4.     var VSHADER_SOURCE =
  5.         'void main() {\n' +
  6.         '  gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n' + // 设置图元的顶点坐标
  7.         '  gl_PointSize = 10.0;\n' +                    // 设置点的大小
  8.         '}\n';
  9.     // Fragment shader program  片元着色器
  10.     var FSHADER_SOURCE =
  11.         'void main() {\n' +
  12.         '  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' + // 颜色
  13.         '}\n';
  14.     var canvas = document.getElementById('example1');
  15.     // 获取 WebGL 环境
  16.     var gl = getWebGLContext(canvas);
  17.     // 初始化着色器
  18.     if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE))
  19.     {
  20.         console.log('Failed to intialize shaders.');
  21.         return;
  22.     }
  23.    
  24.     //设置并清除颜色缓冲区
  25.     gl.clearColor(0.0, 0.0, 0.0, 1.0);
  26.     gl.clear(gl.COLOR_BUFFER_BIT);
  27.     gl.drawArrays(gl.Points, 0, 1);
  28. }
复制代码

作者: happy886rr    时间: 2017-7-8 17:44

回复 2# 523066680
我也觉得前端很好玩,打算放弃C语言,转学前端。
作者: 523066680    时间: 2017-7-8 17:49

本帖最后由 523066680 于 2017-7-8 17:55 编辑

回复 3# happy886rr

    C/C++属于终身技能,说"放弃",言重了。只是临时换口味。而且 js 还是类C语言,花括号分号一样一样的。
作者: 523066680    时间: 2017-7-8 19:15

本帖最后由 523066680 于 2017-7-8 19:29 编辑

昨天把自己那个1024特效用shader完成了,用WebGL是为了方便学习和实践,本质上我还是在用纯C作为主程序,希望能一直用下去。

实时动态渲染
  1. #include <GL/glew.h>
  2. #include <GL/freeglut.h>
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. #include <math.h>
  6. #include <time.h>
  7. #define SIZE_X 500
  8. #define SIZE_Y 500
  9. int winID;
  10. int program;
  11. GLuint vTest;
  12. GLfloat test = 200.0;
  13. GLuint vAng;
  14. GLfloat ang = 0.0;
  15. const GLchar* readShader( const char *filename );
  16. void display(void)
  17. {
  18.     static const GLfloat black[] = { 0.0f, 0.0f, 0.0f, 1.0f };
  19.     glClearBufferfv(GL_COLOR, 0, black );
  20.     glDrawArrays(GL_POINTS, 0, 1);
  21.     glutSwapBuffers();
  22. }
  23. void idle(void)
  24. {
  25.     usleep(10000);
  26.     ang += 0.05;
  27.     glVertexAttrib1f( vAng, ang );
  28.     glutPostRedisplay();
  29. }
  30. void reshape(int Width,int Height)
  31. {
  32.     glViewport(0, 0, Width, Height);     //视口范围
  33. }
  34. void keypress(unsigned char key, int mousex, int mousey)
  35. {
  36.     switch (key)
  37.     {
  38.         case 'q':
  39.             glutDestroyWindow(winID);
  40.             exit(0);
  41.             break;
  42.         case 'Q':
  43.             glutDestroyWindow(winID);
  44.             exit(0);
  45.             break;
  46.         case ']':
  47.             test += test*0.1;
  48.             glVertexAttrib1f( vTest, test );
  49.             glutPostRedisplay();
  50.             break;
  51.         case '[':
  52.             test -= test*0.1;
  53.             glVertexAttrib1f( vTest, test );
  54.             glutPostRedisplay();
  55.             break;
  56.     }
  57. }
  58. void init(void)
  59. {
  60.     glClearColor(0.0, 0.0, 0.0, 0.0);
  61.     //允许修改点元素大小
  62.     glEnable(GL_PROGRAM_POINT_SIZE);
  63.     srand(time(NULL));
  64. }
  65. int loadShader(void)
  66. {
  67.     // Very Important !
  68.     glewInit();
  69.     const GLchar * vs_src;
  70.     const GLchar * fs_src;
  71.     vs_src = readShader( "pointTest.vert" );
  72.     fs_src = readShader( "pointTest.frag" );
  73.     GLuint vs = glCreateShader(GL_VERTEX_SHADER);
  74.     glShaderSource(vs, 1, &vs_src, NULL);
  75.     glCompileShader(vs);
  76.     GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
  77.     glShaderSource(fs, 1, &fs_src, NULL);
  78.     glCompileShader(fs);
  79.     program = glCreateProgram();
  80.     glAttachShader(program, vs);
  81.     glAttachShader(program, fs);
  82.     glLinkProgram(program);
  83.     glUseProgram(program);
  84.     vTest = glGetAttribLocation( program, "vTest" );
  85.     glVertexAttrib1f( vTest, test );
  86.     printf("%d\n", vTest);
  87.     vAng = glGetAttribLocation( program, "vAng" );
  88.     glVertexAttrib1f( vAng, ang );
  89. }
  90. int main(int argc, char *argv[])
  91. {
  92.     glutInit(&argc, argv);
  93.             //显示模式   双缓冲         RGBA  
  94.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
  95.     glutInitWindowSize(SIZE_X, SIZE_Y);       //窗口大小
  96.     glutInitWindowPosition(10, 10);         //位置
  97.     winID = glutCreateWindow("Simple");  //窗口句柄
  98.     init();
  99.     loadShader();
  100.     glutDisplayFunc(display);          //显示
  101.     glutKeyboardFunc(keypress);        //按键事件响应
  102.     glutReshapeFunc(reshape);          //窗口事件响应
  103.     glutIdleFunc(idle);                //闲时回调函数
  104.     glutMainLoop();                    //开始主循环
  105.     return 0;
  106. }
  107. const GLchar* readShader( const char *filename )
  108. {
  109.     FILE *FILE = fopen(filename, "rb");
  110.     GLchar *source;
  111.     int size;
  112.     fseek( FILE, 0, SEEK_END  );
  113.     size = ftell(FILE) + 1;
  114.     fseek( FILE, 0, SEEK_SET  );  //turn back
  115.     source = (GLchar *) malloc( sizeof(GLchar) * size );
  116.     fread( source, 1, size, FILE);
  117.     return (const GLchar*)(source);  //强制转换
  118. }
复制代码
Vertex Shader
  1. #version 420 core
  2. attribute float vTest;
  3. attribute float vAng;
  4. out vec4 coord;
  5. out float fTest;
  6. out float fAng;
  7. void main(void)
  8. {
  9.     gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
  10.     gl_PointSize = 480.0;
  11.     coord = gl_Position;
  12.     fTest = vTest;
  13.     fAng = vAng;
  14. }
  15. /*
  16.     备注:attribute 只能在 顶点着色器中使用
  17.     实际测试 如果 main 中没有用到 传入的变量
  18.     主程序中就无法通过 GetAttribLocation 获取该变量索引。
  19. */
复制代码
Fragment Sahder
  1. #version 420 core
  2. in float fTest;
  3. in float fAng;
  4. float RGB(float x, float y, float e)
  5. {
  6.     return ( x * tan(x/y) ) * ( y * tan( x/y + fAng*e ) ) / fTest;
  7. }
  8. void main(void)
  9. {
  10.     vec4 coord = (gl_FragCoord - 250.0)*2.0; //平移,并扩大两倍计算范围
  11.     gl_FragColor =
  12.         vec4(
  13.             int(RGB(coord.x, coord.y, 0.33))%255/255.0,
  14.             int(RGB(coord.x, coord.y, 0.66))%255/255.0,
  15.             int(RGB(coord.x, coord.y, 0.99))%255/255.0,
  16.             0.0
  17.         );
  18. }
复制代码
编译脚本(实在记不住 makefile 语法,用批处理)
  1. @echo off
  2. set path=D:\tdm-gcc-64\bin
  3. :Compile
  4. gcc -std=c11 "%1" -o "%~n1.exe" ^
  5.                    -ID:\Lib\freeglut-MinGW-3.0.0-1.mp\include  ^
  6.                    -LD:\Lib\freeglut-MinGW-3.0.0-1.mp\lib\x64 ^
  7.                    -ID:\Lib\glew-1.13.0\include ^
  8.                    -LD:\Lib\glew-1.13.0\lib ^
  9.                    -lfreeglut -lglew32 -lopengl32 -lglu32
  10. :Run
  11. if %errorlevel% == 0 (
  12. %~n1.exe
  13. ) else (
  14. echo Compile Error
  15. pause
  16. )
复制代码

作者: 523066680    时间: 2017-7-8 19:36

本帖不再更新,对于有兴趣的朋友,推荐:《WebGL Programming Guide》




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2