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