2023/09/13 - 12:09
Why use OpenGL?
- all adobe image manipulation tools are built with openGL
- CAD software uses OpenGL
- blender uses openGL as well as other 3d animation software
- Unity and unreal engine use it a bit
OpenGL
- platofrm independent API
- reasonable defaults for most settings which is nice when you're learning because it means that you don't have to set up every possible thing to draw a simple triangle
- close enough to the hardware to get excellent performance
- openGL is a state machine.. states will not change unless you change them.
- you can set rendering states like color, point size, line width..
→ glColor3f(0.0,0.0,0.0)
→ glLineWidth(2.0)
- you can request state information
- openGL is not object oriented, instead it will have several versions of the same functions
Function format:
[gl][Vertex][3f](x,y,z)
- belongs to gl library
- what the function does
- number of params and their type
glVertex3fv(p) ← p is a pointer to an array
#include <freeglut.h> should also include gl.h and glu.h
there are some GL defined terms and datatype like Glfloat, Gldouble
Draw a white square
- create teh glut window
- start the event loop
- main function ends with the program entering an event loop
- program defines a display callback function mamed myDisplay
- you're never going to call the drawing function... you dont even know when it needs to be drawn
- display callback is ececuted whenever GLUT decides the display must be refreshed, e.g. when the window is opened
- display callback ends with glFlush
- you're not gonna have a big loop that keeps calling your own function. just worry about the current frame and the function to draw the current frame.
#include <freeglut.h>
void myDisplay(){
glClear(GL_COLOR_BUFFER_BIT);
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();
}
int main( int argc, char** argv){
glutInit(&argc,argv);
glutCreateWindow("simple");
glutDisplayFunc(myDisplay);
glutMainLoop();
}
- didnt set a lot of settings because we jsut rely on the defaults
- default window size, clear color, drawing colour, and 2d coordinate system
- if you go more than 3 vertices you have to be careful you dont twist your polygon, the order you draw the vertices matters
- GLUT provides reasonable defaults
C compilation review
- our own code is declared in .h files and defined in .c files
- .obj files contain our compiled code in binary form
- it's not yet executable
- include <> is for external library files, “” searches for local .h files
- linker is the final step which inserts the binary code and creates the final executable
- .lib files contain binary and are linked statically, .dll files are linked dynamically
- Most openG: programs have a structure that contains
→ main:
⇒ defines callback functions
⇒ call initializeGL() ... throws initializing functions to get things starting
⇒ opens one or more windows with the required properties
⇒ enters an event loop (last executable statement)
→ initializeGL()
⇒ set the initial state variables and viewing variables and attributes
→ callbacks
⇒ display function
⇒ input and window functions
⇒ idle functions
- in simple2.c we will se the same output but we will define relevant state values ourselves instead of relying on defaults
Important GLUT functions:
- glutInit : allows application to pass command line arguments and initializes system
- glutInitDisplayMode : rgb color
- glutWindowSize (pixels)
- glutWindowPosition (from top left)
- glutCreateWindow (with title “simple”)
- glutDisplayFunc (display callback)
- glutMainLoop (enter infinite event loop)
#include <GL/freeglut.h>
int main(argc...){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
ehhh
}
void initializeGL(){
clClearColor(0.0,0.0,0.0,1.0); // last value is opacity
glColor3f(1.0,1.0,1.0); //drawing color is white
glMatrixMode(GL_PROJECTION); //change viewing
glLoadIdentity(); //initialize viewing matrix
gluOrtho2D(-1.0,1.0,-1.0,1.0); //viewing camera
}
Do not have to use the entire window for the image, can define with
glViewport(x,y,width,height)
Values are in pixels
2023/09/18 - 11:51
Other primitives:
- GL_POINTS
→ define a set of points
- GL_LINES
→ define a set of lines
- GL_LINE_STRIP
→ define a set of lines that connect end to end
- GL_LINE_LOOP
→ define a set of lines that connect to the beginning to make a loop
- GL_TRIANGLES
- GL_TRIANGLE_STRIP
→ connect triangles along the last 2 vertices of the previous trianges
- GL_TRIANGLE_FAN
→ connect triangles from the first vertex ever entered, connected along the edge of the last vertex
- GL_POLYGON
→ add any nnumber of vertices to define the polygon
→ have to keep it flat, simple, and convex
- GL_QUAD_STRIP
→ alagous to triangle strips but with quadrilaterals, connects to the last two points of the previous quad
- openGL will only display polygons correctly that are:
→ simple
→ convex
→ flat
- user program has to check for those
- triangles automatically satisfy all 3 conditions
- edges cannot cross
→ the order you select your vertices matters for this reason.
→ you can go clockwise or counter clockwise, and the starting point doesnt matter.
→ as we get into lighting, clockwise or counter clockwise will start to matter, as it will define the front and back of the object
- the polygon has to be convex: if you pick any 2 vertices and draw a line between them, if it leaves the object it is concave and ILLEGAL!!
- Attributes we can use to modify the objects:
→ color
→ size
→ width
→ stipple patterns
→ can also set display mode of polygons, make them filled, wireframe, flat shaded, smooth shaded...
→ can change the attributes on a vertex-basis instead of polygon, up to openGL to interpolate the in betweens
Exercise:
- draw the triangle on the grid and then write the code that goes with it.
- use functions:
→ glBegin()
→ glEnd()
→ glVertex2f(x,y)
→ glColor3f(r,g,b)
- assume
→ gluOrtho2D(0.0,1.0,0.0,1.0)
- my answer:
- glBegin(GL_TRIANGLE)
glColor3f(0,0,1)
glVertex2f(0,0.5)
glColor3f(1,0,0)
glVertex2f(0,0)
glVertex2f(0.5,0)
glEnd()
- ok i guess he wanted us to use the whole grid so i will have to change my coordinates
- he also did the red vertices first but i dont think that matters
glBegin(GL_TRIANGLE)
glColor3f(1,0,0)
glVertex2f(0,0)
glVertex2f(1,0)
glColor3f(0,0,1)
glVertex2f(0,1)
glEnd()
- next do it for a T shape that has a gradient from blue to red to yellow
- i started at the bottom, the yellow end
glBegin(GL_POLYGON)
glColor3f(whatever the rgb for yellow is)
glVertex2f(0.4,0)
glVertex2f(0.6,0)
glColor3f(1,0,0) //red
glVertex2f(0.6,0.8)
glVertex2f(1,0.8)
glColor3f(0,0,1) //blue
glVertex(
//WAIT omg its concave so it cant all be one polygon i didnt think of that
glBegin(GL_POLYGON); // top rectangle
glColor3f(0,0,1); //blue
glVertex2f(0,1);
glVertex2f(1,1);
glColor3f(1,0,0); //red
glVertex2f(1,0.8);
glVertex2f(0,0.8);
glEnd();
glBegin(GL_POLYGON); //bottom rectangle
//start at the red end
glVertex2f(0.4,0.8);
glVertex2f(0.6,0.8);
glColor3f(1,1,0);
glVertex2f(0.6,0);
glVertex2f(0.4,0);
glEnd();
Interpolation:
- the calculated value between two other values
- openGL automatically interpolates colours between vertices
- linear interpolation : take a weighted average of the RGB values (or whatever it may be) based on how close you are to either vertex
→ assumes you know the endpoint values
→ no discontinuity
→ we can define the line segment itself with lienar interpolation
→ can use it to morph positions
- v(u) = (1-u) * v1 + (u) * v2
- 0 <= u <= 1
- where u is the position on the line
- imagine instead of 2 points, it was 2 sets of points and you have a 1-1 correspondence between each point in the set... then if it was like a face or something, you can morph between face 1 and face 2
- example onscreen is a T shape where the colour is interpolated across the two rectangles in a way that doesnt nicely split across the vertices like the last example.
- exercise: how would you separate this polygon to achieve the interpolation of colour?
- my idea: break off the two sides of the T, and the base, and then have the square in the middle. define each of their colours accordingly
- you cant just add additional points to the polygons that are different colours because openGL will ignore colinear points.
- next exercise: draw the L shape with the colour interpolation but use a triangle strip to do it
glBegin(GL_TRIANGLE_STRIP)
glColor3f(1,1,0) //yellow
//starting with top left corner
//draw top edge in yellow
glVertex2f(0,1)
glvertex2f(0.1,1)
//ghange color to red
glVertex2f(
glEnd()
2023/09/20 - 11:40
- other attributes:
→ line stipple
⇒ give args bit width and hexadeximal pattern, where each 1 is coloured and 0 is not
→ transparency
⇒ color has 4 components now, R,G,B and Alpha
⇒ alpha sets level of opacity, 1 is fully opaque, 0 is transparent
⇒ why would you want transparency? e.g. fading in and out
⇒ if you want to use it we have to use glEnable(GL_BLENDING)
⇒ and we have to set the method of blending with glBlendFunc(GL_SRC_ALPHA(how much we see of the object), GL_ONE_MINUS_SRC_ALPHA (how much we see of what was there before))
⇒ and you need to set display mode to glutInitDisplayMode(RGBA)
A partly transparent green line:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA...)
glBegin(GL_LINES);
glColor
idk bro just look at the slides for this one
- shading mode can be set to smooth or flat
→ smooth inteprolates the colours between the vertices
→ in flat shading the colour of the first vertex determines the color of the whole polygon
- jagged lines
→ default line mode is jagged
- u can turn on smooth lines which will do some anti aliasing
- aliasing: looks at pixels just above and below the lines we are actually drawing and add them a little bit
- line smoothing does not effect the edges of polygons
bitmap text
- glut library has every letter stored as a bitmap image
- letters are not drawn with lines and curves, theyre just premade little images
- still have to set the drawing position
- glut will not draw a string for you
- set the raster position which is basically just the coordinates
- we position the bottom lefthand corner of the letter Index