创建program

        //创建着色器对象//顶点着色器(GL_VERTEX_SHADER)/片段着色器(GL_FRAGMENT_SHADER)int shader = glCreateShader(type);if (shader == 0) return 0;//创建失败//加载着色器源glShaderSource(shader, shaderSource);//编译着色器glCompileShader(shader);//检查编译状态int[] compiled = new int[1];glGetShaderiv(shader, GL_COMPILE_STATUS, compiled, 0);if (compiled[0] == 0) {Log.e(TAG, glGetShaderInfoLog(shader));glDeleteShader(shader);Log.e(TAG, "failed to compile shader");//编译失败return 0;}int program = glCreateProgram();if (program == 0){Log.e(TAG, "failed to create program");}//绑定着色器到程序glAttachShader(program, vertexShader);glAttachShader(program, fragmentShader);//连接程序glLinkProgram(program);//检查连接状态int[] linked = new int[1];glGetProgramiv(program,GL_LINK_STATUS, linked, 0);if (linked[0] == 0){glDeleteProgram(program);Log.e(TAG, "failed to link program");//link失败return 0;}

顶点shader source:

#version 300 eslayout (location = 0) in vec4 a_Position;
layout (location = 1) in vec2 a_texCoord;
uniform mat4 u_matrix;
uniform mat4 watermark_matrix;
out vec2 v_texCoord;
out vec2 watermark_texCoord;void main()
{gl_Position = u_matrix * a_Position;watermark_texCoord = (watermark_matrix*vec4(a_texCoord.xy,1.0,1.0)).xy;v_texCoord = a_texCoord;
}

片段shader source:

#version 300 es
precision mediump float;in vec2 v_texCoord;
in vec2 watermark_texCoord;
out vec4 outColor;
uniform sampler2D s_texture;
uniform sampler2D textureLUT;
uniform sampler2D bgtexture;
uniform sampler2D watermarktexture;
uniform int colorFlag;//滤镜类型
uniform int viewType;//绿布背景替换显示,水印显示,等//rgb转hsl
vec3 rgb2hsl(vec3 color){vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);vec4 p = mix(vec4(color.bg, K.wz), vec4(color.gb, K.xy), step(color.b, color.g));vec4 q = mix(vec4(p.xyw, color.r), vec4(color.r, p.yzx), step(p.x, color.r));float d = q.x - min(q.w, q.y);float e = 1.0e-10;return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}//hsl转rgb
vec3 hsl2rgb(vec3 color){vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);vec3 p = abs(fract(color.xxx + K.xyz) * 6.0 - K.www);return color.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), color.y);
}//灰度
void grey(inout vec4 color){float weightMean = color.r * 0.3 + color.g * 0.59 + color.b * 0.11;color.r = color.g = color.b = weightMean;
}//黑白
void blackAndWhite(inout vec4 color){float threshold = 0.5;float mean = (color.r + color.g + color.b) / 3.0;color.r = color.g = color.b = mean >= threshold ? 1.0 : 0.0;
}//反向
void reverse(inout vec4 color){color.r = 1.0 - color.r;color.g = 1.0 - color.g;color.b = 1.0 - color.b;
}//亮度
void light(inout vec4 color){vec3 hslColor = vec3(rgb2hsl(color.rgb));hslColor.z += 0.15;color = vec4(hsl2rgb(hslColor), color.a);
}void light2(inout vec4 color){color.r += 0.15;color.g += 0.15;color.b += 0.15;
}//查找表滤镜
vec4 lookupTable(vec4 color){float blueColor = color.b * 63.0;vec2 quad1;quad1.y = floor(floor(blueColor) / 8.0);quad1.x = floor(blueColor) - (quad1.y * 8.0);vec2 quad2;quad2.y = floor(ceil(blueColor) / 8.0);quad2.x = ceil(blueColor) - (quad2.y * 8.0);vec2 texPos1;texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);vec2 texPos2;texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);vec4 newColor1 = texture(textureLUT, texPos1);vec4 newColor2 = texture(textureLUT, texPos2);vec4 newColor = mix(newColor1, newColor2, fract(blueColor));return vec4(newColor.rgb, color.w);
}//色调分离
void posterization(inout vec4 color){//计算灰度值float grayValue = color.r * 0.3 + color.g * 0.59 + color.b * 0.11;//转换到hsl颜色空间vec3 hslColor = vec3(rgb2hsl(color.rgb));//根据灰度值区分阴影和高光,分别处理if(grayValue < 0.3){//添加蓝色if(hslColor.x < 0.68 || hslColor.x > 0.66){hslColor.x = 0.67;}//增加饱和度hslColor.y += 0.3;}else if(grayValue > 0.7){//添加黄色if(hslColor.x < 0.18 || hslColor.x > 0.16){hslColor.x = 0.17;}//降低饱和度hslColor.y -= 0.3;}color = vec4(hsl2rgb(hslColor), color.a);
}
void filterBlue(inout vec4 tc){float r = tc.r * 255.0;float g = tc.g * 255.0;float b = tc.b * 255.0;if(g>140.0 && r<128.0 && b<128.0){tc.r =1.0;tc.g =1.0;tc.b =1.0;tc.a =0.0;}else{tc.a =1.0;}
}vec4 replaceBlue(inout vec4 base , inout vec4 bg){vec4 tempColor;if(base.r == 1.0 && base.g == 1.0 && base.b == 1.0 && base.a == 0.0){//tempColor.r = base.a*base.r + bg.r * (1.0 - base.a);//tempColor.g = base.a*base.g + bg.g * (1.0 - base.a);//tempColor.b = base.a*base.b + bg.b * (1.0 - base.a);//tempColor.a = base.a;tempColor.r = bg.r;tempColor.g = bg.g;tempColor.b = bg.b;tempColor.a = bg.a;}else{tempColor.r = base.r;tempColor.g = base.g;tempColor.b = base.b;tempColor.a = base.a;}return tempColor;
}vec4 addWaterMark(inout vec4 camera , inout vec4 watermark){float r = watermark.r + (1.0 - watermark.a) * camera.r;float g = watermark.g + (1.0 - watermark.a) * camera.g;float b = watermark.b + (1.0 - watermark.a) * camera.b;return vec4(r, g, b, 1.0);
}void main(){vec4 tmpColor = texture(s_texture, v_texCoord);if (colorFlag == 1){ //灰度//filterBlue(tmpColor);if(viewType == 1){vec4 background = texture(bgtexture, v_texCoord);outColor = background;return;}else if(viewType == 2){filterBlue(tmpColor);vec4 background = texture(bgtexture, v_texCoord);outColor = replaceBlue(tmpColor , background);return;}else if(viewType == 3){vec4 watermark = texture(watermarktexture, watermark_texCoord);outColor = addWaterMark( tmpColor , watermark);return;}else if(viewType == 4){outColor = tmpColor;return;}//vec4 background = texture(bgtexture, v_texCoord);//outColor = background;//outColor = replaceBlue(tmpColor , background);//vec4 watermark = texture(watermarktexture, watermark_texCoord);//outColor = addWaterMark( tmpColor , watermark);//outColor = watermark;return;} else if (colorFlag == 2){ //黑白blackAndWhite(tmpColor);} else if (colorFlag == 3){ //反向reverse(tmpColor);} else if (colorFlag == 4){ //亮度light(tmpColor);} else if(colorFlag == 5){ //亮度2light2(tmpColor);} else if(colorFlag == 6){//lutoutColor = lookupTable(tmpColor);return;} else if(colorFlag == 7){//色调分离posterization(tmpColor);}outColor = tmpColor;
}//将颜色值约束在[0.0-1.0] 之间
void checkColor(vec4 color){color.r=max(min(color.r, 1.0), 0.0);color.g=max(min(color.g, 1.0), 0.0);color.b=max(min(color.b, 1.0), 0.0);color.a=max(min(color.a, 1.0), 0.0);
}

关联属性值:

hVertex = glGetAttribLocation(program, VERTEX_ATTRIB_POSITION);
hMatrix = glGetUniformLocation(program, UNIFORM_MATRIX);
hTextureCoord = glGetAttribLocation(program, VERTEX_ATTRIB_TEXTURE_POSITION);
hTexture = glGetUniformLocation(program, UNIFORM_TEXTURE);

一些需要加载或设置的参数:

     public static final float[] vertex ={-1f,1f,0.0f,//左上-1f,-1f,0.0f,//左下1f,-1f,0.0f,//右下1f,1f,0.0f//右上};public static final float[] textureCoord = {0.0f,1.0f,0.0f,0.0f,1.0f,0.0f,1.0f,1.0f};bgTextureID = GLUtil.loadTextureFromFile("/sdcard/container.jpg");int[] nums =      GLUtil.loadTextureFromRes(R.drawable.icon_push_office);watermarkTextureID = nums[0];watermarkWidth = nums[1];//720watermarkHeight = nums[2];//1366xRatio = 720/(float)watermarkWidth;yRatio = 1366/(float)watermarkHeight;mWaterMarkMatrix = new float[]{xRatio,0,0,0,0,yRatio,0,0,0,0,1,0,0,0,0,1};//上面的public static int loadTextureFromFile(String path){//创建纹理对象int[] textureId = new int[1];//生成纹理:纹理数量、保存纹理的数组,数组偏移量glGenTextures(1, textureId,0);if(textureId[0] == 0){Log.e(TAG, "创建纹理对象失败");}//原尺寸加载位图资源(禁止缩放)BitmapFactory.Options options = new BitmapFactory.Options();options.inScaled = false;Bitmap bitmap = BitmapFactory.decodeFile(path);if (bitmap == null){//删除纹理对象glDeleteTextures(1, textureId, 0);Log.e(TAG, "加载位图失败");}//绑定纹理到openglglBindTexture(GL_TEXTURE_2D, textureId[0]);//设置放大、缩小时的纹理过滤方式,必须设定,否则纹理全黑glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);//将位图加载到opengl中,并复制到当前绑定的纹理对象上texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);//释放bitmap资源(上面已经把bitmap的数据复制到纹理上了)bitmap.recycle();//解绑当前纹理,防止其他地方以外改变该纹理glBindTexture(GL_TEXTURE_2D, 0);//返回纹理对象return textureId[0];}

绘制:

    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer[0]);glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, frameTexture[0], 0);glViewport(0,0,width,height);glUseProgram(program);glUniformMatrix4fv(hMatrix, 1, false, getMatrix(),0);glUniform1i(hColorFlag, COLOR_FLAG);glUniformMatrix4fv(watermatrixLoc, 1, false,getWaterMarkMatrix(),0);//bindTextureif (COLOR_FLAG == COLOR_FLAG_USE_LUT){glActiveTexture(GL_TEXTURE0 + 1);glBindTexture(GL_TEXTURE_2D, LUTTextureId);glUniform1i(hTextureLUT, 1);}if (COLOR_FLAG == 1) {/*glActiveTexture(GL_TEXTURE0 + 1);glBindTexture(GL_TEXTURE_2D, bgTextureID);glUniform1i(bgTexture, 1);*/glActiveTexture(GL_TEXTURE0+1);glBindTexture(GL_TEXTURE_2D , bgTextureID);glUniform1i(bgTexture , 1);glActiveTexture(GL_TEXTURE0+2);glBindTexture(GL_TEXTURE_2D , watermarkTextureID);glUniform1i(watermarkTextureLoc , 2);}glEnableVertexAttribArray(hVertex);glEnableVertexAttribArray(hTextureCoord);glVertexAttribPointer(hVertex,VERTEX_ATTRIB_POSITION_SIZE,GL_FLOAT,false,0,vertexBuffer);glVertexAttribPointer(hTextureCoord,VERTEX_ATTRIB_TEXTURE_POSITION_SIZE,GL_FLOAT,false,0,textureCoordBuffer);glClearColor(1.0f, 1.0f, 1.0f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glDrawArrays(GL_TRIANGLE_FAN,0,vertex.length / 3);glDisableVertexAttribArray(hVertex);glDisableVertexAttribArray(hTextureCoord);glBindFramebuffer(GL_FRAMEBUFFER, 0);

对Texture操作

    glGenTextures(exportTexture.length, exportTexture, 0);glBindTexture(GL_TEXTURE_2D, exportTexture[0]);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,        null);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);glBindTexture(GL_TEXTURE_2D, 0);//将显存中的数据回传到内存中ByteBuffer exportBuffer = ByteBuffer.allocate(width * height * 4);//8888存储格式glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, exportBuffer);

附上网上的一些资料 opengl内嵌函数和变量

1、uint CreateShader(enum type) : 创建空的shader object; type:
VERTEX_SHADER,

2、void ShaderSource(uint shader, sizeicount, const **string, const int
*length):加载shader源码进shader object;可能多个字符串

3、void CompileShader(uint shader):编译shader object;

shader object有状态 表示编译结果

4、void DeleteShader( uint shader ):删除 shader object;

5、void ShaderBinary( sizei count, const uint *shaders, enum
binaryformat, const void *binary, sizei length ): 加载预编译过的shader 二进制串;

6、uint CreateProgram( void ):创建空的program object, programe
object组织多个shader object,成为executable;

7、void AttachShader( uint program, uint shader ):关联shader
object和program object;

8、void DetachShader( uint program, uint shader ):解除关联;

9、void LinkProgram( uint program ):program object准备执行,其关联的shader
object必须编译正确且符合限制条件;

10、void UseProgram( uint program ):执行program object;

11、void ProgramParameteri( uint program, enum pname, int value ):
设置program object的参数;

12、void DeleteProgram( uint program ):删除program object;

13、shader 变量的qualifier:

默认:无修饰符,普通变量读写, 与外界无连接;const:常量 const vec3 zAxis = vec3(0.0, 0.0, 1.0);attribute: 申明传给vertex shader的变量;只读;不能为array或struct;attribute vec4 position;uniform: 表明整个图元处理中值相同;只读; uniform vec4 lightPos;varying: 被差值;读写; varying vec3 normal;in, out, inout;

14、shader变量的精度:

highp, mediump, lowp

15、shader内置变量:

gl_Position: 用于vertex shader, 写顶点位置;被图元收集、裁剪等固定操作功能所使用;其内部声明是:highp vec4 gl_Position;gl_PointSize: 用于vertex shader, 写光栅化后的点大小,像素个数;其内部声明是:mediump float gl_Position;gl_FragColor: 用于Fragment shader,写fragment color;被后续的固定管线使用;mediump vec4 gl_FragColor;gl_FragData: 用于Fragment shader,是个数组,写gl_FragData[n] 为data n;被后续的固定管线使用;mediump vec4 gl_FragData[gl_MaxDrawBuffers];gl_FragColor和gl_FragData是互斥的,不会同时写入;gl_FragCoord: 用于Fragment shader,只读, Fragment相对于窗口的坐标位置 x,y,z,1/w; 这个是固定管线图元差值后产生的;z 是深度值; mediump vec4 gl_FragCoord;gl_FrontFacing: 用于判断 fragment是否属于 front-facing primitive;只读;bool gl_FrontFacing;   gl_PointCoord: 仅用于 point primitive; mediump vec2 gl_PointCoord;

16、shader内置常量:

const mediump int gl_MaxVertexAttribs = 8;const mediump int gl_MaxVertexUniformVectors = 128;const mediump int gl_MaxVaryingVectors = 8;const mediump int gl_MaxVertexTextureImageUnits = 0;const mediump int gl_MaxCombinedTextureImageUnits = 8;const mediump int gl_MaxTextureImageUnits = 8;const mediump int gl_MaxFragmentUnitformVectors = 16;const mediump int gl_MaxDrawBuffers = 1;

17、shader内置函数:

一般默认都用弧度;radians(degree) : 角度变弧度;degrees(radian) : 弧度变角度;sin(angle), cos(angle), tan(angle)asin(x): arc sine, 返回弧度 [-PI/2, PI/2];acos(x): arc cosine,返回弧度 [0, PI];atan(y, x): arc tangent, 返回弧度 [-PI, PI];atan(y/x): arc tangent, 返回弧度 [-PI/2, PI/2];pow(x, y): x的y次方;exp(x): 指数, log(x):exp2(x): 2的x次方, log2(x):sqrt(x): x的根号; inversesqrt(x): x根号的倒数abs(x): 绝对值sign(x): 符号, 1, 0 或 -1floor(x): 底部取整ceil(x): 顶部取整fract(x): 取小数部分mod(x, y): 取模, x - y*floor(x/y)min(x, y): 取最小值max(x, y): 取最大值clamp(x, min, max):  min(max(x, min), max);mix(x, y, a): x, y的线性混叠, x(1-a) + y*a;step(edge, x): 如 edge>x 0.0,否则1.0smoothstep(edge0, edge1, x): threshod  smooth transition时使用。 edge0<=edge0时为0.0, x>=edge1时为1.0length(x): 向量长度distance(p0, p1): 两点距离, length(p0-p1);dot(x, y): 点积,各分量分别相乘 后 相加cross(x, y): 差积,x[1]*y[2]-y[1]*x[2], x[2]*y[0] - y[2]*x[0], x[0]*y[1] - y[0]*x[1]normalize(x): 归一化, length(x)=1;faceforward(N, I, Nref): 如 dot(Nref, I)< 0则N, 否则 -Nreflect(I, N): I的反射方向, I -2*dot(N, I)*N, N必须先归一化refract(I, N, eta): 折射,k=1.0-eta*eta*(1.0 - dot(N, I) * dot(N, I)); 如k<0.0 则0.0,否则 eta*I - (eta*dot(N, I)+sqrt(k))*NmatrixCompMult(matX, matY): 矩阵相乘, 每个分量 自行相乘, 即 r[i][j] = x[i][j]*y[i][j];矩阵线性相乘,直接用 *lessThan(vecX, vecY): 向量 每个分量比较 x < ylessThanEqual(vecX, vecY): 向量 每个分量比较 x<=ygreaterThan(vecX, vecY): 向量 每个分量比较 x>ygreaterThanEqual(vecX, vecY): 向量 每个分量比较 x>=yequal(vecX, vecY): 向量 每个分量比较 x==ynotEqual(vecX, vexY): 向量 每个分量比较 x!=yany(bvecX): 只要有一个分量是true, 则trueall(bvecX): 所有分量是true, 则truenot(bvecX): 所有分量取反texture2D(sampler2D, coord): texture lookuptexture2D(sampler2D, coord, bias): LOD bias, mip-mapped texturetexture2DProj(sampler2D, coord):texture2DProj(sampler2D, coord, bias):texture2DLod(sampler2D, coord, lod):texture2DProjLod(sampler2D, coord, lod):textureCube(samplerCube, coord):textureCube(samplerCube, coord, bias):textureCubeLod(samplerCube, coord, lod):

安卓opengl基本使用相关推荐

  1. 安卓OpenGL ES——透视投影

    本文通过学习<OpenGL ES应用开发实践指南>,了解透视投影并使用 代码地址 相关博文: 安卓OpenGL ES 2.0 入门 安卓OpenGL ES--正交投影 一.透视除法 1.1 ...

  2. 【脚下生根】之深度探索安卓OpenGL投影矩阵

    世界变化真快,前段时间windows开发技术热还在如火如荼,web技术就开始来势汹汹,正当web呈现欣欣向荣之际,安卓小机器人,咬过一口的苹果,winPhone开发平台又如闪电般划破了混沌的web世界 ...

  3. Android OpenGl ES使用原理总结与代码示例

    一.相关概念简介: OpenGl : OpenGl是一个定义好的跨平台图形处理接口库,通过它可操作GPU来完成图像处理.它跨平台是因为各个硬件厂家都按照这套接口规范具体实现了对应功能,供上层调用. O ...

  4. OpenGL实现物体动画和视频特效(视频水印、美白、滤镜等)

    1.OpenGL实现视频的水印.滤镜?OpenGL实现视频的剪裁.旋转? 2.2D/3D物体的 旋转,平移,缩放? OpenGL图片滤镜与视频滤镜? 矩阵(Matrix)是一个按照长方阵列排列的复数或 ...

  5. OpenGL ES 2.0 完全入门

    1. 基本概念 在 OpenGL 的世界里,我们只能画点.线.三角形,复杂的图形都是由三角形构成的. 在 OpenGL 里有两个最基本的概念:Vertex 和 Fragment.一切图形都从 Vert ...

  6. 关于java解析bvh动作文件

    最近正在学习安卓openGL(其实各个平台相差不多),为了让人物模型上来自己动,而且不要动的那么露骨,我就在网上找现成的动作数据想将它绑定到模型对象上,搜了一下才发现原来这种数据有几种专门的文件格式来 ...

  7. java opengl书_GitHub - cy-cyx/OpenGlDome: OpenGl的使用练习(安卓 Java opengl3.0)

    项目中现有的功能模块 1.fbo文件下 使用帧缓冲区,使用一个纹理作为帧缓冲的颜色缓冲区 注意:安卓的纹理的原点是在左上角,fbo的纹理的原点是在左下角 2.blend文件下 混合模式的使用 3.li ...

  8. 【音视频安卓开发 (三)】OpenGL ES 直接绘制YUV

    EGL OpenGL与窗口对应的的适配层,针对安卓平台的适配器. surface 交互到窗口显示

  9. 安卓学习笔记38:利用OpenGL ES绘制旋转立方体

    文章目录 零.学习目标 一.绘制图形基本步骤 二.绘制旋转立方体 (一)运行效果 (二)实现步骤 1.创建安卓应用[DrawRotatingCube] 2.建模:立方体类 - Cube 3.渲染:立方 ...

最新文章

  1. 仅需一部摄像机即可实现基于AI的3D重建
  2. 通过xrdp远程访问ubuntu出现输入d最小化问题的处理
  3. 1.13 空字符串和null的区别
  4. java web的运行方式_在运行 Javaweb项目时报错,不知道什么原因,百度了好多方法跟着人家的方法做了还是报错...
  5. docker安装mysql后怎么链接_使用docker安装mysql并连接
  6. java自动gc_具有Java 7中自动资源管理功能的GC
  7. oracle group by 两项,Oracle中group by 的扩展函数rollup、cube、grouping sets
  8. react中类组件this指向
  9. “考虑对方的感受”之案例
  10. 上下相机贴合对位计算公式_ccd视觉自动对位贴合机主要应用在哪里?
  11. 前端度分秒与经纬度互转
  12. arduino下载库出错_纯干货!关于Arduino 库在多种操作系统安装使用最详细、最全面的指南及常见问题解决办法!...
  13. 一刹那,是幡然悔悟的一刹那
  14. 2022-华为-大数据研发工程师-秋招面经
  15. 以太坊社区开发者大会(EDCON 2020)精彩回顾
  16. 新MLC颗粒来了!让SSD写入提升2倍 寿命翻10倍
  17. 《Speech and Language Processing》读书笔记——语法规则及其解析
  18. 紫光云oracle,紫光云计算机.pdf
  19. Vue调用本地摄像头权限
  20. 如何下载吉林省卫星图高清版大图

热门文章

  1. 谈谈Processing 3D世界 五
  2. python开源web项目-15个最受欢迎的Python开源框架(转载)
  3. AD18 所有过孔盖油
  4. 金山文字 职称计算机,计算机职称考试软件金山文字2005 播谷鸟计算机职称考试软件金山文字2005 v5.1...
  5. windows10安装
  6. python学习实验报告(第四周)
  7. 从键盘输入10个学生的姓名,再从键盘输入一个姓名,查找这个姓名是否在前面输入的10个姓名之中。
  8. android 8.0 nexus7,Android 7.0系统更新将在8月22日推送,谷歌Nexus将获更新
  9. PHP+学生成绩管理系统 毕业设计-附源码201829
  10. SQL update left join查询