]> git.jsancho.org Git - guile-irrlicht.git/blob - src/video-driver.cpp
61683f2436459c24734641160e9588b227ab27e1
[guile-irrlicht.git] / src / video-driver.cpp
1 /* guile-irrlicht --- GNU Guile bindings for Irrlicht Engine
2
3    Copyright (C) 2020 Javier Sancho <jsf@jsancho.org>
4
5    This file is part of guile-irrlicht.
6
7    guile-irrlicht is free software; you can redistribute it and/or modify
8    it under the terms of the GNU Lesser General Public License as
9    published by the Free Software Foundation; either version 3 of the
10    License, or (at your option) any later version.
11
12    guile-irrlicht is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16
17    You should have received a copy of the GNU Lesser General Public
18    License along with guile-irrlicht. If not, see
19    <http://www.gnu.org/licenses/>.
20 */
21
22 #include <irrlicht/irrlicht.h>
23 #include <libguile.h>
24
25 #include "color.h"
26 #include "gsubr.h"
27 #include "gui-environment.h"
28 #include "material.h"
29 #include "matrix4.h"
30 #include "primitive-types.h"
31 #include "rect.h"
32 #include "scene-manager.h"
33 #include "texture.h"
34 #include "vertex3d.h"
35 #include "video-driver.h"
36 #include "wrapped.h"
37
38 extern "C" {
39
40   void
41   init_video_driver (void)
42   {
43     init_video_driver_type ();
44     DEFINE_GSUBR ("begin-scene", 1, 0, 1, irr_video_beginScene);
45     DEFINE_GSUBR ("draw-vertex-primitive-list", 3, 0, 1, irr_video_drawVertexPrimitiveList);
46     DEFINE_GSUBR ("end-scene", 1, 0, 0, irr_video_endScene);
47     DEFINE_GSUBR ("get-fps", 1, 0, 0, irr_video_getFPS);
48     DEFINE_GSUBR ("get-texture", 2, 0, 0, irr_video_getTexture);
49     DEFINE_GSUBR ("set-transform!", 3, 0, 0, irr_video_setTransform);
50   }
51
52   DEFINE_WRAPPED_TYPE (irr::video::IVideoDriver*, "video-driver",
53                        init_video_driver_type, video_driver_p,
54                        wrap_video_driver, unwrap_video_driver);
55
56   SCM
57   irr_video_beginScene (SCM wrapped_video_driver,
58                         SCM rest)
59   {
60     SCM back_buffer = SCM_BOOL_T;
61     SCM z_buffer = SCM_BOOL_T;
62     SCM color = scm_list_4 (scm_from_uint32 (255),
63                             scm_from_uint32 (0),
64                             scm_from_uint32 (0),
65                             scm_from_uint32 (0));
66     SCM video_data = SCM_BOOL_F;
67     SCM source_rect = SCM_UNDEFINED;
68
69     scm_c_bind_keyword_arguments ("begin-scene", rest, (scm_t_keyword_arguments_flags)0,
70                                   scm_from_utf8_keyword ("back-buffer"), &back_buffer,
71                                   scm_from_utf8_keyword ("z-buffer"), &z_buffer,
72                                   scm_from_utf8_keyword ("color"), &color,
73                                   scm_from_utf8_keyword ("video-data"), &video_data,
74                                   scm_from_utf8_keyword ("source-rect"), &source_rect,
75                                   SCM_UNDEFINED);
76
77     irr::video::IVideoDriver* driver = unwrap_video_driver (wrapped_video_driver);
78     irr::core::rect<irr::s32>* sourceRectAddress = 0;
79     if (source_rect != SCM_UNDEFINED)
80       {
81         irr::core::rect<irr::s32> sourceRect = scm_to_rect_s32 (source_rect);
82         sourceRectAddress = &sourceRect;
83       }
84     return scm_from_bool (driver->beginScene (scm_to_bool (back_buffer),
85                                               scm_to_bool (z_buffer),
86                                               scm_to_color (color),
87                                               irr::video::SExposedVideoData (),
88                                               sourceRectAddress));
89   }
90
91   SCM
92   irr_video_drawVertexPrimitiveList (SCM wrapped_video_driver,
93                                      SCM vertices,
94                                      SCM indices,
95                                      SCM rest)
96   {
97     SCM v_type = scm_from_utf8_symbol ("standard");
98     SCM p_type = scm_from_utf8_symbol ("triangles");
99
100     scm_c_bind_keyword_arguments ("draw-vertex-primitive-list", rest, (scm_t_keyword_arguments_flags)0,
101                                   scm_from_utf8_keyword ("vertex-type"), &v_type,
102                                   scm_from_utf8_keyword ("primitive-type"), &p_type,
103                                   SCM_UNDEFINED);
104
105     // Build vertex array
106     irr::u32 vertex_count = scm_to_uint32 (scm_length (vertices));
107     irr::video::S3DVertex s3d_vertices [vertex_count];
108     for (int i = 0; i < vertex_count; i++)
109       {
110         irr::video::S3DVertex* vertex = unwrap_vertex3d (scm_list_ref (vertices, scm_from_int (i)));
111         s3d_vertices[i] = irr::video::S3DVertex (vertex->Pos,
112                                                  vertex->Normal,
113                                                  vertex->Color,
114                                                  vertex->TCoords);
115       }
116
117     // Build index array
118     irr::u32 index_count = scm_to_uint32 (scm_length (indices));
119     SCM flat_indices = scm_apply_0 (scm_eval_string (scm_from_utf8_string ("append")),
120                                     indices);
121     int flat_length = scm_to_int (scm_length (flat_indices));
122     irr::u32 c_indices [flat_length];
123     for (int i = 0; i < flat_length; i++)
124       {
125         c_indices[i] = scm_to_uint32 (scm_list_ref (flat_indices, scm_from_int (i)));
126       }
127
128     // Draw vertices
129     irr::video::IVideoDriver* driver = unwrap_video_driver (wrapped_video_driver);
130     driver->drawVertexPrimitiveList (&s3d_vertices[0],
131                                      vertex_count,
132                                      &c_indices[0],
133                                      index_count,
134                                      scm_to_vertex_type (v_type),
135                                      scm_to_primitive_type (p_type),
136                                      irr::video::EIT_32BIT);
137     return SCM_UNSPECIFIED;
138   }
139
140   SCM
141   irr_video_endScene (SCM wrapped_video_driver)
142   {
143     irr::video::IVideoDriver* driver = unwrap_video_driver (wrapped_video_driver);
144     return scm_from_bool (driver->endScene ());
145   }
146
147   SCM
148   irr_video_getFPS (SCM wrapped_video_driver)
149   {
150     irr::video::IVideoDriver* driver = unwrap_video_driver (wrapped_video_driver);
151     return scm_from_int32 (driver->getFPS ());
152   }
153
154   SCM
155   irr_video_getTexture (SCM wrapped_video_driver,
156                         SCM filename)
157   {
158     irr::video::IVideoDriver* driver = unwrap_video_driver (wrapped_video_driver);
159     irr::video::ITexture* texture = driver->getTexture (scm_to_utf8_stringn (filename, NULL));
160     return wrap_texture (texture);
161   }
162
163   SCM
164   irr_video_setMaterial (SCM wrapped_video_driver,
165                          SCM material)
166   {
167     irr::video::IVideoDriver* driver = unwrap_video_driver (wrapped_video_driver);
168     driver->setMaterial (*(unwrap_material (material)));
169     return SCM_UNSPECIFIED;
170   }
171
172   SCM
173   irr_video_setTransform (SCM wrapped_video_driver,
174                           SCM state,
175                           SCM mat)
176   {
177     irr::video::IVideoDriver* driver = unwrap_video_driver (wrapped_video_driver);
178     driver->setTransform (scm_to_transformation_state (state),
179                           scm_to_matrix4 (mat));
180     return SCM_UNSPECIFIED;
181   }
182
183   irr::video::E_TRANSFORMATION_STATE
184   scm_to_transformation_state (SCM transformation_state)
185   {
186     char* state = scm_to_utf8_stringn (scm_symbol_to_string (transformation_state), NULL);
187     if (!strcmp (state, "view"))
188       {
189         return irr::video::ETS_VIEW;
190       }
191     else if (!strcmp (state, "world"))
192       {
193         return irr::video::ETS_WORLD;
194       }
195     else if (!strcmp (state, "projection"))
196       {
197         return irr::video::ETS_PROJECTION;
198       }
199     else if (!strcmp (state, "texture0"))
200       {
201         return irr::video::ETS_TEXTURE_0;
202       }
203     else if (!strcmp (state, "texture1"))
204       {
205         return irr::video::ETS_TEXTURE_1;
206       }
207     else if (!strcmp (state, "texture2"))
208       {
209         return irr::video::ETS_TEXTURE_2;
210       }
211     else if (!strcmp (state, "texture3"))
212       {
213         return irr::video::ETS_TEXTURE_3;
214       }
215     else
216       {
217         scm_error (scm_arg_type_key, NULL, "Wrong transformation state: ~S",
218                    scm_list_1 (transformation_state), scm_list_1 (transformation_state));
219       }
220   }
221
222 }