Opengl 如何使用WebGL渲染二维精灵?
我正在努力使用Dart和WebGL将2D精灵渲染到画布上。我可以在网上找到很少的例子;大多数都是3D的,或者包含大量的意大利面代码,但没有真正解释它们在做什么。我正在尝试做最简单的事情来渲染精灵 到目前为止,我已经成功地在画布上渲染了一个绿色正方形(两个三角形)。我正在努力解决的问题是,如何将这一点从一个绿色正方形改为使用我的纹理(我相信纹理已正确加载和绑定)。我认为这需要对着色器进行更改(以获取纹理坐标,而不是颜色),并传递与缓冲区中顶点相关的纹理坐标 这个代码 注意:这只是一个一次性样品;大多数代码都存在于构造函数中;我现在对代码的整洁程度不太感兴趣;当我看到屏幕上有精灵的时候,我就可以整理了 注意:我对使用第三方库不感兴趣;我这样做是为了学习WebGLOpengl 如何使用WebGL渲染二维精灵?,opengl,opengl-es,html5-canvas,dart,webgl,Opengl,Opengl Es,Html5 Canvas,Dart,Webgl,我正在努力使用Dart和WebGL将2D精灵渲染到画布上。我可以在网上找到很少的例子;大多数都是3D的,或者包含大量的意大利面代码,但没有真正解释它们在做什么。我正在尝试做最简单的事情来渲染精灵 到目前为止,我已经成功地在画布上渲染了一个绿色正方形(两个三角形)。我正在努力解决的问题是,如何将这一点从一个绿色正方形改为使用我的纹理(我相信纹理已正确加载和绑定)。我认为这需要对着色器进行更改(以获取纹理坐标,而不是颜色),并传递与缓冲区中顶点相关的纹理坐标 这个代码 注意:这只是一个一次性样品;大
<!DOCTYPE html>
<html>
<head>
<title>MySecondGame</title>
</head>
<body>
<canvas width="1024" height="768"></canvas>
<div style="display: none;">
<img id="img-player" src="assets/player.png" />
</div>
<script id="vertex" type="x-shader">
attribute vec2 aVertexPosition;
void main() {
gl_Position = vec4(aVertexPosition, 0.0, 1.0);
}
</script>
<script id="fragment" type="x-shader">
#ifdef GL_ES
precision highp float;
#endif
uniform vec4 uColor;
void main() {
gl_FragColor = uColor;
}
</script>
<script type="application/dart">
import 'dart:async';
import 'dart:html';
import 'dart:math';
import 'dart:typed_data';
import 'dart:web_gl';
Game game;
main() {
game = new Game(document.querySelector('canvas'));
}
class Game {
RenderingContext _gl;
Buffer vbuffer;
int numItems;
Texture playerTexture;
double elapsedTime;
double fadeAmount;
Game(CanvasElement canvas) {
_gl = canvas.getContext3d();
playerTexture = _gl.createTexture();
_gl.bindTexture(TEXTURE_2D, playerTexture);
_gl.texImage2DUntyped(TEXTURE_2D, 0, RGBA, RGBA, UNSIGNED_BYTE, document.querySelector('#img-player'));
_gl.texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, NEAREST);
_gl.texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, LINEAR_MIPMAP_NEAREST);
_gl.generateMipmap(TEXTURE_2D);
_gl.bindTexture(TEXTURE_2D, null);
var vsScript = document.querySelector('#vertex');
var vs = _gl.createShader(VERTEX_SHADER);
_gl.shaderSource(vs, vsScript.text);
_gl.compileShader(vs);
var fsScript = document.querySelector('#fragment');
var fs = _gl.createShader(FRAGMENT_SHADER);
_gl.shaderSource(fs, fsScript.text);
_gl.compileShader(fs);
var program = _gl.createProgram();
_gl.attachShader(program, vs);
_gl.attachShader(program, fs);
_gl.linkProgram(program);
if (!_gl.getShaderParameter(vs, COMPILE_STATUS))
print(_gl.getShaderInfoLog(vs));
if (!_gl.getShaderParameter(fs, COMPILE_STATUS))
print(_gl.getShaderInfoLog(fs));
if (!_gl.getProgramParameter(program, LINK_STATUS))
print(_gl.getProgramInfoLog(program));
var aspect = canvas.width / canvas.height;
var vertices = new Float32List.fromList([
-0.5, 0.5 * aspect, 0.5, 0.5 * aspect, 0.5, -0.5 * aspect, // Triangle 1
-0.5, 0.5 * aspect, 0.5,-0.5 * aspect, -0.5, -0.5 * aspect // Triangle 2
]);
vbuffer = _gl.createBuffer();
_gl.bindBuffer(ARRAY_BUFFER, vbuffer);
_gl.bufferData(ARRAY_BUFFER, vertices, STATIC_DRAW);
numItems = vertices.length ~/ 2;
_gl.useProgram(program);
var uColor = _gl.getUniformLocation(program, "uColor");
_gl.uniform4fv(uColor, new Float32List.fromList([0.0, 0.3, 0.0, 1.0]));
var aVertexPosition = _gl.getAttribLocation(program, "aVertexPosition");
_gl.enableVertexAttribArray(aVertexPosition);
_gl.vertexAttribPointer(aVertexPosition, 2, FLOAT, false, 0, 0);
window.animationFrame.then(_gameLoop);
}
_gameLoop(num time) {
elapsedTime = time;
_update();
_render();
window.animationFrame.then(_gameLoop);
}
_update() {
// Use sine curve for fading. Sine is -1-1, so tweak to be 0 - 1.
fadeAmount = (sin(elapsedTime/1000) / 2) + 0.5;
}
_render() {
// Set colour for clearing to.
_gl.clearColor(fadeAmount, 1 - fadeAmount, 0.0, 1.0);
// Clear.
_gl.clear(RenderingContext.COLOR_BUFFER_BIT);
_gl.bindTexture(TEXTURE_2D, playerTexture);
_gl.drawArrays(TRIANGLES, 0, numItems);
_gl.bindTexture(TEXTURE_2D, null);
}
}
</script>
<script src="packages/browser/dart.js"></script>
</body>
</html>
MySecondName
属性向量2;
void main(){
gl_位置=vec4(0.0,1.0);
}
#国际财务报告准则
高精度浮点;
#恩迪夫
均匀的维柯色;
void main(){
gl_FragColor=uColor;
}
导入“dart:async”;
导入“dart:html”;
导入“dart:math”;
导入“dart:键入的_数据”;
导入“dart:web_gl”;
游戏;
main(){
游戏=新游戏(document.querySelector('canvas');
}
班级游戏{
渲染上下文_gl;
缓冲区缓冲区;
int numItems;
纹理织物;
双延时;
双法德蒙特;
游戏(CanvasElement画布){
_gl=canvas.getContext3d();
playerTexture=_gl.createTexture();
_gl.bindTexture(纹理2D,playerTexture);
_gl.texImage2Untyped(纹理2D,0,RGBA,RGBA,无符号字节,document.querySelector('img player'));
_gl.texParameteri(纹理2D,纹理贴图过滤器,最近的);
_gl.texParameteri(纹理2D、纹理最小过滤器、线性MIPMAP最近);
_gl.generateMipmap(纹理_2D);
_gl.bindTexture(纹理为2D,空);
var vsScript=document.querySelector(“#vertex”);
var vs=_gl.createShader(顶点着色器);
_gl.shaderSource(vs,vsScript.text);
_总帐编译主管(vs);
var fsScript=document.querySelector('#fragment');
var fs=_gl.createShader(片段着色器);
_gl.shaderSource(fs,fsScript.text);
_总帐编辑主任(fs);
var program=_gl.createProgram();
_总分类:attachShader(项目,vs);
_总承包商助理(项目,财政司);
_总账链接程序(程序);
if(!\u总账getShaderParameter(vs,编译状态))
打印(_gl.getShaderInfoLog(vs));
if(!\u总账getShaderParameter(fs,编译状态))
打印(_gl.getShaderInfoLog(fs));
if(!\u总账getProgramParameter(程序、链接状态))
打印(_gl.getProgramInfoLog(程序));
var aspect=canvas.width/canvas.height;
var顶点=新Float32List.fromList([
-0.5,0.5*纵横比,0.5,0.5*纵横比,0.5,-0.5*纵横比,//三角形1
-0.5,0.5*纵横比,0.5,-0.5*纵横比,-0.5,-0.5*纵横比//三角形2
]);
vbuffer=_gl.createBuffer();
_gl.bindBuffer(数组_BUFFER,vbuffer);
_gl.bufferData(数组缓冲区、顶点、静态绘制);
numItems=顶点.length~/2;
_gl.useProgram(程序);
变量uColor=_gl.getUniformLocation(程序,“uColor”);
_gl.uniform4fv(uColor,新Float32List.fromList([0.0,0.3,0.0,1.0]);
var aVertexPosition=_gl.GetAttriblLocation(程序,“aVertexPosition”);
_gl.EnableVertexAttributeArray(可编程逻辑阵列);
_gl.VertexAttributePointer(1,2,FLOAT,false,0,0);
然后(_gameLoop);
}
_gameLoop(num时间){
elapsedTime=时间;
_更新();
_render();
然后(_gameLoop);
}
_更新(){
//使用正弦曲线进行衰减。正弦为-1-1,因此调整为0-1。
fadeAmount=(sin(elapsedTime/1000)/2)+0.5;
}
_render(){
//设置清除颜色。
_gl.clearColor(fadeAmount,1-fadeAmount,0.0,1.0);
//清楚。
_gl.clear(RenderingContext.COLOR\u BUFFER\u位);
_gl.bindTexture(纹理2D,playerTexture);
_gl.绘图阵列(三角形,0,numItems);
_gl.bindTexture(纹理为2D,空);
}
}
(也用
opengl
标记它,因为我相信解决方案很可能与WebGL/opengl相同)。好的,成功地实现了这一点。你可以
我可能错了;但我似乎希望在设置缓冲区时设置缓冲区中的数据;但我找不到任何方法来说明哪些数据是针对哪个缓冲区的。我将代码拆分为一些设置代码:
vbuffer = _gl.createBuffer();
_gl.bindBuffer(ARRAY_BUFFER, vbuffer);
_gl.bufferData(ARRAY_BUFFER, vertices, STATIC_DRAW);
numItems = vertices.length ~/ 2;
tbuffer = _gl.createBuffer();
_gl.bindBuffer(ARRAY_BUFFER, tbuffer);
_gl.bufferData(ARRAY_BUFFER, textureCoords, STATIC_DRAW);
aVertexPosition = _gl.getAttribLocation(program, "aVertexPosition");
_gl.enableVertexAttribArray(aVertexPosition);
aTextureCoord = _gl.getAttribLocation(program, "aTextureCoord");
_gl.enableVertexAttribArray(aTextureCoord);
uSampler = _gl.getUniformLocation(program, "uSampler");
和一些渲染代码:
_gl.bindBuffer(ARRAY_BUFFER, vbuffer);
_gl.vertexAttribPointer(aVertexPosition, 2, FLOAT, false, 0, 0);
_gl.bindBuffer(ARRAY_BUFFER, tbuffer);
_gl.vertexAttribPointer(aTextureCoord, 2, FLOAT, false, 0, 0);
_gl.bindTexture(TEXTURE_2D, playerTexture);
_gl.uniform1i(uSampler, 0);
_gl.drawArrays(TRIANGLES, 0, numItems);
我不完全确定这是否正确(感觉好像每帧都发送相同的顶点和纹理命令),但它工作正常
?@gman谢谢;还没看过这个,就要看穿了!你没有每帧发送任何数据。你告诉WebGL你已经发送了哪些数据要使用。@gman哦,是的!我知道纹理就是这样,但不知怎的把我的顶点缓冲区和实际数组搞混了。这是一个漫长的下午!:)@gman在其他方面看起来是否相同;我在设置和循环中得到了正确的代码吗?是的,看起来很正常。大多数人可能会在这里添加矩阵乘法
gl_Position=vec4(0.0,1.0)