Add support for Lua in world, and create the Lua Pattern (pattern can be defined with a lua function)
This commit is contained in:
@@ -17,6 +17,11 @@ if (SHOW_STATS)
|
|||||||
add_compile_options(-DRENDER_STATS)
|
add_compile_options(-DRENDER_STATS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
option(USE_LUA "Enable the use of Lua" ON)
|
||||||
|
if (USE_LUA)
|
||||||
|
add_compile_options(-DENABLE_LUA_SUPPORT)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (ENABLE_COVERAGE AND COVERALLS)
|
if (ENABLE_COVERAGE AND COVERALLS)
|
||||||
message(FATAL_ERROR "You can't enable both ENABLE_COVERAGE and COVERALLS at the same time")
|
message(FATAL_ERROR "You can't enable both ENABLE_COVERAGE and COVERALLS at the same time")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -14,7 +14,13 @@ file(GLOB RAY_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ${CMAKE_CURRENT_SOURCE_D
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/worldbuilder/*.cpp)
|
${CMAKE_CURRENT_SOURCE_DIR}/worldbuilder/*.cpp)
|
||||||
|
|
||||||
target_include_directories(rayonnement PUBLIC include pattern)
|
target_include_directories(rayonnement PUBLIC include pattern)
|
||||||
add_dependencies(rayonnement LuaCore)
|
|
||||||
|
if (USE_LUA)
|
||||||
|
add_dependencies(rayonnement LuaCore)
|
||||||
|
target_link_libraries(rayonnement ${LUA_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(rayonnement PUBLIC include ${LODEPNG_INCLUDE_FOLDER} ${LUA_INCLUDE_DIR})
|
||||||
target_sources(rayonnement PRIVATE ${RAY_HEADERS} ${RAY_SOURCES})
|
target_sources(rayonnement PRIVATE ${RAY_HEADERS} ${RAY_SOURCES})
|
||||||
target_link_libraries(rayonnement LodePNG)
|
target_link_libraries(rayonnement LodePNG)
|
||||||
|
|
||||||
@@ -22,11 +28,14 @@ if (USE_OPENMP)
|
|||||||
target_link_libraries(rayonnement OpenMP::OpenMP_CXX)
|
target_link_libraries(rayonnement OpenMP::OpenMP_CXX)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
# The main executable
|
||||||
add_executable(dorayme main.cpp)
|
add_executable(dorayme main.cpp)
|
||||||
|
|
||||||
add_dependencies(dorayme LuaCore)
|
add_dependencies(dorayme LuaCore)
|
||||||
target_include_directories(rayonnement PUBLIC include ${LODEPNG_INCLUDE_FOLDER} ${LUA_INCLUDE_DIR})
|
|
||||||
target_link_libraries(dorayme rayonnement ${LUA_LIBRARIES})
|
target_link_libraries(dorayme rayonnement ${LUA_LIBRARIES})
|
||||||
|
|
||||||
|
|
||||||
if (COVERALLS)
|
if (COVERALLS)
|
||||||
set(COVERAGE_SRCS ${RAY_HEADERS} ${RAY_SOURCES} ${COVERAGE_SRCS} PARENT_SCOPE)
|
set(COVERAGE_SRCS ${RAY_HEADERS} ${RAY_SOURCES} ${COVERAGE_SRCS} PARENT_SCOPE)
|
||||||
endif()
|
endif()
|
||||||
@@ -16,6 +16,12 @@
|
|||||||
#include <ray.h>
|
#include <ray.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef ENABLE_LUA_SUPPORT
|
||||||
|
extern "C" {
|
||||||
|
#include <lua.h>
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
class World
|
class World
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -29,6 +35,10 @@ private:
|
|||||||
Light* *lightList;
|
Light* *lightList;
|
||||||
Shape* *objectList;
|
Shape* *objectList;
|
||||||
|
|
||||||
|
#ifdef ENABLE_LUA_SUPPORT
|
||||||
|
lua_State *L;
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
World();
|
World();
|
||||||
~World();
|
~World();
|
||||||
|
|||||||
107
source/pattern/luapattern.h
Normal file
107
source/pattern/luapattern.h
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Lua based Pattern header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_LUAPATTERN_H
|
||||||
|
#define DORAYME_LUAPATTERN_H
|
||||||
|
|
||||||
|
#include <pattern.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef ENABLE_LUA_SUPPORT
|
||||||
|
#error Cannot use the Lua Pattern generator with no Lua support disabled!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <lua.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
class LuaPattern : public Pattern
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
lua_State *L;
|
||||||
|
char funcName[50];
|
||||||
|
|
||||||
|
public:
|
||||||
|
LuaPattern(Colour a, Colour b) : Pattern(a, b), L(nullptr) { };
|
||||||
|
|
||||||
|
void setLua(lua_State *L) {
|
||||||
|
this->L = L;
|
||||||
|
};
|
||||||
|
|
||||||
|
void setLuaFunctionName(const char *name) {
|
||||||
|
strncpy(this->funcName, name, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
Colour patternAt(Tuple point)
|
||||||
|
{
|
||||||
|
int isnum;
|
||||||
|
double r, g, b;
|
||||||
|
|
||||||
|
lua_getglobal(this->L, this->funcName);
|
||||||
|
lua_pushnumber(this->L, point.x);
|
||||||
|
lua_pushnumber(this->L, point.y);
|
||||||
|
lua_pushnumber(this->L, point.z);
|
||||||
|
|
||||||
|
lua_createtable(L, 3, 0);
|
||||||
|
lua_pushnumber(L, this->a.x);
|
||||||
|
lua_setfield(L, -2, "r");
|
||||||
|
lua_pushnumber(L, this->a.y);
|
||||||
|
lua_setfield(L, -2, "g");
|
||||||
|
lua_pushnumber(L, this->a.z);
|
||||||
|
lua_setfield(L, -2, "b");
|
||||||
|
|
||||||
|
lua_createtable(L, 3, 0);
|
||||||
|
lua_pushnumber(L, this->b.x);
|
||||||
|
lua_setfield(L, -2, "r");
|
||||||
|
lua_pushnumber(L, this->b.y);
|
||||||
|
lua_setfield(L, -2, "g");
|
||||||
|
lua_pushnumber(L, this->b.z);
|
||||||
|
lua_setfield(L, -2, "b");
|
||||||
|
|
||||||
|
if (lua_pcall(this->L, 5, 3, 0) != LUA_OK)
|
||||||
|
{
|
||||||
|
printf("Error running the Lua function '%s': %s\n", this->funcName,
|
||||||
|
lua_tostring(this->L, -1));
|
||||||
|
return Colour(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = lua_tonumberx(this->L, -3, &isnum);
|
||||||
|
if (!isnum)
|
||||||
|
{
|
||||||
|
printf("Error: function '%s' must return numbers\n", this->funcName);
|
||||||
|
lua_pop(this->L, 1);
|
||||||
|
return Colour(0, 0, 0);
|
||||||
|
}
|
||||||
|
g = lua_tonumberx(this->L, -2, &isnum);
|
||||||
|
if (!isnum)
|
||||||
|
{
|
||||||
|
printf("Error: function '%s' must return numbers\n", this->funcName);
|
||||||
|
lua_pop(this->L, 1);
|
||||||
|
return Colour(0, 0, 0);
|
||||||
|
}
|
||||||
|
b = lua_tonumberx(this->L, -1, &isnum);
|
||||||
|
if (!isnum)
|
||||||
|
{
|
||||||
|
printf("Error: function '%s' must return numbers\n", this->funcName);
|
||||||
|
lua_pop(this->L, 1);
|
||||||
|
return Colour(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(this->L, 1);
|
||||||
|
return Colour(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp) {
|
||||||
|
fprintf(fp, "\"Type\": \"Lua\",\n");
|
||||||
|
Pattern::dumpMe(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_LUAPATTERN_H */
|
||||||
@@ -12,6 +12,14 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef ENABLE_LUA_SUPPORT
|
||||||
|
extern "C" {
|
||||||
|
#include <lua.h>
|
||||||
|
#include <lauxlib.h>
|
||||||
|
#include <lualib.h>
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MIN_ALLOC (2)
|
#define MIN_ALLOC (2)
|
||||||
|
|
||||||
World::World() : objectCount(0), lightCount(0)
|
World::World() : objectCount(0), lightCount(0)
|
||||||
@@ -23,6 +31,11 @@ World::World() : objectCount(0), lightCount(0)
|
|||||||
this->allocatedObjectCount = MIN_ALLOC;
|
this->allocatedObjectCount = MIN_ALLOC;
|
||||||
this->objectList = (Shape **)calloc(sizeof(Shape *), MIN_ALLOC);
|
this->objectList = (Shape **)calloc(sizeof(Shape *), MIN_ALLOC);
|
||||||
this->objectCount = 0;
|
this->objectCount = 0;
|
||||||
|
|
||||||
|
#ifdef ENABLE_LUA_SUPPORT
|
||||||
|
this->L = luaL_newstate(); /* opens Lua */
|
||||||
|
luaL_openlibs(L); /* opens the basic library */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
World::~World()
|
World::~World()
|
||||||
|
|||||||
@@ -19,6 +19,15 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <material.h>
|
#include <material.h>
|
||||||
|
|
||||||
|
#ifdef ENABLE_LUA_SUPPORT
|
||||||
|
extern "C" {
|
||||||
|
#include <lua.h>
|
||||||
|
#include <lauxlib.h>
|
||||||
|
#include <lualib.h>
|
||||||
|
}
|
||||||
|
#include <luapattern.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
Colour black = Colour(0, 0, 0);
|
Colour black = Colour(0, 0, 0);
|
||||||
Colour white = Colour(1, 1, 1);
|
Colour white = Colour(1, 1, 1);
|
||||||
|
|
||||||
@@ -208,4 +217,47 @@ TEST(PatternTest, Checkers_should_repeat_in_z)
|
|||||||
ASSERT_EQ(pattern.patternAt(Point(0, 0, 0)), white);
|
ASSERT_EQ(pattern.patternAt(Point(0, 0, 0)), white);
|
||||||
ASSERT_EQ(pattern.patternAt(Point(0, 0, 0.99)), white);
|
ASSERT_EQ(pattern.patternAt(Point(0, 0, 0.99)), white);
|
||||||
ASSERT_EQ(pattern.patternAt(Point(0, 0, 1.01)), black);
|
ASSERT_EQ(pattern.patternAt(Point(0, 0, 1.01)), black);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_LUA_SUPPORT
|
||||||
|
TEST(PatternTest, Simple_test_of_a_lua_pattern)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
LuaPattern pattern = LuaPattern(white, black);
|
||||||
|
lua_State *L = luaL_newstate();
|
||||||
|
luaL_openlibs(L);
|
||||||
|
|
||||||
|
pattern.setLua(L);
|
||||||
|
|
||||||
|
pattern.setLuaFunctionName("pat");
|
||||||
|
|
||||||
|
error = luaL_loadstring(L, "function pat(x, y, z, a, b)\n"
|
||||||
|
" local v = math.floor(x) + math.floor(y) + math.floor(z)\n"
|
||||||
|
" if (v % 2) == 0 then\n"
|
||||||
|
" return a.r, a.g, a.b\n"
|
||||||
|
" end\n"
|
||||||
|
" return b.r, b.g, b.b\n"
|
||||||
|
"end");
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s\n", lua_tostring(L, -1));
|
||||||
|
lua_pop(L, 1); /* pop error message from the stack */
|
||||||
|
}
|
||||||
|
ASSERT_EQ(error, 0);
|
||||||
|
|
||||||
|
error = lua_pcall(L, 0, 0, 0);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s\n", lua_tostring(L, -1));
|
||||||
|
lua_pop(L, 1); /* pop error message from the stack */
|
||||||
|
}
|
||||||
|
ASSERT_EQ(error, 0);
|
||||||
|
|
||||||
|
ASSERT_EQ(pattern.patternAt(Point(0, 0, 0)), white);
|
||||||
|
ASSERT_EQ(pattern.patternAt(Point(0, 0.99, 0)), white);
|
||||||
|
ASSERT_EQ(pattern.patternAt(Point(0, 1.01, 0)), black);
|
||||||
|
|
||||||
|
lua_close(L);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user