You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无库情况下如何删除WebGL中的特定对象(以食物元素为例)

How to Remove Specific Objects in WebGL (No Libraries)

Hey there! Let's clear up a key misunderstanding first: WebGL doesn't work like the DOM where you have "objects" you can delete directly. When you call gl.drawArrays() or similar functions, you're just painting pixels onto the canvas—WebGL doesn't keep track of the rectangles you drew as separate entities. To "remove" a food item, you need to:

  1. Keep track of all your food data yourself (positions, sizes, colors)
  2. Re-render the entire scene from scratch every time something changes (like deleting a food)

Here's how to adjust your code to make this work:

Step 1: Maintain a Food Data Array

Instead of drawing all foods immediately on init, store each food's properties in an array. This way, you can easily add/remove items and re-render them.

Step 2: Create a Render Function

Write a function that clears the canvas, then loops through your food array and draws each item one by one.

Step 3: Handle Removal (Collision Trigger)

When your collision detection logic identifies a food to remove, splice it from the array and call the render function again.

Modified Full Code

var gl;
var points;
var foodArray = []; // Store all food data here
var foodSize = 20;
var canvas;

window.onload = function init() {
    canvas = document.getElementById("gl-canvas");
    gl = WebGLUtils.setupWebGL(canvas);
    if (!gl) { alert("WebGL isn't available"); }

    // Configure WebGL
    gl.viewport(0, 0, canvas.width, canvas.height);
    gl.clearColor(0.0, 0.0, 0.0, 1.0);

    // Load shaders and initialize attribute buffers
    var program = initShaders(gl, "vertex-shader", "fragment-shader");
    gl.useProgram(program);

    // Create buffer once (we'll reuse it for all foods)
    var bufferId = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);

    // Setup attribute pointers
    var vPosition = gl.getAttribLocation(program, "vPosition");
    var size = 2;
    var type = gl.FLOAT;
    var normalize = false;
    var stride = 0;
    var offset = 0;
    gl.vertexAttribPointer(vPosition, size, type, normalize, stride, offset);
    gl.enableVertexAttribArray(vPosition);

    // Setup uniforms
    var vResolution = gl.getUniformLocation(program, "vResolution");
    gl.uniform2f(vResolution, gl.canvas.width, gl.canvas.height);
    window.fColor = gl.getUniformLocation(program, "fColor");

    // Generate initial food data
    generateFood(50);

    // Initial render
    render();

    // Example: Add a click handler to simulate removal (replace with your collision logic)
    canvas.addEventListener("click", function(e) {
        // For demo: Find and remove the clicked food
        const mouseX = e.offsetX;
        const mouseY = e.offsetY;
        const targetIndex = foodArray.findIndex(food => 
            mouseX >= food.x && mouseX <= food.x + foodSize &&
            mouseY >= food.y && mouseY <= food.y + foodSize
        );
        if (targetIndex !== -1) {
            foodArray.splice(targetIndex, 1);
            render();
        }
    });
};

// Generate food and add to array
function generateFood(count) {
    for (let i = 0; i < count; i++) {
        const foodX = randomInt(canvas.width - foodSize);
        const foodY = randomInt(canvas.height - foodSize);
        foodArray.push({
            x: foodX,
            y: foodY,
            color: [Math.random(), Math.random(), Math.random(), 1]
        });
    }
}

// Render all food from the array
function render() {
    // Clear the entire canvas first
    gl.clear(gl.COLOR_BUFFER_BIT);

    // Loop through each food and draw it
    foodArray.forEach(food => {
        setRectangle(gl, food.x, food.y, foodSize, foodSize);
        gl.uniform4fv(fColor, food.color);
        gl.drawArrays(gl.TRIANGLES, 0, 6);
    });
}

// Helper functions (unchanged except minor tweaks)
function randomInt(range) {
    return Math.floor(Math.random() * range);
}

function setRectangle(gl, x, y, width, height) {
    var x1 = x;
    var x2 = x + width;
    var y1 = y;
    var 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);
}

Key Changes Explained

  • foodArray: Stores all food items with their position and color—this is your source of truth for what should be on screen.
  • render(): Clears the canvas every time, then redraws every food in the array. This is how "removal" works: if an item isn't in the array, it won't get drawn.
  • Click Handler: A working demo of collision detection—when you click a food, it gets removed from the array and the scene re-renders. This uses simple bounding box checks, which you can refine later if needed.

内容的提问来源于stack exchange,提问作者hwijun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 18:27:34