WEBGL使用texture单点绘制图片图片怎么设置?

发布于 2024-06-27 00:07:34

我按照2022年WebGL入门教程BV1Kb4y1x72q课程的最后一节内容做了,但是图片怎么调都不出现,代码也没报错,麻烦各位大佬帮忙看看是啥地方的问题。图片随便找一张就行。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>点精灵</title>
    <script src="../../lib/glMatrix-0.9.6.js" ></script>
    <script>
        
        /** @type {WebGLRenderingContext} */
        var webgl  // context
        var uniformTexture;  // 纹理变量
        var projMatrix4 = mat4.create() // 初始化投影矩阵,使用了glMatrix-0.9.6.js的方法
        var vertexString = `
        attribute vec4 a_position;
            uniform mat4 proj;
            void main(){
                gl_Position = proj * a_position;
            }
        `
        /**
         * precision mediump float; This determines how much precision the GPU uses when calculating floats. highp is high precision, and of course more intensive than mediump (medium precision) and lowp (low precision).
         * texture2D是shader中的函数,传入纹理及像素坐标系,转化为各个像素的颜色
         * discard;表示不显示该像素
        */
        var fragmentString = `
            precision mediump float;
            uniform sampler2D texture;

            void main(){
                vec4 color = texture2D(texture,gl_PointCoord);
                // if(color.a<0.1){
                //     discard;
                // }
                gl_FragColor = color;
            }
        `
        function init(){
            initWebgl()
            initShader()
            initBuffer()
            
        }
        function initWebgl(){
            const canvas = document.getElementById("webglcanvas")

            webgl = canvas.getContext('webgl');

            if (!webgl) {
                alert("无法初始化 WebGL,你的浏览器、操作系统或硬件等可能不支持 WebGL。");
                return;
            }
            webgl.viewport(0,0,canvas.clientWidth,canvas.clientHeight) 
            mat4.ortho(0,canvas.clientWidth,canvas.clientHeight,0,-1,1,projMatrix4)
           
        }
        function initShader(){
            let vsShader = webgl.createShader(webgl.VERTEX_SHADER)
            let frShader = webgl.createShader(webgl.FRAGMENT_SHADER)
            webgl.shaderSource(vsShader,vertexString)
            webgl.shaderSource(frShader,fragmentString)
            webgl.compileShader(vsShader)
            if(!webgl.getShaderParameter(vsShader,webgl.COMPILE_STATUS)){
                console.log('SHADER COMPILE error');
                console.log(webgl.getShaderInfoLog(vsShader));
                webgl.deleteShader(vsShader)
                return 
            }
            webgl.compileShader(frShader)
            if(!webgl.getShaderParameter(frShader,webgl.COMPILE_STATUS)){
                console.log('SHADER COMPILE error');
                console.log(webgl.getShaderInfoLog(frShader));
                webgl.deleteShader(frShader)
                return 
            }
            let program = webgl.createProgram()
            webgl.attachShader(program,vsShader)
            webgl.attachShader(program,frShader)

            webgl.linkProgram(program)
            if(!webgl.getProgramParameter(program, webgl.LINK_STATUS)){
                console.log('Program link error');
                console.log(webgl.getProgramInfoLog(program));
                webgl.deleteProgram(program);
                return null;
            }
            webgl.useProgram(program)
            webgl.program = program

        }
      

        // 数据缓冲区初始化
        function initBuffer(){

            // 坐标
            let arr = [
                100.0,100.0,0.0,1.0,
                100.0,104.0,0.0,1.0,
                100.0,200.0,0.0,1.0,
                200.0,200.0,0.0,1.0
            ]
            let pointPosition = new Float32Array(arr)
            let aPosition = webgl.getAttribLocation(webgl.program,"a_position") 

            let pointBuf = webgl.createBuffer()  // 顶点缓冲区
            webgl.bindBuffer(webgl.ARRAY_BUFFER,pointBuf)
            webgl.bufferData(webgl.ARRAY_BUFFER,pointPosition,webgl.STATIC_DRAW) 
            webgl.enableVertexAttribArray(aPosition)   
            webgl.vertexAttribPointer(aPosition,4,webgl.FLOAT,false,16,0)  

            let uniProj = webgl.getUniformLocation(webgl.program,"proj")
            webgl.uniformMatrix4fv(uniProj,false,projMatrix4)

            // 纹理
            uniformTexture = webgl.getUniformLocation(webgl.program,"texture")
            webgl.enable(webgl.BLEND)  // 为上下文启用特定的 WebGL 的功能,这里BLEND是激活片元的颜色融合计算
            /** 
             * void gl.blendFunc(sfactor, dfactor); 
             * 指定多层纹理如何混合的
             * 混合颜色的公式可以这样描述:color(RGBA) = (sourceColor * sfactor) + (destinationColor * dfactor). RBGA 值在 0 到 1 之间。
             * 目标颜色是指不加上sourceColor该颜色之前的像素颜色
             * sfactor为源混合因子指定一个乘数,dfactor为源目标合因子指定一个乘数
             * webgl.SRC_ALPHA 所有像素乘以源像素的alpha值
             * webgl.ONE_MINUS_SRC_ALPHA 所有像素乘以(1-源像素alpha值)
             * */
            webgl.blendFunc(webgl.SRC_ALPHA, webgl.ONE_MINUS_SRC_ALPHA)
            

            
           
        }

        // 设置纹理图片相关参数
        function handleLoadedTexture(textureHandler){
            webgl.activeTexture(webgl.TEXTURE0)
            
            webgl.bindTexture(webgl.TEXTURE_2D,textureHandler)
            webgl.texImage2D(webgl.TEXTURE_2D,0,webgl.RGBA,webgl.RGBA,webgl.UNSIGNED_BYTE,textureHandler.image)
            webgl.texParameteri(webgl.TEXTURE_2D,webgl.TEXTURE_MAG_FILTER,webgl.NEAREST)
            webgl.texParameteri(webgl.TEXTURE_2D,webgl.TEXTURE_MIN_FILTER,webgl.NEAREST)
            // webgl.texParameteri(webgl.TEXTURE_2D,webgl.TEXTURE_WRAP_S,webgl.REPEAT)
            // webgl.texParameteri(webgl.TEXTURE_2D,webgl.TEXTURE_WRAP_T,webgl.REPEAT)
            webgl.texParameteri(webgl.TEXTURE_2D,webgl.TEXTURE_WRAP_S,webgl.CLAMP_TO_EDGE)
            webgl.texParameteri(webgl.TEXTURE_2D,webgl.TEXTURE_WRAP_T,webgl.CLAMP_TO_EDGE)
            webgl.uniform1i(uniformTexture,0)  // 将纹理存入shader中
            return textureHandler
        }

        function initTexture(imgPath){
            let textureHandler = webgl.createTexture()  // 创建纹理
            textureHandler.image = new Image()    
            textureHandler.image.src = imgPath
            textureHandler.image.onload = function(){
                // 异步代码,所以在此处调用
                handleLoadedTexture(textureHandler)
                draw()
            }
            
            
        }

        // 绘制图形
        function draw(){
            webgl.clearColor(1,0,0,1)  
            webgl.clear(webgl.COLOR_BUFFER_BIT | webgl.DEPTH_BUFFER_BIT)
            webgl.enable(webgl.DEPTH_TEST) 
            webgl.drawArrays(webgl.POINTS,0,4)
        }

        window.onload = function(){
            init()
            initTexture("./point01.png")
        }
        

    </script>
</head>
<body>
    <canvas id="webglcanvas" width="1280px" height="960px"></canvas>
</body>
</html>

查看更多

关注者
1
被浏览
235
Jsonco
Jsonco 图形社区官方人员 2024-06-27
奔驰的蜗牛

从代码段里没有看出问题,给你几个思路排除下:
1、注销掉纹理赋值的有关代码,直接去绘制点,点的颜色赋值纯色,看能否出来。如果不出来那就看绘制点inbuffer是否有问题,如果能出来,说明就是纹理参数问题,有的时候图片也存在问题。
2、F12看一下是否有异常告警的错误,也有可能是异常告警导致的。
3、我看你div 写的cavas 中 width height有问题 应该是 width=“1280” height=“960”
4、试着修改下顶点中点的大小 gl_PointSize = 64;顶点着色器

1 个回答

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览