Skip to content

Transform feedback without rendering sample request #164

@DanielMazurkiewicz

Description

@DanielMazurkiewicz

Hi!
Would be nice to have some super simple example of transform feedback with vertex shader like this:

#version 300 es
        precision highp float;
        precision highp int;

        flat out int vertexId;

        void main() {
          vertexId = gl_VertexID + 1;
        }

My (finally) working example:

interface GLShaderInfo {
  name?: string,
  src: string,
  type: number 
}

const createGLShader = (gl: WebGL2RenderingContext, shaderInfo: GLShaderInfo) => {
  const shader = gl.createShader(shaderInfo.type);
  if (shader) {
    const shaderSource = shaderInfo.src.trim();
    gl.shaderSource(shader, shaderSource);
    gl.compileShader(shader);
    const compileStatus = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
    if (!compileStatus) {
      const error_message = gl.getShaderInfoLog(shader);
      throw "Could not compile shader \"" +
          shaderInfo.name +
          "\" \n" +
          error_message;
    }
  }
  return shader;
}
  

const createGLProgram = (
  gl: WebGL2RenderingContext, shaderInfos: GLShaderInfo[], transformFeedbackVaryings?: string[]
) => {
  const program = gl.createProgram();
  if (program) {
    for (let i = 0; i < shaderInfos.length; i++) {
      const shaderInfo = shaderInfos[i];
      const shader = createGLShader(gl, shaderInfo);
      if (shader) {
        gl.attachShader(program, shader);
      }
    }
  

    if (transformFeedbackVaryings != null) {
      gl.transformFeedbackVaryings(program,
        transformFeedbackVaryings,
        gl.INTERLEAVED_ATTRIBS);
    }
    gl.linkProgram(program);
    var link_status = gl.getProgramParameter(program, gl.LINK_STATUS);
    if (!link_status) {
      var error_message = gl.getProgramInfoLog(program);
      throw "Could not link program.\n" + error_message;
    }
  }
  return program;
}


const createGL = (width?: number, height?: number, canvas = document.createElement("canvas")) => {
  if (width) canvas.width = width;
  if (height) canvas.height = height;
  return canvas.getContext("webgl2");
}


function main() {
  const gl = createGL()
  if (gl != null) {
    document.body.appendChild(<HTMLCanvasElement>gl.canvas);



    
    const vs = {
      type: gl.VERTEX_SHADER,
      src: `#version 300 es
        precision highp float;
        precision highp int;

        flat out int vertexId;

        void main() {
          vertexId = gl_VertexID + 1;
        }
        `
      }
    
    const fs = {
      type: gl.FRAGMENT_SHADER,
      src: `#version 300 es
      precision mediump float;
      
      out vec4 outColor;
      
      void main() {
        outColor = vec4(1, 0, 0, 1);
      }
      `
    }

    // setup GLSL program
    const program = createGLProgram(gl, [vs, fs], ['vertexId']);
    if (program) {
      const totalLoops = 20;      
      gl.useProgram(program);

      // https://open.gl/feedback

      const vertexArray = gl.createVertexArray();
      gl.bindVertexArray(vertexArray);

      const glTransformOutputBuffer = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, glTransformOutputBuffer);
      gl.bufferData(gl.ARRAY_BUFFER, totalLoops * 16, gl.STATIC_READ);
      
      gl.enable(gl.RASTERIZER_DISCARD); // don't use fragment shader

      gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, glTransformOutputBuffer);


      gl.bindBuffer(gl.ARRAY_BUFFER, null);


      gl.beginTransformFeedback(gl.POINTS);

      const offset = 0;
      gl.drawArrays(gl.POINTS, offset, totalLoops);

      gl.endTransformFeedback();
      gl.flush();

      const transformOutputBuffer = new Uint32Array(totalLoops);
      
      gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, transformOutputBuffer);

      console.log(transformOutputBuffer);
    }
  } else {
    document.write("WebGL2 is not supported by your browser");
  }
}
  

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions