Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 286 lines (236 sloc) 9.074 kb
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
1 #include "Camera.h"
2 #include "Frame.h"
9d754b3 @johnbartholomew create a new 'galaxy' subdir and pull various files into it
johnbartholomew authored
3 #include "galaxy/StarSystem.h"
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
4 #include "Space.h"
5 #include "Player.h"
6 #include "Pi.h"
8aba485 @robn move most of the world render loop out of Space into Camera. still need ...
authored
7 #include "Sfx.h"
252d1e9 @robn rename SpaceManager to Game, for I have discovered the long-sought-after...
authored
8 #include "Game.h"
a8a32e6 @robn add headers and declarations to make it build on linux
authored
9 #include "Planet.h"
484f060 @robn move all the render stuff, old and new, under the Graphics:: namespace. ...
authored
10 #include "graphics/Graphics.h"
11 #include "graphics/Renderer.h"
12 #include "graphics/VertexArray.h"
13 #include "graphics/Material.h"
14
15 using namespace Graphics;
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
16
928c8fa @Luomu FOV is now a property of camera
Luomu authored
17 Camera::Camera(const Body *body, float width, float height, float fovY, float znear, float zfar) :
ae724f2 @Luomu Make drawing of camera bodies optional
Luomu authored
18 m_showCameraBody(true),
34341f0 @robn fix init order
authored
19 m_body(body),
9db2f06 @robn rework the frustum class so its immutable. it now just captures the curr...
authored
20 m_width(width),
21 m_height(height),
928c8fa @Luomu FOV is now a property of camera
Luomu authored
22 m_fovAng(fovY),
b97b3b0 @Luomu Replace Render::GetNearFarClipPlane
Luomu authored
23 m_zNear(znear),
24 m_zFar(zfar),
25 m_frustum(m_width, m_height, m_fovAng, znear, zfar),
8346978 @johnbartholomew Combine Camera::m_{pos,orient} into a single matrix (much simpler to wor...
johnbartholomew authored
26 m_pose(matrix4x4d::Identity()),
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
27 m_camFrame(0),
28 m_renderer(0)
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
29 {
354898b @robn swap spaces before doing the draw to get all the old bodies cleaned up. ...
authored
30 m_onBodyDeletedConnection = m_body->onDelete.connect(sigc::mem_fun(this, &Camera::OnBodyDeleted));
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
31 }
32
33 Camera::~Camera()
34 {
354898b @robn swap spaces before doing the draw to get all the old bodies cleaned up. ...
authored
35 if (m_onBodyDeletedConnection.connected())
36 m_onBodyDeletedConnection.disconnect();
37
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
38 if (m_camFrame) {
39 m_body->GetFrame()->RemoveChild(m_camFrame);
40 delete m_camFrame;
41 }
42 }
43
354898b @robn swap spaces before doing the draw to get all the old bodies cleaned up. ...
authored
44 void Camera::OnBodyDeleted()
45 {
46 m_onBodyDeletedConnection.disconnect();
47 m_body = 0;
48 }
49
153938d @robn rework Camera::Light into Camera::LightSource and don't inherit from Gra...
authored
50 static void position_system_lights(Frame *camFrame, Frame *frame, std::vector<Camera::LightSource> &lights)
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
51 {
707530c @Luomu Use SetLights to position camera lights
Luomu authored
52 if (lights.size() > 3) return;
00421ae @johnbartholomew global replace SBody -> SystemBody
johnbartholomew authored
53 // not using frame->GetSystemBodyFor() because it snoops into parent frames,
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
54 // causing duplicate finds for static and rotating frame
00421ae @johnbartholomew global replace SBody -> SystemBody
johnbartholomew authored
55 SystemBody *body = frame->m_sbody;
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
56
00421ae @johnbartholomew global replace SBody -> SystemBody
johnbartholomew authored
57 if (body && (body->GetSuperType() == SystemBody::SUPERTYPE_STAR)) {
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
58 matrix4x4d m;
59 Frame::GetFrameTransform(frame, camFrame, m);
60 vector3d lpos = (m * vector3d(0,0,0));
61 double dist = lpos.Length() / AU;
62 lpos *= 1.0/dist; // normalize
63
64 const float *col = StarSystem::starRealColors[body->type];
65
707530c @Luomu Use SetLights to position camera lights
Luomu authored
66 Color lightCol(col[0], col[1], col[2], 0.f);
67 Color ambCol(0.f);
68 vector3f lightpos(lpos.x, lpos.y, lpos.z);
153938d @robn rework Camera::Light into Camera::LightSource and don't inherit from Gra...
authored
69 lights.push_back(Camera::LightSource(frame->m_astroBody, Graphics::Light(Graphics::Light::LIGHT_DIRECTIONAL, lightpos, lightCol, ambCol, lightCol)));
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
70 }
71
72 for (std::list<Frame*>::iterator i = frame->m_children.begin(); i!=frame->m_children.end(); ++i) {
707530c @Luomu Use SetLights to position camera lights
Luomu authored
73 position_system_lights(camFrame, *i, lights);
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
74 }
75 }
76
77 void Camera::Update()
78 {
354898b @robn swap spaces before doing the draw to get all the old bodies cleaned up. ...
authored
79 if (!m_body) return;
80
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
81 // make temporary camera frame at the body
82 m_camFrame = new Frame(m_body->GetFrame(), "camera", Frame::TEMP_VIEWING);
83
84 // interpolate between last physics tick position and current one,
85 // to remove temporal aliasing
8346978 @johnbartholomew Combine Camera::m_{pos,orient} into a single matrix (much simpler to wor...
johnbartholomew authored
86 matrix4x4d bodyPose = m_body->GetInterpolatedTransform();
87 m_camFrame->SetTransform(bodyPose * m_pose);
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
88
89 // make sure old orient and interpolated orient (rendering orient) are not rubbish
90 m_camFrame->ClearMovement();
91
8aba485 @robn move most of the world render loop out of Space into Camera. still need ...
authored
92 // evaluate each body and determine if/where/how to draw it
93 m_sortedBodies.clear();
d69ea20 @robn rename IteratorBegin/IteratorEnd to BodiesBegin/BodiesEnd to make it cle...
authored
94 for (Space::BodyIterator i = Pi::game->GetSpace()->BodiesBegin(); i != Pi::game->GetSpace()->BodiesEnd(); ++i) {
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
95 Body *b = *i;
8aba485 @robn move most of the world render loop out of Space into Camera. still need ...
authored
96
ab1bc55 @robn spell out some of the detail around the body render attributes
authored
97 // prepare attrs for sorting and drawing
98 BodyAttrs attrs;
99 attrs.body = b;
100 Frame::GetFrameRenderTransform(b->GetFrame(), m_camFrame, attrs.viewTransform);
101 attrs.viewCoords = attrs.viewTransform * b->GetInterpolatedPosition();
102 attrs.camDist = attrs.viewCoords.Length();
103 attrs.bodyFlags = b->GetFlags();
104 m_sortedBodies.push_back(attrs);
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
105 }
8aba485 @robn move most of the world render loop out of Space into Camera. still need ...
authored
106
107 // depth sort
b481f6f @robn restore depth sort
authored
108 m_sortedBodies.sort();
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
109 }
110
0750745 @Luomu Pass renderer to camera
Luomu authored
111 void Camera::Draw(Renderer *renderer)
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
112 {
354898b @robn swap spaces before doing the draw to get all the old bodies cleaned up. ...
authored
113 if (!m_body) return;
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
114 if (!renderer) return;
115
116 m_renderer = renderer;
354898b @robn swap spaces before doing the draw to get all the old bodies cleaned up. ...
authored
117
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
118 glPushAttrib(GL_ALL_ATTRIB_BITS);
119
a61c1aa @Luomu Use SetPerspective...SetTransform in camera
Luomu authored
120 m_renderer->SetPerspectiveProjection(m_fovAng, m_width/m_height, m_zNear, m_zFar);
121 m_renderer->SetTransform(matrix4x4f::Identity());
e5c5436 @Luomu Replace glClearColor & glClear
Luomu authored
122 m_renderer->ClearScreen();
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
123
124 matrix4x4d trans2bg;
8c987c6 @WaveMotion Draw starfield with interpolated transform
WaveMotion authored
125 Frame::GetFrameRenderTransform(Pi::game->GetSpace()->GetRootFrame(), m_camFrame, trans2bg);
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
126 trans2bg.ClearToRotOnly();
127
707530c @Luomu Use SetLights to position camera lights
Luomu authored
128 // Pick up to four suitable system light sources (stars)
153938d @robn rework Camera::Light into Camera::LightSource and don't inherit from Gra...
authored
129 m_lightSources.clear();
130 m_lightSources.reserve(4);
131 position_system_lights(m_camFrame, Pi::game->GetSpace()->GetRootFrame(), m_lightSources);
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
132
153938d @robn rework Camera::Light into Camera::LightSource and don't inherit from Gra...
authored
133 if (m_lightSources.empty()) {
9800f26 @johnbartholomew fix typo
johnbartholomew authored
134 // no lights means we're somewhere weird (eg hyperspace).
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
135 // fake one up and give a little ambient light so that we can see and
136 // so that things that need lights don't explode
707530c @Luomu Use SetLights to position camera lights
Luomu authored
137 Color col(1.f);
153938d @robn rework Camera::Light into Camera::LightSource and don't inherit from Gra...
authored
138 m_lightSources.push_back(LightSource(0, Graphics::Light(Graphics::Light::LIGHT_DIRECTIONAL, vector3f(0.f), col, col, col)));
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
139 }
140
c3636aa @Luomu Fade space background based on atmosphere thickness and sunlight angle
Luomu authored
141 //fade space background based on atmosphere thickness and light angle
142 float bgIntensity = 1.f;
143 if (m_camFrame->m_parent) {
144 //check if camera is near a planet
145 Body *camParentBody = m_camFrame->m_parent->GetBodyFor();
146 if (camParentBody && camParentBody->IsType(Object::PLANET)) {
147 Planet *planet = static_cast<Planet*>(camParentBody);
148 const vector3f relpos(planet->GetPositionRelTo(m_camFrame));
149 double altitude(relpos.Length());
150 double pressure, density;
151 planet->GetAtmosphericState(altitude, &pressure, &density);
152
153 //go through all lights to calculate something resembling light intensity
154 float angle = 0.f;
153938d @robn rework Camera::Light into Camera::LightSource and don't inherit from Gra...
authored
155 for(std::vector<LightSource>::const_iterator it = m_lightSources.begin();
156 it != m_lightSources.end(); ++it) {
157 const vector3f lightDir(it->GetLight().GetPosition().Normalized());
158 angle += std::max(0.f, lightDir.Dot(-relpos.Normalized())) * it->GetLight().GetDiffuse().GetLuminance();
c3636aa @Luomu Fade space background based on atmosphere thickness and sunlight angle
Luomu authored
159 }
160 //calculate background intensity with some hand-tweaked fuzz applied
161 bgIntensity = Clamp(1.f - std::min(1.f, float(density) * (0.3f + angle)), 0.f, 1.f);
162 }
163 }
164
165 Pi::game->GetSpace()->GetBackground().SetIntensity(bgIntensity);
166 Pi::game->GetSpace()->GetBackground().Draw(renderer, trans2bg);
167
153938d @robn rework Camera::Light into Camera::LightSource and don't inherit from Gra...
authored
168 {
169 std::vector<Graphics::Light> rendererLights;
170 for (size_t i = 0; i < m_lightSources.size(); i++)
171 rendererLights.push_back(m_lightSources[i].GetLight());
172 renderer->SetLights(rendererLights.size(), &rendererLights[0]);
173 }
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
174
1a612ac @robn use preincrement for iterator loops
authored
175 for (std::list<BodyAttrs>::iterator i = m_sortedBodies.begin(); i != m_sortedBodies.end(); ++i) {
ab1bc55 @robn spell out some of the detail around the body render attributes
authored
176 BodyAttrs *attrs = &(*i);
177
ae724f2 @Luomu Make drawing of camera bodies optional
Luomu authored
178 if (attrs->body == GetBody() && !m_showCameraBody) continue;
8aba485 @robn move most of the world render loop out of Space into Camera. still need ...
authored
179
ae724f2 @Luomu Make drawing of camera bodies optional
Luomu authored
180 double rad = attrs->body->GetClipRadius();
31bd8df @robn star exclusion no long appears necessary
authored
181 if (!m_frustum.TestPointInfinite((*i).viewCoords, rad))
b62e61e @robn move frustum-related stuff (culling, projection) into a seperate class. ...
authored
182 continue;
8aba485 @robn move most of the world render loop out of Space into Camera. still need ...
authored
183
e343966 @robn restore spikes
authored
184 // draw spikes for far objects
ab1bc55 @robn spell out some of the detail around the body render attributes
authored
185 double screenrad = 500 * rad / attrs->camDist; // approximate pixel size
f2c64e4 use smaller size for projectiles so player can see where they go
Ziusudra authored
186 if (attrs->body->IsType(Object::PLANET) && screenrad < 2) {
8aba485 @robn move most of the world render loop out of Space into Camera. still need ...
authored
187 // absolute bullshit
188 double spikerad = (7 + 1.5*log10(screenrad)) * rad / screenrad;
e343966 @robn restore spikes
authored
189 DrawSpike(spikerad, attrs->viewCoords, attrs->viewTransform);
8aba485 @robn move most of the world render loop out of Space into Camera. still need ...
authored
190 }
f2c64e4 use smaller size for projectiles so player can see where they go
Ziusudra authored
191 else if (screenrad >= 2 || attrs->body->IsType(Object::STAR) ||
192 (attrs->body->IsType(Object::PROJECTILE) && screenrad > 0.25))
9bb6d54 @Ae-2222 Initial commit.
Ae-2222 authored
193 attrs->body->Render(renderer, this, attrs->viewCoords, attrs->viewTransform);
8aba485 @robn move most of the world render loop out of Space into Camera. still need ...
authored
194 }
195
12a3e31 @Luomu Use DrawPointSprites in several places
Luomu authored
196 Sfx::RenderAll(renderer, Pi::game->GetSpace()->GetRootFrame(), m_camFrame);
484f060 @robn move all the render stuff, old and new, under the Graphics:: namespace. ...
authored
197 UnbindAllBuffers();
aca5b8a @robn move worldview draw stuff into a separate camera class. make separate ca...
authored
198
199 m_body->GetFrame()->RemoveChild(m_camFrame);
200 delete m_camFrame;
201 m_camFrame = 0;
202
203 glPopAttrib();
204 }
e343966 @robn restore spikes
authored
205
206 void Camera::DrawSpike(double rad, const vector3d &viewCoords, const matrix4x4d &viewTransform)
207 {
5de64d5 @Luomu Remove Frustum::Enable/Disable as it's GL specific
Luomu authored
208 // draw twinkly star-thing on faraway objects
209 // XXX this seems like a good case for drawing in 2D - use projected position, then the
210 // "face the camera dammit" bits can be skipped
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
211 if (!m_renderer) return;
212
5de64d5 @Luomu Remove Frustum::Enable/Disable as it's GL specific
Luomu authored
213 const double newdist = m_zNear + 0.5f * (m_zFar - m_zNear);
b005a76 @Luomu Replace some matrix handling
Luomu authored
214 const double scale = newdist / viewCoords.Length();
e343966 @robn restore spikes
authored
215
b005a76 @Luomu Replace some matrix handling
Luomu authored
216 matrix4x4d trans = matrix4x4d::Identity();
217 trans.Translate(scale*viewCoords.x, scale*viewCoords.y, scale*viewCoords.z);
e343966 @robn restore spikes
authored
218
219 // face the camera dammit
220 vector3d zaxis = viewCoords.Normalized();
221 vector3d xaxis = vector3d(0,1,0).Cross(zaxis).Normalized();
222 vector3d yaxis = zaxis.Cross(xaxis);
223 matrix4x4d rot = matrix4x4d::MakeInvRotMatrix(xaxis, yaxis, zaxis);
b005a76 @Luomu Replace some matrix handling
Luomu authored
224 trans = trans * rot;
e343966 @robn restore spikes
authored
225
00e6e2d @Luomu Replace GL_DEPTH_TEST
Luomu authored
226 m_renderer->SetDepthTest(false);
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
227 m_renderer->SetBlendMode(BLEND_ALPHA_ONE);
e343966 @robn restore spikes
authored
228
229 // XXX WRONG. need to pick light from appropriate turd.
230 GLfloat col[4];
231 glGetLightfv(GL_LIGHT0, GL_DIFFUSE, col);
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
232 col[3] = 1.f;
233
d85787a @Luomu Update VA usage after previous change
Luomu authored
234 VertexArray va(ATTRIB_POSITION | ATTRIB_DIFFUSE);
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
235
c721104 @Luomu Consistentify some usage
Luomu authored
236 const Color center(col[0], col[1], col[2], col[2]);
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
237 const Color edges(col[0], col[1], col[2], 0.f);
e343966 @robn restore spikes
authored
238
c721104 @Luomu Consistentify some usage
Luomu authored
239 //center
240 va.Add(vector3f(0.f), center);
241
e343966 @robn restore spikes
authored
242 const float spikerad = float(scale*rad);
243
244 // bezier with (0,0,0) control points
245 {
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
246 const vector3f p0(0,spikerad,0), p1(spikerad,0,0);
e343966 @robn restore spikes
authored
247 float t=0.1f; for (int i=1; i<10; i++, t+= 0.1f) {
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
248 const vector3f p = (1-t)*(1-t)*p0 + t*t*p1;
c721104 @Luomu Consistentify some usage
Luomu authored
249 va.Add(p, edges);
e343966 @robn restore spikes
authored
250 }
251 }
252 {
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
253 const vector3f p0(spikerad,0,0), p1(0,-spikerad,0);
e343966 @robn restore spikes
authored
254 float t=0.1f; for (int i=1; i<10; i++, t+= 0.1f) {
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
255 const vector3f p = (1-t)*(1-t)*p0 + t*t*p1;
c721104 @Luomu Consistentify some usage
Luomu authored
256 va.Add(p, edges);
e343966 @robn restore spikes
authored
257 }
258 }
259 {
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
260 const vector3f p0(0,-spikerad,0), p1(-spikerad,0,0);
e343966 @robn restore spikes
authored
261 float t=0.1f; for (int i=1; i<10; i++, t+= 0.1f) {
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
262 const vector3f p = (1-t)*(1-t)*p0 + t*t*p1;
c721104 @Luomu Consistentify some usage
Luomu authored
263 va.Add(p, edges);
e343966 @robn restore spikes
authored
264 }
265 }
266 {
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
267 const vector3f p0(-spikerad,0,0), p1(0,spikerad,0);
e343966 @robn restore spikes
authored
268 float t=0.1f; for (int i=1; i<10; i++, t+= 0.1f) {
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
269 const vector3f p = (1-t)*(1-t)*p0 + t*t*p1;
c721104 @Luomu Consistentify some usage
Luomu authored
270 va.Add(p, edges);
e343966 @robn restore spikes
authored
271 }
272 }
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
273
b005a76 @Luomu Replace some matrix handling
Luomu authored
274 Material mat;
275 mat.unlit = true;
276 mat.vertexColors = true;
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
277
b005a76 @Luomu Replace some matrix handling
Luomu authored
278 glPushMatrix();
279 m_renderer->SetTransform(trans);
280 m_renderer->DrawTriangles(&va, &mat, TRIANGLE_FAN);
0826a66 @Luomu DrawTriangleFan. Draw star spikes.
Luomu authored
281 m_renderer->SetBlendMode(BLEND_SOLID);
00e6e2d @Luomu Replace GL_DEPTH_TEST
Luomu authored
282 m_renderer->SetDepthTest(true);
e343966 @robn restore spikes
authored
283 glPopMatrix();
284 }
285
Something went wrong with that request. Please try again.