summaryrefslogtreecommitdiffstats
path: root/kue/graphics.cpp
blob: a0568aff101a15c81f587ba0e5aa67655520781f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#include <GL/gl.h>
#include <GL/glu.h>
#include <tdeglobal.h>
#include <tdeconfig.h>
#include <tqptrvector.h>

#include "physics.h"
#include "global.h"
#include "pocket.h"
#include "billiard.h"
#include "config.h"
#include "graphics.h"

// Constants

const double FIELD_WIDTH = 0.127;
const double FIELD_LENGTH = 0.254;

GLfloat LightAmbient[] = { 0.2, 0.2, 0.2, 1.0 };
GLfloat LightDiffuse[] = { 0.8, 0.8, 0.8, 1.0 };
GLfloat LightPosition[] = { FIELD_LENGTH / 2.0, FIELD_WIDTH / 2.0, 0.0, 1.0 };

GLdouble eyex = FIELD_LENGTH / 2.0;
GLdouble eyey = FIELD_WIDTH / 2.0;
GLdouble eyez = 0.1;

GLdouble centerx = FIELD_LENGTH / 2.0;
GLdouble centery = FIELD_WIDTH / 2.0;
GLdouble centerz = -FIELD_LENGTH / 2.0;

void graphics::resize(int width, int height)
{
	// We want to use the whole window
	glViewport(0, 0, width, height);

	// 3D-specific OpenGL setup

	// Modify the projection matrix
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	// Set up a perspective view based on our window's aspect ratio
	gluPerspective(45.0f, (GLdouble)width / (GLdouble)height, 0.1f, 100.0f);

	// Go back to modifying the modelview matrix (the default)
	glMatrixMode(GL_MODELVIEW);
}

bool graphics::init()
{
	// Clear the window to black when we start to draw
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	// Clear the depth buffer to 1.0
	glClearDepth(1.0);
	glShadeModel(GL_SMOOTH);	// Enables Smooth Color Shading

	// Enable texturing
	glEnable(GL_TEXTURE_2D);
	
	// Initialize our light
	glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
	glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);

	// Enable our light
	glEnable(GL_LIGHT0);

	// Don't draw polygons that aren't facing us (big speedup on cheap 486s ;)
//	glEnable(GL_CULL_FACE);

	// Have we enabled lighting?
	TDEGlobal::config()->setGroup("Graphics");
	if (TDEGlobal::config()->readBoolEntry("Lighting", true)) {
		// Turn on lighting
		glEnable(GL_LIGHTING);

		// Whenever we use glColor(), set the lighting system automatically know what
		// the new color is.
		glEnable(GL_COLOR_MATERIAL);
	}

	glDepthFunc(GL_LESS);	   // The Type Of Depth Test To Do
	glEnable(GL_DEPTH_TEST);	// Enables Depth Testing

	// Makes texturing drawing slight more accurate
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

	return true;
}

void graphics::startDraw()
{
	// Reset our origin, rotation, and scaling
	glLoadIdentity();

	glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);

	glTranslatef(0.0, 0.0, -FIELD_LENGTH / 2.0);

	// Set the camera position and angle
	gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, 0.0, 0.0, 1.0);

	// Clear our window to the default color set by glClearColor (i.e. black)
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


}

void graphics::endDraw()
{
	// Execute any backlogged commands right now
	glFlush();;
}

void graphics::lookAt(GLdouble _eyex, GLdouble _eyey, GLdouble _eyez, GLdouble _centerx, GLdouble _centery, GLdouble _centerz)
{
	// Update our internal viewpoint variables
	// These values are used in startDraw() to update the view

	// The eye coordinates are where we're looking from
	eyex = _eyex;
	eyey = _eyey;
	eyez = _eyez;

	// And the center coordinates are what we're looing at
	centerx = _centerx;
	centery = _centery;
	centerz = _centerz;
}

// Simple OpenGL wrapper
void graphics::setColor(double r, double g, double b)
{
	glColor3d(r, g, b);
}

void graphics::drawScene()
{
	const TQPtrVector<KuePocket>& pockets = KueGlobal::physics()->pockets();
	const TQPtrVector<KueBilliard>& billiards = KueGlobal::physics()->billiards();

	// Display the billiards and pockets

	// The pockets are black without a texture
	graphics::setColor(0.0, 0.0, 0.0);
	KueTexture::null().makeCurrent();

	// Draw all of the textures
	for (unsigned int i = 0;i < pockets.size();i++)
	{
		if (pockets[i])
			disc::draw(pockets[i]->positionX(), pockets[i]->positionY(), pockets[i]->radius());
	}

	// Now we need to turn the color to white,
	// so we don't interfere with the texture
	// color
	graphics::setColor(1.0, 1.0, 1.0);

	for (unsigned int i = 0;i < billiards.size();i++)
	{
		if (billiards[i])
		{
			double circ = billiards[i]->radius() * 2.0 * M_PI;
			double pos_x = billiards[i]->positionX();
			double pos_y = billiards[i]->positionY();
			double rot_x = fmod(pos_x, circ) / circ * 360.0;
			double rot_y = fmod(pos_y, circ) / circ * 360.0;

			billiards[i]->texture().makeCurrent();

			sphere::draw(pos_x, pos_y, billiards[i]->radius(), rot_x, rot_y);
		}
	}

}