• No results found

CSE 5542 - Real Time Rendering Week 3

N/A
N/A
Protected

Academic year: 2021

Share "CSE 5542 - Real Time Rendering Week 3"

Copied!
88
0
0

Loading.... (view fulltext now)

Full text

(1)

CSE 5542 - Real Time Rendering

Week 3

(2)

The Anatomy of *GL*

Program

http://www.cs.unm.edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_

(3)

The Sierpinski Gasket

(4)

The Sierpinski Gasket

(5)

Pseudo-code

Immediate Mode

Retained Mode

(6)

Sierpinski in GLSL thru GLUT

int

main( int argc, char **argv ) {

glutInit( &argc, argv );

glutInitDisplayMode( GLUT_RGBA );

glutInitWindowSize( 512, 512 );

glutCreateWindow( "Sierpinski Gasket" );

init();

glutDisplayFunc( display );

glutKeyboardFunc( keyboard );

glutMainLoop();

return 0;

(7)

Callbacks – Event-based

..

glutDisplayFunc( display );

glutKeyboardFunc( keyboard );

void

keyboard( unsigned char key, int x, int y ) {

switch ( key ) { case 033:

exit( EXIT_SUCCESS );

break;

} } void

display( void ) {

glClear( GL_COLOR_BUFFER_BIT ); //

clear the window

glDrawArrays( GL_POINTS, 0, NumPoints ); // draw the points

glFlush();

}

(8)

8

E. Angel and D. Shreiner: Interactive Computer Graphics 6E ©

*GL*

(9)

void

init( void ) {

vec2 points[NumPoints];

// Specifiy the vertices for a triangle vec2 vertices[3] = {

vec2( -1.0, -1.0 ), vec2( 0.0, 1.0 ), vec2( 1.0, -1.0 )

};

// Select an arbitrary initial point inside of the triangle

points[0] = vec2( 0.25, 0.50 );

// compute and store N-1 new points for ( int i = 1; i < NumPoints; ++i ) { int j = rand() % 3; // pick a vertex at random

// Compute the point halfway between the selected vertex

// and the previous point points[i] = ( points[i - 1] + vertices[j] ) / 2.0;

}

// Create a vertex array object GLuint vao[1];

glGenVertexArrays( 1, vao );

glBindVertexArray( vao[0] );

// Create and initialize a buffer object GLuint buffer;

glGenBuffers( 1, &buffer );

glBindBuffer( GL_ARRAY_BUFFER, buffer );

glBufferData( GL_ARRAY_BUFFER,

sizeof(points), points, GL_STATIC_DRAW );

Sierpinski in GLSL

(10)

// Load shaders and use the resulting shader program GLuint program = InitShader( "vshader21.glsl",

"fshader21.glsl" );

glUseProgram( program );

// Initialize the vertex position attribute from the vertex shader

GLuint loc = glGetAttribLocation( program, "vPosition" );

glEnableVertexAttribArray( loc );

glVertexAttribPointer( loc, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );

glClearColor( 1.0, 1.0, 1.0, 1.0 ); // white background

Sierpinski in GLSL

(11)

Sierpinski Vertex Shader

attribute vec4 vPosition;

void main() {

gl_Position = vPosition;

}

// Load shaders and use the resulting shader program GLuint program = InitShader( "vshader21.glsl",

"fshader21.glsl" );

glUseProgram( program );

..

(12)

Sierpinski Fragment Shader

void main() {

gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );

// Load shaders and use the resulting shader program GLuint program = InitShader( "vshader21.glsl",

"fshader21.glsl" );

glUseProgram( program );

..

(13)

Compiling Code

(14)

MacOs

http://www.cs.unm.edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDIT ION/apple

(15)

Windows/VC++

http://www.cs.unm.edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDITI ON/vc

(16)

Linux

http://www.cs.unm.edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDITI ON/linux

(17)

Another Example

(18)

Triangles.cpp

#include <iostream>

using namespace std;

#include "vgl.h”

#include "LoadShader.h”

enum VAO_IDs { Triangles, NumVAOs };

enum Buffer_IDs { ArrayBuffer, NumBuffers };

enum Attrib_IDs { vPosition = 0 };

GLuint VAOs[NumVAOs];

GLuint Buffers[NumBuffers];

const GLuint NumVertices = 6;

void

init(void) {

glGenVertexArrays(NumVAOs, VAOs);

glBindVertexArray(VAOs[Triangles]);

GLfloat vertices[NumVertices][2] = { { -0.90, -0.90 }, // Triangle 1 { 0.85, -0.90 },

{ -0.90, 0.85 },

{ 0.90, -0.85 }, // Triangle 2 { 0.90, 0.90 },

{ -0.85, 0.90 } };

glGenBuffers(NumBuffers, Buffers);

glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),

(19)

ShaderInfo

ShaderInfo shaders[] = { { GL_VERTEX_SHADER,

"triangles.vert" },

{ GL_FRAGMENT_SHADER,

"triangles.frag" },

{ GL_NONE, NULL } };

GLuint program = LoadShaders(*shaders);

glUseProgram(program);

glVertexAttribPointer(vPosition, 2, GL_FLOAT,

GL_FALSE, 0, BUFFER_OFFSET(0));

glEnableVertexAttribArray(vPosition);

}

void display(void) {

glClear(GL_COLOR_BUFFER_BIT);

glBindVertexArray(VAOs[Triangles]);

glDrawArrays(GL_TRIANGLES, 0, NumVertices);

glFlush();

}

(20)

Main()

Int

main(int argc, char** argv) {

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_RGBA);

glutInitWindowSize(512, 512);

glutInitContextVersion(4, 3);

glutInitContextProfile(GLUT_CORE_PROFILE);

glutCreateWindow(argv[0]);

glewExperimental = GL_TRUE;

if (glewInit()) {

cerr << "Unable to initialize GLEW ... exiting" << endl;

exit(EXIT_FAILURE);

} init();

glutDisplayFunc(display);

glutMainLoop();

(21)
(22)

// Create a vertex array object GLuint vao[1];

glGenVertexArrays( 1, vao );

glBindVertexArray( vao[0] );

(23)

Vertex Arrays

• Vertices can have many attributes

– Position – Color

– Texture Coordinates – Application data

• A vertex array holds these data

• Using types in vec.h

23

point2 vertices[3] = {point2(0.0, 0.0), point2( 0.0, 1.0), point2(1.0, 1.0)};

(24)

Vertex Array Object

• Bundles all vertex data (positions, colors, ..,)

• Get name for buffer then bind

• At this point we have a current vertex array but no contents

• Use of glBindVertexArray lets us switch between VBOs

Glunit abuffer;

glGenVertexArrays(1, &abuffer);

glBindVertexArray(abuffer);

(25)

// Create and initialize a buffer object GLuint buffer;

glGenBuffers( 1, &buffer );

glBindBuffer( GL_ARRAY_BUFFER, buffer );

glBufferData( GL_ARRAY_BUFFER,

sizeof(points), points, GL_STATIC_DRAW );

(26)

Buffer Object

• Buffers objects allow us to transfer large amounts of data to the GPU

• Need to create, bind and identify data

• Data in current vertex array is sent to GPU

Gluint buffer;

glGenBuffers(1, &buffer);

glBindBuffer(GL_ARRAY_BUFFER, buffer);

glBufferData(GL_ARRAY_BUFFER, sizeof(points), points);

(27)

http://www.khronos.org/files/opengl-quick- reference-card.pdf

(28)

OpenGL Recipes

(29)

Sierpinski Again

void main(int argc, char** argv) {

/* Standard GLUT initialization */

glutInit(&argc,argv);

glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); /* default, not needed */

glutInitWindowSize(500,500); /* 500 x 500 pixel window */

glutInitWindowPosition(0,0); /* place window top left on display */

glutCreateWindow("Sierpinski Gasket"); /* window title */

glutDisplayFunc(display); /* display callback invoked when window opened */

myinit(); /* set attributes */

glutMainLoop(); /* enter event loop */

}

(30)

Sierpinski World

/* Two-Dimensional Sierpinski Gasket */

/* Generated Using Randomly Selected Vertices */

/* And Bisection */

void myinit() {

/* attributes */

glClearColor(1.0, 1.0, 1.0, 1.0);

/* white background */

glColor3f(1.0, 0.0, 0.0); /* draw in red

*/

/* set up viewing */

/* 500 x 500 window with origin lower left

*/

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluOrtho2D(0.0, 50.0, 0.0, 50.0);

glMatrixMode(GL_MODELVIEW);

(31)

No Shaders Here

void display( void )

{ GLfloat vertices[3][2]={{0.0,0.0},{25.0,50.0},{50.0,0.0}};

/* A triangle */

int j, k;

int rand(); /* standard random number generator */

GLfloat p[2] ={7.5,5.0};

/* An arbitrary initial point inside traingle */

glClear(GL_COLOR_BUFFER_BIT); /*clear the window */

/* compute and plots 5000 new points */

glBegin(GL_POINTS);

for( k=0; k<5000; k++){

j=rand()%3; /* pick a vertex at random */

/* Compute point halfway between selected vertex and old point */

p[0] = (p[0]+vertices[j][0])/2.0;

p[1] = (p[1]+vertices[j][1])/2.0; /* plot new point */

glVertex2fv(p); } glEnd();

glFlush(); /* clear buffers */

}

(32)

A Recursive OpenGL

Example

(33)

The Basic Shape

* initial triangle */

GLfloat v[3][2]={{-1.0, -0.58}, {1.0, -0.58}, {0.0, 1.15}};

int n;

void triangle( GLfloat *a, GLfloat *b, GLfloat *c) /* specify one triangle */

{

glVertex2fv(a);

glVertex2fv(b);

glVertex2fv(c);

}

(34)

The Inductive step

void divide_triangle(GLfloat *a, GLfloat *b, GLfloat *c, int m)

{

/* triangle subdivision using vertex numbers */

GLfloat v0[2], v1[2], v2[2];

int j;

if(m>0) {

for(j=0; j<2; j++) v0[j]=(a[j]+b[j])/2;

for(j=0; j<2; j++) v1[j]=(a[j]+c[j])/2;

for(j=0; j<2; j++) v2[j]=(b[j]+c[j])/2;

divide_triangle(a, v0, v1, m-1);

divide_triangle(c, v1, v2, m-1);

divide_triangle(b, v2, v0, m-1);

}

else triangle(a,b,c); /* draw triangle at end of recursion */

(35)

Callbacks – same as before

void display() {

glClear(GL_COLOR_BUFFER_BIT);

glBegin(GL_TRIANGLES);

divide_triangle(v[0], v[1], v[2], n);

glEnd();

glFlush();

}

void myinit() {

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluOrtho2D(-2.0, 2.0, -2.0, 2.0);

glMatrixMode(GL_MODELVIEW);

glClearColor (1.0, 1.0, 1.0, 1.0);

glColor3f(0.0,0.0,0.0);

}

(36)

The main() – same as before

int main(int argc, char **argv) {

n=atoi(argv[1]); /* or set number of subdivision steps here */

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

glutInitWindowSize(500, 500);

glutCreateWindow("Sierpinski Gasket");

glutDisplayFunc(display);

myinit();

glutMainLoop();

(37)

Now As Shaders

(38)

Shading & Subdivision

#include "Angel.h”

using namespace std;

const int NumTimesToSubdivide = 5;

const int NumTriangles = 243; // 3^5 triangles generated const int NumVertices = 3 * NumTriangles;

vec2 points[NumVertices];

int Index = 0;

void triangle( const vec2& a, const vec2& b, const vec2& c ) {

points[Index++] = a;

points[Index++] = b;

points[Index++] = c;

(39)

Induction

void divide_triangle( const vec2& a, const vec2& b, const vec2& c, int count )

{

if ( count > 0 ) {

vec2 v0 = ( a + b ) / 2.0;

vec2 v1 = ( a + c ) / 2.0;

vec2 v2 = ( b + c ) / 2.0;

divide_triangle( a, v0, v1, count - 1 );

divide_triangle( c, v1, v2, count - 1 );

divide_triangle( b, v2, v0, count - 1 );

}

else {

triangle( a, b, c ); // draw triangle at end of recursion

} }

(40)

Shader Mechanics

void init( void )

{ vec2 vertices[3] =

{vec2( -1.0, -1.0 ), vec2( 0.0, 1.0 ), vec2( 1.0, -1.0 )};

// Subdivide the original triangle

divide_triangle( vertices[0], vertices[1], vertices[2],

NumTimesToSubdivide );

// Create a vertex array object GLuint vao;

glGenVertexArraysAPPLE( 1, &vao );

glBindVertexArrayAPPLE( vao );

// Create and initialize a buffer object GLuint buffer;

glGenBuffers( 1, &buffer );

glBindBuffer( GL_ARRAY_BUFFER, buffer );

glBufferData( GL_ARRAY_BUFFER,

sizeof(points), points, GL_STATIC_DRAW );

// Load shaders and use the resulting shader program

GLuint program =

InitShader( "vshader22.glsl",

"fshader22.glsl" );

glUseProgram( program );

// Initialize vertex position attribute from vertex shader

GLuint loc = glGetAttribLocation(program,

"vPosition" );

glEnableVertexAttribArray( loc );

glVertexAttribPointer( loc, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );

glClearColor( 1.0, 1.0, 1.0, 1.0 );

/* white background */

}

(41)

Same Callbacks

void display( void ) {

glClear( GL_COLOR_BUFFER_BIT );

glDrawArrays( GL_TRIANGLES, 0, NumVertices );

glFlush();

}

void keyboard( unsigned char key, int x, int y ) {

switch ( key ) { case 033:

exit( EXIT_SUCCESS );

break;

} }

(42)

And the same main()

int main( int argc, char **argv ) {

glutInit( &argc, argv );

glutInitDisplayMode( GLUT_RGBA );

glutInitWindowSize( 512, 512 );

glutCreateWindow( "Simple GLSL example" );

init();

glutDisplayFunc( display );

glutKeyboardFunc( keyboard );

glutMainLoop();

return 0;

(43)

One Last Example

(44)

OpenGL 1.x Code Example

void Display() {

  glClear(GL_COLOR_BUFFER_BIT);

  glColor4f(1,1,0,1);

  glBegin(GL_POLYGON);

    glVertex2f(-0.5, -0.5);

    glVertex2f(-0.5,  0.5);

    glVertex2f(0.5, 0.5);

    glVertex2f(0.5, -0.5);

  glEnd();

  glFlush();

}

(45)

45

OpenGL Functions

• Primitives

– Points

– Line Segments – Triangles

• Attributes

• Transformations

– Viewing – Modeling

• Control (GLUT)

• Input (GLUT)

• Query

(46)

OpenGL and GLSL

(47)

OpenGL and GLSL

• Shader based OpenGL is based less on a

state machine model than a data flow model

• Most state variables, attributes and related pre 3.1 OpenGL functions have been

deprecated

• Action happens in shaders

• Job is application is to get data to GPU

47

(48)

OpenGL State

• OpenGL is a state machine

• OpenGL functions are of two types – Primitive generating

• Can cause output if primitive is visible

• How vertices are processed and appearance of primitive are controlled by the state

– State changing

• Transformation functions

• Attribute functions

• Under 3.1 most state variables are defined by the application and sent to the shaders

(49)

GLSL

• OpenGL Shading Language

• C-like with

– Matrix and vector types (2, 3, 4 dimensional) – Overloaded operators

– C++ like constructors

• Similar to Nvidia’ s Cg and Microsoft HLSL

• Code sent to shaders as source code

• New OpenGL functions to compile, link and get information to shaders

49

(50)

Still Maximal Portability

• Display device independent

• Window system independent

• Operating system independent

(51)

The End

References

Related documents