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