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