]> git.jsancho.org Git - guile-irrlicht.git/blob - src/video-driver.cpp
35491116ff13fcc1e039736c8e26a29456128dca
[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 #include "color.h"
25 #include "gsubr.h"
26 #include "matrix4.h"
27 #include "primitive-types.h"
28 #include "rect.h"
29 #include "vertex3d.h"
30 #include "video-driver.h"
31 #include "wrapped.h"
32
33 using namespace irr;
34
35 SCM
36 IVideoDriver_beginScene (SCM video_driver,
37                          SCM back_buffer,
38                          SCM z_buffer,
39                          SCM color,
40                          SCM video_data,
41                          SCM source_rect)
42 {
43   video::IVideoDriver* driver = (video::IVideoDriver*) scm_to_irr_pointer (video_driver);
44
45   // Source rect
46   core::rect<s32>* sourceRectAddress = 0;
47   if (!scm_is_false (source_rect))
48     {
49       core::rect<s32> sourceRect = scm_to_rect_s32 (source_rect);
50       sourceRectAddress = &sourceRect;
51     }
52
53   return scm_from_bool (driver->beginScene (scm_to_bool (back_buffer),
54                                             scm_to_bool (z_buffer),
55                                             scm_to_color (color),
56                                             video::SExposedVideoData (),
57                                             sourceRectAddress));
58 }
59
60 SCM
61 IVideoDriver_drawVertexPrimitiveList (SCM video_driver,
62                                       SCM vertices,
63                                       SCM indices,
64                                       SCM v_type,
65                                       SCM p_type)
66 {
67   // Build vertex array
68   u32 vertex_count = scm_to_uint32 (scm_length (vertices));
69   video::S3DVertex s3d_vertices [vertex_count];
70   for (int i = 0; i < vertex_count; i++)
71     {
72       video::S3DVertex* vertex =
73         (video::S3DVertex*) scm_to_irr_pointer (scm_list_ref (vertices, scm_from_int (i)));
74       s3d_vertices[i] = video::S3DVertex (vertex->Pos,
75                                           vertex->Normal,
76                                           vertex->Color,
77                                           vertex->TCoords);
78     }
79
80   // Build index array
81   u32 index_count = scm_to_uint32 (scm_length (indices));
82   SCM flat_indices = scm_apply_0 (scm_eval_string (scm_from_utf8_string ("append")),
83                                   indices);
84   int flat_length = scm_to_int (scm_length (flat_indices));
85   u32 c_indices [flat_length];
86   for (int i = 0; i < flat_length; i++)
87     {
88       c_indices[i] = scm_to_uint32 (scm_list_ref (flat_indices, scm_from_int (i)));
89     }
90
91   // Draw vertices
92   video::IVideoDriver* driver = (video::IVideoDriver*) scm_to_irr_pointer (video_driver);
93   driver->drawVertexPrimitiveList (&s3d_vertices[0],
94                                    vertex_count,
95                                    &c_indices[0],
96                                    index_count,
97                                    scm_to_vertex_type (v_type),
98                                    scm_to_primitive_type (p_type),
99                                    video::EIT_32BIT);
100   return SCM_UNSPECIFIED;
101 }
102
103 SCM
104 IVideoDriver_endScene (SCM video_driver)
105 {
106   video::IVideoDriver* driver = (video::IVideoDriver*) scm_to_irr_pointer (video_driver);
107   return scm_from_bool (driver->endScene ());
108 }
109
110 SCM
111 IVideoDriver_getFPS (SCM video_driver)
112 {
113   video::IVideoDriver* driver = (video::IVideoDriver*) scm_to_irr_pointer (video_driver);
114   return scm_from_int32 (driver->getFPS ());
115 }
116
117 SCM
118 IVideoDriver_getName (SCM video_driver)
119 {
120   video::IVideoDriver* driver = (video::IVideoDriver*) scm_to_irr_pointer (video_driver);
121   return scm_from_utf32_string ((scm_t_wchar*) driver->getName ());
122 }
123
124 SCM
125 IVideoDriver_getTexture (SCM video_driver,
126                          SCM filename)
127 {
128   char* cfilename = scm_to_utf8_string (filename);
129   video::IVideoDriver* driver = (video::IVideoDriver*) scm_to_irr_pointer (video_driver);
130   video::ITexture* texture = driver->getTexture (cfilename);
131   free (cfilename);
132   return scm_from_pointer ((void*) texture, NULL);
133 }
134
135 SCM
136 IVideoDriver_setMaterial (SCM video_driver,
137                           SCM material)
138 {
139   video::IVideoDriver* driver = (video::IVideoDriver*) scm_to_irr_pointer (video_driver);
140   driver->setMaterial (*((video::SMaterial*) scm_to_irr_pointer (material)));
141   return SCM_UNSPECIFIED;
142 }
143
144 SCM
145 IVideoDriver_setTransform (SCM video_driver,
146                            SCM state,
147                            SCM mat)
148 {
149   video::IVideoDriver* driver = (video::IVideoDriver*) scm_to_irr_pointer (video_driver);
150   driver->setTransform (scm_to_transformation_state (state),
151                         scm_to_matrix4 (mat));
152   return SCM_UNSPECIFIED;
153 }
154
155
156 void
157 init_video_driver (void)
158 {
159   DEFINE_GSUBR ("IVideoDriver_beginScene", 6, 0, 0, IVideoDriver_beginScene);
160   DEFINE_GSUBR ("IVideoDriver_drawVertexPrimitiveList", 5, 0, 1,
161                 IVideoDriver_drawVertexPrimitiveList);
162   DEFINE_GSUBR ("IVideoDriver_endScene", 1, 0, 0, IVideoDriver_endScene);
163   DEFINE_GSUBR ("IVideoDriver_getFPS", 1, 0, 0, IVideoDriver_getFPS);
164   DEFINE_GSUBR ("IVideoDriver_getName", 1, 0, 0, IVideoDriver_getName);
165   DEFINE_GSUBR ("IVideoDriver_getTexture", 2, 0, 0, IVideoDriver_getTexture);
166   DEFINE_GSUBR ("IVideoDriver_setMaterial", 2, 0, 0, IVideoDriver_setMaterial);
167   DEFINE_GSUBR ("IVideoDriver_setTransform", 3, 0, 0, IVideoDriver_setTransform);
168 }
169
170 video::E_TRANSFORMATION_STATE
171 scm_to_transformation_state (SCM transformation_state)
172 {
173   char* state_name = scm_to_utf8_string (scm_symbol_to_string (transformation_state));
174   video::E_TRANSFORMATION_STATE state;
175
176   if (!strcmp (state_name, "view"))
177     {
178       state = video::ETS_VIEW;
179     }
180   else if (!strcmp (state_name, "world"))
181     {
182       state = video::ETS_WORLD;
183     }
184   else if (!strcmp (state_name, "projection"))
185     {
186       state = video::ETS_PROJECTION;
187     }
188   else if (!strcmp (state_name, "texture0"))
189     {
190       state = video::ETS_TEXTURE_0;
191     }
192   else if (!strcmp (state_name, "texture1"))
193     {
194       state = video::ETS_TEXTURE_1;
195     }
196   else if (!strcmp (state_name, "texture2"))
197     {
198       state = video::ETS_TEXTURE_2;
199     }
200   else if (!strcmp (state_name, "texture3"))
201     {
202       state = video::ETS_TEXTURE_3;
203     }
204   else
205     {
206       scm_error (scm_arg_type_key, NULL, "Wrong transformation state: ~S",
207                  scm_list_1 (transformation_state), scm_list_1 (transformation_state));
208     }
209
210   free (state_name);
211   return state;
212 }