Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

WebGL A Generalized Cylinder is a 3D geometric object created by sweeping a 2D face (often a circle/square/polygon/etc) across a spine, which is some line

WebGL

A Generalized Cylinder is a 3D geometric object created by "sweeping" a 2D face (often a circle/square/polygon/etc) across a spine, which is some line or curve in space. In our case, you will use your polyline as the spine, and a 12-sided regular polygon as the face. You will also only be drawing the Wireframe, that is, the faces will be hollow, and we will only see the outlines of the sides (the "skeleton"). Here are some examples of what it should look like:

image text in transcribed image text in transcribed

There are several things to note:

There is no perspective; the cylinder looks completely 2D. This is called an "orthographic projection," which will be covered later in the course. Essentially, our 3D model looks flattened in the z-direction, removing any depth. Your generalized cylinder model SHOULD, however, be specified in 3D coordinates, as later assignments will allow us to rotate and move around our generalized cylinders with perspective.

There are a lot of extra, crisscrossing lines. Typically when you think of a cylinder, you imagine it having rectangular faces going down the side, and polygonal faces at the ends. However, it is more typical to specify faces in computer graphics with triangles. Thus in the images above, each rectangular face is actually represented with two triangles. (If you look closely, however, it appears like each rectangle is four triangles in a sort of 'X' shape. This is not actually the case: we are simply looking through the cylinder to the other side, which is also broken up into two triangles, giving the illusion of four triangles).

The sections of the cylinder intersect cleanly. If you simply stick together a bunch of cylinders like the one in the first picture together for each section of your polyline, you will end up with weird gaps at the intersections. So, you need to implement some method of seamlessly connecting the sections.

Saving and Loading:

Saving and loading generalized cylinders will be done using the 'ioSOR.js' script, which is provided. The functions in this script will turn your models (stored as arrays of vertices and indices) into OBJ format and back.

How you should proceed:

In the end, your assignment should first allow the user to draw a polyline. When the user right clicks to finish the polyline, a 12-sided generalized cylinder is then drawn around the polyline.

Instead of going directly for this, first try just drawing a single, fixed-position generalized cylinder of fixed-length. Then, once that is comfortable, move on to figuring out how to attach that cylinder to the polyline. From there you can then move on to the additional points. This will all be talked about in more detail in lab.

As for the saving and loading portion of the assignment, since it is a pretty separate feature, you can easily save this for the end. However, take care about how you store your vertices (how your points and indices are organized in your arrays) and how you read them back to reconstruct the generalized cylinder. That is, make sure you interpret the vertices you get from a file the same way that you store them.

Here's a video of a working version of this program: https://vimeo.com/264728025

Here's some starter code:

("webgl-utils.js", "webgl-debug.js", and "cuon-utils.js" are libraries that can be found online.)

HTML file:

Assignment 2

Please use a browser that supports "canvas"

Javascript files

(load-file.js):

// load text from a file, and calls 'load_handle(file_string)' when done function loadFile(file_name, load_handle) { var request = new XMLHttpRequest(); request.onreadystatechange = function() { if (request.readyState === 4 & request.status != 404) load_handle(request.responseText); } request.open('GET', file_name, true); request.send(); }

(driver.js):

var FSIZE = 4; // size of a vertex coordinate (32-bit float)

var VSHADER_SOURCE = null; // vertex shader program

var FSHADER_SOURCE = null; // fragment shader program

var g_points = []; // array of mouse presses

// called when page is loaded

function main() {

// retrieve element

var canvas = document.getElementById('webgl');

// get the rendering context for WebGL

var gl = getWebGLContext(canvas);

if (!gl) {

console.log('Failed to get the rendering context for WebGL');

return;

}

// load shader files (calls 'setShader' when done loading)

loadFile("shader.vert", function(shader_src) {

setShader(gl, canvas, gl.VERTEX_SHADER, shader_src); });

loadFile("shader.frag", function(shader_src) {

setShader(gl, canvas, gl.FRAGMENT_SHADER, shader_src); });

}

// set appropriate shader and start if both are loaded

function setShader(gl, canvas, shader, shader_src) {

if (shader == gl.VERTEX_SHADER)

VSHADER_SOURCE = shader_src;

if (shader == gl.FRAGMENT_SHADER)

FSHADER_SOURCE = shader_src;

if (VSHADER_SOURCE && FSHADER_SOURCE)

start(gl, canvas);

}

// called by 'setShader' when shaders are done loading

function start(gl, canvas) {

// initialize shaders

if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {

console.log('Failed to intialize shaders.');

return;

}

// initialize buffers

var success = initVertexBuffer(gl);

success = success && initIndexBuffer(gl);

// initialize attributes

success = success && initAttributes(gl);

// check success

if (!success) {

console.log('Failed to initialize buffers.');

return;

}

// specify the color for clearing

gl.clearColor(0, 0, 0, 1);

// clear

gl.clear(gl.COLOR_BUFFER_BIT);

// Register function (event handler) to be called on a mouse press

canvas.onmousedown = function(ev){ click(ev, gl, canvas); };

}

// initialize vertex buffer

function initVertexBuffer(gl) {

// create buffer object

var vertex_buffer = gl.createBuffer();

if (!vertex_buffer) {

console.log("failed to create vertex buffer");

return false;

}

// bind buffer objects to targets

gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

return true;

}

// initialize index buffer

function initIndexBuffer(gl) {

// create buffer object

var index_buffer = gl.createBuffer();

if (!index_buffer) {

console.log("failed to create index buffer");

return false;

}

// bind buffer objects to targets

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);

return true;

}

// set data in vertex buffer (given typed float32 array)

function setVertexBuffer(gl, vertices) {

gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

}

// set data in index buffer (given typed uint16 array)

function setIndexBuffer(gl, indices) {

gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

}

// initializes attributes

function initAttributes(gl) {

// assign buffer to a_Position and enable assignment

var a_Position = gl.getAttribLocation(gl.program, 'a_Position');

if (a_Position

console.log("failed to get storage location of a_Position");

return false;

}

gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 3, 0);

gl.enableVertexAttribArray(a_Position);

return true;

}

// Called when user clicks on canvas

function click(ev, gl, canvas) {

var x = ev.clientX; // x coordinate of a mouse pointer

var y = ev.clientY; // y coordinate of a mouse pointer

var rect = ev.target.getBoundingClientRect();

x = ((x - rect.left) - canvas.width/2)/(canvas.width/2);

y = (canvas.height/2 - (y - rect.top))/(canvas.height/2);

// Store the coordinates to g_points array

g_points.push(x);

g_points.push(y);

g_points.push(0); // z-coordinate is 0; polyline lines in xy-plane z=0

// Clear canvas

gl.clear(gl.COLOR_BUFFER_BIT);

// Draw polyline

drawPolyline(gl);

// If user right clicks, finish polyline and draw cylinder

if (ev.button == 2) {

// Clear canvas

gl.clear(gl.COLOR_BUFFER_BIT);

/* PUT CODE TO GENERATE VERTICES/INDICES OF CYLINDER AND DRAW HERE */

drawRectangles(gl); // TEMP: Generates rectangles whose corners are connected

// Remove click handle

canvas.onmousedown = null;

}

}

// Draws the polyline based on clicked points

function drawPolyline(gl) {

// Set vertices

setVertexBuffer(gl, new Float32Array(g_points));

var n = Math.floor(g_points.length/3);

// Set indices (just an array of the numbers 0 to (n-1), which connects them one by one)

var ind = [];

for (i = 0; i

ind.push(i);

setIndexBuffer(gl, new Uint16Array(ind));

// Draw points and lines

gl.drawElements(gl.POINTS, n, gl.UNSIGNED_SHORT, 0);

/* PUT CODE TO DRAW LINES CONNECTING POINTS OF POLYLINES HERE (should only be 1 line of code) */

}

// Draws connected rectangles between clicked points

function drawRectangles(gl) {

var n = g_points.length - 1; // Number of rectangles

var vert = [];

var ind = [];

// Draw each individual rectangle separately

/* NOTE: You can also draw them all at once (single call to 'drawElements') if you want */

for (i = 0; i

// First corner of rectangle

vert.push(g_points[i*3]);

vert.push(g_points[i*3 + 1]);

vert.push(0);

ind.push(0);

// Second corner of rectangle

vert.push(g_points[i*3]);

vert.push(g_points[(i+1)*3 + 1]);

vert.push(0);

ind.push(1);

// Third corner of rectangle

vert.push(g_points[(i+1)*3]);

vert.push(g_points[(i+1)*3 + 1]);

vert.push(0);

ind.push(2);

// Fourth corner of rectangle

vert.push(g_points[(i+1)*3]);

vert.push(g_points[i*3 + 1]);

vert.push(0);

ind.push(3);

// First corner again to wrap lines around

vert.push(g_points[i*3]);

vert.push(g_points[i*3 + 1]);

vert.push(0);

ind.push(0);

// Set vertices

setVertexBuffer(gl, new Float32Array(vert));

var n = Math.floor(vert.length/3);

// Set indices

setIndexBuffer(gl, new Uint16Array(ind));

// Draw rectangle

gl.drawElements(gl.LINE_STRIP, n, gl.UNSIGNED_SHORT, 0);

// Reset vertices and indices

vert = [];

ind = [];

}

}

Other files:

(shader.frag):

void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }

(shader.vert):

attribute vec4 a_Position; void main() { gl_Position = a_Position; gl_PointSize = 10.0; }

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Data Analysis Using SQL And Excel

Authors: Gordon S Linoff

2nd Edition

111902143X, 9781119021438

More Books

Students also viewed these Databases questions