luapattern.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. * DoRayMe - a quick and dirty Raytracer
  3. * Lua based Pattern header
  4. *
  5. * Created by Manoël Trapier
  6. * Copyright (c) 2020 986-Studio.
  7. *
  8. */
  9. #ifndef DORAYME_LUAPATTERN_H
  10. #define DORAYME_LUAPATTERN_H
  11. #include <pattern.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #ifndef ENABLE_LUA_SUPPORT
  15. #error Cannot use the Lua Pattern generator with no Lua support disabled!
  16. #endif
  17. extern "C" {
  18. #include <lua.h>
  19. }
  20. class LuaPattern : public Pattern
  21. {
  22. private:
  23. lua_State *L;
  24. char funcName[50];
  25. public:
  26. LuaPattern(Colour a, Colour b) : Pattern(a, b), L(nullptr) { };
  27. void setLua(lua_State *L) {
  28. this->L = L;
  29. };
  30. void setLuaFunctionName(const char *name) {
  31. strncpy(this->funcName, name, 50);
  32. }
  33. Colour patternAt(Tuple point)
  34. {
  35. int isnum;
  36. double r, g, b;
  37. lua_getglobal(this->L, this->funcName);
  38. lua_pushnumber(this->L, point.x);
  39. lua_pushnumber(this->L, point.y);
  40. lua_pushnumber(this->L, point.z);
  41. lua_createtable(L, 3, 0);
  42. lua_pushnumber(L, this->a.x);
  43. lua_setfield(L, -2, "r");
  44. lua_pushnumber(L, this->a.y);
  45. lua_setfield(L, -2, "g");
  46. lua_pushnumber(L, this->a.z);
  47. lua_setfield(L, -2, "b");
  48. lua_createtable(L, 3, 0);
  49. lua_pushnumber(L, this->b.x);
  50. lua_setfield(L, -2, "r");
  51. lua_pushnumber(L, this->b.y);
  52. lua_setfield(L, -2, "g");
  53. lua_pushnumber(L, this->b.z);
  54. lua_setfield(L, -2, "b");
  55. if (lua_pcall(this->L, 5, 3, 0) != LUA_OK)
  56. {
  57. printf("Error running the Lua function '%s': %s\n", this->funcName,
  58. lua_tostring(this->L, -1));
  59. return Colour(0, 0, 0);
  60. }
  61. r = lua_tonumberx(this->L, -3, &isnum);
  62. if (!isnum)
  63. {
  64. printf("Error: function '%s' must return numbers\n", this->funcName);
  65. lua_pop(this->L, 1);
  66. return Colour(0, 0, 0);
  67. }
  68. g = lua_tonumberx(this->L, -2, &isnum);
  69. if (!isnum)
  70. {
  71. printf("Error: function '%s' must return numbers\n", this->funcName);
  72. lua_pop(this->L, 1);
  73. return Colour(0, 0, 0);
  74. }
  75. b = lua_tonumberx(this->L, -1, &isnum);
  76. if (!isnum)
  77. {
  78. printf("Error: function '%s' must return numbers\n", this->funcName);
  79. lua_pop(this->L, 1);
  80. return Colour(0, 0, 0);
  81. }
  82. lua_pop(this->L, 1);
  83. return Colour(r, g, b);
  84. }
  85. void dumpMe(FILE *fp) {
  86. fprintf(fp, "\"Type\": \"Lua\",\n");
  87. Pattern::dumpMe(fp);
  88. }
  89. };
  90. #endif /* DORAYME_LUAPATTERN_H */