Introduction to OpenGL. CS 4620 Daniel Schroeder, 2013 Pramook Khungurn, 2012

Similar documents
Image Processing and Computer Graphics. Rendering Pipeline. Matthias Teschner. Computer Science Department University of Freiburg

Chapter 2 - Graphics Programming with JOGL

Android and OpenGL. Android Smartphone Programming. Matthias Keil. University of Freiburg

GUI GRAPHICS AND USER INTERFACES. Welcome to GUI! Mechanics. Mihail Gaianu 26/02/2014 1

OpenGL & Delphi. Max Kleiner. 1/22

How To Teach Computer Graphics

2: Introducing image synthesis. Some orientation how did we get here? Graphics system architecture Overview of OpenGL / GLU / GLUT

Game Development in Android Disgruntled Rats LLC. Sean Godinez Brian Morgan Michael Boldischar

CSE 564: Visualization. GPU Programming (First Steps) GPU Generations. Klaus Mueller. Computer Science Department Stony Brook University

Silverlight for Windows Embedded Graphics and Rendering Pipeline 1

Introduction to Computer Graphics

Computer Graphics Hardware An Overview

Experiences with 2-D and 3-D Mathematical Plots on the Java Platform

Monash University Clayton s School of Information Technology CSE3313 Computer Graphics Sample Exam Questions 2007

Radeon HD 2900 and Geometry Generation. Michael Doggett

Using WPF for Computer Graphics

Introduction to Computer Graphics

INTRODUCTION TO RENDERING TECHNIQUES

Simulation of Human Body Thermoregulation

L20: GPU Architecture and Models

Introduction to WebGL

Introduction to GPU Programming Languages

Institutionen för systemteknik Department of Electrical Engineering

Optimizing AAA Games for Mobile Platforms

OpenGL Performance Tuning

Computer Graphics CS 543 Lecture 12 (Part 1) Curves. Prof Emmanuel Agu. Computer Science Dept. Worcester Polytechnic Institute (WPI)

GPUs Under the Hood. Prof. Aaron Lanterman School of Electrical and Computer Engineering Georgia Institute of Technology

Introduction to GPGPU. Tiziano Diamanti

Computer Graphics. Anders Hast

Programming 3D Applications with HTML5 and WebGL

Beginning Android 4. Games Development. Mario Zechner. Robert Green

Aston University. School of Engineering & Applied Science

Writing Applications for the GPU Using the RapidMind Development Platform

Lecture 3: Coordinate Systems and Transformations

Computer Graphics on Mobile Devices VL SS ECTS

GPU Architecture. Michael Doggett ATI

Shader Model 3.0. Ashu Rege. NVIDIA Developer Technology Group

TEACHING GRAPHICS PROGRAMMING ON MOBILE DEVICES

Windows Phone 7 Game Development using XNA

Advanced Graphics and Animations for ios Apps

AMD GPU Architecture. OpenCL Tutorial, PPAM Dominik Behr September 13th, 2009

Graphics Pipeline in a Nutshell

A Crash Course on Programmable Graphics Hardware

Finger Paint: Cross-platform Augmented Reality

Realtime 3D Computer Graphics Virtual Reality

QNX Software Development Platform 6.6. Screen Graphics Subsystem Developer's Guide

Introduction GPU Hardware GPU Computing Today GPU Computing Example Outlook Summary. GPU Computing. Numerical Simulation - from Models to Software

3D Graphics and Cameras

Equalizer. Parallel OpenGL Application Framework. Stefan Eilemann, Eyescale Software GmbH

Programmable Graphics Hardware

Transformations in the pipeline

Performance Optimization and Debug Tools for mobile games with PlayCanvas

Web-Based Enterprise Data Visualization a 3D Approach. Oleg Kachirski, Black and Veatch

Ch 1: What is Game Programming Really Like? Ch 2: What s in a Game? Quiz #1 Discussion

Implementação. Interfaces Pessoa Máquina 2010/ Salvador Abreu baseado em material Alan Dix. Thursday, June 2, 2011

The Evolution of Computer Graphics. SVP, Content & Technology, NVIDIA

CS 4204 Computer Graphics

Recent Advances and Future Trends in Graphics Hardware. Michael Doggett Architect November 23, 2005

Java game programming. Game engines. Fayolle Pierre-Alain

Radeon GPU Architecture and the Radeon 4800 series. Michael Doggett Graphics Architecture Group June 27, 2008

Visualizing Data: Scalable Interactivity

3D Application and Game Development With OpenGL

Optimizing Unity Games for Mobile Platforms. Angelo Theodorou Software Engineer Unite 2013, 28 th -30 th August

VisIt Visualization Tool

Lecture Notes, CEng 477

Tutorial 9: Skeletal Animation

QCD as a Video Game?

Windows Presentation Foundation: What, Why and When

CMSC 427 Computer Graphics 1

Intel Graphics Media Accelerator 900

3D Augmented Reality Mobile Application Prototype for Visual Planning Support

NVPRO-PIPELINE A RESEARCH RENDERING PIPELINE MARKUS TAVENRATH MATAVENRATH@NVIDIA.COM SENIOR DEVELOPER TECHNOLOGY ENGINEER, NVIDIA

Plug-in Software Developer Kit (SDK)

GPU(Graphics Processing Unit) with a Focus on Nvidia GeForce 6 Series. By: Binesh Tuladhar Clay Smith

GPU Shading and Rendering: Introduction & Graphics Hardware

Web Based 3D Visualization for COMSOL Multiphysics

3D VIRTUAL DESKTOP APPLICATION Of UNSW. Introduction. What we propose to do 2/4. What we propose to do 1/4. What we propose to do 4/4

Operating System Components

Proseminar Graphikprogrammierung

Hardware design for ray tracing

Developer Tools. Tim Purcell NVIDIA

Master Thesis. Document : Thesis Version : 1.0 Date : 27 March 2006 Document nr. : 546

GearVRf Developer Guide

Lecture 1 Introduction to Android

JavaFX Session Agenda

ANDROID DEVELOPER TOOLS TRAINING GTC Sébastien Dominé, NVIDIA

Parallel Web Programming

Chapter 6 - The Scene Graph

Learning Modern 3D Graphics Programming. Jason L. McKesson

Tegra Android Accelerometer Whitepaper

PART-A Questions. 2. How does an enumerated statement differ from a typedef statement?

Graph visualization with OpenGL

CS 4204 Computer Graphics

An Introduction to 3D Computer Graphics, Stereoscopic Image, and Animation in OpenGL and C/C++ Fore June

Last Class: OS and Computer Architecture. Last Class: OS and Computer Architecture

Optimisation of a Graph Visualization Tool: Vizz3D

OpenGL Insights. Edited by. Patrick Cozzi and Christophe Riccio

Given a point cloud, polygon, or sampled parametric curve, we can use transformations for several purposes:

XBOX Performances XNA. Part of the slide set taken from: Understanding XNA Framework Performance Shawn Hargreaves GameFest 2007

Overview. Lecture 1: an introduction to CUDA. Hardware view. Hardware view. hardware view software view CUDA programming

Transcription:

Introduction to OpenGL CS 4620 Daniel Schroeder, 2013 Pramook Khungurn, 2012

Introduction Show how to produce graphics using OpenGL Introduce our framework for OpenGL programming

OpenGL Open Graphics Library API for GPU-accelerated 2D / 3D rendering Cross-platform (Windows, OS X, Linux, ios, Android,...) Developed by SGI in 1992 2009: OpenGL 3.2 2010: OpenGL 4.0 2011: OpenGL 4.2 Main alternative: Direct3D (Windows / XBox)

Why Use OpenGL? Tap massive power of GPU hardware to render images Use GPU without worrying about exact details of hardware

What OpenGL Does For Us Controls GPU Lets user specify resources...: Geometry (vertices and primitives) Textures Shaders (programs that run in the graphics pipeline) Etc....and use them: Rasterize and draw geometry

How We'll Use OpenGL OpenGL version We use 2.1, plus extensions Some features in 2.1 are no longer commonly used Code uses subset of features used in 3.x and 4.x JOGL Java bindings for OpenGL API CS 4620 Framework Simplifies creating and using OpenGL resources

Creating an OpenGL Program

GLCanvas Java UI component Can display images created by OpenGL OpenGL context Stores OpenGL state (geometry, buffers, etc.) Provides the framebuffer that we draw to Usage: create and put into a Java window

Events GL canvas can trigger certain events Something happens (e.g. user resizes window) Canvas broadcasts a message Objects interested in the event can sign up as listeners When event happens, OpenGL calls method in listener These events let us interact with OpenGL

GLEventListener Interface for classes that can listen for OpenGL events Implementations can perform OpenGL commands Usage: Create class implementing GLEventListener Implement four methods Call GLCanvas.addGLListener

GLEventListener Methods init Called once when OpenGL context is created display Called when GLCanvas wants to update the image it shows resize Called when canvas is resized dispose Called when OpenGL context is destroyed

GLEventListener Methods init Use to create GL resources (geometry, textures, etc.) display Use to draw to the canvas resize Use to update information based on new window size dispose Use to free up GL resources

Demo: Hello World!

OpenGL Commands and Resources

Example: Hello World's display() @Override public void display(glautodrawable drawable) { final GL2 gl = drawable.getgl().getgl2(); gl.glclearcolor(0.0f, 0.0f, 0.0f, 1.0f); gl.glclear(gl2.gl_color_buffer_bit); Program.use(gl, program); program.setcolor(gl, 1.0f, 1.0f, 1.0f); boxarray.draw(gl); } Program.unuse(gl);

OpenGL Commands final GL2 gl = drawable.getgl().getgl2() Get OpenGL context for canvas GL2 object exposes underlying C API for OpenGL API calls: gl.glsomecommandname gl.glclearcolor(0.0f, 0.0f, 0.0f, 1.0f) Set black as the color to use when clearing the screen gl.glclear(gl2.gl_color_buffer_bit) Clear the display buffer using the color given by glclearcolor

Framework Commands Program.use(gl, program) Set which shader program the pipeline will use to draw geometry More about this on another day... program.setcolor(gl, 1.0f, 1.0f, 1.0f); Tell shader program to draw geometry in white boxarray.draw(gl) Draw the geometry described by boxarray Program.unuse(gl) Tell OpenGL we are done drawing for now Each of these has OpenGL commands under the hood

Framework Commands Program.use(gl, program) Set which shader program the pipeline will use to draw geometry More about this on another day... program.setcolor(gl, 1.0f, 1.0f, 1.0f); Tell shader program to draw geometry in white boxarray.draw(gl) Draw the geometry described by boxarray Program.unuse(gl) Tell OpenGL we are done drawing for now Each of these has OpenGL commands under the hood Framework commands that need access to OpenGL take the gl object as their first argument

Why Have a Framework? You write: boxarray.draw(gl) Framework does: gl.glbindvertexarray(boxarray.id); gl.glbindbuffer(gl2.gl_element_array_buffer, boxarray.indexbuffer.id); gl.gldrawelements(boxarray.geometrytype, boxarray.indexbuffer.numelements, boxarray.indexbuffer.format, 0); gl.glbindbuffer(gl2.gl_element_array_buffer, 0); gl.glbindvertexarray(0); Annoying to retype full sequence of commands for every draw

Framework and GL Resources OpenGL API has objects that hold rendering resources Geometry, textures, shader programs, etc. Framework represents these with Java classes Program (shader programs) VertexBuffer, VertexArray (used to specify geometry) Constructing an object creates OpenGL resource Object's data lives in GPU memory Allows faster access while rendering

OpenGL Resources: Geometry

Demo: Two Boxes

What We're Seeing Box on left: two triangles Box on right: four lines

Vertices Foundation for all geometry OpenGL: specify with VertexBuffer

Primitives Basic shapes built from vertices; e.g. triangles, lines Assemble to build more complicated shapes OpenGL: specify with VertexArray and IndexBuffer

Specifying Vertices: VertexBuffer OpenGL object to store vertices Info needed: Array of floats representing vertices How many dimensions per vertex (2D? 3D?) ( [-0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5], 2 floats per vertex ) VertexBuffer -0.5, -0.5 0.5, -0.5 0.5, 0.5-0.5, 0.5 = 3 2 0 1 2 3 0 1

Specifying Vertices: TwoBoxes' init() @Override public void init(glautodrawable drawable) { if(initialized) return; GL2 gl = drawable.getgl().getgl2(); // define vertex positions float [] vertexpositions = { -0.5f, -0.5f, // vertex 0 0.5f, -0.5f, // vertex 1 0.5f, 0.5f, // vertex 2-0.5f, 0.5f // vertex 3 }; VertexBuffer vertexbuffer = new VertexBuffer(gl, vertexpositions, 2);...

Grouping Vertices into Primitives VertexBuffer gives vertices in some order VertexBuffer -0.5, -0.5 0.5, -0.5 0.5, 0.5-0.5, 0.5 = 3 2 0 1 2 3 0 1 Can re-order vertices to form primitives, so that: Every three vertices form a triangle Every two vertices form a line [0, 1, 2, 0, 2, 3] 3 2 0 1 3 2 [0, 1, 1, 2, 2, 3, 3, 0] 0 1

Grouping Vertices: IndexBuffer OpenGL object to store sequence of vertex indices Info needed: List of integer indices [0, 1, 2, 0, 2, 3] [0, 1, 1, 2, 2, 3, 3, 0] 0, 1, 2, 0, 2, 3 0, 1, 1, 2, 2, 3, 3, 0 IndexBuffer IndexBuffer

Ways to Group: GL Primitives OpenGL declares several primitive types Determine how to group a sequence of verts into primitives (adapted from http://www.ntu.edu.sg/home/ehchua/programming/opengl/cg_basicstheory.html)

Ways to Group: GL Primitives OpenGL declares several primitive types Determine how to group a sequence of verts into primitives (adapted from http://www.ntu.edu.sg/home/ehchua/programming/opengl/cg_basicstheory.html)

Putting it Together VertexBuffer: what the vertices are IndexBuffer: in what order to put them Primitive Type: how to group ordered vertices into primitives Together, fully describes geometry VertexBuffer -0.5, -0.5 0.5, -0.5 0.5, 0.5-0.5, 0.5 0 1 2 3 IndexBuffer 0, 1, 2, 0, 2, 3 Primitive Type GL_TRIANGLES

Putting it Together: VertexArray OpenGL object to fully describe a piece of geometry Can be drawn by OpenGL Info needed: VertexBuffer, IndexBuffer, primitive type VertexArray VertexBuffer -0.5, -0.5 0.5, -0.5 0.5, 0.5-0.5, 0.5 0 1 2 3 IndexBuffer 0, 1, 2, 0, 2, 3 Primitive Type GL_TRIANGLES

VertexArray in TwoBoxes' init()... // earlier, filled VertexBuffer vertexpositions int [] linesindices = { 0, 1, 1, 2, 2, 3, 3, 0 }; int [] trianglesindices = { 0, 1, 2, 0, 2, 3 }; // make index buffers linesbuffer = new IndexBuffer(gl, linesindices); trianglesbuffer = new IndexBuffer(gl, trianglesindices);...

VertexArray in TwoBoxes' init()... // earlier: made VertexBuffer vertexbuffer // filled IndexBuffer linesbuffer, trianglesbuffer boxarray = new VertexArray(gl, GL2.GL_TRIANGLES); boxarray.setindexbuffer(gl, trianglesbuffer); boxarray.setattributebuffer(gl, TwoDimProgram.VERTEX_INDEX, vertexbuffer); boxlinesarray = new VertexArray(gl, GL2.GL_LINES); boxlinesarray.setindexbuffer(gl, linesbuffer); boxlinesarray.setattributebuffer(gl, TwoDimProgram.VERTEX_INDEX, vertexbuffer);

VertexArray in TwoBoxes' init()... // earlier: made VertexBuffer vertexbuffer // filled IndexBuffer linesbuffer, trianglesbuffer boxarray = new VertexArray(gl, GL2.GL_TRIANGLES); boxarray.setindexbuffer(gl, trianglesbuffer); boxarray.setattributebuffer(gl, TwoDimProgram.VERTEX_INDEX, vertexbuffer); boxlinesarray = new VertexArray(gl, GL2.GL_LINES); boxlinesarray.setindexbuffer(gl, linesbuffer); boxlinesarray.setattributebuffer(gl, TwoDimProgram.VERTEX_INDEX, vertexbuffer); Construct VertexArray and say what primitives we will build One will make triangles, the other lines

VertexArray in TwoBoxes' init()... // earlier: made VertexBuffer vertexbuffer // filled IndexBuffer linesbuffer, trianglesbuffer boxarray = new VertexArray(gl, GL2.GL_TRIANGLES); boxarray.setindexbuffer(gl, trianglesbuffer); boxarray.setattributebuffer(gl, TwoDimProgram.VERTEX_INDEX, vertexbuffer); boxlinesarray = new VertexArray(gl, GL2.GL_LINES); boxlinesarray.setindexbuffer(gl, linesbuffer); boxlinesarray.setattributebuffer(gl, TwoDimProgram.VERTEX_INDEX, vertexbuffer); Tell array how to order the vertices when building primitives Triangles and lines will need different vertex orders

VertexArray in TwoBoxes' init()... // earlier: made VertexBuffer vertexbuffer // filled IndexBuffer linesbuffer, trianglesbuffer boxarray = new VertexArray(gl, GL2.GL_TRIANGLES); boxarray.setindexbuffer(gl, trianglesbuffer); boxarray.setattributebuffer(gl, TwoDimProgram.VERTEX_INDEX, vertexbuffer); boxlinesarray = new VertexArray(gl, GL2.GL_LINES); boxlinesarray.setindexbuffer(gl, linesbuffer); boxlinesarray.setattributebuffer(gl, TwoDimProgram.VERTEX_INDEX, vertexbuffer); Tell arrays what vertex data to use Both boxes use the same buffer of four vertices

VertexArray in TwoBoxes' init()... // earlier: made VertexBuffer vertexbuffer // filled IndexBuffer linesbuffer, trianglesbuffer boxarray = new VertexArray(gl, GL2.GL_TRIANGLES); boxarray.setindexbuffer(gl, trianglesbuffer); boxarray.setattributebuffer(gl, TwoDimProgram.VERTEX_INDEX, vertexbuffer); boxlinesarray = new VertexArray(gl, GL2.GL_LINES); boxlinesarray.setindexbuffer(gl, linesbuffer); boxlinesarray.setattributebuffer(gl, TwoDimProgram.VERTEX_INDEX, vertexbuffer); What is this about?

Vertices are More than Positions A vertex has a position But it can also have other attributes: Normal vector Color Texture coordinate etc. Use multiple VertexBuffers to store this info Positions Colors 0 1 2 3-0.5, -0.5 0.5, -0.5 0.5, 0.5-0.5, 0.5 1, 0, 0 0, 1, 0 0, 0, 1 1, 1, 0 3 2 0 1

... The Full Power of VertexArray Accepts multiple VertexBuffers specifying different attributes Each buffer mapped to some index in array of attributes VertexArray Array of Vertex Attributes 0 1 2 3-0.5, -0.5 0.5, -0.5 0.5, 0.5-0.5, 0.5 1, 0, 0 0, 1, 0 0, 0, 1 1, 1, 0 0 1 2 IndexBuffer Primitive Type 0, 1, 2, 0, 2, 3 GL_TRIANGLES

...... Attribute Indices Shader program draws vertices using same array of attributes Program declares where it wants each attribute to be VertexArray Program Array of Vertex Attributes 0 1 2 3-0.5, -0.5 0.5, -0.5 0.5, 0.5-0.5, 0.5 1, 0, 0 0, 1, 0 0, 0, 1 1, 1, 0 0 1 0 1 = Position = Color 2 2 IndexBuffer Primitive Type 0, 1, 2, 0, 2, 3 GL_TRIANGLES Vertex Attributes Wanted

Demo: Color Boxes

ColorBoxes' init() @Override public void init(glautodrawable drawable) {... // fill vertexbuffer as before float [] vertexcolors = { 1.0f, 0.0f, 0.0f, // vertex 0 0.0f, 1.0f, 0.0f, // vertex 1 0.0f, 0.0f, 1.0f, // vertex 2 1.0f, 1.0f, 0.0f // vertex 3 }; VertexBuffer colorsbuffer = new VertexBuffer(gl, vertexcolors, 3);...

ColorBoxes' init()... // fill IndexBuffers trianglesbuffer and linesbuffer boxarray = new VertexArray(gl, GL2.GL_TRIANGLES); boxarray.setindexbuffer(gl, trianglesbuffer); boxarray.setattributebuffer(gl, TwoDimColorProgram.VERTEX_INDEX, vertexbuffer); boxarray.setattributebuffer(gl, TwoDimColorProgram.COLOR_INDEX, colorsbuffer); boxlinesarray = new VertexArray(gl, GL2.GL_LINES); boxlinesarray.setindexbuffer(gl, linesbuffer); boxlinesarray.setattributebuffer(gl, TwoDimColorProgram.VERTEX_INDEX, vertexbuffer); boxlinesarray.setattributebuffer(gl, TwoDimColorProgram.COLOR_INDEX, colorsbuffer);

ColorBoxes' init()... // fill IndexBuffers trianglesbuffer and linesbuffer boxarray = new VertexArray(gl, GL2.GL_TRIANGLES); boxarray.setindexbuffer(gl, trianglesbuffer); boxarray.setattributebuffer(gl, TwoDimColorProgram.VERTEX_INDEX, vertexbuffer); boxarray.setattributebuffer(gl, TwoDimColorProgram.COLOR_INDEX, colorsbuffer); boxlinesarray = new VertexArray(gl, GL2.GL_LINES); boxlinesarray.setindexbuffer(gl, linesbuffer); boxlinesarray.setattributebuffer(gl, TwoDimColorProgram.VERTEX_INDEX, vertexbuffer); boxlinesarray.setattributebuffer(gl, TwoDimColorProgram.COLOR_INDEX, colorsbuffer); Put vertex positions at index where shader program wants them

ColorBoxes' init()... // fill IndexBuffers trianglesbuffer and linesbuffer boxarray = new VertexArray(gl, GL2.GL_TRIANGLES); boxarray.setindexbuffer(gl, trianglesbuffer); boxarray.setattributebuffer(gl, TwoDimColorProgram.VERTEX_INDEX, vertexbuffer); boxarray.setattributebuffer(gl, TwoDimColorProgram.COLOR_INDEX, colorsbuffer); boxlinesarray = new VertexArray(gl, GL2.GL_LINES); boxlinesarray.setindexbuffer(gl, linesbuffer); boxlinesarray.setattributebuffer(gl, TwoDimColorProgram.VERTEX_INDEX, vertexbuffer); boxlinesarray.setattributebuffer(gl, TwoDimColorProgram.COLOR_INDEX, colorsbuffer); Put vertex colors at index where shader program wants them

Transformations

Representing Transformations We will use Matrix3f, Matrix4f classes Set matrix contents: Matrix3f translate = new Matrix3f(1.0f, 0.0f, 3.0f, 0.0f, 1.0f, -4.0f, 0.0f, 0.0f, 1.0f); Copy matrices: Matrix3f translateagain = new Matrix3f(translate); Multiply matrices: translate.mul(translateagain); // translate = translate * translateagain Transform points: Vertex3f vert = new Vertex3f(2.0f, 0.0f, 1.0f); translate.transform(vert); // vert = translate * vert

Transforms Class Provides various useful transformation matrices Identity matrices Translations, scales, rotations Projection matrices Command names indicate dimension: translate3dh(): 4x4 matrix, expects 3D homogeneous coords identity3d(): 3x3 matrix, expects 3D non-homogeneous coords

Transforming a Vertex VertexArray gives vertices to shader program Program transforms them onto screen before drawing Screen position = Transformation px py pz 1

Transforming a Vertex Applies two transforms: Projection and ModelView Very basic description now; will discuss topic more later Screen position = Projection ModelView px py pz 1

ModelView matrix Transforms vertex into coordinates of the viewer Modify matrix to transform objects to different places Camera plane p eye ModelView p

Projection matrix Projects point down onto camera plane Usually set matrix once at beginning of display() Camera plane Camera plane p screen Projection p eye

Setting Matrices You tell the shader program what matrices to use program.setprojection(projectionmatrix); program.setmodelview(modelviewmatrix); Program keeps drawing with the same matrices until you change them Common use pattern: program.setmodelview(transformforthisobject); thisobject.draw()

Demo: Sierpinski Triangle

Sierpinski's draw() @Override public void display(glautodrawable drawable) { final GL2 gl = drawable.getgl().getgl2(); gl.glclearcolor(0.0f, 0.0f, 0.0f, 1.0f); gl.glclear(gl2.gl_color_buffer_bit); Program.use(gl, program); program.setprojection(gl, Transforms.ortho2DH(-1.0f, 1.0f, -1.0f, 1.0f)); program.setcolor(gl, 1.0f, 1.0f, 1.0f); sierpinski(gl, Transforms.identity2DH(), 8); } Program.unuse(gl);

Recursively Drawing Fractal Define levels of Sierpinski triangles Level 0 Level 1 Level 2 Level 3 Recursive function sierpinski(gl, modelview, k) Level 0: a single triangle Build level k recursively from three copies of level k-1 Use modelview matrix to transform the three copies Example of drawing a hierarchy

sierpinski() void sierpinski(gl2 gl, Matrix3f modelview, int k) { if (k == 0) triangle(gl, modelview); else { Matrix3f next; // make next = modelview * (transform to top corner) next = new Matrix3f(modelView); next.mul(transforms.translate2dh(0.0f, 0.5f / sqrt(3.0f))); next.mul(transforms.scale2dh(0.5f)); sierpinski(gl, next, k-1); // make next = modelview * (transform to bottom right corner) next = new Matrix3f(modelView); next.mul(transforms.translate2dh(0.25f, -0.25f / sqrt(3.0f))); next.mul(transforms.scale2dh(0.5f)); sierpinski(gl, next, k-1); } } // make next = modelview * (transform to bottom left corner) next = new Matrix3f(modelView); next.mul(transforms.translate2dh(-0.25f, -0.25f / sqrt(3.0f))); next.mul(transforms.scale2dh(0.5f)); sierpinski(gl, next, k-1);

sierpinski() modelview void sierpinski(gl2 gl, Matrix3f modelview, int k) { if (k == 0) triangle(gl, modelview); }

sierpinski() modelview void sierpinski(gl2 gl, Matrix3f modelview, int k) { else { Matrix3f next; } // make next = modelview * (transform to top corner) next = new Matrix3f(modelView); next.mul(transforms.translate2dh(0.0f, 0.5f / sqrt(3.0f))); next.mul(transforms.scale2dh(0.5f)); sierpinski(gl, next, k-1); }

sierpinski() void sierpinski(gl2 gl, Matrix3f modelview, int k) { modelview next else { Matrix3f next; } // make next = modelview * (transform to top corner) next = new Matrix3f(modelView); next.mul(transforms.translate2dh(0.0f, 0.5f / sqrt(3.0f))); next.mul(transforms.scale2dh(0.5f)); sierpinski(gl, next, k-1); }

sierpinski() void sierpinski(gl2 gl, Matrix3f modelview, int k) { modelview next else { Matrix3f next; } // make next = modelview * (transform to top corner) next = new Matrix3f(modelView); next.mul(transforms.translate2dh(0.0f, 0.5f / sqrt(3.0f))); next.mul(transforms.scale2dh(0.5f)); sierpinski(gl, next, k-1); }

sierpinski() modelview void sierpinski(gl2 gl, Matrix3f modelview, int k) { if (k == 0) triangle(gl, modelview); else { Matrix3f next; // make next = modelview * (transform to top corner) next = new Matrix3f(modelView); next.mul(transforms.translate2dh(0.0f, 0.5f / sqrt(3.0f))); next.mul(transforms.scale2dh(0.5f)); sierpinski(gl, next, k-1); // make next = modelview * (transform to bottom right corner) next = new Matrix3f(modelView); next.mul(transforms.translate2dh(0.25f, -0.25f / sqrt(3.0f))); next.mul(transforms.scale2dh(0.5f)); sierpinski(gl, next, k-1); } } // make next = modelview * (transform to bottom left corner) next = new Matrix3f(modelView); next.mul(transforms.translate2dh(-0.25f, -0.25f / sqrt(3.0f))); next.mul(transforms.scale2dh(0.5f)); sierpinski(gl, next, k-1);