]> git.jsancho.org Git - guile-irrlicht.git/blob - src/material.cpp
8380924fc210249324a254c33bf420eecabd7a1d
[guile-irrlicht.git] / src / material.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 "material.h"
28 #include "material-types.h"
29
30 using namespace irr;
31
32 SCM
33 SMaterial_make (SCM rest)
34 {
35   SCM material_type;
36   SCM ambient_color;
37   SCM diffuse_color;
38   SCM emissive_color;
39   SCM specular_color;
40   SCM shininess;
41   SCM material_type_param;
42   SCM material_type_param_2;
43   SCM thickness;
44   SCM z_buffer;
45   SCM anti_aliasing;
46   SCM color_mask;
47   SCM color_material;
48   SCM blend_operation;
49   SCM polygon_offset_factor;
50   SCM polygon_offset_direction;
51   SCM wireframe;
52   SCM point_cloud;
53   SCM gouraud_shading;
54   SCM lighting;
55   SCM z_write_enable;
56   SCM backface_culling;
57   SCM frontface_culling;
58   SCM fog_enable;
59   SCM normalize_normals;
60   SCM use_mip_maps;
61
62   scm_c_bind_keyword_arguments
63     ("video_SMaterial_make", rest, (scm_t_keyword_arguments_flags)0,
64      scm_from_utf8_keyword ("material-type"), &material_type,
65      scm_from_utf8_keyword ("ambient-color"), &ambient_color,
66      scm_from_utf8_keyword ("diffuse-color"), &diffuse_color,
67      scm_from_utf8_keyword ("emissive-color"), &emissive_color,
68      scm_from_utf8_keyword ("specular-color"), &specular_color,
69      scm_from_utf8_keyword ("shininess"), &shininess,
70      scm_from_utf8_keyword ("material-type-param"), &material_type_param,
71      scm_from_utf8_keyword ("material-type-param-2"), &material_type_param_2,
72      scm_from_utf8_keyword ("thickness"), &thickness,
73      scm_from_utf8_keyword ("z-buffer"), &z_buffer,
74      scm_from_utf8_keyword ("anti-aliasing"), &anti_aliasing,
75      scm_from_utf8_keyword ("color-mask"), &color_mask,
76      scm_from_utf8_keyword ("color-material"), &color_material,
77      scm_from_utf8_keyword ("blend-operation"), &blend_operation,
78      scm_from_utf8_keyword ("polygon-offset-factor"), &polygon_offset_factor,
79      scm_from_utf8_keyword ("polygon-offset-direction"), &polygon_offset_direction,
80      scm_from_utf8_keyword ("wireframe"), &wireframe,
81      scm_from_utf8_keyword ("point-cloud"), &point_cloud,
82      scm_from_utf8_keyword ("gouraud-shading"), &gouraud_shading,
83      scm_from_utf8_keyword ("lighting"), &lighting,
84      scm_from_utf8_keyword ("z-write-enable"), &z_write_enable,
85      scm_from_utf8_keyword ("backface-culling"), &backface_culling,
86      scm_from_utf8_keyword ("frontface-culling"), &frontface_culling,
87      scm_from_utf8_keyword ("fog-enable"), &fog_enable,
88      scm_from_utf8_keyword ("normalize-normals"), &normalize_normals,
89      scm_from_utf8_keyword ("use-mip-maps"), &use_mip_maps,
90      SCM_UNDEFINED);
91
92   video::SMaterial* material = new video::SMaterial ();
93   material->MaterialType = scm_to_material_type(material_type);
94   material->AmbientColor = scm_to_color (ambient_color);
95   material->DiffuseColor = scm_to_color (diffuse_color);
96   material->EmissiveColor = scm_to_color (emissive_color);
97   material->SpecularColor = scm_to_color (specular_color);
98   material->Shininess = scm_to_double (shininess);
99   material->MaterialTypeParam = scm_to_double (material_type_param);
100   material->MaterialTypeParam2 = scm_to_double (material_type_param_2);
101   material->Thickness = scm_to_double (thickness);
102   material->ZBuffer = scm_to_comparison_func (z_buffer);
103   material->AntiAliasing = scm_to_anti_aliasing_mode (anti_aliasing);
104   material->ColorMask = scm_to_color_plane (color_mask);
105   material->ColorMaterial = scm_to_color_material (color_material);
106   material->BlendOperation = scm_to_blend_operation (blend_operation);
107   material->PolygonOffsetFactor = scm_to_uint8 (polygon_offset_factor);
108   material->PolygonOffsetDirection = scm_to_polygon_offset (polygon_offset_direction);
109   material->Wireframe = scm_to_bool (wireframe);
110   material->PointCloud = scm_to_bool (point_cloud);
111   material->GouraudShading = scm_to_bool (gouraud_shading);
112   material->Lighting = scm_to_bool (lighting);
113   material->ZWriteEnable = scm_to_bool (z_write_enable);
114   material->BackfaceCulling = scm_to_bool (backface_culling);
115   material->FrontfaceCulling = scm_to_bool (frontface_culling);
116   material->FogEnable = scm_to_bool (fog_enable);
117   material->NormalizeNormals = scm_to_bool (normalize_normals);
118   material->UseMipMaps = scm_to_bool (use_mip_maps);
119   return scm_from_pointer ((void*) material, NULL);
120 }
121
122 void
123 init_material (void)
124 {
125   DEFINE_GSUBR ("SMaterial_make", 0, 0, 1, SMaterial_make);
126 }
127
128 video::E_ANTI_ALIASING_MODE
129 scm_to_anti_aliasing_mode (SCM anti_aliasing_mode)
130 {
131   char* mode_name = scm_to_utf8_string (scm_symbol_to_string (anti_aliasing_mode));
132   video::E_ANTI_ALIASING_MODE mode;
133
134   if (!strcmp (mode_name, "off"))
135     {
136       mode = video::EAAM_OFF;
137     }
138   else if (!strcmp (mode_name, "simple"))
139     {
140       mode = video::EAAM_SIMPLE;
141     }
142   else if (!strcmp (mode_name, "quality"))
143     {
144       mode = video::EAAM_QUALITY;
145     }
146   else if (!strcmp (mode_name, "line-smooth"))
147     {
148       mode = video::EAAM_LINE_SMOOTH;
149     }
150   else if (!strcmp (mode_name, "point-smooth"))
151     {
152       mode = video::EAAM_POINT_SMOOTH;
153     }
154   else if (!strcmp (mode_name, "full-basic"))
155     {
156       mode = video::EAAM_FULL_BASIC;
157     }
158   else if (!strcmp (mode_name, "alpha-to-coverage"))
159     {
160       mode = video::EAAM_ALPHA_TO_COVERAGE;
161     }
162   else
163     {
164       scm_error (scm_arg_type_key, NULL, "Wrong anti aliasing mode: ~S",
165                  scm_list_1 (anti_aliasing_mode), scm_list_1 (anti_aliasing_mode));
166     }
167
168   free (mode_name);
169   return mode;
170 }
171
172 video::E_BLEND_OPERATION
173 scm_to_blend_operation (SCM blend_operation)
174 {
175   char* operation_name = scm_to_utf8_string (scm_symbol_to_string (blend_operation));
176   video::E_BLEND_OPERATION operation;
177
178   if (!strcmp (operation_name, "none"))
179     {
180       operation = video::EBO_NONE;
181     }
182   else if (!strcmp (operation_name, "add"))
183     {
184       operation = video::EBO_ADD;
185     }
186   else if (!strcmp (operation_name, "subtract"))
187     {
188       operation = video::EBO_SUBTRACT;
189     }
190   else if (!strcmp (operation_name, "rev-subtract"))
191     {
192       operation = video::EBO_REVSUBTRACT;
193     }
194   else if (!strcmp (operation_name, "min"))
195     {
196       operation = video::EBO_MIN;
197     }
198   else if (!strcmp (operation_name, "max"))
199     {
200       operation = video::EBO_MAX;
201     }
202   else if (!strcmp (operation_name, "min-factor"))
203     {
204       operation = video::EBO_MIN_FACTOR;
205     }
206   else if (!strcmp (operation_name, "max-factor"))
207     {
208       operation = video::EBO_MAX_FACTOR;
209     }
210   else if (!strcmp (operation_name, "min-alpha"))
211     {
212       operation = video::EBO_MIN_ALPHA;
213     }
214   else if (!strcmp (operation_name, "max-alpha"))
215     {
216       operation = video::EBO_MAX_ALPHA;
217     }
218   else
219     {
220       scm_error (scm_arg_type_key, NULL, "Wrong blend operation: ~S",
221                  scm_list_1 (blend_operation), scm_list_1 (blend_operation));
222     }
223
224   free (operation_name);
225   return operation;
226 }
227
228 video::E_COLOR_MATERIAL
229 scm_to_color_material (SCM color_material)
230 {
231   char* material_name = scm_to_utf8_string (scm_symbol_to_string (color_material));
232   video::E_COLOR_MATERIAL material;
233
234   if (!strcmp (material_name, "none"))
235     {
236       material = video::ECM_NONE;
237     }
238   else if (!strcmp (material_name, "diffuse"))
239     {
240       material = video::ECM_DIFFUSE;
241     }
242   else if (!strcmp (material_name, "ambient"))
243     {
244       material = video::ECM_AMBIENT;
245     }
246   else if (!strcmp (material_name, "emissive"))
247     {
248       material = video::ECM_EMISSIVE;
249     }
250   else if (!strcmp (material_name, "specular"))
251     {
252       material = video::ECM_SPECULAR;
253     }
254   else if (!strcmp (material_name, "diffuse-and-ambient"))
255     {
256       material = video::ECM_DIFFUSE_AND_AMBIENT;
257     }
258   else
259     {
260       scm_error (scm_arg_type_key, NULL, "Wrong color material: ~S",
261                  scm_list_1 (color_material), scm_list_1 (color_material));
262     }
263
264   free (material_name);
265   return material;
266 }
267
268 video::E_COLOR_PLANE
269 scm_to_color_plane (SCM color_plane)
270 {
271   char* plane_name = scm_to_utf8_string (scm_symbol_to_string (color_plane));
272   video::E_COLOR_PLANE plane;
273
274   if (!strcmp (plane_name, "none"))
275     {
276       plane = video::ECP_NONE;
277     }
278   else if (!strcmp (plane_name, "alpha"))
279     {
280       plane = video::ECP_ALPHA;
281     }
282   else if (!strcmp (plane_name, "red"))
283     {
284       plane = video::ECP_RED;
285     }
286   else if (!strcmp (plane_name, "green"))
287     {
288       plane = video::ECP_GREEN;
289     }
290   else if (!strcmp (plane_name, "blue"))
291     {
292       plane = video::ECP_BLUE;
293     }
294   else if (!strcmp (plane_name, "rgb"))
295     {
296       plane = video::ECP_RGB;
297     }
298   else if (!strcmp (plane_name, "all"))
299     {
300       plane = video::ECP_ALL;
301     }
302   else
303     {
304       scm_error (scm_arg_type_key, NULL, "Wrong color plane: ~S",
305                  scm_list_1 (color_plane), scm_list_1 (color_plane));
306     }
307
308   free (plane_name);
309   return plane;
310 }
311
312 video::E_COMPARISON_FUNC
313 scm_to_comparison_func (SCM comparison_func)
314 {
315   char* func_name = scm_to_utf8_string (scm_symbol_to_string (comparison_func));
316   video::E_COMPARISON_FUNC func;
317
318   if (!strcmp (func_name, "never"))
319     {
320       func = video::ECFN_NEVER;
321     }
322   else if (!strcmp (func_name, "less-equal"))
323     {
324       func = video::ECFN_LESSEQUAL;
325     }
326   else if (!strcmp (func_name, "equal"))
327     {
328       func = video::ECFN_EQUAL;
329     }
330   else if (!strcmp (func_name, "less"))
331     {
332       func = video::ECFN_LESS;
333     }
334   else if (!strcmp (func_name, "not-equal"))
335     {
336       func = video::ECFN_NOTEQUAL;
337     }
338   else if (!strcmp (func_name, "greater-equal"))
339     {
340       func = video::ECFN_GREATEREQUAL;
341     }
342   else if (!strcmp (func_name, "greater"))
343     {
344       func = video::ECFN_GREATER;
345     }
346   else if (!strcmp (func_name, "always"))
347     {
348       func = video::ECFN_ALWAYS;
349     }
350   else
351     {
352       scm_error (scm_arg_type_key, NULL, "Wrong comparison func: ~S",
353                  scm_list_1 (comparison_func), scm_list_1 (comparison_func));
354     }
355
356   free (func_name);
357   return func;
358 }
359
360 video::E_POLYGON_OFFSET
361 scm_to_polygon_offset (SCM polygon_offset)
362 {
363   char* offset_name = scm_to_utf8_string (scm_symbol_to_string (polygon_offset));
364   video::E_POLYGON_OFFSET offset;
365
366   if (!strcmp (offset_name, "back"))
367     {
368       offset = video::EPO_BACK;
369     }
370   else if (!strcmp (offset_name, "front"))
371     {
372       offset = video::EPO_FRONT;
373     }
374   else
375     {
376       scm_error (scm_arg_type_key, NULL, "Wrong polygon offset: ~S",
377                  scm_list_1 (polygon_offset), scm_list_1 (polygon_offset));
378     }
379
380   free (offset_name);
381   return offset;
382 }