Part of the Graphics Log series:
- Intro into Computer Graphics
- Animated Clock using 2D Graphics
- Creating an Animated Barber Pole with OpenGL
- Basic Texturing
- Creating a flag using Bezier Curves
- Understanding Subdivision Surfaces in Computer Graphics
- Lighting in Computer Graphics : A Practical Guide with OpenGL
- Techniques for Object Creation
- Practical tips for efficient development with OpenGLThis post!
- Computer Graphics: Top Learning Resources for beginners
Introduction
As you navigate the intricacies of OpenGL development, adopting smart practices can significantly enhance your efficiency and code quality. To enhance your proficiency in the aspect of graphics programming, let’s explore some valuable tips derived from practical experiences in my CS308 lab sessions. I hope these tips would help you set up a good development workflow.
1. OpenGL Code Template for Project Initialization:
Having a well-structured code template for OpenGL projects is essential. The provided template is one example which includes components such as initialization, display function, keyboard input handling, timer function, and window reshaping.You can use any template suited to your needs.This not only saves time by providing a consistent starting point but also helps enforce good programming practices.
cpp 1
2 #include <GL/glut.h>
3 #include <math.h>
4
5 void init() {
6 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
7
8 }
9
10 void drawAxes() {
11
12
13 }
14 void DrawGrid() {
15
16 }
17
18 void drawObject() {
19
20 }
21
22 void display() {
23
24 glClear(GL_COLOR_BUFFER_BIT);
25 glutSwapBuffers();
26
27 }
28
29 void keyboardSpecial(int key, int x, int y) {
30
31 glutPostRedisplay();
32 }
33
34 void keyboard(unsigned char key, int x, int y) {
35
36 glutPostRedisplay();
37
38 }
39
40 void Timer(int x) {
41
42 glutPostRedisplay();
43
44 glutTimerFunc(60, Timer, 1);
45 }
46
47 void reshape(GLsizei w, GLsizei h) {
48
49 }
50
51 int main(int argc, char** argv) {
52
53 glutInit(&argc, argv);
54 glutInitDisplayMode(GLUT_DOUBLE);
55 glutInitWindowSize(500, 500);
56 glutInitWindowPosition(150, 150);
57 glutCreateWindow("A 3D Graphic");
58 glutDisplayFunc(display);
59 glutReshapeFunc(reshape);
60
61 glutKeyboardFunc(keyboard);
62 glutSpecialFunc(keyboardSpecial);
63
64 glutTimerFunc(60.0, Timer, 1);
65 init();
66 glutMainLoop();
67
68 return 0;
69 }
2. Drawing Grids and Axes for Object Placement:
Visual aids like grids and axes can significantly assist in object placement, translation, and rotation. Implementing functions like drawAxes()
and DrawGrid()
allows for a better understanding of spatial relationships within the scene, aiding in the precise positioning of objects.
1void drawAxes() {
2
3 glBegin(GL_LINES);
4
5 glLineWidth(1.5);
6
7 glColor3f(1.0, 0.0, 0.0); // RED - X
8 glVertex3f(-40, 0, 0);
9 glVertex3f(40, 0, 0);
10
11 glColor3f(0.0, 1.0, 0.0); //GREEN -Y
12 glVertex3f(0, -40, 0);
13 glVertex3f(0, 40, 0);
14
15 glColor3f(0.0, 0.0, 1.0); //BLUE -Z
16 glVertex3f(0, 0, -40);
17 glVertex3f(0, 0, 40);
18
19 glEnd();
20
21}
22
23void DrawGrid() {
24 GLfloat ext = 40.0f;
25 GLfloat step = 1.0f;
26 GLfloat yGrid = -0.4f;
27 GLint line;
28
29 glBegin(GL_LINES);
30 for (line = -ext; line <= ext; line += step)
31 {
32 glVertex3f(line, yGrid, ext);
33 glVertex3f(line, yGrid, -ext);
34
35 glVertex3f(ext, yGrid, line);
36 glVertex3f(-ext, yGrid, line);
37 }
38 glEnd();
39}
3. Using Reshape Function for Window Size Changes:
To prevent warping and maintain a proper aspect ratio when resizing the window, leverage the reshape
function. This ensures that the perspective projection frustum is adjusted accordingly, providing a consistent and visually pleasing experience.
1 reshape(GLsizei w, GLsizei h)
2 {
3 glViewport(0, 0, w, h);
4 GLfloat aspect_ratio = h == 0 ? w / 1 : (GLfloat)w / (GLfloat)h;
5
6 glMatrixMode(GL_PROJECTION);
7 glLoadIdentity();
8
9 gluPerspective(120.0, aspect_ratio, 1.0, 100.0);
10
11 }
4. Organizing Code with Header Files:
As projects grow in complexity, it becomes crucial to maintain a well-organized codebase. Using header files to separate different parts of the project helps avoid clutter and enhances code readability. This practice simplifies maintenance and collaboration among developers.
cpp1 #include "pinetree.h"
2 #include "cablecarpole.h"
3 #include "sled.h"
5. Leveraging Vertex Arrays for Efficient Object Creation:
In OpenGL programming, optimizing the creation of objects is essential for both performance and maintainability. One powerful technique to achieve this is by utilizing vertex arrays to manage sets of vertices efficiently. The provided array, float vertices[][3], exemplifies a collection of vertices in 3D space.
cpp1 float vertices[][3] =
2 { {-1,-1,1}, {-1,1,1} ,{1,1,1},{1,-1,1} , {1,-1,-1 } ,{1,1,-1},{-1,1,-1},{-1,-1,-1} ,
3 {-1,-1,0},{0,-1,1},{1,-1,0},{0,-1,-1 },{1,0,-1},{0,1,-1} , {-1,0,-1},{-1,1,0},{-1,0,1},{1,1,0},{1,0,1},{0,1,1}
4 };
Each vertex could then be refered later using array indices without redefining a new array each time it is needed.
6. Efficient Surface Generation Methods:
Reducing code repetition is vital for efficient development. Define methods for generating surfaces with varying numbers of vertices. This helps streamline the creation of 3 and 4-faced surfaces, promoting code reusability and readability.
cpp 1 void surface4(int v1,int v2,int v3,int v4) {
2 glPushMatrix();
3 glBegin(GL_POLYGON);
4 glVertex3fv(vertices[v1]);
5 glVertex3fv(vertices[v2]);
6 glVertex3fv(vertices[v3]);
7 glVertex3fv(vertices[v4]);
8 glEnd();
9 glPopMatrix();
10 }
Conclusion:
Optimizing object modeling in OpenGL involves a combination of code structuring, visual aids, and efficient coding practices. By implementing the tips provided, you’ll not only enhance the efficiency of your graphics programming but also contribute to a more maintainable and scalable codebase.