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
24GLifeView::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
37GLifeView::~GLifeView(void)
38{
39	delete m_pglgGrid;
40}
41
42
43// ------------------------------------------------------
44//  GLifeView Class AttachedToWindow Definition
45void
46GLifeView::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
74void
75GLifeView::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
178void
179GLifeView::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