diff options
Diffstat (limited to 'src/extantz/crappisspuke.cpp')
-rw-r--r-- | src/extantz/crappisspuke.cpp | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/src/extantz/crappisspuke.cpp b/src/extantz/crappisspuke.cpp new file mode 100644 index 0000000..2af9dde --- /dev/null +++ b/src/extantz/crappisspuke.cpp | |||
@@ -0,0 +1,294 @@ | |||
1 | |||
2 | #include <irrlicht.h> | ||
3 | #include "extantz.h" | ||
4 | #include "CDemo.h" | ||
5 | |||
6 | |||
7 | SExposedVideoData videoData; | ||
8 | |||
9 | IAnimatedMeshSceneNode *node; | ||
10 | CDemo *myDemo; | ||
11 | // This is the movement speed in units per second. | ||
12 | const f32 MOVEMENT_SPEED = 5.f; | ||
13 | // In order to do framerate independent movement, we have to know | ||
14 | // how long it was since the last frame | ||
15 | u32 then; | ||
16 | |||
17 | #ifdef __cplusplus | ||
18 | extern "C" { | ||
19 | #endif | ||
20 | |||
21 | EAPI int startIrr(GLData *gld) | ||
22 | { | ||
23 | SIrrlichtCreationParameters params; | ||
24 | IrrlichtDevice *device; | ||
25 | IVideoDriver *driver; | ||
26 | ISceneManager *smgr; | ||
27 | bool additive = true; | ||
28 | |||
29 | if (!gld->useIrr) | ||
30 | return 1; // Return 1 so that the caller stops asking on each frame. | ||
31 | |||
32 | #if USE_IRR | ||
33 | void *display = NULL; | ||
34 | unsigned long sfc = 0; | ||
35 | void *ctx = NULL; | ||
36 | // Evas_GL_API *gl = gld->glApi; | ||
37 | |||
38 | #if USE_DEMO | ||
39 | myDemo = new CDemo(gld, additive); | ||
40 | #endif | ||
41 | |||
42 | /* Raster says - | ||
43 | 4. evas exposes an opengl-es2 api. any existing engine needs to be adapted to | ||
44 | use this. that's pretty much the end of that. if the engine doesn't have a | ||
45 | gles2 port.. it will need one. once it has one, then it is a simple matter of | ||
46 | replacing all the gl calls as follows: | ||
47 | |||
48 | glDrawArrays() -> api->glDrawArrays() | ||
49 | glBindBuffer() -> api->glBindBuffer() | ||
50 | |||
51 | you could make the port switchable with a macro: | ||
52 | |||
53 | #ifdef EVASGL | ||
54 | #define EG() my_evas_gl_api-> | ||
55 | #else | ||
56 | #define EG() | ||
57 | #endif | ||
58 | |||
59 | then fix up all the gl calls to be | ||
60 | |||
61 | EG()glDrawArrays() | ||
62 | EG()glBindBuffer() | ||
63 | |||
64 | etc. | ||
65 | |||
66 | doing the above allows evas to decide how to share context. it may allocate a | ||
67 | separate context or share its own. either way as far as the evasgl api user is | ||
68 | concerned.. they get their own private context to play with. if it does NOT do | ||
69 | the above (use the api exposed by evas gl) then wrapping can't context switches | ||
70 | can't work. all gl calls HAVE to go through the wrapped api to work right. this | ||
71 | is because we can't REPLACE the internals of the gl driver which otherwise | ||
72 | would be managing context and state all internally and we have zero access to | ||
73 | that - especially with closed drivers. we'd end up writing a proxy gl library | ||
74 | which conflicts with real gl symbol-wise (thus taking over and replacing | ||
75 | normal gl calls) and i know i have no interest in maintaining a separate | ||
76 | libGLwhatever.so that is an exact copy of gl and it's api's just to wrap it | ||
77 | when we expose that wrapper without symbol complications via evas gl. | ||
78 | |||
79 | 5. the engine will need to be adapted so the draw function is callable - eg by | ||
80 | elm_glview. then it's easy to switch where rendering happens. evas offers a fast | ||
81 | path to avoid buffer copies and make the gl view draw part of the evas | ||
82 | rendering path directly. this would offer almost zero overhead vs doing it | ||
83 | directly with egl/gles etc. to your backbuffer yourself, BUT gets you the bonus | ||
84 | of having your 3d view as part of a larger scenegraph. combine 2 or 3 of them | ||
85 | in a single window. overlay with evas objects or elm widgets for hud etc. all | ||
86 | for free. this also implies the engine has to integrate to the efl mainloop | ||
87 | etc. of course. | ||
88 | */ | ||
89 | |||
90 | |||
91 | sfc = ecore_evas_window_get(gld->ee); | ||
92 | // This is the way Raster wants me to do things, but these functions are not actually available. Pffft | ||
93 | // ctx = gl->glGetCurrentContext(); | ||
94 | // display = gl->glGetCurrentDisplay(); | ||
95 | ctx = glXGetCurrentContext(); | ||
96 | display = glXGetCurrentDisplay(); | ||
97 | /* For using a pre existing X11 window (with optional OpenGL). */ | ||
98 | videoData = SExposedVideoData(); | ||
99 | videoData.OpenGLLinux.X11Display = display; // void * - Connection to the X server. | ||
100 | videoData.OpenGLLinux.X11Window = sfc; // unsigned long - Specifies a GLX drawable. Must be either an X window ID or a GLX pixmap ID. | ||
101 | videoData.OpenGLLinux.X11Context = ctx; // void * - Specifies a GLX rendering context that is to be attached to drawable. | ||
102 | |||
103 | /* | ||
104 | The most important function of the engine is the createDevice() | ||
105 | function. The IrrlichtDevice is created by it, which is the root | ||
106 | object for doing anything with the engine. createDevice() has 7 | ||
107 | parameters: | ||
108 | |||
109 | - deviceType: Type of the device. This can currently be the Null-device, | ||
110 | one of the two software renderers, D3D8, D3D9, or OpenGL. In this | ||
111 | example we use EDT_SOFTWARE, but to try out, you might want to | ||
112 | change it to EDT_BURNINGSVIDEO, EDT_NULL, EDT_DIRECT3D8, | ||
113 | EDT_DIRECT3D9, or EDT_OPENGL. | ||
114 | |||
115 | - windowSize: Size of the Window or screen in FullScreenMode to be | ||
116 | created. In this example we use 640x480. | ||
117 | |||
118 | - bits: Amount of color bits per pixel. This should be 16 or 32. The | ||
119 | parameter is often ignored when running in windowed mode. | ||
120 | |||
121 | - fullscreen: Specifies if we want the device to run in fullscreen mode | ||
122 | or not. | ||
123 | |||
124 | - stencilbuffer: Specifies if we want to use the stencil buffer (for | ||
125 | drawing shadows). | ||
126 | |||
127 | - vsync: Specifies if we want to have vsync enabled, this is only useful | ||
128 | in fullscreen mode. | ||
129 | |||
130 | - eventReceiver: An object to receive events. We do not want to use this | ||
131 | parameter here, and set it to 0. | ||
132 | |||
133 | Always check the return value to cope with unsupported drivers, | ||
134 | dimensions, etc. | ||
135 | */ | ||
136 | |||
137 | params.DeviceType = EIDT_X11; // EIDT_BEST might be preferable. | ||
138 | if (ctx) | ||
139 | params.DriverType = video::EDT_OPENGL; | ||
140 | else | ||
141 | params.DriverType = video::EDT_BURNINGSVIDEO; | ||
142 | params.WindowSize = dimension2d<u32>(gld->sfc_w, gld->sfc_h); | ||
143 | params.Bits = 32; // Ignored in windowed mode? | ||
144 | params.ZBufferBits = 16; // Default 16. | ||
145 | params.Fullscreen = false; // The default anyway. | ||
146 | params.Stencilbuffer = false; // For shadows. | ||
147 | params.Vsync = false; | ||
148 | params.AntiAlias=true; | ||
149 | params.WithAlphaChannel = true; | ||
150 | params.IgnoreInput = true; | ||
151 | params.EventReceiver = myDemo; // Probably useless, EFL might not let Irrlicht grab the input. | ||
152 | params.WindowId = (void *) videoData.OpenGLLinux.X11Window; | ||
153 | params.VideoData = &videoData; | ||
154 | |||
155 | device = createDeviceEx(params); | ||
156 | |||
157 | if (!device) | ||
158 | return 0; | ||
159 | gld->device = device; | ||
160 | |||
161 | /* | ||
162 | Get a pointer to the VideoDriver and the SceneManager so that we do not always have to write | ||
163 | device->getVideoDriver() or device->getSceneManager(). | ||
164 | */ | ||
165 | driver = device->getVideoDriver(); gld->driver = driver; | ||
166 | smgr = device->getSceneManager(); gld->smgr = smgr; | ||
167 | |||
168 | // FIXME - this is what makes the window vanish in EFL 1.8, but worked fine in 1.7 I think. | ||
169 | // device->setResizable(true); | ||
170 | driver->OnResize(dimension2d<u32>(gld->img_w, gld->img_h)); | ||
171 | // Just gives me a blank screen. grrrr | ||
172 | // driver->setViewPort(rect<s32>(0, 0, gld->img_w, gld->img_h)); | ||
173 | |||
174 | // set ambient light | ||
175 | smgr->setAmbientLight (video::SColorf(0x00c0c0c0)); | ||
176 | |||
177 | #if USE_DEMO | ||
178 | myDemo->setup(gld); | ||
179 | #else | ||
180 | /* | ||
181 | To show something interesting, we load a Quake 2 model and display it. | ||
182 | We only have to get the Mesh from the Scene Manager with getMesh() and add | ||
183 | a SceneNode to display the mesh with addAnimatedMeshSceneNode(). We | ||
184 | check the return value of getMesh() to become aware of loading problems | ||
185 | and other errors. | ||
186 | |||
187 | Instead of writing the filename sydney.md2, it would also be possible | ||
188 | to load a Maya object file (.obj), a complete Quake3 map (.bsp) or any | ||
189 | other supported file format. By the way, that cool Quake 2 model | ||
190 | called sydney was modelled by Brian Collins. | ||
191 | */ | ||
192 | IAnimatedMesh* mesh = smgr->getMesh("media/Irrlicht/sydney.md2"); | ||
193 | if (!mesh) | ||
194 | { | ||
195 | device->drop(); | ||
196 | return 0; | ||
197 | } | ||
198 | node = smgr->addAnimatedMeshSceneNode(mesh); | ||
199 | |||
200 | /* | ||
201 | To let the mesh look a little bit nicer, we change its material. We | ||
202 | disable lighting because we do not have a dynamic light in here, and | ||
203 | the mesh would be totally black otherwise. Then we set the frame loop, | ||
204 | such that the predefined STAND animation is used. And last, we apply a | ||
205 | texture to the mesh. Without it the mesh would be drawn using only a | ||
206 | color. | ||
207 | */ | ||
208 | if (node) | ||
209 | { | ||
210 | // node->setMaterialFlag(EMF_LIGHTING, false); | ||
211 | node->setMD2Animation(scene::EMAT_STAND); | ||
212 | node->setMaterialTexture(0, driver->getTexture("media/Irrlicht/sydney.bmp")); | ||
213 | } | ||
214 | |||
215 | /* | ||
216 | To look at the mesh, we place a camera into 3d space at the position | ||
217 | (0, 30, -40). The camera looks from there to (0,5,0), which is | ||
218 | approximately the place where our md2 model is. | ||
219 | */ | ||
220 | smgr->addCameraSceneNode(0, vector3df(50, 70, -65), vector3df(0, 50, 0)); | ||
221 | #endif | ||
222 | |||
223 | then = device->getTimer()->getTime(); | ||
224 | #endif | ||
225 | return 1; | ||
226 | } | ||
227 | |||
228 | EAPI void drawIrr_start(GLData *gld) | ||
229 | { | ||
230 | if (gld->useIrr) | ||
231 | { | ||
232 | IrrlichtDevice *device = gld->device; | ||
233 | IVideoDriver *driver = gld->driver; | ||
234 | ISceneManager *smgr = gld->smgr; | ||
235 | |||
236 | // Increase virtual timer time, instead of device->run() if doing our own input processing. | ||
237 | device->getTimer()->tick(); | ||
238 | |||
239 | // Work out a frame delta time. | ||
240 | const u32 now = device->getTimer()->getTime(); | ||
241 | // const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds | ||
242 | then = now; | ||
243 | |||
244 | |||
245 | #if USE_DEMO | ||
246 | myDemo->preDraw(gld, now); | ||
247 | #else | ||
248 | core::vector3df nodePosition = node->getPosition(); | ||
249 | // nodePosition.Y -= MOVEMENT_SPEED * frameDeltaTime; | ||
250 | node->setPosition(nodePosition); | ||
251 | #endif | ||
252 | |||
253 | /* | ||
254 | Anything can be drawn between a beginScene() and an endScene() | ||
255 | call. The beginScene() call clears the screen with a color and | ||
256 | the depth buffer, if desired. Then we let the Scene Manager and | ||
257 | the GUI Environment draw their content. With the endScene() | ||
258 | call everything is presented on the screen. | ||
259 | */ | ||
260 | driver->beginScene(true, true, SColor(255, 255, 255, 255), videoData, NULL); // This does the context change, then clearBuffers() | ||
261 | |||
262 | smgr->drawAll(); | ||
263 | } | ||
264 | } | ||
265 | |||
266 | EAPI void drawIrr_end(GLData *gld) | ||
267 | { | ||
268 | IVideoDriver *driver = gld->driver; | ||
269 | |||
270 | if (gld->useIrr) | ||
271 | driver->endScene(); | ||
272 | } | ||
273 | |||
274 | EAPI void finishIrr(GLData *gld) | ||
275 | { | ||
276 | IrrlichtDevice *device = gld->device; | ||
277 | |||
278 | /* | ||
279 | After we are done with the render loop, we have to delete the Irrlicht | ||
280 | Device created before with createDevice(). In the Irrlicht Engine, you | ||
281 | have to delete all objects you created with a method or function which | ||
282 | starts with 'create'. The object is simply deleted by calling ->drop(). | ||
283 | See the documentation at irr::IReferenceCounted::drop() for more | ||
284 | information. | ||
285 | */ | ||
286 | if (gld->useIrr) | ||
287 | device->drop(); | ||
288 | } | ||
289 | |||
290 | |||
291 | #ifdef __cplusplus | ||
292 | } | ||
293 | #endif | ||
294 | |||