首页 > 其他分享 >WebGL之图片偏移(基础)

WebGL之图片偏移(基础)

时间:2024-01-19 21:32:59浏览次数:24  
标签:canvas const WebGL shader program 偏移 gl image 图片

一, index.html

WebGL之图片偏移(基础)_Cocos

二, shader.js

/**
 * 加载图片
 * @param imageName
 * @param pork
 * @param callback
 */
function loadImage(imageName, pork, callback) {
	const image = new Image();
	image.src = "http://127.0.0.1:" + pork + "/WebGLDemo/textures/" + imageName;
	image.onload = () => {
		callback(image);
	};
}


function setTexture(gl, image) {
	const texture = gl.createTexture();
	gl.bindTexture(gl.TEXTURE_2D, texture);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); //gl.LINEAR
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); //gl.NEAREST
	gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
}

function setRectangle(gl, x, y, width, height) {
	const x1 = x;
	const x2 = x + width;
	const y1 = y;
	const y2 = y + height;
	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
		x1, y1,
		x2, y1,
		x1, y2,
		x1, y2,
		x2, y1,
		x2, y2,
	]), gl.STATIC_DRAW);
}


/**
 * 获得绘图上下文gl WebGLRenderingContext
 * @param {Object} width
 * @param {Object} height
 */
function getWebGLRenderingContext(width, height) {
	const canvas = document.createElement("canvas");
	document.getElementsByTagName("body")[0].appendChild(canvas);

	canvas.width = width;
	canvas.height = height;

	const gl = canvas.getContext("webgl");
	if (!gl) {
		console.log("%c不支持webgl", "color:#F00");
		return null;
	}
	return gl;
}

function getShaderSource(isVertex) {
	let source;
	if (isVertex) {
		source = document.querySelector("#vertex-shader-2d").text;
	} else {
		source = document.querySelector("#fragment-shader-2d").text;
	}
	return source;
}

/**
 * @param {Object} gl WebGLReanderingContext
 * @param {Object} type gl.VERTEX_SHADER/gl.FRAGMENT_SHADER
 * @param {Object} source source string
 */
function createShader(gl, type, source) {
	const shader = gl.createShader(type); //创建相关类型的shader
	gl.shaderSource(shader, source); //提供shader的资源
	gl.compileShader(shader); //编译shader
	const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
	if (success) {
		return shader;
	}
	console.log(gl.getShaderInfoLog(shader));
	gl.deleteShader(shader);
}

/**
 * 链接(link)2个shader,得到着色程序program
 * @param {Object} gl WebGLReanderingContext
 * @param {Object} vertexShader 顶点着色器
 * @param {Object} fragmentShader 片段着色器
 */
function createProgram(gl, vertexShader, fragmentShader) {
	const program = gl.createProgram();
	gl.attachShader(program, vertexShader);
	gl.attachShader(program, fragmentShader);
	gl.linkProgram(program);
	const success = gl.getProgramParameter(program, gl.LINK_STATUS);
	if (success) {
		return program;
	}
	console.log(gl.getProgramInfoLog(program));
	gl.deleteProgram(program);
}

function render(gl, program, image) {
	const positionAttributeLocation = gl.getAttribLocation(program, "a_position");
	const texCoordAttributeLocation = gl.getAttribLocation(program, "a_texCoord");
	const resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution");
	const translationUniformLocation = gl.getUniformLocation(program, "u_translation");

	let translations = [0, 0];

	const positionBuffer = gl.createBuffer();
	gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
	setRectangle(gl, 0, 0, image.width, image.height); //矩形(2个三角形)


	const texCoordBuffer = gl.createBuffer();
	gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
		0.0, 0.0,
		1.0, 0.0,
		0.0, 1.0,
		0.0, 1.0,
		1.0, 0.0,
		1.0, 1.0
	]), gl.STATIC_DRAW);

	//开始渲染
	gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
	gl.clearColor(0, 0, 0, 0);
	gl.clear(gl.COLOR_BUFFER_BIT);

	gl.useProgram(program);
	// uniform: 设置全局属性
	gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);


	gl.enableVertexAttribArray(positionAttributeLocation);
	gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
	const size = 2; //每次迭代运行提取2个单位数据
	const type = gl.FLOAT; //每个单位数据是32位的浮点数
	const normaliza = false; //不需要归一化数据
	const stride = 0; //0 = 移动单位数量 * 每个单位占用的内存(sizeof(type))
	const offset = 0; //每次迭代运行运动多少内存到下一个数据开始点,从缓冲起始位置开始读取
	gl.vertexAttribPointer(positionAttributeLocation, size, type, normaliza, stride, offset);

	gl.enableVertexAttribArray(texCoordAttributeLocation);
	gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
	gl.vertexAttribPointer(texCoordAttributeLocation, 2, gl.FLOAT, false, 0, 0);


	setTexture(gl, image);


	const primitiveType = gl.TRIANGLES; //绘制三角形
	const pOffset = 0; //从第一个点开始绘制
	const count = 6; //绘制6个点(运行6次)
	setInterval(() => {
		translations[0] += 1;
		translations[1] += 1;
		if(translations[0] > gl.canvas.width || translations[1] > gl.canvas.height){
			translations[0] = translations[1] = 0;
		}
		gl.uniform2fv(translationUniformLocation,translations);
		gl.drawArrays(primitiveType, pOffset, count);
	}, 15);
}

function main() {
	const WIDTH = 400;
	const HEIGHT = 300;
	const gl = getWebGLRenderingContext(WIDTH, HEIGHT);
	if (!gl) return;
	//#region 构建2个shader
	const vertexShader = createShader(gl, gl.VERTEX_SHADER, getShaderSource(true));
	const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, getShaderSource(false));
	//#endregion

	//#region link2个shader
	const program = createProgram(gl, vertexShader, fragmentShader);
	//#endregiopn
	loadImage("cocos.png", 8848, (image) => {
		render(gl, program, image);
	});
}

main();

三,结果

WebGL之图片偏移(基础)_WebGL_02

标签:canvas,const,WebGL,shader,program,偏移,gl,image,图片
From: https://blog.51cto.com/aonaufly/9336595

相关文章

  • 图片与Base64编码相互转换、优势分析和技术实现
    在Web开发中,图片与Base64编码的相互转换是一个非常实用的技能。图片Base64编码是将图片文件转换为字符串格式,以便于在网络上传输和存储。本文将详细介绍图片与Base64编码的转换方法,以及图片Base64编码的优势。图片Base64相互转换|一个覆盖广泛主题工具的高效在线平台(amd......
  • excel宏-表格通过图片的网络路径下载展示图片
    1、原理通过图片的网络路径,将图片下载到本地,excel读取本地路径,显示图片。注意:下载的图片路径改变将无法展示2、准备2.1、excel版本MS_Office_20162.2、excel开启宏选项-》信任中心-》信任中心设置-》宏设置-》启用所有宏2.3、另存为宏文件表格数据另存为宏文件......
  • c4d阿诺德怎么渲染高清图片
    c4d作为也可热门建模工具,该渲染器支持多种渲染器使用,很多人在选择阿诺德渲染器是出现了高清图片无法渲染的问题,阿诺德可提供逼真的光影效果和物理材质,那么怎么利永阿诺德渲染高清的图片呢,一起来简单看看吧。c4d阿诺德怎么渲染高清图片1、调整输出设置:在渲染设置中找到"输出"(O......
  • SpringSecurity-图片验证码
    图片验证码生成Core模块封装验证码类publicclassImageCode{    privateBufferedImageimage;    /**     *code是一个随机数,图片是根据随机数生成的,     *存放到session里面,后面用户提交登录请求时候要去验证的     */    private......
  • rosbag 包提取图片和点云数据
    环境Ubuntu20.04ROSnoeticPython3.8.10⚠️注意:Python版本很重要,建议用3.8.10版本,如果使用更新的版本,会导致程序需要的库版本不对应,会报错。建议使用conda创建一个虚拟环境最佳,创建指令:condacreate-nros_envpython=3.8.10。安装所需的包在创建的Python3.8.......
  • fastapi接收图片文件
    #api接口,主函数importbase64importioimportcv2importosimporttimefromPILimportImageimportnumpyasnpfromfastapiimportFastAPI,HTTPExceptionimportuvicornapp=FastAPI()##############################################@app.post("/upload......
  • WebGL之贴图处理(基础)
    一,index.html二,shader.js/***加载图片*@paramimageName*@parampork*@paramcallback*/functionloadImage(imageName,pork,callback){ constimage=newImage(); image.src="http://127.0.0.1:"+pork+"/WebGLDemo/textures/"+......
  • 上传图片,必填增加校验
    <el-form-itemlabel="产品照片:"class="product-manual-box":prop="`infoTabs[${index}].productfmId`":rules="{required:true,message:'请上传产品照片',trigger:'change'}">......
  • 根据后端id去请求拿取图片组件
    1.组件<template><img :src="srcImg?srcImg:defaultImage?getDefaultImage:''" v-bind="{...otheAttribute}" alt=""/></template><script>import{getFileInfoApi}from'@/a......
  • Python_python读写图片以及对应的库比较
    图片读写通过numpy来做数据计算的沟通JPEG是一种有损格式, 图像PNG,是一种无损格式cv2.imdecode()作用是将图像数据从存储格式中解析出来并转化为OpenCV中的图像格式 imdecode得到的影像波段顺序是RGBnp.fromfile将文本或二进制文件中数据构造成数组 cv2.imencod......