返回列表 发帖

[原创教程] Html5 Canvas + WebGL 简单示例

HTML5 Canvas 示例


          <!DOCTYPE html>
          <html lang="en">
            <head>
              <meta charset="utf-8" />
              <title>Canvas</title>
            </head>

            <body onload="main()">
              <canvas id="example1" width="400" height="400">
                Please use a browser that supports "canvas"
              </canvas>
              <script>
                function main()
                {
                  var canvas = document.getElementById('example1');
                  if (! canvas )
                  {
                    console.log('Failed to retrieve the <canvas> element');
                    return;
                  }
                  
                  var ctx = canvas.getContext('2d');      // 注意是小写'd'
                  
                  ctx.fillStyle = 'rgba(0, 0, 255, 1.0)'; //设置填充颜色
                  ctx.fillRect(120, 10, 150, 150);        //矩形填充,设置范围
                }
              </script>
            </body>
          </html>

      在线展示:
      http://runjs.cn/code/8r9cqjly

      通过 var canvas = document.getElementById('example1') 获取指定id的 canvas 元素,
      ID名称 example1 和前面的 <canvas id="example1" width="400" height="400"> 相对应 ,
      其中 width 和 height 指定了画布尺寸。

      然后获取 2d 绘制环境 var ctx = canvas.getContext('2d');

      接下来对这个代码进行修改,仍旧需要 html5 画布作为基础,但是渲染环境改为 WebGL

          <html lang="en">
            <head>
              <meta charset="utf-8" />
              <title>Canvas</title>
            </head>

            <body onload="main()">
              <canvas id="example1" width="400" height="400">
                Please use a browser that supports "canvas"
              </canvas>
              <!-- 加载 WebGL 工具库 -->
              <script src="./lib/webgl-utils.js"></script>
              <script src="./lib/webgl-debug.js"></script>
              <script src="./lib/cuon-utils.js"></script>

              <script>
                function main()
                {
                  var canvas = document.getElementById('example1');

                  // 获取 WebGL 渲染环境
                  var gl = getWebGLContext(canvas);

                  // 设置清屏颜色
                  gl.clearColor(0.0, 0.0, 0.0, 1.0);

                  // 刷新颜色缓冲区
                  gl.clear(gl.COLOR_BUFFER_BIT);
                }
              </script>
            </body>
          </html>

      在线示例:
      http://runjs.cn/code/xvrr2zpv


WebGL工具库:
[attach]10725[/attach]
[url=][/url]

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

评分人数

[url=][/url]

TOP

回复 2# 523066680
我也觉得前端很好玩,打算放弃C语言,转学前端。

TOP

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

回复 3# happy886rr

    C/C++属于终身技能,说"放弃",言重了。只是临时换口味。而且 js 还是类C语言,花括号分号一样一样的。
[url=][/url]

TOP

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

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

实时动态渲染
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <stdio.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#define SIZE_X 500
#define SIZE_Y 500
int winID;
int program;
GLuint vTest;
GLfloat test = 200.0;
GLuint vAng;
GLfloat ang = 0.0;
const GLchar* readShader( const char *filename );
void display(void)
{
    static const GLfloat black[] = { 0.0f, 0.0f, 0.0f, 1.0f };
    glClearBufferfv(GL_COLOR, 0, black );
    glDrawArrays(GL_POINTS, 0, 1);
    glutSwapBuffers();
}
void idle(void)
{
    usleep(10000);
    ang += 0.05;
    glVertexAttrib1f( vAng, ang );
    glutPostRedisplay();
}
void reshape(int Width,int Height)
{
    glViewport(0, 0, Width, Height);     //视口范围
}
void keypress(unsigned char key, int mousex, int mousey)
{
    switch (key)
    {
        case 'q':
            glutDestroyWindow(winID);
            exit(0);
            break;
        case 'Q':
            glutDestroyWindow(winID);
            exit(0);
            break;
        case ']':
            test += test*0.1;
            glVertexAttrib1f( vTest, test );
            glutPostRedisplay();
            break;
        case '[':
            test -= test*0.1;
            glVertexAttrib1f( vTest, test );
            glutPostRedisplay();
            break;
    }
}
void init(void)
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    //允许修改点元素大小
    glEnable(GL_PROGRAM_POINT_SIZE);
    srand(time(NULL));
}
int loadShader(void)
{
    // Very Important !
    glewInit();
    const GLchar * vs_src;
    const GLchar * fs_src;
    vs_src = readShader( "pointTest.vert" );
    fs_src = readShader( "pointTest.frag" );
    GLuint vs = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vs, 1, &vs_src, NULL);
    glCompileShader(vs);
    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fs, 1, &fs_src, NULL);
    glCompileShader(fs);
    program = glCreateProgram();
    glAttachShader(program, vs);
    glAttachShader(program, fs);
    glLinkProgram(program);
    glUseProgram(program);
    vTest = glGetAttribLocation( program, "vTest" );
    glVertexAttrib1f( vTest, test );
    printf("%d\n", vTest);
    vAng = glGetAttribLocation( program, "vAng" );
    glVertexAttrib1f( vAng, ang );
}
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
            //显示模式   双缓冲         RGBA  
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(SIZE_X, SIZE_Y);       //窗口大小
    glutInitWindowPosition(10, 10);         //位置
    winID = glutCreateWindow("Simple");  //窗口句柄
    init();
    loadShader();
    glutDisplayFunc(display);          //显示
    glutKeyboardFunc(keypress);        //按键事件响应
    glutReshapeFunc(reshape);          //窗口事件响应
    glutIdleFunc(idle);                //闲时回调函数
    glutMainLoop();                    //开始主循环
    return 0;
}
const GLchar* readShader( const char *filename )
{
    FILE *FILE = fopen(filename, "rb");
    GLchar *source;
    int size;
    fseek( FILE, 0, SEEK_END  );
    size = ftell(FILE) + 1;
    fseek( FILE, 0, SEEK_SET  );  //turn back
    source = (GLchar *) malloc( sizeof(GLchar) * size );
    fread( source, 1, size, FILE);
    return (const GLchar*)(source);  //强制转换
}COPY
Vertex Shader
#version 420 core
attribute float vTest;
attribute float vAng;
out vec4 coord;
out float fTest;
out float fAng;
void main(void)
{
    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
    gl_PointSize = 480.0;
    coord = gl_Position;
    fTest = vTest;
    fAng = vAng;
}
/*
    备注:attribute 只能在 顶点着色器中使用
    实际测试 如果 main 中没有用到 传入的变量
    主程序中就无法通过 GetAttribLocation 获取该变量索引。
*/COPY
Fragment Sahder
#version 420 core
in float fTest;
in float fAng;
float RGB(float x, float y, float e)
{
    return ( x * tan(x/y) ) * ( y * tan( x/y + fAng*e ) ) / fTest;
}
void main(void)
{
    vec4 coord = (gl_FragCoord - 250.0)*2.0; //平移,并扩大两倍计算范围
    gl_FragColor =
        vec4(
            int(RGB(coord.x, coord.y, 0.33))%255/255.0,
            int(RGB(coord.x, coord.y, 0.66))%255/255.0,
            int(RGB(coord.x, coord.y, 0.99))%255/255.0,
            0.0
        );
}COPY
编译脚本(实在记不住 makefile 语法,用批处理)
@echo off
set path=D:\tdm-gcc-64\bin
:Compile
gcc -std=c11 "%1" -o "%~n1.exe" ^
                   -ID:\Lib\freeglut-MinGW-3.0.0-1.mp\include  ^
                   -LD:\Lib\freeglut-MinGW-3.0.0-1.mp\lib\x64 ^
                   -ID:\Lib\glew-1.13.0\include ^
                   -LD:\Lib\glew-1.13.0\lib ^
                   -lfreeglut -lglew32 -lopengl32 -lglu32
:Run
if %errorlevel% == 0 (
%~n1.exe
) else (
echo Compile Error
pause
)COPY
[url=][/url]

TOP

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

TOP

返回列表