xref: /haiku/src/add-ons/screen_savers/glife/GLifeView.cpp (revision 5fae0bc1a2f74ccf56b7e3958149317d6af2cccc)
1 /*
2  * Copyright 2012, Haiku, Inc.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  * 		Aaron Hill <serac@hillvisions.com>
7  *		Alexander von Gluck <kallisti5@unixzen.com>
8  */
9 
10 
11 #include "GLifeView.h"
12 
13 #include <GL/glu.h>
14 #include <GLView.h>
15 #include <math.h>
16 #include <stdlib.h>
17 
18 #include "GLifeGrid.h"
19 #include "GLifeState.h"
20 
21 
22 // ------------------------------------------------------
23 //  GLifeView Class Constructor Definition
24 GLifeView::GLifeView(BRect rect, const char* name, ulong resizingMode,
25 	ulong options, GLifeState* pglsState)
26 	:
27 	BGLView(rect, name, resizingMode, 0, options),
28 	m_pglsState(pglsState)
29 {
30 	// Setup the grid
31 	m_pglgGrid = new GLifeGrid(pglsState->GridWidth(), pglsState->GridHeight());
32 
33 	LockGL();
34 
35 	glClearDepth(1.0);
36 	glDepthFunc(GL_LESS);
37 	glEnable(GL_DEPTH_TEST);
38 
39 	glEnable(GL_BLEND);
40 	glBlendFunc(GL_SRC_ALPHA, GL_ONE);
41 #if 0
42 	glShadeModel(GL_SMOOTH);
43 #endif
44 	glMatrixMode(GL_PROJECTION);
45 	glLoadIdentity();
46 	gluPerspective(45.0, rect.Width() / rect.Height(), 2.0, 20000.0);
47 	glTranslatef(0.0, 0.0, -50.0);
48 	glMatrixMode(GL_MODELVIEW);
49 
50 	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
51 
52 	UnlockGL();
53 }
54 
55 
56 // ------------------------------------------------------
57 //  GLifeView Class Destructor Definition
58 GLifeView::~GLifeView(void)
59 {
60 	delete m_pglgGrid;
61 }
62 
63 
64 // ------------------------------------------------------
65 //  GLifeView Class AttachedToWindow Definition
66 void
67 GLifeView::AttachedToWindow(void)
68 {
69 	LockGL();
70 	BGLView::AttachedToWindow();
71 	UnlockGL();
72 }
73 
74 
75 // ------------------------------------------------------
76 //  GLifeView Class Draw Definition
77 void
78 GLifeView::Draw(BRect updateRect)
79 {
80 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
81 
82 	// TODO:  Dynamic colors or user-specified coloring
83 	GLfloat glfGreen[] = {0.05, 0.8, 0.15, 1.0};
84 	GLfloat glfOrange[] = {0.65, 0.3, 0.05, 1.0};
85 
86 	// Border control
87 	bool bColor;
88 
89 	int32 iWidth = m_pglsState->GridWidth();
90 	int32 iHeight = m_pglsState->GridHeight();
91 	int32 iBorder = m_pglsState->GridBorder();
92 
93 	glPushMatrix();
94 
95 	glRotatef(m_glfDelta * 3, 1.0, 0.0, 0.0);
96 	glRotatef(m_glfDelta * 1, 0.0, 0.0, 1.0);
97 	glRotatef(m_glfDelta * 2, 0.0, 1.0, 0.0);
98 
99 	for(int32 iRow = (0 - iBorder); iRow < (iHeight + iBorder); ++iRow) {
100 		GLfloat glfY = (GLfloat)iRow - ((GLfloat)iHeight / 2);
101 
102 		for(int32 iColumn = (0 - iBorder); iColumn < (iWidth + iBorder); ++iColumn) {
103 
104 			GLfloat glfX = (GLfloat)iColumn - ((GLfloat) iWidth / 2);
105 
106 			bColor = (iColumn < 0) || (iColumn >= iWidth) || (iRow < 0) || (iRow >= iHeight);
107 
108 			if (m_pglgGrid->Occupied(iRow, iColumn)) {
109 				glPushMatrix();
110 
111 				glTranslatef(glfX, glfY, 0.0);
112 				glScalef(0.45, 0.45, 0.45);
113 
114 				// GL Begin
115 				glBegin(GL_QUAD_STRIP);
116 				if (bColor)
117 					glColor3f( 0.65, 0.3, 0.05 );
118 				else
119 					glColor3f( 0.05, 0.8, 0.15 );
120 
121 				glMaterialfv(GL_FRONT, GL_DIFFUSE, bColor ? glfOrange : glfGreen);
122 				glNormal3f(0.0,  1.0, 0.0);
123 				glVertex3f(1.0,  1.0, -1.0);
124 				glVertex3f(-1.0,  1.0, -1.0);
125 				glVertex3f(1.0,  1.0, 1.0);
126 				glVertex3f(-1.0,  1.0, 1.0);
127 
128 				glNormal3f(0.0, 0.0, 1.0);
129 				glVertex3f(-1.0, 1.0, 1.0);
130 				glVertex3f(1.0, 1.0, 1.0);
131 				glVertex3f(-1.0, -1.0, 1.0);
132 				glVertex3f(1.0, -1.0, 1.0);
133 
134 				glNormal3f(0.0, -1.0, 0.0);
135 				glVertex3f(-1.0, -1.0, 1.0);
136 				glVertex3f(1.0, -1.0, 1.0);
137 				glVertex3f(-1.0, -1.0, -1.0);
138 				glVertex3f(1.0, -1.0, -1.0);
139 				glEnd();
140 				// GL End
141 
142 				// GL Begin
143 				glBegin( GL_QUAD_STRIP);
144 				if (bColor)
145 					glColor3f(0.65, 0.3, 0.05);
146 				else
147 					glColor3f(0.05, 0.8, 0.15);
148 
149 				glMaterialfv(GL_FRONT, GL_DIFFUSE, bColor ? glfOrange : glfGreen);
150 				glNormal3f(-1.0, 0.0, 0.0);
151 				glVertex3f(-1.0, 1.0, 1.0);
152 				glVertex3f(-1.0, -1.0, 1.0);
153 				glVertex3f(-1.0, 1.0, -1.0);
154 				glVertex3f(-1.0, -1.0, -1.0);
155 
156 				glNormal3f(0.0, 0.0, -1.0);
157 				glVertex3f(-1.0, 1.0, -1.0);
158 				glVertex3f(-1.0, -1.0, -1.0);
159 				glVertex3f(1.0, 1.0, -1.0);
160 				glVertex3f(1.0, -1.0, -1.0);
161 
162 				glNormal3f(1.0, 0.0, 0.0);
163 				glVertex3f(1.0, 1.0, -1.0);
164 				glVertex3f(1.0, -1.0, -1.0);
165 				glVertex3f(1.0, 1.0, 1.0);
166 				glVertex3f(1.0, -1.0, 1.0);
167 				glEnd();
168 				// GL End
169 
170 				glPopMatrix();
171 			}
172 		}
173 	}
174 
175 	glPopMatrix();
176 }
177 
178 
179 // ------------------------------------------------------
180 //  GLifeView Class Advance Definition
181 void
182 GLifeView::Advance(void)
183 {
184 	if (m_glfDelta++ > 360.0)
185 		m_glfDelta -= 360.0;
186 
187 	int32 gridDelay = m_pglsState->GridDelay();
188 	if (m_iStep++ > gridDelay) {
189 		m_iStep = 0;
190 		m_pglgGrid->Generation();
191 	}
192 
193 	LockGL();
194 	BRect location(0,0,0,0);
195 	Draw(location);
196 	SwapBuffers();
197 	UnlockGL();
198 }
199