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

Similar documents
CS4621/5621 Fall Computer Graphics Practicum Intro to OpenGL/GLSL

Ciril Bohak. - INTRODUCTION TO WEBGL

Graphics Programming. Computer Graphics, VT 2016 Lecture 2, Chapter 2. Fredrik Nysjö Centre for Image analysis Uppsala University

OPENGL AND GLSL. Computer Graphics

CS 4620 Program 3: Pipeline

OUTLINE. Learn the basic design of a graphics system Introduce pipeline architecture Examine software components for a graphics system

Shaders. Slide credit to Prof. Zwicker

Spring 2009 Prof. Hyesoon Kim

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

Spring 2011 Prof. Hyesoon Kim

SHADER PROGRAMMING. Based on Jian Huang s lecture on Shader Programming

The Application Stage. The Game Loop, Resource Management and Renderer Design

CS451Real-time Rendering Pipeline

OpenGL refresher. Advanced Computer Graphics 2012

Shader Programs. Lecture 30 Subsections 2.8.2, Robb T. Koether. Hampden-Sydney College. Wed, Nov 16, 2011

CS4621/5621 Fall Basics of OpenGL/GLSL Textures Basics

COMP3421 Computer Graphics

Rasterization Overview

last time put back pipeline figure today will be very codey OpenGL API library of routines to control graphics calls to compile and load shaders

CS230 : Computer Graphics Lecture 4. Tamar Shinar Computer Science & Engineering UC Riverside

Models and Architectures

Outline. Introduction Surface of Revolution Hierarchical Modeling Blinn-Phong Shader Custom Shader(s)

Programmable GPUs. Real Time Graphics 11/13/2013. Nalu 2004 (NVIDIA Corporation) GeForce 6. Virtua Fighter 1995 (SEGA Corporation) NV1

Computer graphics 2: Graduate seminar in computational aesthetics

CS 428: Fall Introduction to. OpenGL primer. Andrew Nealen, Rutgers, /13/2010 1

CS 432 Interactive Computer Graphics

COMP371 COMPUTER GRAPHICS

CSE 4431/ M Advanced Topics in 3D Computer Graphics. TA: Margarita Vinnikov

C P S C 314 S H A D E R S, O P E N G L, & J S RENDERING PIPELINE. Mikhail Bessmeltsev

Lab 1 Sample Code. Giuseppe Maggiore

CS452/552; EE465/505. Review & Examples

Rendering Objects. Need to transform all geometry then

CSE 167: Lecture #4: Vertex Transformation. Jürgen P. Schulze, Ph.D. University of California, San Diego Fall Quarter 2012

Could you make the XNA functions yourself?

Shader Series Primer: Fundamentals of the Programmable Pipeline in XNA Game Studio Express

CS GPU and GPGPU Programming Lecture 2: Introduction; GPU Architecture 1. Markus Hadwiger, KAUST

Approximate Catmull-Clark Patches. Scott Schaefer Charles Loop

CS 381 Computer Graphics, Fall 2012 Midterm Exam Solutions. The Midterm Exam was given in class on Tuesday, October 16, 2012.

CSE 167: Introduction to Computer Graphics Lecture #4: Vertex Transformation

Introduction to Computer Graphics with WebGL

From system point of view, a graphics application handles the user input, changes the internal state, called the virtual world by modeling or

WebGL A quick introduction. J. Madeira V. 0.2 September 2017

Lecture 2. Shaders, GLSL and GPGPU

OpenGL Programmable Shaders

CENG 477 Introduction to Computer Graphics. Graphics Hardware and OpenGL

CIS 581 Interactive Computer Graphics

CS770/870 Spring 2017 Open GL Shader Language GLSL

CS770/870 Spring 2017 Open GL Shader Language GLSL

Today s Agenda. Basic design of a graphics system. Introduction to OpenGL

The Importance of Matrices in the DirectX API. by adding support in the programming language for frequently used calculations.

CSC 8470 Computer Graphics. What is Computer Graphics?

Adaptive Point Cloud Rendering

Programming shaders & GPUs Christian Miller CS Fall 2011

Introduction to OpenGL

INFOGR Computer Graphics

CS 450: COMPUTER GRAPHICS REVIEW: INTRODUCTION TO COMPUTER GRAPHICS SPRING 2016 DR. MICHAEL J. REALE

Sign up for crits! Announcments

WebGL (Web Graphics Library) is the new standard for 3D graphics on the Web, designed for rendering 2D graphics and interactive 3D graphics.

CS 381 Computer Graphics, Fall 2008 Midterm Exam Solutions. The Midterm Exam was given in class on Thursday, October 23, 2008.

Mobile Application Programing: Android. OpenGL Operation

BCA611 Video Oyunları için 3B Grafik

Computer Graphics (CS 543) Lecture 10: Soft Shadows (Maps and Volumes), Normal and Bump Mapping

Pipeline Operations. CS 4620 Lecture Steve Marschner. Cornell CS4620 Spring 2018 Lecture 11

Graphics Hardware. Graphics Processing Unit (GPU) is a Subsidiary hardware. With massively multi-threaded many-core. Dedicated to 2D and 3D graphics

Metal. GPU-accelerated advanced 3D graphics rendering and data-parallel computation. source rebelsmarket.com

Recall: Indexing into Cube Map

Computer Graphics. Lecture 02 Graphics Pipeline. Edirlei Soares de Lima.

CS450/550. Pipeline Architecture. Adapted From: Angel and Shreiner: Interactive Computer Graphics6E Addison-Wesley 2012

Building Models. CS 537 Interactive Computer Graphics Prof. David E. Breen Department of Computer Science

CS 354R: Computer Game Technology

Drawing in 3D (viewing, projection, and the rest of the pipeline)

COMP3421/9415 Computer Graphics

Transformation Pipeline

Chapter Answers. Appendix A. Chapter 1. This appendix provides answers to all of the book s chapter review questions.

TSBK03 Screen-Space Ambient Occlusion

CS 432 Interactive Computer Graphics

The Projection Matrix

PROFESSIONAL. WebGL Programming DEVELOPING 3D GRAPHICS FOR THE WEB. Andreas Anyuru WILEY. John Wiley & Sons, Ltd.

Drawing in 3D (viewing, projection, and the rest of the pipeline)

Overview. By end of the week:

Pipeline Operations. CS 4620 Lecture 14

X. GPU Programming. Jacobs University Visualization and Computer Graphics Lab : Advanced Graphics - Chapter X 1

Introduction to 2D Graphics

Real-Time Rendering (Echtzeitgraphik) Michael Wimmer

CS 591B Lecture 9: The OpenGL Rendering Pipeline

Game Architecture. 2/19/16: Rasterization

To Do. Computer Graphics (Fall 2008) Course Outline. Course Outline. Methodology for Lecture. Demo: Surreal (HW 3)

CMSC427 Transformations II: Viewing. Credit: some slides from Dr. Zwicker

Lecture 12: Mid-term test solution & project. CITS 3003 Graphics & Animation

CS 380 Introduction to Computer Graphics. LAB (1) : OpenGL Tutorial Reference : Foundations of 3D Computer Graphics, Steven J.

Comp 410/510 Computer Graphics Spring Programming with OpenGL Part 4: Three Dimensions

Module Contact: Dr Stephen Laycock, CMP Copyright of the University of East Anglia Version 1

Real - Time Rendering. Graphics pipeline. Michal Červeňanský Juraj Starinský

Today. Rendering pipeline. Rendering pipeline. Object vs. Image order. Rendering engine Rendering engine (jtrt) Computergrafik. Rendering pipeline

CMSC427 Fall 2017 OpenGL Notes A: Starting with JOGL and OpenGL Objectives of notes Readings Computer Graphics Programming in OpenGL with Java

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

Drawing Fast The Graphics Pipeline

CS475/CS675 - Computer Graphics. OpenGL Drawing

Computer Graphics and Visualization. Graphics Systems and Models

CS452/552; EE465/505. Image Formation

Transcription:

Introduction to OpenGL CS 4620 Balazs Kovacs, 2014 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 LWJGL Lightweight Java Game Library Java bindings for OpenGL API CS 4620 Framework Simplifies creating and using OpenGL resources

Creating an OpenGL Program

MainGame A window which can display GameScreens Initializes OpenGL context Forwards keyboard and mouse events to the event dispatcher Usage Inherit from MainGame and implement methods Create instance and call run method

MainGame @Override protected void buildscreenlist() { // Create objects inherited from GameScreen and // initialize screenlist attribute } @Override protected void fullinitialize() { // Code Executed Before Window Is Created } @Override protected void fullload() { // Code Executed With An Active OpenGL Context }

GameScreen Can display images created by OpenGL OpenGL context Stores OpenGL state (geometry, buffers, etc.) Usage Inherit from class and implement methods Create instance in MainGame.buildScreenList

GameScreen @Override public void update(gametime gametime) { // Animation: Update position of scene objects, camera } @Override public void draw(gametime gametime) { // Drawing: Use LWJGL to draw to the screen } @Override public void onentry(gametime gametime) { // Initialization code } @Override public void onexit(gametime gametime) { // Destruction, free allocated resources here }

Events MainGame can trigger certain events Something happens (e.g. user resizes window) MainGame forwards event to the event dispatcher KeyboardEventDispatcher MouseEventDispatcher Objects interested in the event can sign up as listeners E.g. KeyboardEventDispatcher.OnKeyPressed.add( ) These events let us interact with OpenGL

Demo: Hello World!

OpenGL Commands and Resources

Example: Hello World's draw() @Override public void draw(gametime gametime) { GL11.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); GL11.glClear(GL11.GL_COLOR_BUFFER_BIT); program.use(); GLUniform.setST(program.getUniform("VP"), new Matrix4(), false); GLUniform.set(program.getUniform("uGridColor"), new Vector4(1, 1, 1, 1)); vb.useasattrib(program.getattribute("vpos")); ib.bind(); GL11.glDrawElements(GL11.GL_TRIANGLES, indexcount, GLType.UnsignedInt, 0); ib.unbind(); } GLProgram.unuse();

OpenGL Commands Get OpenGL context is already initialized API calls: glxx.glsomecommandname GL11.glClearColor(0.0f, 0.0f, 0.0f, 1.0f) Set black as the color to use when clearing the screen GL11.glClear(GL11.GL_COLOR_BUFFER_BIT) Clear the display buffer using the color given by glclearcolor GL11.glDrawElements( ) Draw primitives (now triangles)

Framework Commands program.use() Set which shader program the pipeline will use to draw geometry We talked about this during the GLSL lecture GLUniform.setST(program.getUniform("VP"), ) Tell shader program to use the specified transformation as VP GLUniform.set(program.getUniform("uGridColor"), ) Tell shader program to use the specified color as ugridcolor GLProgram.unuse() Tell OpenGL we are done drawing for now Each of these has OpenGL commands under the hood

Framework Commands vb.useasattrib(program.getattribute("vpos")) Tell shader program to use vb as vertex buffer and access vertex position using vpos ib.bind(), ib.unbind() Bind (and unbind) the index buffer to tell OpenGL about how we use the vertices in the vertex buffer

Why Have a Framework? You write: vb.useasattrib(program.getattribute("vpos")); Framework does: GL15.glBindBuffer(GL11.GL_ARRAY_BUFFER, vb.id); GL15.glEnableVertexAttribArray(program.getAttribute("vPos")); GL15.glVertexAttribPointer(program.getAttribute("vPos"), componentcount, componentformat, norm, elementbytesize, offset * elementbytesize); 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 GLProgram (shader programs) GLBuffer (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 GLBuffer

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

GLBuffer OpenGL object to store arrays like vertex positions, vertex colors, indices We have to specify How many component per element Color: 3D vector Position: 2D/3D vector Index: 1D Type of stored element components (int, float, double, ) Array of element components The stored data itself

Specifying Vertices GLBuffer: store sequence of vertex positions 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 ) GLBuffer -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 onentry(gametime gametime) { // 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 }; GLBuffer vertexbuffer = GLBuffer.createAsVertex( vertexpositions, 2, BufferUsageHint.StaticDraw);...

Grouping Vertices into Primitives GLBuffer gives vertices in some order GLBuffer -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] [0, 1, 1, 2, 2, 3, 3, 0] 3 2 0 1 3 2 0 1

Grouping Vertices GLBuffer: 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 GLBuffer GLBuffer

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 GLBuffer 0: what the vertices are GLBuffer 1 (index array): in what order to put them Primitive Type: how to group ordered vertices into primitives Together, fully describes geometry GLBuffer 0-0.5, -0.5 0.5, -0.5 0.5, 0.5-0.5, 0.5 0 1 2 3 GLBuffer 1 0, 1, 2, 0, 2, 3 Primitive Type GL_TRIANGLES

Putting it Together: Bindings Bind buffer elements to vertex attributes Bind indices to buffer in OpenGL Draw using OpenGL Info needed: GLBuffer with vertice attributes, GLBuffer with indices, primitive type GLBuffer 0-0.5, -0.5 0.5, -0.5 0.5, 0.5-0.5, 0.5 0 1 2 3 GLBuffer 1 0, 1, 2, 0, 2, 3 Primitive Type GL_TRIANGLES

Index arrays in TwoBoxes' onentry()... // earlier, filled GLBuffer vertexpositions int [] linesindices = { 0, 1, 1, 2, 2, 3, 3, 0 }; int [] trianglesindices = { 0, 1, 2, 0, 2, 3 }; // make index buffers iblines = GLBuffer.createAsIndex(linesIndices, BufferUsageHint.StaticDraw); indexcountlines = linesindices.length; ibtriangles = GLBuffer.createAsIndex(trianglesIndices, BufferUsageHint.StaticDraw); indexcounttriangles = trianglesindices.length;...

TwoBoxes' draw()... // Use box vertices we defined before vb.useasattrib(program.getattribute("vpos")); // Setup transformations... // Binding indices and drawing ibtriangles.bind(); GL11.glDrawElements(GL11.GL_TRIANGLES, indexcounttriangles, GLType.UnsignedInt, 0); ibtriangles.unbind(); // Setup transformations... // Binding indices and drawing iblines.bind(); GL11.glDrawElements(GL11.GL_LINES, indexcountlines, GLType.UnsignedInt, 0); iblines.unbind();

TwoBoxes' draw()... // Use box vertices we defined before vb.useasattrib(program.getattribute("vpos")); // Setup transformations... // Binding indices and drawing ibtriangles.bind(); GL11.glDrawElements(GL11.GL_TRIANGLES, indexcounttriangles, GLType.UnsignedInt, 0); ibtriangles.unbind(); // Setup transformations... // Binding indices and drawing iblines.bind(); GL11.glDrawElements(GL11.GL_LINES, indexcountlines, GLType.UnsignedInt, 0); iblines.unbind(); Bind index array and say what primitives we will build One will make triangles, the other lines

TwoBoxes' draw()... // Use box vertices we defined before vb.useasattrib(program.getattribute("vpos")); // Setup transformations... // Binding indices and drawing ibtriangles.bind(); GL11.glDrawElements(GL11.GL_TRIANGLES, indexcounttriangles, GLType.UnsignedInt, 0); ibtriangles.unbind(); // Setup transformations... // Binding indices and drawing iblines.bind(); GL11.glDrawElements(GL11.GL_LINES, indexcountlines, GLType.UnsignedInt, 0); iblines.unbind(); Tell OpenGL how to order the vertices when building primitives Triangles and lines will need different vertex orders

TwoBoxes' draw()... // Use box vertices we defined before vb.useasattrib(program.getattribute("vpos")); // Setup transformations... // Binding indices and drawing ibtriangles.bind(); GL11.glDrawElements(GL11.GL_TRIANGLES, indexcounttriangles, GLType.UnsignedInt, 0); ibtriangles.unbind(); // Setup transformations... // Binding indices and drawing iblines.bind(); GL11.glDrawElements(GL11.GL_LINES, indexcountlines, GLType.UnsignedInt, 0); iblines.unbind(); Both boxes use the same buffer of four vertices

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 GLBuffers 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

Multiple Vertex Attributes We can bind a GLBuffer to a vertex attribute We can use multiple attributes per vertex 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 Index Array Primitive Type 0, 1, 2, 0, 2, 3 GL_TRIANGLES

Attribute Bindings Shader program draws vertices using array of attributes Program declares a variable (vpos, vcolor) for each attribute Program f Vertex Attributes 0 1 2 3-0.5, -0.5 0.5, -0.5 0.5, 0.5-0.5, 0.5 0 0 = vpos 1, 0, 0 0, 1, 0 0, 0, 1 1, 1, 0 1 1 = vcolor 2 2 Index Array 0, 1, 2, 0, 2, 3 Vertex Attribut Primitive Type GL_TRIANGLES

Demo: Color Boxes

ColorBoxes' onentry() @Override public void onentry(gametime gametime) {... // 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 }; vbcolor = GLBuffer.createAsVertex(vertexColors, 3, BufferUsageHint.StaticDraw);...

ColorBoxes' draw()... // Use box vertex positions and colors as we defined before // Bind attribute array values to a variable in the shader vb.useasattrib(program.getattribute("vpos")); vbcolor.useasattrib(program.getattribute("vcolor")); // Draw the two boxes as we did before...

Transformations

Representing Transformations We will use Matrix3, Matrix4 classes Set matrix contents: Matrix3 translate = new Matrix3(1.0f, 0.0f, 3.0f, 0.0f, 1.0f, -4.0f, 0.0f, 0.0f, 1.0f); Copy matrices: Matrix3 translateagain = new Matrix3(translate); Multiply matrices: translate.mulbefore(translateagain); // translate = translate * translateagain Transform points: Vector3 vert = new Vector3(2.0f, 0.0f, 1.0f); translate.mulpos(vert); // vert = translate * vert

Matrix3/4 Class Static functions provide various useful transformation matrices Identity matrices Translations, scales, rotations Projection matrices

Transforming a Vertex GLBuffer 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; we have discussed this topic already 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 draw() Camera plane Camera plane p screen Projection p eye

Setting Matrices You tell the shader program what matrices to use GLUniform.setST(program.getUniform("VP"), tr, false); You can bind a matrix to a variable in the shader, similarly to vertex attributes Program keeps drawing with the same matrices until you change them Common use pattern: GLUniform.setST(program.getUniform( tr"), transformforthisobject, false); GL11.glDrawElements( ) Define other transformation Draw something else

Demo: Sierpinski Triangle

Sierpinski's draw() @Override public void draw(gametime gametime) { GL11.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); GL11.glClear(GL11.GL_COLOR_BUFFER_BIT); program.use(); GLUniform.set(program.getUniform("uGridColor"), new Vector4(1, 1, 1, 1)); // Use box vertices vb.useasattrib(program.getattribute("vpos")); // Transformation Matrix4 tr = new Matrix4(); tr.mulafter(matrix4.createtranslation( new Vector3(0.0f, -(float)math.sqrt(3)/6, 0.0f))); sierpinski(iblines, tr, 10); } GLProgram.unuse();

Recursively Drawing Fractal sierpinski(gl, tr, k): Draw a level-k Sierpinski triangle, and transform by tr k = 0: draw triangle to the right Recursively: at level k, draw three k-1 Sierpinski triangles, transforming them to the three corners of the triangle

sierpinski() public void sierpinski(glbuffer lines, Matrix4 tr, int k) { if (k == 0) { GLUniform.setST(program.getUniform("VP"), tr, false); // Draw the triangle iblines.bind(); GL11.glDrawElements(GL11.GL_LINES, indexcountlines, GLType.UnsignedInt, 0); iblines.unbind(); } else { Matrix4 next; //draw the up triangle next = new Matrix4(tr); next.mulafter(matrix4.createscale(new Vector3(0.5f, 0.5f, 0.5f))); next.mulafter(matrix4.createtranslation(new Vector3(0.0f, 0.5f / (float)math.sqrt(3.0f), 0.0f))); sierpinski(lines, next, k-1); //draw the right triangle next = new Matrix4(tr); next.mulafter(matrix4.createscale(new Vector3(0.5f, 0.5f, 0.5f))); next.mulafter(matrix4.createtranslation(new Vector3(0.25f, -0.25f / (float)math.sqrt(3.0f), 0.0f))); sierpinski(lines, next, k-1); } } //draw the left triangle next = new Matrix4(tr); next.mulafter(matrix4.createscale(new Vector3(0.5f, 0.5f, 0.5f))); next.mulafter(matrix4.createtranslation(new Vector3(-0.25f, -0.25f / (float)math.sqrt(3.0f), 0.0f))); sierpinski(lines, next, k-1);

sierpinski() public void sierpinski(glbuffer lines, Matrix4 tr, int k) { if (k == 0) { GLUniform.setST(program.getUniform("VP"), tr, false); // Draw the triangle iblines.bind(); GL11.glDrawElements(GL11.GL_LINES, indexcountlines, GLType.UnsignedInt, 0); iblines.unbind(); } else { [...] tr } }

sierpinski() public void sierpinski(glbuffer lines, Matrix4 tr, int k) { [...] } else { Matrix4 next; //draw the up triangle next = new Matrix4(tr); next.mulafter(matrix4.createscale(new Vector3(0.5f, 0.5f, 0.5f))); next.mulafter(matrix4.createtranslation( new Vector3(0.0f, 0.5f / (float)math.sqrt(3.0f), 0.0f))); sierpinski(lines, next, k-1); tr } } [...]

sierpinski() public void sierpinski(glbuffer lines, Matrix4 tr, int k) { [...] } else { Matrix4 next; //draw the up triangle next = new Matrix4(tr); next.mulafter(matrix4.createscale(new Vector3(0.5f, 0.5f, 0.5f))); next.mulafter(matrix4.createtranslation( new Vector3(0.0f, 0.5f / (float)math.sqrt(3.0f), 0.0f))); sierpinski(lines, next, k-1); tr up triangle } } [...]

sierpinski() public void sierpinski(glbuffer lines, Matrix4 tr, int k) { [...] } else { Matrix4 next; //draw the up triangle next = new Matrix4(tr); next.mulafter(matrix4.createscale(new Vector3(0.5f, 0.5f, 0.5f))); next.mulafter(matrix4.createtranslation( new Vector3(0.0f, 0.5f / (float)math.sqrt(3.0f), 0.0f))); sierpinski(lines, next, k-1); tr up triangle } } [...]

sierpinski() public void sierpinski(glbuffer lines, Matrix4 tr, int k) { if (k == 0) { GLUniform.setST(program.getUniform("VP"), tr, false); // Draw the triangle iblines.bind(); GL11.glDrawElements(GL11.GL_LINES, indexcountlines, GLType.UnsignedInt, 0); iblines.unbind(); } else { Matrix4 next; //draw the up triangle next = new Matrix4(tr); next.mulafter(matrix4.createscale(new Vector3(0.5f, 0.5f, 0.5f))); next.mulafter(matrix4.createtranslation(new Vector3(0.0f, 0.5f / (float)math.sqrt(3.0f), 0.0f))); sierpinski(lines, next, k-1); //draw the right triangle next = new Matrix4(tr); next.mulafter(matrix4.createscale(new Vector3(0.5f, 0.5f, 0.5f))); next.mulafter(matrix4.createtranslation(new Vector3(0.25f, -0.25f / (float)math.sqrt(3.0f), 0.0f))); sierpinski(lines, next, k-1); } } //draw the left triangle next = new Matrix4(tr); next.mulafter(matrix4.createscale(new Vector3(0.5f, 0.5f, 0.5f))); next.mulafter(matrix4.createtranslation(new Vector3(-0.25f, -0.25f / (float)math.sqrt(3.0f), 0.0f))); sierpinski(lines, next, k-1);